about summary refs log tree commit diff
path: root/ops/besadii
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2021-11-29T16·20+0300
committerVincent Ambo <mail@tazj.in>2021-12-02T10·10+0300
commitdcb241098251a80d69557eb172f3b719cc4c9d30 (patch)
tree90c3b46658a5235ac838ae55969d98ed8e3abc4b /ops/besadii
parente48ae26e8e8f82f58b30a232a8ea32accb4a8b82 (diff)
refactor(ops/besadii): Generalise for use with non-TVL URLs r/3136
This makes it possible to use besadii for any TVL-ish setup using
Gerrit and Buildkite, with the same hook functionality as for TVL.

Change-Id: I1144b68d7ec01c4c8e34f7bee4da590f2ff8c53c
Diffstat (limited to 'ops/besadii')
-rw-r--r--ops/besadii/main.go76
1 files changed, 30 insertions, 46 deletions
diff --git a/ops/besadii/main.go b/ops/besadii/main.go
index a5a144efea89..8bb4b34740cd 100644
--- a/ops/besadii/main.go
+++ b/ops/besadii/main.go
@@ -26,7 +26,6 @@ import (
 	"path"
 	"regexp"
 	"strconv"
-	"strings"
 )
 
 // Regular expression to extract change ID out of a URL
@@ -135,18 +134,18 @@ func loadConfig() (*config, error) {
 }
 
 // updateGerrit posts a comment on a Gerrit CL to indicate the current build status.
