зеркало из https://github.com/golang/build.git
internal/task: create the branch for the first rc in minor release
A local relui screenshot is at https://github.com/golang/vscode-go/issues/3500#issuecomment-2313610047 For golang/vscode-go#3500 Change-Id: Ie6b5650eef8f84d1fe7264e35894f80043cad109 Reviewed-on: https://go-review.googlesource.com/c/build/+/608817 Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Auto-Submit: Hongxiang Jiang <hxjiang@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Родитель
e049c5c65c
Коммит
a15ffe2c8f
|
@ -220,9 +220,14 @@ func (g *FakeGerrit) ReadBranchHead(ctx context.Context, project, branch string)
|
|||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// TODO: If the branch doesn't exist, return an error matching gerrit.ErrResourceNotExist.
|
||||
out, err := repo.dir.RunCommand(ctx, "rev-parse", "refs/heads/"+branch)
|
||||
if err != nil {
|
||||
// TODO(hxjiang): switch to git show-ref --exists refs/heads/branch after
|
||||
// upgrade git to 2.43.0.
|
||||
// https://git-scm.com/docs/git-show-ref/2.43.0#Documentation/git-show-ref.txt---exists
|
||||
if strings.Contains(err.Error(), "unknown revision or path not in the working tree") {
|
||||
return "", gerrit.ErrResourceNotExist
|
||||
}
|
||||
// Returns empty string if the error is nil to align the same behavior with
|
||||
// the real Gerrit client.
|
||||
return "", err
|
||||
|
|
|
@ -551,6 +551,8 @@ func parseSemver(v string) (_ semversion, ok bool) {
|
|||
return parsed, ok
|
||||
}
|
||||
|
||||
// prereleaseVersion extracts the integer component from a pre-release version
|
||||
// string in the format "${STRING}.${INT}".
|
||||
func (s *semversion) prereleaseVersion() (int, error) {
|
||||
parts := strings.Split(s.Pre, ".")
|
||||
if len(parts) == 1 {
|
||||
|
|
|
@ -6,11 +6,13 @@ package task
|
|||
|
||||
import (
|
||||
_ "embed"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/google/go-github/v48/github"
|
||||
"golang.org/x/build/gerrit"
|
||||
"golang.org/x/build/internal/relui/groups"
|
||||
"golang.org/x/build/internal/workflow"
|
||||
wf "golang.org/x/build/internal/workflow"
|
||||
|
@ -130,6 +132,7 @@ func (r *ReleaseVSCodeGoTasks) NewPrereleaseDefinition() *wf.Definition {
|
|||
approved := wf.Action1(wd, "await release coordinator's approval", r.approveVersion, semv)
|
||||
|
||||
_ = wf.Task1(wd, "create release milestone and issue", r.createReleaseMilestoneAndIssue, semv, wf.After(approved))
|
||||
_ = wf.Action1(wd, "create release branch", r.createReleaseBranch, semv, wf.After(approved))
|
||||
|
||||
return wd
|
||||
}
|
||||
|
@ -173,6 +176,52 @@ func (r *ReleaseVSCodeGoTasks) createReleaseMilestoneAndIssue(ctx *wf.TaskContex
|
|||
return *issue.Number, nil
|
||||
}
|
||||
|
||||
// createReleaseBranch creates corresponding release branch only for the initial
|
||||
// release candidate of a minor version.
|
||||
func (r *ReleaseVSCodeGoTasks) createReleaseBranch(ctx *wf.TaskContext, semv semversion) error {
|
||||
branch := fmt.Sprintf("release-v%v.%v", semv.Major, semv.Minor)
|
||||
releaseHead, err := r.Gerrit.ReadBranchHead(ctx, "vscode-go", branch)
|
||||
|
||||
if err == nil {
|
||||
ctx.Printf("Found the release branch %q with head pointing to %s\n", branch, releaseHead)
|
||||
return nil
|
||||
}
|
||||
|
||||
if !errors.Is(err, gerrit.ErrResourceNotExist) {
|
||||
return fmt.Errorf("failed to read the release branch: %w", err)
|
||||
}
|
||||
|
||||
// Require vscode release branch existence if this is a non-minor release.
|
||||
if semv.Patch != 0 {
|
||||
return fmt.Errorf("release branch is required for patch releases: %w", err)
|
||||
}
|
||||
|
||||
rc, err := semv.prereleaseVersion()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Require vscode release branch existence if this is not the first rc in
|
||||
// a minor release.
|
||||
if rc != 1 {
|
||||
return fmt.Errorf("release branch is required for non-initial release candidates: %w", err)
|
||||
}
|
||||
|
||||
// Create the release branch using the revision from the head of master branch.
|
||||
head, err := r.Gerrit.ReadBranchHead(ctx, "vscode-go", "master")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx.DisableRetries() // Beyond this point we want retries to be done manually, not automatically.
|
||||
_, err = r.Gerrit.CreateBranch(ctx, "vscode-go", branch, gerrit.BranchInput{Revision: head})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx.Printf("Created branch %q at revision %s.\n", branch, head)
|
||||
return nil
|
||||
}
|
||||
|
||||
// nextPrereleaseVersion determines the next pre-release version for the
|
||||
// upcoming stable release of vscode-go by examining all existing tags in the
|
||||
// repository.
|
||||
|
|
|
@ -6,6 +6,7 @@ package task
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-github/v48/github"
|
||||
|
@ -79,6 +80,83 @@ func TestCreateReleaseMilestoneAndIssue(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestCreateReleaseBranch(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
testcases := []struct {
|
||||
name string
|
||||
version string
|
||||
existingBranch bool
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "nil if the release branch does not exist for first rc in a minor release",
|
||||
version: "v0.44.0-rc.1",
|
||||
existingBranch: false,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "nil if the release branch already exist for non-initial rc in a minor release",
|
||||
version: "v0.44.0-rc.4",
|
||||
existingBranch: true,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "fail if the release branch does not exist for non-initial rc in a minor release",
|
||||
version: "v0.44.0-rc.4",
|
||||
existingBranch: false,
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "nil if the release branch already exist for a patch version",
|
||||
version: "v0.44.3-rc.3",
|
||||
existingBranch: true,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "fail if the release branch does not exist for a patch version",
|
||||
version: "v0.44.3-rc.3",
|
||||
existingBranch: false,
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
semv, ok := parseSemver(tc.version)
|
||||
if !ok {
|
||||
t.Fatalf("failed to parse the want version: %q", tc.version)
|
||||
}
|
||||
|
||||
vscodego := NewFakeRepo(t, "vscode-go")
|
||||
commit := vscodego.Commit(map[string]string{
|
||||
"go.mod": "module github.com/golang/vscode-go\n",
|
||||
"go.sum": "\n",
|
||||
})
|
||||
if tc.existingBranch {
|
||||
vscodego.Branch(fmt.Sprintf("release-v%v.%v", semv.Major, semv.Minor), commit)
|
||||
}
|
||||
|
||||
gerrit := NewFakeGerrit(t, vscodego)
|
||||
tasks := &ReleaseVSCodeGoTasks{
|
||||
Gerrit: gerrit,
|
||||
}
|
||||
|
||||
err := tasks.createReleaseBranch(&workflow.TaskContext{Context: ctx, Logger: &testLogger{t, ""}}, semv)
|
||||
if tc.wantErr && err == nil {
|
||||
t.Errorf("createReleaseBranch(%q) should return error but return nil", tc.version)
|
||||
} else if !tc.wantErr && err != nil {
|
||||
t.Errorf("createReleaseBranch(%q) should return nil but return err: %v", tc.version, err)
|
||||
}
|
||||
|
||||
if !tc.wantErr {
|
||||
if _, err := gerrit.ReadBranchHead(ctx, "vscode-go", fmt.Sprintf("release-v%v.%v", semv.Major, semv.Minor)); err != nil {
|
||||
t.Errorf("createReleaseBranch(%q) should ensure the release branch creation: %v", tc.version, err)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNextPrereleaseVersion(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
|
Загрузка…
Ссылка в новой задаче