From b650beeb8e08f22ae1f21d747504f0a11bd75d95 Mon Sep 17 00:00:00 2001 From: Hongxiang Jiang Date: Tue, 1 Oct 2024 20:23:43 +0000 Subject: [PATCH] internal/task: add new heading for stable minor release in change log - Add a new heading for stable minor release (vX.EVEN.0). - Move the content under "## Unreleased" to the new heading "## vX.EVEN.0". - Insert release dates in form of YYYY-MM-DD. A local relui screenshot is at https://github.com/golang/vscode-go/issues/3500#issuecomment-2386998493 For golang/vscode-go#3500 Change-Id: Id26caff28ecbab9db483fe21412f0ea3af0f6445 Reviewed-on: https://go-review.googlesource.com/c/build/+/617276 LUCI-TryBot-Result: Go LUCI Reviewed-by: Hyang-Ah Hana Kim --- internal/task/releasevscodego.go | 73 ++++++++++++++- internal/task/releasevscodego_test.go | 124 ++++++++++++++++++++++++++ 2 files changed, 195 insertions(+), 2 deletions(-) diff --git a/internal/task/releasevscodego.go b/internal/task/releasevscodego.go index de206ca404..567945188a 100644 --- a/internal/task/releasevscodego.go +++ b/internal/task/releasevscodego.go @@ -15,6 +15,7 @@ import ( "strconv" "strings" "text/template" + "time" "cloud.google.com/go/cloudbuild/apiv1/v2/cloudbuildpb" "github.com/google/go-github/v48/github" @@ -1063,6 +1064,8 @@ func (r *ReleaseVSCodeGoTasks) NewReleaseDefinition() *wf.Definition { wd := wf.New(wf.ACL{Groups: []string{groups.ToolsTeam}}) versionBumpStrategy := wf.Param(wd, nextVersionParam) + reviewers := wf.Param(wd, reviewersParam) + release := wf.Task1(wd, "determine the release version", r.determineReleaseVersion, versionBumpStrategy) prerelease := wf.Task1(wd, "find the latest pre-release version", r.latestPrereleaseVersion, release) @@ -1074,9 +1077,13 @@ func (r *ReleaseVSCodeGoTasks) NewReleaseDefinition() *wf.Definition { build := wf.Task3(wd, "generate package extension (.vsix) from release candidate tag", r.generatePackageExtension, release, wf.Const(""), commit) tagged := wf.Action3(wd, "tag the stable release", r.tag, commit, release, wf.Const(""), wf.After(build)) - released := wf.Action3(wd, "create release note", r.createGitHubReleaseDraft, release, wf.Const(""), build, wf.After(tagged)) - published := wf.Action2(wd, "publish to vscode marketplace", r.publishPackageExtension, release, build) + + changeID := wf.Task2(wd, "update CHANGELOG.md in the master branch", r.addChangeLogHeading, release, reviewers, wf.After(build)) + submitted := wf.Task1(wd, "await config CL submission", clAwaiter{r.Gerrit}.awaitSubmission, changeID) + // Publish only after the CHANGELOG.md update is merged to ensure the change + // log reflects the latest released version. + published := wf.Action2(wd, "publish to vscode marketplace", r.publishPackageExtension, release, build, wf.After(submitted)) wf.Action4(wd, "mail announcement", r.mailAnnouncement, release, wf.Const(""), wf.Const(""), wf.Const(0), wf.After(released), wf.After(published)) return wd @@ -1107,3 +1114,65 @@ func (r *ReleaseVSCodeGoTasks) findVSCodeReleaseCommit(ctx *wf.TaskContext, rele return info.Revision, nil } + +// addChangeLogHeading updates the CHANGELOG.md file in the master branch of the +// vscode-go repository with a new heading for the released version. +// It moves all content from the "Unreleased" section to the new version's +// section, but only for minor releases. +// For more details on changelog format, see: https://keepachangelog.com/en/1.1.0/ +func (r *ReleaseVSCodeGoTasks) addChangeLogHeading(ctx *wf.TaskContext, release releaseVersion, reviewers []string) (string, error) { + if release.Patch != 0 { + ctx.Printf("not creating CL: %s is not a minor release", release) + return "", nil + } + + clTitle := "CHANGELOG.md: add release heading for " + release.String() + + openCL, err := openCL(ctx, r.Gerrit, "vscode-go", "master", clTitle) + if err != nil { + return "", err + } + if openCL != "" { + ctx.Printf("not creating CL: found existing CL %s", openCL) + return openCL, nil + } + + head, err := r.Gerrit.ReadBranchHead(ctx, "vscode-go", "master") + if err != nil { + return "", err + } + + content, err := r.Gerrit.ReadFile(ctx, "vscode-go", head, "CHANGELOG.md") + if err != nil { + return "", err + } + + lines := bytes.Split(content, []byte("\n")) + var output bytes.Buffer + + for i, line := range lines { + output.Write(line) + // Only add a newline if it's not the last line + if i < len(lines)-1 { + output.WriteString("\n") + } + if string(line) == "## Unreleased" { + output.WriteString("\n") + output.WriteString("## " + release.String() + "\n") + output.WriteString("\n") + output.WriteString("Date: " + time.Now().Format(time.DateOnly) + "\n") + } + } + + cl, err := r.Gerrit.CreateAutoSubmitChange(ctx, gerrit.ChangeInput{ + Project: "vscode-go", + Branch: "master", + Subject: fmt.Sprintf("%s\n\nThis is an automated CL which updates the CHANGELOG.md.\n", clTitle), + }, reviewers, map[string]string{"CHANGELOG.md": output.String()}) + if err != nil { + return "", err + } + + ctx.Printf("created auto-submit change %s under branch master in vscode-go repo.", cl) + return cl, nil +} diff --git a/internal/task/releasevscodego_test.go b/internal/task/releasevscodego_test.go index 50d13f8735..5351a798c5 100644 --- a/internal/task/releasevscodego_test.go +++ b/internal/task/releasevscodego_test.go @@ -8,6 +8,7 @@ import ( "context" "fmt" "io" + "regexp" "testing" "github.com/google/go-cmp/cmp" @@ -886,3 +887,126 @@ esac }) } } + +func TestAddChangeLogHeading(t *testing.T) { + changelog := `# Changelog + +All notable changes to this project will be documented in this file. +The format is based on [Keep a Changelog](http://keepachangelog.com/). + +## Unreleased + +CHANGE FOR v0.44.0 + +## v0.42.1 + +CHANGE FOR v0.42.1 +` + testcases := []struct { + name string + release releaseVersion + wantChangeLog string + }{ + { + name: "add v0.44.0 heading", + release: releaseVersion{Major: 0, Minor: 44, Patch: 0}, + wantChangeLog: `# Changelog + +All notable changes to this project will be documented in this file. +The format is based on [Keep a Changelog](http://keepachangelog.com/). + +## Unreleased + +## v0.44.0 + +Date: 2002-01-02 + +CHANGE FOR v0.44.0 + +## v0.42.1 + +CHANGE FOR v0.42.1 +`, + }, + { + name: "add v0.46.0 heading", + release: releaseVersion{Major: 0, Minor: 46, Patch: 0}, + wantChangeLog: `# Changelog + +All notable changes to this project will be documented in this file. +The format is based on [Keep a Changelog](http://keepachangelog.com/). + +## Unreleased + +## v0.46.0 + +Date: 2002-01-02 + +CHANGE FOR v0.44.0 + +## v0.42.1 + +CHANGE FOR v0.42.1 +`, + }, + { + name: "no update for non-minor version", + release: releaseVersion{Major: 0, Minor: 44, Patch: 3}, + wantChangeLog: `# Changelog + +All notable changes to this project will be documented in this file. +The format is based on [Keep a Changelog](http://keepachangelog.com/). + +## Unreleased + +CHANGE FOR v0.44.0 + +## v0.42.1 + +CHANGE FOR v0.42.1 +`, + }, + } + + for _, tc := range testcases { + t.Run(tc.name, func(t *testing.T) { + vscodego := NewFakeRepo(t, "vscode-go") + vscodego.Commit(map[string]string{ + "CHANGELOG.md": changelog, + }) + + gerrit := NewFakeGerrit(t, vscodego) + ctx := &workflow.TaskContext{ + Context: context.Background(), + Logger: &testLogger{t, ""}, + } + + tasks := &ReleaseVSCodeGoTasks{ + CloudBuild: NewFakeCloudBuild(t, gerrit, "", nil), + Gerrit: gerrit, + } + + _, err := tasks.addChangeLogHeading(ctx, tc.release, nil) + if err != nil { + t.Fatal(err) + } + + head, err := gerrit.ReadBranchHead(ctx, "vscode-go", "master") + if err != nil { + t.Fatal(err) + } + + gotFile, err := gerrit.ReadFile(ctx, "vscode-go", head, "CHANGELOG.md") + if err != nil { + t.Fatal(err) + } + + re := regexp.MustCompile(`Date: (.*)\n`) + want := re.ReplaceAllString(tc.wantChangeLog, "\n") + got := re.ReplaceAllString(string(gotFile), "\n") + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("change log content mismatch (-want +got):\n%s", diff) + } + }) + } +}