-func updateGerrit(review reviewInput, changeId, patchset string) {
+func updateGerrit(cfg *config, review reviewInput, changeId, patchset string) {
 	body, _ := json.Marshal(review)
 	reader := ioutil.NopCloser(bytes.NewReader(body))
 
-	url := fmt.Sprintf("https://cl.tvl.fyi/a/changes/%s/revisions/%s/review", changeId, patchset)
+	url := fmt.Sprintf("%s/a/changes/%s/revisions/%s/review", cfg.GerritUrl, changeId, patchset)
 	req, err := http.NewRequest("POST", url, reader)
 	if err != nil {
 		fmt.Fprintf(os.Stderr, "failed to create an HTTP request: %w", err)
 		os.Exit(1)
 	}
 
-	req.SetBasicAuth("buildkite", gerritPassword())
+	req.SetBasicAuth(cfg.GerritUser, cfg.GerritPassword)
 	req.Header.Add("Content-Type", "application/json")
 
 	resp, err := http.DefaultClient.Do(req)
@@ -159,12 +158,12 @@ func updateGerrit(review reviewInput, changeId, patchset string) {
 		respBody, _ := ioutil.ReadAll(resp.Body)
 		fmt.Fprintf(os.Stderr, "received non-success response from Gerrit: %s (%v)", respBody, resp.Status)
 	} else {
-		fmt.Printf("Added CI status comment on https://cl.tvl.fyi/c/depot/+/%s/%s", changeId, patchset)
+		fmt.Printf("Added CI status comment on %s/c/%s/+/%s/%s", cfg.GerritUrl, cfg.Repository, changeId, patchset)
 	}
 }
 
 // Trigger a build of a given branch & commit on Buildkite
-func triggerBuild(log *syslog.Writer, token string, trigger *buildTrigger) error {
+func triggerBuild(cfg *config, log *syslog.Writer, trigger *buildTrigger) error {
 	env := make(map[string]string)
 
 	// Pass information about the originating Gerrit change to the
@@ -172,11 +171,11 @@ func triggerBuild(log *syslog.Writer, token string, trigger *buildTrigger) error
 	//
 	// This information is later used by besadii when invoked by Gerrit
 	// to communicate the build status back to Gerrit.
-	canonBuild := true
+	headBuild := true
 	if trigger.changeId != "" && trigger.patchset != "" {
 		env["GERRIT_CHANGE_ID"] = trigger.changeId
 		env["GERRIT_PATCHSET"] = trigger.patchset
-		canonBuild = false
+		headBuild = false
 	}
 
 	build := Build{
@@ -191,12 +190,13 @@ func triggerBuild(log *syslog.Writer, token string, trigger *buildTrigger) error
 	body, _ := json.Marshal(build)
 	reader := ioutil.NopCloser(bytes.NewReader(body))
 
-	req, err := http.NewRequest("POST", "https://api.buildkite.com/v2/organizations/tvl/pipelines/depot/builds", reader)
+	bkUrl := fmt.Sprintf("https://api.buildkite.com/v2/organizations/%s/pipelines/%s/builds", cfg.BuildkiteOrg, cfg.BuildkiteProject)
+	req, err := http.NewRequest("POST", bkUrl, reader)
 	if err != nil {
 		return fmt.Errorf("failed to create an HTTP request: %w", err)
 	}
 
-	req.Header.Add("Authorization", "Bearer "+token)
+	req.Header.Add("Authorization", "Bearer "+cfg.BuildkiteToken)
 	req.Header.Add("Content-Type", "application/json")
 
 	resp, err := http.DefaultClient.Do(req)
@@ -223,8 +223,8 @@ func triggerBuild(log *syslog.Writer, token string, trigger *buildTrigger) error
 
 	fmt.Fprintf(log, "triggered build for ref %q at commit %q: %s", trigger.ref, trigger.commit, buildResp.WebUrl)
 
-	// For builds of canon there is nothing else to do
-	if canonBuild {
+	// For builds of the HEAD branch there is nothing else to do
+	if headBuild {
 		return nil
 	}
 
@@ -239,7 +239,7 @@ func triggerBuild(log *syslog.Writer, token string, trigger *buildTrigger) error
 		// Do not update the attention set for this comment.
 		IgnoreDefaultAttentionSetRules: true,
 	}
-	updateGerrit(review, trigger.changeId, trigger.patchset)
+	updateGerrit(cfg, review, trigger.changeId, trigger.patchset)
 
 	return nil
 }
@@ -279,7 +279,7 @@ func ignoreFlags(ignore []string) {
 // Extract the buildtrigger struct out of the flags passed to besadii
 // when invoked as Gerrit's 'patchset-created' hook. This hook is used
 // for triggering CI on in-progress CLs.
-func buildTriggerFromPatchsetCreated() (*buildTrigger, error) {
+func buildTriggerFromPatchsetCreated(cfg *config) (*buildTrigger, error) {
 	// Information that needs to be returned
 	var trigger buildTrigger
 
@@ -299,10 +299,10 @@ func buildTriggerFromPatchsetCreated() (*buildTrigger, error) {
 
 	flag.Parse()
 
-	// If the patchset is not for depot@canon then we can ignore it. It
-	// might be some other kind of change (refs/meta/config or
-	// Gerrit-internal), but it is not an error.
-	if trigger.project != "depot" || targetBranch != "canon" {
+	// If the patchset is not for the HEAD branch of the monorepo, then
+	// we can ignore it. It might be some other kind of change
+	// (refs/meta/config or Gerrit-internal), but it is not an error.
+	if trigger.project != cfg.Repository || targetBranch != cfg.Branch {
 		return nil, nil
 	}
 
@@ -323,8 +323,8 @@ func buildTriggerFromPatchsetCreated() (*buildTrigger, error) {
 
 // Extract the buildtrigger struct out of the flags passed to besadii
 // when invoked as Gerrit's 'change-merged' hook. This hook is used
-// for triggering canon builds after change submission.
-func buildTriggerFromChangeMerged() *buildTrigger {
+// for triggering HEAD builds after change submission.
+func buildTriggerFromChangeMerged(cfg *config) *buildTrigger {
 	// Information that needs to be returned
 	var trigger buildTrigger
 
@@ -341,12 +341,13 @@ func buildTriggerFromChangeMerged() *buildTrigger {
 
 	flag.Parse()
 
-	// Skip builds for anything other than depot@canon
-	if trigger.project != "depot" || targetBranch != "canon" {
+	// If the patchset is not for the HEAD branch of the monorepo, then
+	// we can ignore it.
+	if trigger.project != cfg.Repository || targetBranch != cfg.Branch {
 		return nil
 	}
 
-	trigger.ref = "refs/heads/canon"
+	trigger.ref = "refs/heads/" + targetBranch
 
 	return &trigger
 }
@@ -357,14 +358,7 @@ func gerritHookMain(cfg *config, log *syslog.Writer, trigger *buildTrigger) {
 		os.Exit(0)
 	}
 
-	buildkiteTokenBytes, err := ioutil.ReadFile("/etc/secrets/buildkite-besadii")
-	if err != nil {
-		log.Alert(fmt.Sprintf("buildkite token could not be read: %s", err))
-		os.Exit(1)
-	}
-	buildkiteToken := strings.TrimSpace(string(buildkiteTokenBytes))
-
-	err = triggerBuild(log, buildkiteToken, trigger)
+	err := triggerBuild(cfg, log, trigger)
 
 	if err != nil {
 		log.Err(fmt.Sprintf("failed to trigger Buildkite build: %s", err))
@@ -378,17 +372,7 @@ func gerritHookMain(cfg *config, log *syslog.Writer, trigger *buildTrigger) {
 	}
 }
 
-func gerritPassword() string {
-	gerritPassword, err := ioutil.ReadFile("/etc/secrets/buildkite-gerrit")
-	if err != nil {
-		fmt.Fprintf(os.Stderr, "Gerrit password could not be read: %s", err)
-		os.Exit(1)
-	}
-
-	return string(gerritPassword)
-}
-
-func postCommandMain() {
+func postCommandMain(cfg *config) {
 	changeId := os.Getenv("GERRIT_CHANGE_ID")
 	patchset := os.Getenv("GERRIT_PATCHSET")
 
@@ -429,7 +413,7 @@ func postCommandMain() {
 
 		Tag: "autogenerated:buildkite~result",
 	}
-	updateGerrit(review, changeId, patchset)
+	updateGerrit(cfg, review, changeId, patchset)
 }
 
 func main() {
@@ -452,17 +436,17 @@ func main() {
 	}
 
 	if bin == "patchset-created" {
-		trigger, err := buildTriggerFromPatchsetCreated()
+		trigger, err := buildTriggerFromPatchsetCreated(cfg)
 		if err != nil {
 			log.Crit("failed to parse 'patchset-created' invocation from args")
 			os.Exit(1)
 		}
 		gerritHookMain(cfg, log, trigger)
 	} else if bin == "change-merged" {
-		trigger := buildTriggerFromChangeMerged()
+		trigger := buildTriggerFromChangeMerged(cfg)
 		gerritHookMain(cfg, log, trigger)
 	} else if bin == "post-command" {
-		postCommandMain()
+		postCommandMain(cfg)
 	} else {
 		fmt.Fprintf(os.Stderr, "besadii does not know how to be invoked as %q, sorry!", bin)
 		os.Exit(1)