Skip to content

Commit b48717b

Browse files
cmd/relui,internal/task: add workflow for re-syncing go-private master
This is currently a manual process that requires a high-priv grant, a workflow significantly reduces the likelihood of getting this wrong. It also lets us use a cron-like schedule to automate these updates. Updates golang/go#59717 Change-Id: Iff7ce7c37f2ecd9dfee79ee8e80cfb98810011e6 Reviewed-on: https://go-review.googlesource.com/c/build/+/486575 Run-TryBot: Roland Shoemaker <[email protected]> Reviewed-by: Heschi Kreinick <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent 5e3904f commit b48717b

File tree

3 files changed

+99
-0
lines changed

3 files changed

+99
-0
lines changed

cmd/relui/main.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,12 @@ func main() {
245245
}
246246
dh.RegisterDefinition("Tag a new version of x/telemetry/config (if necessary)", tagTelemetryTasks.NewDefinition())
247247

248+
privateSyncTask := &task.PrivateMasterSyncTask{
249+
PrivateGerritURL: "https://team.googlesource.com/golang/go-private",
250+
Ref: "public",
251+
}
252+
dh.RegisterDefinition("Sync go-private master branch with public", privateSyncTask.NewDefinition())
253+
248254
var base *url.URL
249255
if *baseURL != "" {
250256
base, err = url.Parse(*baseURL)

internal/task/sync_private.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright 2023 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package task
6+
7+
import (
8+
"fmt"
9+
10+
wf "golang.org/x/build/internal/workflow"
11+
)
12+
13+
type PrivateMasterSyncTask struct {
14+
PrivateGerritURL string
15+
Ref string
16+
}
17+
18+
func (t *PrivateMasterSyncTask) NewDefinition() *wf.Definition {
19+
wd := wf.New()
20+
// We use a Task, instead of an Action, even though we don't actually want
21+
// to return any result, because nothing depends on the Action, and if we
22+
// use an Action the definition will tell us we don't reference it anywhere
23+
// and say it should be deleted.
24+
synced := wf.Task0(wd, "Sync go-private master to public", func(ctx *wf.TaskContext) (string, error) {
25+
git := &Git{}
26+
repo, err := git.Clone(ctx, t.PrivateGerritURL)
27+
if err != nil {
28+
return "", err
29+
}
30+
31+
// NOTE: we assume this is generally safe in the case of a race between
32+
// submitting a patch and resetting the master branch due to the ordering
33+
// of operations at Gerrit. If the submit wins, we reset the master
34+
// branch, and the submitted commit is orphaned, which is the expected
35+
// behavior anyway. If the reset wins, the submission will either be
36+
// cherry-picked onto the new base, which should either succeed, or fail
37+
// due to a merge conflict, or Gerrit will reject the submission because
38+
// something changed underneath it. Either case seems fine.
39+
if _, err := repo.RunCommand(ctx.Context, "push", "--force", "origin", fmt.Sprintf("origin/%s:refs/heads/master", t.Ref)); err != nil {
40+
return "", err
41+
}
42+
43+
return "finished", nil
44+
})
45+
wf.Output(wd, fmt.Sprintf("Reset master to %s", t.Ref), synced)
46+
return wd
47+
}

internal/task/sync_private_test.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package task
2+
3+
import (
4+
"context"
5+
"strings"
6+
"testing"
7+
"time"
8+
9+
"golang.org/x/build/internal/workflow"
10+
)
11+
12+
func TestSyncPrivate(t *testing.T) {
13+
fakeRepo := NewFakeRepo(t, "fake")
14+
masterCommit := fakeRepo.CommitOnBranch("master", map[string]string{
15+
"hello": "there",
16+
})
17+
fakeRepo.Branch("public", masterCommit)
18+
publicCommit := fakeRepo.CommitOnBranch("public", map[string]string{
19+
"general": "kenobi",
20+
})
21+
22+
sync := &PrivateMasterSyncTask{
23+
PrivateGerritURL: fakeRepo.dir.dir, // kind of wild that this works
24+
Ref: "public",
25+
}
26+
27+
wd := sync.NewDefinition()
28+
w, err := workflow.Start(wd, map[string]any{})
29+
if err != nil {
30+
t.Fatal(err)
31+
}
32+
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
33+
defer cancel()
34+
_, err = w.Run(ctx, &verboseListener{t: t})
35+
if err != nil {
36+
t.Fatal(err)
37+
}
38+
39+
fakeRepo.runGit("switch", "master")
40+
newMasterCommit := strings.TrimSpace(string(fakeRepo.runGit("rev-parse", "HEAD")))
41+
// newMasterCommit := fakeRepo.ReadBranchHead(context.Background(), )
42+
43+
if newMasterCommit != publicCommit {
44+
t.Fatalf("unexpected master commit: got %q, want %q", newMasterCommit, publicCommit)
45+
}
46+
}

0 commit comments

Comments
 (0)