From 82bb8f30269a1fb34756d0f4b4da4eab7cbe2cdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BF=AE=E9=9B=A8?= <47820304+PeterGuy326@users.noreply.github.com> Date: Sat, 11 Jul 2026 19:27:00 +0800 Subject: [PATCH] fix(release): preserve unreleased changelog entries (#55) (cherry picked from commit e7989c1bb03ec461c638de89337d175f8ef115e4) --- scripts/release/prepare-changelog.sh | 25 +++++++++++++++---- test/scripts/release_script_test.go | 36 ++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/scripts/release/prepare-changelog.sh b/scripts/release/prepare-changelog.sh index 99f0fb91..0c718fa3 100755 --- a/scripts/release/prepare-changelog.sh +++ b/scripts/release/prepare-changelog.sh @@ -79,14 +79,29 @@ trap cleanup EXIT HUP INT TERM } > "$section" inserted=0 +in_unreleased=0 while IFS= read -r line || [ -n "$line" ]; do + case "$line" in + '## [Unreleased]') + in_unreleased=1 + ;; + '## '*) + if [ "$in_unreleased" -eq 1 ]; then + cat "$section" >> "$output" + printf '\n' >> "$output" + inserted=1 + in_unreleased=0 + fi + ;; + esac printf '%s\n' "$line" >> "$output" - if [ "$line" = '## [Unreleased]' ]; then - printf '\n' >> "$output" - cat "$section" >> "$output" - inserted=1 - fi done < "$CHANGELOG" + +if [ "$in_unreleased" -eq 1 ]; then + printf '\n' >> "$output" + cat "$section" >> "$output" + inserted=1 +fi [ "$inserted" -eq 1 ] || { printf 'CHANGELOG is missing ## [Unreleased]\n' >&2; exit 1; } cp "$output" "$CHANGELOG" diff --git a/test/scripts/release_script_test.go b/test/scripts/release_script_test.go index 50773aff..ab424c80 100644 --- a/test/scripts/release_script_test.go +++ b/test/scripts/release_script_test.go @@ -593,6 +593,42 @@ func TestReleasePrepareChangelogCreatesGuardedTemplate(t *testing.T) { } } +func TestReleasePrepareChangelogKeepsUnreleasedContentAboveNewVersion(t *testing.T) { + r := newReleaseTestRepo(t) + releaseCopyFile(t, r.lib, filepath.Join(r.root, "scripts", "release", "release-lib.sh"), 0o644) + releaseCopyFile(t, r.prepare, filepath.Join(r.root, "scripts", "release", "prepare-changelog.sh"), 0o755) + mustWriteFile(t, filepath.Join(r.root, "CHANGELOG.md"), []byte("# Changelog\n\n## [Unreleased]\n\n### Changed\n\n- Keep this unreleased note.\n\n## [1.0.0] - 2026-07-01\n\n### Changed\n\n- Initial release.\n"), 0o644) + r.commitAndPush(t, "add unreleased changelog note") + + cmd := exec.Command("sh", filepath.Join(r.root, "scripts", "release", "prepare-changelog.sh"), "prerelease", "v1.0.1-beta.1") + cmd.Dir = r.root + cmd.Env = append(os.Environ(), "DWS_RELEASE_DATE=2026-07-11") + if output, err := cmd.CombinedOutput(); err != nil { + t.Fatalf("prepare changelog error = %v\noutput:\n%s", err, output) + } + data, err := os.ReadFile(filepath.Join(r.root, "CHANGELOG.md")) + if err != nil { + t.Fatalf("ReadFile(CHANGELOG.md) error = %v", err) + } + content := string(data) + positions := []int{ + strings.Index(content, "## [Unreleased]"), + strings.Index(content, "- Keep this unreleased note."), + strings.Index(content, "## [1.0.1-beta.1] - 2026-07-11"), + strings.Index(content, "## [1.0.0] - 2026-07-01"), + } + for index, position := range positions { + if position < 0 { + t.Fatalf("prepared changelog is missing expected marker %d:\n%s", index, content) + } + } + for index := 1; index < len(positions); index++ { + if positions[index-1] >= positions[index] { + t.Fatalf("prepared changelog order is invalid: %v\n%s", positions, content) + } + } +} + func TestReleaseMirrorUsesChannelSpecificPointer(t *testing.T) { sourceRoot, err := filepath.Abs(filepath.Join("..", "..")) if err != nil {