From eab155261fc657f315831d97fca33589c9859827 Mon Sep 17 00:00:00 2001 From: Paul Jolly Date: Mon, 25 Sep 2023 06:02:38 +0100 Subject: [PATCH] cmd/cueckoo: do not over-run trybots MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In case we already have a trybot result for the requested change, there is no real point requesting them again, unless in exceptional circumstances or we want to force the run. We can use labels to conditionally trigger the trybots. This short-circuit can be overridden by passing the --force (or -f for short) flag to runtrybot. Otherwise, the trybots are skipped if the revision against which we have requested the trybots is the current revision, and Run-TryBot == +1. Otherwise they are run. Tested against this CL! Signed-off-by: Paul Jolly Change-Id: Ia8ad5b61b6e3754918b73cd0aad39b5818c4fab6 Reviewed-on: https://review.gerrithub.io/c/cue-sh/tools/+/1169892 TryBot-Result: CUEcueckoo Reviewed-by: Daniel Martí --- cmd/cueckoo/cmd/cltrigger.go | 28 +++++++++++++++++++++++++++- cmd/cueckoo/cmd/runtrybot.go | 2 ++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/cmd/cueckoo/cmd/cltrigger.go b/cmd/cueckoo/cmd/cltrigger.go index 4bb778a..2e62a29 100644 --- a/cmd/cueckoo/cmd/cltrigger.go +++ b/cmd/cueckoo/cmd/cltrigger.go @@ -244,7 +244,7 @@ func (c *cltrigger) triggerBuilds(revs []revision) error { func (c *cltrigger) triggerBuild(rev revision) error { in, _, err := c.cfg.gerritClient.Changes.GetChange(rev.changeID, &gerrit.ChangeOptions{ - AdditionalFields: []string{"ALL_REVISIONS"}, + AdditionalFields: []string{"ALL_REVISIONS", "LABELS"}, }) if err != nil { // Note that this may be a "change not found" error when the changeID is @@ -262,6 +262,32 @@ func (c *cltrigger) triggerBuild(rev revision) error { return fmt.Errorf("change %q does not know about revision %q; did you forget to run git codereview mail?", rev.changeID, commit) } + // If we do not have the --force flag, only trigger trybots when we do not + // have a result for the trybots. + // + // Labels are attached to the change itself, not revisions. There is logic + // to reset labels when new revisions are added, logic that removes the + // TryBot-Result when a new patchset is added. + // + // So to be safe, we can only skip the trybots if the revision we requested + // is the current (latest) revision, and the change in question has + // TryBotResult == +1. + isCurrent := rev.revision == in.CurrentRevision + if isCurrent && !flagForce.Bool(c.cmd) { + // Order is significant here; check the request for a trybot first + if tbResult, ok := in.Labels["TryBot-Result"]; ok { + for _, approval := range tbResult.All { + // We are looking for a score of 1. Repo config limits the + // people who can vote on this label, hence we don't care + // who actually voted because it can only have been someone + // with permission to do so. + if approval.Value == 1 { + return nil + } + } + } + } + return c.builder(repositoryDispatchPayload{ CL: in.Number, Patchset: revision.Number, diff --git a/cmd/cueckoo/cmd/runtrybot.go b/cmd/cueckoo/cmd/runtrybot.go index 0f675df..764d26a 100644 --- a/cmd/cueckoo/cmd/runtrybot.go +++ b/cmd/cueckoo/cmd/runtrybot.go @@ -24,6 +24,7 @@ import ( const ( flagChange flagName = "change" flagRunTrybotNoUnity flagName = "nounity" + flagForce flagName = "force" ) // newRuntrybotCmd creates a new runtrybot command @@ -60,6 +61,7 @@ If the --nounity flag is provided, only a trybot run is triggered. } cmd.Flags().Bool(string(flagChange), false, "interpret arguments as change numbers or IDs") cmd.Flags().Bool(string(flagRunTrybotNoUnity), false, "do not simultaenously trigger unity build") + cmd.Flags().BoolP(string(flagForce), string(flagForce[0]), false, "force the trybots to run, ignoring any results") return cmd }