diff options
Diffstat (limited to 'tools/gerrit-hook/buildkite.go')
-rw-r--r-- | tools/gerrit-hook/buildkite.go | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/tools/gerrit-hook/buildkite.go b/tools/gerrit-hook/buildkite.go new file mode 100644 index 0000000..d8723b6 --- /dev/null +++ b/tools/gerrit-hook/buildkite.go @@ -0,0 +1,81 @@ +package main + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io/ioutil" + "log/syslog" + "net/http" + "time" +) + +// https://buildkite.com/docs/apis/rest-api/builds#create-a-Build +type Build struct { + Commit string `json:"commit"` + Branch string `json:"branch"` +} + +type buildResponse struct { + WebUrl string `json:"web_url"` +} + +func triggerBuild(cfg *config, log *syslog.Writer, trigger *buildTrigger) error { + b := Build{ + Commit: trigger.commit, + Branch: trigger.ref, + } + + body, _ := json.Marshal(b) + reader := ioutil.NopCloser(bytes.NewReader(body)) + + bkUrl := fmt.Sprintf("https://api.buildkite.com/v2/organizations/%s/pipelines/%s/builds", cfg.BuildKiteOrganization, trigger.project) + req, err := http.NewRequest("POST", bkUrl, reader) + if err != nil { + return fmt.Errorf("failed to create an HTTP request: %v", err) + } + + req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", cfg.BuildKiteToken)) + req.Header.Add("Content-Type", "application/json") + + // Let's budget this to 10 seconds maximum, this should be more + // than enough, as we're only triggering the build, we're not + // waiting on the status of the build + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + resp, err := http.DefaultClient.Do(req.WithContext(ctx)) + if err != nil { + return fmt.Errorf("failed to send buildKite request: %v", err) + } + defer resp.Body.Close() + + respBody, err := ioutil.ReadAll(resp.Body) + if err != nil { + return fmt.Errorf("failed to parse buildKite response: %v", err) + } + + if resp.StatusCode != http.StatusCreated { + return fmt.Errorf("received a non-success response from buildKite: %s (%v)", respBody, resp.Status) + } + + var buildResp buildResponse + err = json.Unmarshal(respBody, &buildResp) + if err != nil { + return fmt.Errorf("failed to unmarshal build response: %v", err) + } + + // Report the status back to the Gerrit CL so that users can click + // through to the running build. + msg := fmt.Sprintf("started build for patchset #%s on: %s", trigger.patchset, buildResp.WebUrl) + review := reviewInput{ + Message: msg, + OmitDuplicateComments: true, + Tag: "autogenerated:buildkite~trigger", + IgnoreDefaultAttentionSetRules: true, + Notify: "NONE", + } + updateGerrit(cfg, review, trigger.changeId, trigger.patchset) + return nil +} |