aboutsummaryrefslogtreecommitdiff
path: root/tools/gerrit-hook
diff options
context:
space:
mode:
Diffstat (limited to 'tools/gerrit-hook')
-rw-r--r--tools/gerrit-hook/README.org12
-rw-r--r--tools/gerrit-hook/buildkite.go139
-rw-r--r--tools/gerrit-hook/default.nix16
-rw-r--r--tools/gerrit-hook/gerrit.go149
-rw-r--r--tools/gerrit-hook/go.mod3
-rw-r--r--tools/gerrit-hook/main.go68
6 files changed, 0 insertions, 387 deletions
diff --git a/tools/gerrit-hook/README.org b/tools/gerrit-hook/README.org
deleted file mode 100644
index d7146d8..0000000
--- a/tools/gerrit-hook/README.org
+++ /dev/null
@@ -1,12 +0,0 @@
-#+TITLE: gerrit-hook
-
-A hook for gerrit.
-
-* Configuring the gerrit user
-First create the account with =rgerrit create-account CI=.
-
-Next we need to generate the HTTP password for the user, this can be done with =gerrit set-account CI --generate-http-password=.
-
-Store the password in the file [[file:~/workspace/world/hosts/tahoe/secrets/gerrit/hooks.age][gerrit/hook.age]]
-* Configuring the buildKite API key
-You can obtain API token by going to this [[https://buildkite.com/user/api-access-tokens][page]]. Store the API token in the same file as the gerrit user.
diff --git a/tools/gerrit-hook/buildkite.go b/tools/gerrit-hook/buildkite.go
deleted file mode 100644
index 07d2cfd..0000000
--- a/tools/gerrit-hook/buildkite.go
+++ /dev/null
@@ -1,139 +0,0 @@
-package main
-
-import (
- "bytes"
- "context"
- "encoding/json"
- "fmt"
- "io/ioutil"
- "log/syslog"
- "net/http"
- "os"
- "strings"
- "time"
-)
-
-// https://buildkite.com/docs/apis/rest-api/builds#create-a-Build
-type Build struct {
- Commit string `json:"commit"`
- Branch string `json:"branch"`
- Env map[string]string `json:"env"`
-}
-
-type buildResponse struct {
- WebUrl string `json:"web_url"`
-}
-
-func triggerBuild(cfg *config, log *syslog.Writer, trigger *buildTrigger) error {
- env := make(map[string]string)
- branch := trigger.ref
-
- if trigger.changeId != "" && trigger.patchset != "" {
- env["GERRIT_CHANGE_ID"] = trigger.changeId
- env["GERRIT_CHANGE_URL"] = trigger.changeUrl
- env["GERRIT_PATCHSET"] = trigger.patchset
-
- branch = fmt.Sprintf("cl/%v", strings.Split(trigger.ref, "/")[3])
- }
-
- b := Build{
- Commit: trigger.commit,
- Branch: branch,
- Env: env,
- }
-
- 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
-}
-
-func postCommand(cfg *config) {
- changeId := os.Getenv("GERRIT_CHANGE_ID")
- patchSet := os.Getenv("GERRIT_PATCHSET")
-
- if changeId == "" || patchSet == "" {
- fmt.Println("nothing to do")
- return
- }
-
- // our build stage has the label :hammer:
- if os.Getenv("BUILDKITE_LABEL") != ":hammer:" {
- return
- }
-
- var vote int
- var verb string
- var notify string
-
- if os.Getenv("BUILDKITE_COMMAND_EXIT_STATUS") == "0" {
- vote = 1
- verb = "passed"
- notify = "NONE"
- } else {
- vote = -1
- verb = "failed"
- notify = "OWNER"
- }
-
- msg := fmt.Sprintf("Build of patchset %s %s: %s", patchSet, verb, os.Getenv("BUILDKITE_BUILD_URL"))
- review := reviewInput{
- Message: msg,
- OmitDuplicateComments: true,
- IgnoreDefaultAttentionSetRules: vote == 1,
- Tag: "autogenerated:buildkite~result",
- Notify: notify,
- Labels: map[string]int{
- "Verified": vote,
- },
- }
-
- updateGerrit(cfg, review, changeId, patchSet)
-}
diff --git a/tools/gerrit-hook/default.nix b/tools/gerrit-hook/default.nix
deleted file mode 100644
index c0667ae..0000000
--- a/tools/gerrit-hook/default.nix
+++ /dev/null
@@ -1,16 +0,0 @@
-{ pkgs, ... }:
-
-pkgs.buildGoModule rec {
- name = "gerrit-hook";
- src = ./.;
- subPackages = [ "." ];
- vendorSha256 = null;
-
- meta = with pkgs.lib; {
- description = "hooks for gerrit";
- homepage = "https://golang.fcuny.net";
- license = licenses.mit;
- platforms = platforms.linux;
- maintainers = [ ];
- };
-}
diff --git a/tools/gerrit-hook/gerrit.go b/tools/gerrit-hook/gerrit.go
deleted file mode 100644
index 4854427..0000000
--- a/tools/gerrit-hook/gerrit.go
+++ /dev/null
@@ -1,149 +0,0 @@
-package main
-
-import (
- "bytes"
- "context"
- "encoding/json"
- "flag"
- "fmt"
- "io/ioutil"
- "log"
- "log/syslog"
- "net/http"
- "os"
- "regexp"
- "strconv"
- "strings"
- "time"
-)
-
-// Regular expression to extract change ID out of a URL
-var changeIdRegexp = regexp.MustCompile(`^.*/(\d+)$`)
-
-func gerritHookMain(cfg *config, log *syslog.Writer, trigger *buildTrigger) {
- if trigger == nil {
- os.Exit(0)
- }
-
- err := triggerBuild(cfg, log, trigger)
- if err != nil {
- log.Err(fmt.Sprintf("failed to trigger Buildkite build: %s", err))
- os.Exit(1)
- }
-}
-
-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"`
- Notify string `json:"notify,omitempty"`
-}
-
-type buildTrigger struct {
- project string
- change string
- kind string
- changeUrl string
- changeOwner string
- changeOwnerUserName string
- branch string
- topic string
- uploader string
- uploaderUserName string
- commit string
- patchset string
- changeId string
- ref string
-}
-
-// https://gerrit.googlesource.com/plugins/hooks/+/HEAD/src/main/resources/Documentation/hooks.md#patchset_created
-func triggerForPatchsetCreated() (*buildTrigger, error) {
- var trigger buildTrigger
-
- flag.StringVar(&trigger.project, "project", "", "Gerrit project")
- flag.StringVar(&trigger.change, "change", "", "Gerrit change")
- flag.StringVar(&trigger.kind, "kind", "", "Gerrit kind")
- flag.StringVar(&trigger.changeUrl, "change-url", "", "Gerrit URL for the change")
- flag.StringVar(&trigger.changeOwner, "change-owner", "", "Gerrit owner")
- flag.StringVar(&trigger.changeOwnerUserName, "change-owner-username", "", "Gerrit username")
- flag.StringVar(&trigger.branch, "branch", "", "name of the branch")
- flag.StringVar(&trigger.topic, "topic", "", "name of the topic")
- flag.StringVar(&trigger.uploader, "uploader", "", "name ofthe uploader")
- flag.StringVar(&trigger.uploaderUserName, "uploader-username", "", "")
- flag.StringVar(&trigger.commit, "commit", "", "")
- flag.StringVar(&trigger.patchset, "patchset", "", "")
-
- flag.Parse()
-
- // if the name of the repository has dot in it's name, we
- // replace it with the string `-dot-'.
- trigger.project = strings.Replace(trigger.project, ".", "-dot-", -1)
-
- // if the name of the targetted branch is not `main', we don't
- // care about running the tests.
- if trigger.branch != "main" {
- return nil, nil
- }
-
- // We only care about patchset that are actually modifying the
- // code. See
- // https://gerrit-review.googlesource.com/Documentation/config-labels.html
- if trigger.kind == "NO_CODE_CHANGE" || trigger.kind == "NO_CHANGE" {
- return nil, nil
- }
-
- // extract the changeId from the URL
- matches := changeIdRegexp.FindStringSubmatch(trigger.changeUrl)
- trigger.changeId = matches[1]
-
- // build the ref
- changeId, _ := strconv.Atoi(trigger.changeId)
- trigger.ref = fmt.Sprintf(
- "refs/changes/%02d/%s/%s",
- changeId%100, trigger.changeId, trigger.patchset,
- )
-
- return &trigger, nil
-}
-
-// after triggering a build with buildKite, we update gerrit to add a
-// comment that links to the build.
-func updateGerrit(cfg *config, review reviewInput, changeId string, patchSet string) {
- body, err := json.Marshal(review)
- if err != nil {
- log.Fatal(fmt.Sprintf("failed to marshal gerrit update: %v", err))
- os.Exit(1)
- }
-
- reader := ioutil.NopCloser(bytes.NewReader(body))
- 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: %v", err)
- os.Exit(1)
- }
-
- req.SetBasicAuth(cfg.GerritUser, cfg.GerritPassword)
- req.Header.Add("Content-Type", "application/json")
-
- // Let's budget this to 10 seconds maximum, this should be more
- // than enough to add a comment to gerrit.
- ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
- defer cancel()
-
- resp, err := http.DefaultClient.Do(req.WithContext(ctx))
- if err != nil {
- fmt.Fprintf(os.Stderr, "failed to send gerrit request: %v", err)
- os.Exit(1)
- }
- defer resp.Body.Close()
-
- if resp.StatusCode != http.StatusOK {
- respBody, _ := ioutil.ReadAll(resp.Body)
- fmt.Fprintf(os.Stderr, "failed to update gerrit: %s: %s ", respBody, resp.Status)
- } else {
- fmt.Printf("added link to CI build to %s", patchSet)
- }
-}
diff --git a/tools/gerrit-hook/go.mod b/tools/gerrit-hook/go.mod
deleted file mode 100644
index 98968da..0000000
--- a/tools/gerrit-hook/go.mod
+++ /dev/null
@@ -1,3 +0,0 @@
-module golang.fcuny.net/gerrit-hook
-
-go 1.16
diff --git a/tools/gerrit-hook/main.go b/tools/gerrit-hook/main.go
deleted file mode 100644
index ccd2ad6..0000000
--- a/tools/gerrit-hook/main.go
+++ /dev/null
@@ -1,68 +0,0 @@
-package main
-
-import (
- "encoding/json"
- "fmt"
- "io/ioutil"
- "log/syslog"
- "os"
- "path"
-)
-
-// config represents the configuration for the gerrit hook
-type config struct {
- GerritUrl string `json:"gerritUrl"`
- GerritUser string `json:"gerritUser"`
- GerritPassword string `json:"gerritPassword"`
- BuildKiteToken string `json:"buildKiteToken"`
- BuildKiteOrganization string `json:"buildKiteOrganization"`
-}
-
-func loadConfig() (*config, error) {
- configPath := "/var/run/agenix/gerrit/hooks"
-
- configJson, err := ioutil.ReadFile(configPath)
- if err != nil {
- return nil, fmt.Errorf("failed to read configuration file %s: %v", configPath, err)
- }
-
- var cfg config
- err = json.Unmarshal(configJson, &cfg)
- if err != nil {
- return nil, fmt.Errorf("failed to unmarshall configuration: %v", err)
- }
-
- return &cfg, nil
-}
-
-func main() {
- log, err := syslog.New(syslog.LOG_INFO|syslog.LOG_USER, "gerrit-hook")
- if err != nil {
- fmt.Fprintf(os.Stderr, "failed to open syslog: %s\n", err)
- os.Exit(1)
- }
-
- log.Info(fmt.Sprintf("`gerrit-hook' called with arguments: %v\n", os.Args))
-
- cmd := path.Base(os.Args[0])
-
- cfg, err := loadConfig()
- if err != nil {
- os.Exit(1)
- }
-
- switch cmd {
- case "patchset-created":
- trigger, err := triggerForPatchsetCreated()
- if err != nil {
- log.Crit(fmt.Sprintf("failed to create a trigger: %s", err))
- os.Exit(1)
- }
- gerritHookMain(cfg, log, trigger)
- case "post-command":
- postCommand(cfg)
- default:
- log.Info(fmt.Sprintf("`%s' is not a supported command", cmd))
- os.Exit(1)
- }
-}