jenkins-cron/v1/jenkins.go
2025-05-09 17:21:06 +08:00

125 lines
2.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"net/url"
"path"
"strings"
"time"
)
type Build struct {
Actions []Action `json:"actions"`
Number interface{} `json:"number"`
URL string `json:"url"`
}
type Action struct {
Class string `json:"_class"`
Parameters []Parameter `json:"parameters,omitempty"`
}
type Parameter struct {
Name string `json:"name"`
Value interface{} `json:"value"`
}
var client = &http.Client{
Timeout: 10 * time.Second,
}
func FetchBuild(cfg *Config, job string) (*Build, error) {
buildID := cfg.Jenkins.Number
api := fmt.Sprintf("%s://%s/job/%s/%s/api/json",
cfg.Jenkins.Schema,
cfg.Jenkins.URL,
job,
buildID,
)
req, err := http.NewRequest("GET", api, nil)
if err != nil {
log.Printf("failed to create GET request %s: %v", job, err)
return nil, err
}
req.SetBasicAuth(cfg.Jenkins.User, cfg.Jenkins.Token)
resp, err := client.Do(req)
if err != nil {
log.Printf("failed to fetch build %s: %v", job, err)
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
log.Printf("failed to fetch build %s: %s", job, resp.Status)
return nil, fmt.Errorf("failed to fetch build: %s", resp.Status)
}
// io限制1m
body, _ := io.ReadAll(io.LimitReader(resp.Body, 1<<20))
var build Build
if err := json.Unmarshal(body, &build); err != nil {
log.Printf("failed to unmarshal build %s: %v", job, err)
return nil, err
}
return &build, nil
}
func GenerateBuildURL(cfg *Config, build *Build) string {
values := url.Values{}
for _, action := range build.Actions {
if action.Class == "hudson.model.ParametersAction" {
for _, param := range action.Parameters {
values.Set(param.Name, fmt.Sprintf("%v", param.Value))
}
}
}
for _, param := range cfg.Jenkins.DefaultParameters {
for k, v := range param {
values.Set(k, fmt.Sprintf("%v", v))
}
}
u, err := url.Parse(build.URL)
if err != nil {
log.Fatalf("failed to parse build URL: %v", err)
}
parts := strings.Split(strings.TrimSuffix(u.Path, "/"), "/")
if len(parts) > 0 {
u.Path = path.Join(parts[:len(parts)-1]...) + "/buildWithParameters"
}
u.RawQuery = values.Encode()
return u.String()
}
func TriggerBuild(cfg *Config, build *Build) error {
url := GenerateBuildURL(cfg, build)
req, err := http.NewRequest("POST", url, nil)
if err != nil {
log.Printf("failed to create POST request: %v", err)
return err
}
req.SetBasicAuth(cfg.Jenkins.User, cfg.Jenkins.Token)
resp, err := client.Do(req)
if err != nil {
log.Printf("failed to trigger build %s: %v", url, err)
return err
}
defer resp.Body.Close()
log.Printf("triggered build %s: %s", url, resp.Status)
return nil
}