Skip to content

Commit 62e7968

Browse files
committed
feat(dist): auto-update changelog '## Unreleased' section
Teach the release script to update the heading of the '## Unreleased' section in CHANGELOG.md and also add the 'Downloads' link.
1 parent 2faaa97 commit 62e7968

File tree

2 files changed

+80
-2
lines changed

2 files changed

+80
-2
lines changed

dist/release.go

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,13 @@ var Steps []Step = []Step{
5050
Step{
5151
Title: "Update release notes file",
5252
Run: func() {
53-
fmt.Printf("Update the release notes file: docs/CHANGELOG.md\n")
54-
WaitForDone()
53+
changelogPath := "docs/CHANGELOG.md"
54+
if err := UpdateUnreleasedChangelogFile(changelogPath, VersionFileInfo{
55+
VersionNumber: ReleaseVersion,
56+
ReleaseDate: ReleaseDate,
57+
}); err != nil {
58+
Stopf("failed to update changelog file %s: %v", changelogPath, err)
59+
}
5560
},
5661
},
5762

@@ -712,6 +717,40 @@ func UpdateDebianChangelog(changelogFilePath string, versionInfo VersionFileInfo
712717
return nil
713718
}
714719

720+
func UpdateUnreleasedChangelogFile(changelogFilePath string, versionInfo VersionFileInfo) error {
721+
originalData, err := os.ReadFile(changelogFilePath)
722+
if err != nil {
723+
return err
724+
}
725+
726+
newData, err := UpdateUnreleasedChangelog(originalData, versionInfo)
727+
if err != nil {
728+
return err
729+
}
730+
731+
fileMode := fs.FileMode(0644) // Unused, because the file should already exist.
732+
if err := os.WriteFile(changelogFilePath, newData, fileMode); err != nil {
733+
return err
734+
}
735+
736+
return nil
737+
}
738+
739+
func UpdateUnreleasedChangelog(changelog []byte, versionInfo VersionFileInfo) ([]byte, error) {
740+
unreleasedHeadingRegexp := regexp.MustCompile("(?m:^## Unreleased\n)")
741+
newHeading := []byte(fmt.Sprintf(
742+
"## %s (%s)\n\n[Downloads](https://c.quick-lint-js.com/releases/%s/)\n",
743+
versionInfo.VersionNumber,
744+
versionInfo.ReleaseDate.Format("2006-01-02"),
745+
versionInfo.VersionNumber,
746+
))
747+
newChangelog := unreleasedHeadingRegexp.ReplaceAllLiteral(changelog, newHeading)
748+
if bytes.Equal(newChangelog, changelog) {
749+
return nil, fmt.Errorf("could not find '## Unreleased' heading in changelog")
750+
}
751+
return newChangelog, nil
752+
}
753+
715754
func EnsureEmptyDirectory(path string) {
716755
Retry:
717756
err := os.Mkdir(path, 0700)

dist/release_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,45 @@ func TestUpdateDebianChangelog(t *testing.T) {
102102
})
103103
}
104104

105+
func TestUpdateUnreleasedChangelog(t *testing.T) {
106+
t.Run("replaces unreleased heading and adds downlods link", func(t *testing.T) {
107+
losAngeles, err := time.LoadLocation("America/Los_Angeles")
108+
Check(t, err)
109+
110+
newChangelog, err := UpdateUnreleasedChangelog(
111+
[]byte("## Unreleased\n\n## 1.0.0 (2022-01-01)\n"),
112+
VersionFileInfo{
113+
VersionNumber: "2.0.0",
114+
ReleaseDate: time.Date(2022, 2, 8, 16, 56, 37, 0, losAngeles),
115+
},
116+
)
117+
Check(t, err)
118+
AssertStringsEqual(t, string(newChangelog),
119+
"## 2.0.0 (2022-02-08)\n"+
120+
"\n"+
121+
"[Downloads](https://c.quick-lint-js.com/releases/2.0.0/)\n"+
122+
"\n"+
123+
"## 1.0.0 (2022-01-01)\n")
124+
})
125+
126+
t.Run("fails if no unreleased heading", func(t *testing.T) {
127+
losAngeles, err := time.LoadLocation("America/Los_Angeles")
128+
Check(t, err)
129+
130+
_, err = UpdateUnreleasedChangelog(
131+
[]byte("## 1.0.0 (2022-01-01)\n\n"),
132+
VersionFileInfo{
133+
VersionNumber: "2.0.0",
134+
ReleaseDate: time.Date(2022, 2, 8, 16, 56, 37, 0, losAngeles),
135+
},
136+
)
137+
if err == nil {
138+
t.Fatalf("expected error")
139+
}
140+
AssertStringsEqual(t, err.Error(), "could not find '## Unreleased' heading in changelog")
141+
})
142+
}
143+
105144
func TestUpdateReleaseVersions(t *testing.T) {
106145
t.Run("only version number", func(t *testing.T) {
107146
updated, err := UpdateReleaseVersions(UpdateReleaseVersionsOptions{

0 commit comments

Comments
 (0)