From e54734aada394a29cfb4ebe7339129b2afc891f6 Mon Sep 17 00:00:00 2001 From: Hongxiang Jiang Date: Mon, 9 Sep 2024 19:45:21 +0000 Subject: [PATCH] internal/task: add insider release flow and determine insider version A local relui screenshot is at https://github.com/golang/vscode-go/issues/3500#issuecomment-2338958845 For golang/vscode-go#3500 Change-Id: I326d8606224e3500478b140dcde1a7e5eb0e3330 Reviewed-on: https://go-review.googlesource.com/c/build/+/611940 Reviewed-by: Dmitri Shuralyov LUCI-TryBot-Result: Go LUCI Reviewed-by: Hyang-Ah Hana Kim Auto-Submit: Hongxiang Jiang --- cmd/relui/main.go | 1 + internal/task/releasevscodego.go | 42 +++++++++++++++++++++- internal/task/releasevscodego_test.go | 52 +++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 1 deletion(-) diff --git a/cmd/relui/main.go b/cmd/relui/main.go index 28119248d8..e088be1cdf 100644 --- a/cmd/relui/main.go +++ b/cmd/relui/main.go @@ -316,6 +316,7 @@ func main() { ApproveAction: relui.ApproveActionDep(dbPool), } dh.RegisterDefinition("Create a vscode-go release candidate", releaseVSCodeGoTasks.NewPrereleaseDefinition()) + dh.RegisterDefinition("Release a vscode-go insider version", releaseVSCodeGoTasks.NewInsiderDefinition()) tagTelemetryTasks := &task.TagTelemetryTasks{ Gerrit: gerritClient, diff --git a/internal/task/releasevscodego.go b/internal/task/releasevscodego.go index fe96fa4cee..e871094168 100644 --- a/internal/task/releasevscodego.go +++ b/internal/task/releasevscodego.go @@ -281,6 +281,40 @@ func (r *ReleaseVSCodeGoTasks) tag(ctx *wf.TaskContext, commit string, release r return nil } +// NewInsiderDefinition create a new workflow definition for vscode-go insider +// version release. +func (r *ReleaseVSCodeGoTasks) NewInsiderDefinition() *wf.Definition { + wd := wf.New(wf.ACL{Groups: []string{groups.ToolsTeam}}) + + _ = wf.Task0(wd, "determine the insider version", r.determineInsiderVersion) + + return wd +} + +// determineInsiderVersion determines the release version for the upcoming +// insider release of vscode-go by examining all existing tags in the repository. +func (r *ReleaseVSCodeGoTasks) determineInsiderVersion(ctx *wf.TaskContext) (releaseVersion, error) { + tags, err := r.Gerrit.ListTags(ctx, "vscode-go") + if err != nil { + return releaseVersion{}, err + } + + // The insider version must be higher than the latest stable version to be + // recognized by the marketplace. + // VSCode automatically updates extensions to the highest available version. + // https://code.visualstudio.com/api/working-with-extensions/publishing-extension#prerelease-extensions + release, _ := latestVersion(tags, isReleaseVersion, isVSCodeGoStableVersion) + major := release.Major + minor := release.Minor + 1 + + insider, _ := latestVersion(tags, isReleaseVersion, isSameMajorMinor(major, minor)) + if insider == (releaseVersion{}) { + return releaseVersion{Major: major, Minor: minor, Patch: 0}, nil + } + insider.Patch += 1 + return insider, nil +} + func isVSCodeGoStableVersion(release releaseVersion, _ string) bool { return release.Minor%2 == 0 } @@ -303,7 +337,7 @@ func isPrereleaseVersion(_ releaseVersion, prerelease string) bool { // isPrereleaseMatchRegex reports whether the pre-release string of the input // version matches the regex expression. -func isPrereleaseMatchRegex(regex string) func(releaseVersion, string)bool { +func isPrereleaseMatchRegex(regex string) func(releaseVersion, string) bool { return func(_ releaseVersion, prerelease string) bool { if prerelease == "" { return false @@ -324,6 +358,12 @@ func isSameReleaseVersion(want releaseVersion) func(releaseVersion, string) bool } } +func isSameMajorMinor(major, minor int) func(releaseVersion, string) bool { + return func(got releaseVersion, _ string) bool { + return got.Major == major && got.Minor == minor + } +} + // latestVersion returns the releaseVersion and the prerelease tag of the latest // version from the provided version strings. // It considers only versions that are valid and match all the filters. diff --git a/internal/task/releasevscodego_test.go b/internal/task/releasevscodego_test.go index d52996f786..cc8bf53884 100644 --- a/internal/task/releasevscodego_test.go +++ b/internal/task/releasevscodego_test.go @@ -357,3 +357,55 @@ func TestVSCodeGoActiveReleaseBranch(t *testing.T) { }) } } + +func TestDetermineInsiderVersion(t *testing.T) { + testcases := []struct { + name string + existingTags []string + want releaseVersion + }{ + { + name: "pick v0.45.0 because there is no other v0.45.X", + existingTags: []string{"v0.44.0", "v0.44.1", "v0.44.2"}, + want: releaseVersion{Major: 0, Minor: 45, Patch: 0}, + }, + { + name: "pick v0.45.3 because there is v0.45.2", + existingTags: []string{"v0.44.0", "v0.44.1", "v0.44.2", "v0.45.2"}, + want: releaseVersion{Major: 0, Minor: 45, Patch: 3}, + }, + { + name: "pick v0.47.4 because there is v0.47.3", + existingTags: []string{"v0.44.0", "v0.45.2", "v0.46.0", "v0.47.3"}, + want: releaseVersion{Major: 0, Minor: 47, Patch: 4}, + }, + } + + for _, tc := range testcases { + t.Run(tc.name, func(t *testing.T) { + vscodego := NewFakeRepo(t, "vscode-go") + commit := vscodego.Commit(map[string]string{ + "go.mod": "module github.com/golang/vscode-go\n", + "go.sum": "\n", + }) + for _, tag := range tc.existingTags { + vscodego.Tag(tag, commit) + } + + gerrit := NewFakeGerrit(t, vscodego) + ctx := &workflow.TaskContext{ + Context: context.Background(), + Logger: &testLogger{t, ""}, + } + + tasks := &ReleaseVSCodeGoTasks{ + Gerrit: gerrit, + } + + got, err := tasks.determineInsiderVersion(ctx) + if err != nil || got != tc.want { + t.Errorf("determineInsiderVersion() = (%v, %v), want (%v, nil)", got, err, tc.want) + } + }) + } +}