refactor(besadii): Extract logic for posting review comments

Currently besadii only posts comments when builds succeed, but it
might be very useful to also have a link to a build when the build is
started.

This just shuffles code around. The only functional change is that the
`labels` field in the review input is marked as `omitempty`, as this
will not be needed when posting the build start comment.

Change-Id: Id4a43fad8817c9a15da02f01ab2b781d48b46978
Reviewed-on: https://cl.tvl.fyi/c/depot/+/3571
Tested-by: BuildkiteCI
Reviewed-by: lukegb <lukegb@tvl.fyi>
This commit is contained in:
Vincent Ambo 2021-09-18 15:49:39 +03:00 committed by tazjin
parent 9a89446478
commit ae93094ebf

View file

@ -60,6 +60,47 @@ type Build struct {
Env map[string]string `json:"env"` Env map[string]string `json:"env"`
} }
// reviewInput is a struct representing the data submitted to Gerrit
// to post a review on a CL.
//
// https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#review-input
type reviewInput struct {
Message string `json:"message"`
Labels map[string]int `json:"labels,omitempty"`
OmitDuplicateComments bool `json:"omit_duplicate_comments"`
IgnoreDefaultAttentionSetRules bool `json:"ignore_default_attention_set_rules"`
Tag string `json:"tag"`
}
// updateGerrit posts a comment on a Gerrit CL to indicate the current build status.
func updateGerrit(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)
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.Header.Add("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
fmt.Errorf("failed to update CL on Gerrit: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
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)
}
}
// Trigger a build of a given branch & commit on Buildkite // Trigger a build of a given branch & commit on Buildkite
func triggerBuild(log *syslog.Writer, token string, update *refUpdated) error { func triggerBuild(log *syslog.Writer, token string, update *refUpdated) error {
env := make(map[string]string) env := make(map[string]string)
@ -212,16 +253,14 @@ func refUpdatedMain() {
log.Info("triggered sourcegraph index update") log.Info("triggered sourcegraph index update")
} }
// reviewInput is a struct representing the data submitted to Gerrit func gerritPassword() string {
// to post a review on a CL. gerritPassword, err := ioutil.ReadFile("/etc/secrets/buildkite-gerrit")
// if err != nil {
// https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#review-input fmt.Fprintf(os.Stderr, "Gerrit password could not be read: %s", err)
type reviewInput struct { os.Exit(1)
Message string `json:"message"` }
Labels map[string]int `json:"labels"`
OmitDuplicateComments bool `json:"omit_duplicate_comments"` return string(gerritPassword)
IgnoreDefaultAttentionSetRules bool `json:"ignore_default_attention_set_rules"`
Tag string `json:"tag"`
} }
func postCommandMain() { func postCommandMain() {
@ -241,12 +280,6 @@ func postCommandMain() {
return return
} }
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)
}
var verified int var verified int
var verb string var verb string
@ -271,32 +304,7 @@ func postCommandMain() {
Tag: "autogenerated:buildkite~result", Tag: "autogenerated:buildkite~result",
} }
updateGerrit(review, changeId, patchset)
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)
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", string(gerritPassword))
req.Header.Add("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
fmt.Errorf("failed to update CL on Gerrit: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
respBody, _ := ioutil.ReadAll(resp.Body)
fmt.Fprintf(os.Stderr, "received non-success response from Gerrit: %s (%v)", respBody, resp.Status)
} else {
fmt.Printf("Updated CI status on https://cl.tvl.fyi/c/depot/+/%s/%s", changeId, patchset)
}
} }
func main() { func main() {