зеркало из https://github.com/golang/build.git
internal/task: replace reviewers parameter with release coordinators
- Add a check for release coordinators parameter making sure the all coordinators have gerrit user name and github user name. - The first user of the release coordinators will be assigned to the release tracking issues. - All the release coordinators will be added as reviewers for the auto-generated CLs. A local relui screenshot is at https://github.com/golang/vscode-go/issues/3500#issuecomment-2377704665 For golang/vscode-go#3500 For golang/go#57643 Change-Id: If528ab3c5bbc2d589c7198cffa0211f4e5db478f Reviewed-on: https://go-review.googlesource.com/c/build/+/616195 Reviewed-by: Robert Findley <rfindley@google.com> Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com> Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Родитель
959e7b51fa
Коммит
9fd11d6a45
|
@ -2680,7 +2680,7 @@ func init() {
|
|||
addPerson("Taro Aoki", "aizu.s1230022@gmail.com", "@ktr0731")
|
||||
addPerson("Tarrant", "tarrant@keyneston.com", "@tarrant")
|
||||
addPerson("Taru Karttunen", "taruti@taruti.net", "@taruti")
|
||||
addPerson("Tatiana Bradley", "tatiana@golang.org")
|
||||
addPerson("Tatiana Bradley", "tatiana@golang.org", "@tatianab")
|
||||
addPerson("Tatsuhiro Tsujikawa", "tatsuhiro.t@gmail.com", "@tatsuhiro-t")
|
||||
addPerson("Taufiq Rahman", "taufiqrx8@gmail.com", "@Inconnu08")
|
||||
addPerson("Ted Hahn", "teh@uber.com")
|
||||
|
|
|
@ -288,7 +288,7 @@ func mapCoordinators(users []string, f func(*gophers.Person) string) ([]string,
|
|||
}
|
||||
|
||||
// CheckCoordinators checks that all users are known
|
||||
// and have required information (name, Gerrit email).
|
||||
// and have required information (name, Gerrit email, GitHub user name).
|
||||
func CheckCoordinators(users []string) error {
|
||||
var report strings.Builder
|
||||
for _, user := range users {
|
||||
|
@ -309,9 +309,13 @@ func lookupCoordinator(user string) (*gophers.Person, error) {
|
|||
}
|
||||
if person == nil {
|
||||
return nil, fmt.Errorf("unknown username %q: no @golang or @google account", user)
|
||||
} else if person.Name == "" {
|
||||
}
|
||||
if person.Name == "" {
|
||||
return nil, fmt.Errorf("release coordinator %q is missing a name", person.Gerrit)
|
||||
}
|
||||
if person.GitHub == "" {
|
||||
return nil, fmt.Errorf("release coordinator %q is missing github user name", person.Gerrit)
|
||||
}
|
||||
return person, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -76,9 +76,9 @@ func TestPrivXPatch(t *testing.T) {
|
|||
echo "Resolving deltas: 100% (5/5)"
|
||||
echo "Waiting for private key checker: 1/1 objects left"
|
||||
echo "Processing changes: refs: 1, new: 1, done"
|
||||
echo
|
||||
echo
|
||||
echo "SUCCESS"
|
||||
echo
|
||||
echo
|
||||
echo " https://go-review.googlesource.com/c/net/+/558675 net/mail: remove obsolete comment [NEW]"
|
||||
echo`), 0777); err != nil {
|
||||
t.Fatalf("failed to write git pre-receive hook: %s", err)
|
||||
|
@ -111,7 +111,7 @@ echo`), 0777); err != nil {
|
|||
wd := p.NewDefinition(&TagXReposTasks{Gerrit: &privxClient{}})
|
||||
w, err := workflow.Start(wd, map[string]any{
|
||||
"go-internal CL number": "1234",
|
||||
"Reviewer usernames (optional)": []string{},
|
||||
reviewersParam.Name: []string{},
|
||||
"Repository name": filepath.Base(pubRepo.dir.dir),
|
||||
"Skip post submit result (optional)": true,
|
||||
"CVE": "CVE-2024-1234",
|
||||
|
|
|
@ -19,6 +19,16 @@ import (
|
|||
"golang.org/x/mod/semver"
|
||||
)
|
||||
|
||||
var releaseCoordinatorsParam = wf.ParamDef[[]string]{
|
||||
Name: "Release Coordinator Usernames",
|
||||
ParamType: wf.SliceShort,
|
||||
Doc: `Release Coordinator Usernames is a required list of the coordinators of the release.
|
||||
|
||||
The first user in the list will be assigned to the release tracking issue.
|
||||
All users will be added as reviewers for automatically generated CLs.`,
|
||||
Check: CheckCoordinators,
|
||||
}
|
||||
|
||||
// ReleaseGoplsTasks provides workflow definitions and tasks for releasing gopls.
|
||||
type ReleaseGoplsTasks struct {
|
||||
Github GitHubClientInterface
|
||||
|
@ -41,19 +51,19 @@ func (r *ReleaseGoplsTasks) NewPrereleaseDefinition() *wf.Definition {
|
|||
// bump strategy.
|
||||
// Use with caution.
|
||||
inputVersion := wf.Param(wd, wf.ParamDef[string]{Name: "explicit version (optional)"})
|
||||
reviewers := wf.Param(wd, reviewersParam)
|
||||
coordinators := wf.Param(wd, releaseCoordinatorsParam)
|
||||
|
||||
release := wf.Task2(wd, "determine the release version", r.determineReleaseVersion, inputVersion, versionBumpStrategy)
|
||||
prerelease := wf.Task1(wd, "find the next pre-release version", r.nextPrereleaseVersion, release)
|
||||
approved := wf.Action2(wd, "wait for release coordinator approval", r.approvePrerelease, release, prerelease)
|
||||
|
||||
issue := wf.Task2(wd, "create release git issue", r.findOrCreateGitHubIssue, release, wf.Const(true), wf.After(approved))
|
||||
issue := wf.Task3(wd, "create release git issue", r.findOrCreateGitHubIssue, release, coordinators, wf.Const(true), wf.After(approved))
|
||||
branchCreated := wf.Action1(wd, "create new branch if minor release", r.createBranchIfMinor, release, wf.After(issue))
|
||||
|
||||
configChangeID := wf.Task3(wd, "update branch's codereview.cfg", r.updateCodeReviewConfig, release, reviewers, issue, wf.After(branchCreated))
|
||||
configChangeID := wf.Task3(wd, "update branch's codereview.cfg", r.updateCodeReviewConfig, release, coordinators, issue, wf.After(branchCreated))
|
||||
configCommit := wf.Task1(wd, "await config CL submission", clAwaiter{r.Gerrit}.awaitSubmission, configChangeID)
|
||||
|
||||
dependencyChangeID := wf.Task4(wd, "update gopls' x/tools dependency", r.updateXToolsDependency, release, prerelease, reviewers, issue, wf.After(configCommit))
|
||||
dependencyChangeID := wf.Task4(wd, "update gopls' x/tools dependency", r.updateXToolsDependency, release, prerelease, coordinators, issue, wf.After(configCommit))
|
||||
dependencyCommit := wf.Task1(wd, "await gopls' x/tools dependency CL submission", clAwaiter{r.Gerrit}.awaitSubmission, dependencyChangeID)
|
||||
|
||||
verified := wf.Action1(wd, "verify installing latest gopls using release branch dependency commit", r.verifyGoplsInstallation, dependencyCommit)
|
||||
|
@ -61,7 +71,7 @@ func (r *ReleaseGoplsTasks) NewPrereleaseDefinition() *wf.Definition {
|
|||
prereleaseVerified := wf.Action1(wd, "verify installing latest gopls using release branch pre-release version", r.verifyGoplsInstallation, prereleaseVersion)
|
||||
wf.Action4(wd, "mail announcement", r.mailPrereleaseAnnouncement, release, prereleaseVersion, dependencyCommit, issue, wf.After(prereleaseVerified))
|
||||
|
||||
vscodeGoChanges := wf.Task4(wd, "update gopls version in vscode-go", r.updateVSCodeGoGoplsVersion, reviewers, issue, release, prerelease, wf.After(prereleaseVerified))
|
||||
vscodeGoChanges := wf.Task4(wd, "update gopls version in vscode-go", r.updateVSCodeGoGoplsVersion, coordinators, issue, release, prerelease, wf.After(prereleaseVerified))
|
||||
_ = wf.Task1(wd, "await gopls version update CLs submission in vscode-go", clAwaiter{r.Gerrit}.awaitSubmissions, vscodeGoChanges)
|
||||
|
||||
wf.Output(wd, "version", prereleaseVersion)
|
||||
|
@ -144,7 +154,7 @@ func (r *ReleaseGoplsTasks) approveRelease(ctx *wf.TaskContext, release releaseV
|
|||
// If the release issue exists, return the issue ID.
|
||||
// If 'create' is true and no issue exists, a new one is created.
|
||||
// If 'create' is false and no issue exists, an error is returned.
|
||||
func (r *ReleaseGoplsTasks) findOrCreateGitHubIssue(ctx *wf.TaskContext, release releaseVersion, create bool) (int64, error) {
|
||||
func (r *ReleaseGoplsTasks) findOrCreateGitHubIssue(ctx *wf.TaskContext, release releaseVersion, coordinators []string, create bool) (int64, error) {
|
||||
versionString := release.String()
|
||||
milestoneName := fmt.Sprintf("gopls/%s", versionString)
|
||||
// All milestones and issues resides under go repo.
|
||||
|
@ -186,14 +196,20 @@ func (r *ReleaseGoplsTasks) findOrCreateGitHubIssue(ctx *wf.TaskContext, release
|
|||
- [ ] tag gopls/%s
|
||||
- [ ] (if vX.Y.0 release): update dependencies in master for the next release
|
||||
`, versionString, goplsReleaseBranchName(release), versionString, versionString)
|
||||
// TODO(hxjiang): accept a new parameter release coordinator.
|
||||
assignee := "h9jiang"
|
||||
|
||||
if len(coordinators) == 0 {
|
||||
return 0, fmt.Errorf("the input coordinators slice is empty")
|
||||
}
|
||||
assignee, err := lookupCoordinator(coordinators[0])
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to find the coordinator %q", coordinators[0])
|
||||
}
|
||||
issue, _, err := r.Github.CreateIssue(ctx, "golang", "go", &github.IssueRequest{
|
||||
Title: &title,
|
||||
Body: &content,
|
||||
Title: github.String(title),
|
||||
Body: github.String(content),
|
||||
Labels: &[]string{"gopls", "Tools"},
|
||||
Assignee: &assignee,
|
||||
Milestone: &milestoneID,
|
||||
Assignee: github.String(assignee.GitHub),
|
||||
Milestone: github.Int(milestoneID),
|
||||
})
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to create release tracking issue for %q: %w", versionString, err)
|
||||
|
@ -620,7 +636,7 @@ func (r *ReleaseGoplsTasks) NewReleaseDefinition() *wf.Definition {
|
|||
// bump strategy.
|
||||
// Use with caution.
|
||||
inputVersion := wf.Param(wd, wf.ParamDef[string]{Name: "explicit version (optional)"})
|
||||
reviewers := wf.Param(wd, reviewersParam)
|
||||
coordinators := wf.Param(wd, releaseCoordinatorsParam)
|
||||
|
||||
release := wf.Task2(wd, "determine the release version", r.determineReleaseVersion, inputVersion, versionBumpStrategy)
|
||||
prerelease := wf.Task1(wd, "find the latest pre-release version", r.latestPrerelease, release)
|
||||
|
@ -628,13 +644,13 @@ func (r *ReleaseGoplsTasks) NewReleaseDefinition() *wf.Definition {
|
|||
|
||||
tagged := wf.Action2(wd, "tag the release", r.tagRelease, release, prerelease, wf.After(approved))
|
||||
|
||||
issue := wf.Task2(wd, "find release git issue", r.findOrCreateGitHubIssue, release, wf.Const(false))
|
||||
issue := wf.Task3(wd, "find release git issue", r.findOrCreateGitHubIssue, release, wf.Const([]string{}), wf.Const(false))
|
||||
_ = wf.Action1(wd, "mail announcement", r.mailReleaseAnnouncement, release, wf.After(tagged))
|
||||
|
||||
changeID := wf.Task3(wd, "updating x/tools dependency in master branch in gopls sub dir", r.updateDependencyIfMinor, reviewers, release, issue, wf.After(tagged))
|
||||
changeID := wf.Task3(wd, "updating x/tools dependency in master branch in gopls sub dir", r.updateDependencyIfMinor, coordinators, release, issue, wf.After(tagged))
|
||||
_ = wf.Task1(wd, "await x/tools gopls dependency CL submission in gopls sub dir", clAwaiter{r.Gerrit}.awaitSubmission, changeID)
|
||||
|
||||
vscodeGoChanges := wf.Task4(wd, "update gopls version in vscode-go", r.updateVSCodeGoGoplsVersion, reviewers, issue, release, wf.Const(""), wf.After(tagged))
|
||||
vscodeGoChanges := wf.Task4(wd, "update gopls version in vscode-go", r.updateVSCodeGoGoplsVersion, coordinators, issue, release, wf.Const(""), wf.After(tagged))
|
||||
_ = wf.Task1(wd, "await gopls version update CLs submission in vscode-go", clAwaiter{r.Gerrit}.awaitSubmissions, vscodeGoChanges)
|
||||
|
||||
return wd
|
||||
|
|
|
@ -511,7 +511,7 @@ func TestFindOrCreateReleaseIssue(t *testing.T) {
|
|||
if !ok {
|
||||
t.Fatalf("parseVersion(%q) failed", tc.version)
|
||||
}
|
||||
gotIssue, err := tasks.findOrCreateGitHubIssue(&workflow.TaskContext{Context: ctx, Logger: &testLogger{t, ""}}, release, tc.create)
|
||||
gotIssue, err := tasks.findOrCreateGitHubIssue(&workflow.TaskContext{Context: ctx, Logger: &testLogger{t, ""}}, release, []string{"gobot"}, tc.create)
|
||||
|
||||
if tc.wantErr && err == nil {
|
||||
t.Errorf("createReleaseIssue(%s) should return error but return nil", tc.version)
|
||||
|
@ -825,7 +825,7 @@ esac`, tc.wantVersion)
|
|||
|
||||
t.Run("manual input version: "+tc.name, func(t *testing.T) {
|
||||
runTestWithInput(map[string]any{
|
||||
reviewersParam.Name: []string(nil),
|
||||
releaseCoordinatorsParam.Name: []string{"gobot"},
|
||||
"explicit version (optional)": tc.release.String(),
|
||||
"next version": "use explicit version",
|
||||
})
|
||||
|
@ -836,7 +836,7 @@ esac`, tc.wantVersion)
|
|||
}
|
||||
t.Run("interpret version "+versionBump+" : "+tc.name, func(t *testing.T) {
|
||||
runTestWithInput(map[string]any{
|
||||
reviewersParam.Name: []string(nil),
|
||||
releaseCoordinatorsParam.Name: []string{"gobot"},
|
||||
"explicit version (optional)": "",
|
||||
"next version": versionBump,
|
||||
})
|
||||
|
@ -1317,7 +1317,7 @@ esac
|
|||
}
|
||||
t.Run("manual input version: "+tc.name, func(t *testing.T) {
|
||||
runTestWithInput(map[string]any{
|
||||
reviewersParam.Name: []string(nil),
|
||||
releaseCoordinatorsParam.Name: []string{"gobot"},
|
||||
"explicit version (optional)": tc.release.String(),
|
||||
"next version": "use explicit version",
|
||||
})
|
||||
|
@ -1328,7 +1328,7 @@ esac
|
|||
}
|
||||
t.Run("interpret version "+versionBump+": "+tc.name, func(t *testing.T) {
|
||||
runTestWithInput(map[string]any{
|
||||
reviewersParam.Name: []string(nil),
|
||||
releaseCoordinatorsParam.Name: []string{"gobot"},
|
||||
"explicit version (optional)": "",
|
||||
"next version": versionBump,
|
||||
})
|
||||
|
|
|
@ -142,6 +142,7 @@ func (r *ReleaseVSCodeGoTasks) NewPrereleaseDefinition() *wf.Definition {
|
|||
wd := wf.New(wf.ACL{Groups: []string{groups.ToolsTeam}})
|
||||
|
||||
versionBumpStrategy := wf.Param(wd, nextVersionParam)
|
||||
coordinators := wf.Param(wd, releaseCoordinatorsParam)
|
||||
|
||||
release := wf.Task1(wd, "determine the release version", r.determineReleaseVersion, versionBumpStrategy)
|
||||
prerelease := wf.Task1(wd, "find the next pre-release version", r.nextPrereleaseVersion, release)
|
||||
|
@ -150,7 +151,7 @@ func (r *ReleaseVSCodeGoTasks) NewPrereleaseDefinition() *wf.Definition {
|
|||
|
||||
verified := wf.Action1(wd, "verify the release candidate", r.verifyTestResults, revision, wf.After(approved))
|
||||
|
||||
issue := wf.Task1(wd, "create release milestone and issue", r.createReleaseMilestoneAndIssue, release, wf.After(verified))
|
||||
issue := wf.Task2(wd, "create release milestone and issue", r.createReleaseMilestoneAndIssue, release, coordinators, wf.After(verified))
|
||||
branched := wf.Action2(wd, "create release branch", r.createReleaseBranch, release, prerelease, wf.After(verified))
|
||||
build := wf.Task3(wd, "generate package extension (.vsix) for release candidate", r.generatePackageExtension, release, prerelease, revision, wf.After(verified))
|
||||
|
||||
|
@ -221,7 +222,7 @@ chown -R 1000:1000 .
|
|||
return nil
|
||||
}
|
||||
|
||||
func (r *ReleaseVSCodeGoTasks) createReleaseMilestoneAndIssue(ctx *wf.TaskContext, semv releaseVersion) (int, error) {
|
||||
func (r *ReleaseVSCodeGoTasks) createReleaseMilestoneAndIssue(ctx *wf.TaskContext, semv releaseVersion, coordinators []string) (int, error) {
|
||||
version := fmt.Sprintf("v%v.%v.%v", semv.Major, semv.Minor, semv.Patch)
|
||||
|
||||
// The vscode-go release milestone name matches the release version.
|
||||
|
@ -246,12 +247,18 @@ func (r *ReleaseVSCodeGoTasks) createReleaseMilestoneAndIssue(ctx *wf.TaskContex
|
|||
}
|
||||
}
|
||||
|
||||
content := fmt.Sprintf(vscodeGoReleaseIssueTmplStr, version)
|
||||
if len(coordinators) == 0 {
|
||||
return 0, fmt.Errorf("the input coordinators slice is empty")
|
||||
}
|
||||
assignee, err := lookupCoordinator(coordinators[0])
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to find the coordinator %q", coordinators[0])
|
||||
}
|
||||
issue, _, err := r.GitHub.CreateIssue(ctx, "golang", "vscode-go", &github.IssueRequest{
|
||||
Title: &title,
|
||||
Body: &content,
|
||||
Assignee: github.String("h9jiang"),
|
||||
Milestone: &milestoneID,
|
||||
Title: github.String(title),
|
||||
Body: github.String(fmt.Sprintf(vscodeGoReleaseIssueTmplStr, version)),
|
||||
Assignee: github.String(assignee.GitHub),
|
||||
Milestone: github.Int(milestoneID),
|
||||
})
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to create release tracking issue for %q: %w", version, err)
|
||||
|
|
|
@ -136,7 +136,7 @@ func TestCreateReleaseMilestoneAndIssue(t *testing.T) {
|
|||
if !ok {
|
||||
t.Fatalf("parseVersion(%q) failed", tc.version)
|
||||
}
|
||||
issueNumber, err := tasks.createReleaseMilestoneAndIssue(&workflow.TaskContext{Context: context.Background(), Logger: &testLogger{t, ""}}, release)
|
||||
issueNumber, err := tasks.createReleaseMilestoneAndIssue(&workflow.TaskContext{Context: context.Background(), Logger: &testLogger{t, ""}}, release, []string{"gobot"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ func (x *TagXReposTasks) NewSingleDefinition() *wf.Definition {
|
|||
}
|
||||
|
||||
var reviewersParam = wf.ParamDef[[]string]{
|
||||
Name: "Reviewer usernames (optional)",
|
||||
Name: "Reviewer Gerrit Usernames (optional)",
|
||||
ParamType: wf.SliceShort,
|
||||
Doc: `Send code reviews to these users.`,
|
||||
Example: "heschi",
|
||||
|
|
Загрузка…
Ссылка в новой задаче