about summary refs log tree commit diff
path: root/tools/gerrit-hook/buildkite.go
diff options
context:
space:
mode:
Diffstat (limited to 'tools/gerrit-hook/buildkite.go')
-rw-r--r--tools/gerrit-hook/buildkite.go81
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
+}