fix(release): consume active fragments in stable seals

This commit is contained in:
chichuan committed 2026-08-20 17:07:53 +08:00
1 parent 62d72ad84c
commit 74859b966b
7 files changed
+202 -8

No files matched your search

+46
View File
@@ -305,6 +305,52 @@ func TestChangelogPRContentOnlyAcceptsReleaseFragmentArchival(t *testing.T) {
}
}
func TestReleaseFragmentPolicyAcceptsStablePostBetaArchival(t *testing.T) {
repo := newChangelogGateRepo(t)
changelogGateWrite(t, repo.root, ".changes/1236-stable-followup.md", "---\ncategory: Fixed\n---\n\n- Stable follow-up.\n", 0o644)
repo.commit(t, "add post-beta release fragment")
sealBase := strings.TrimSpace(changelogGateGit(t, repo.root, "rev-parse", "HEAD"))
changelogGateWrite(t, repo.root, "CHANGELOG.md", `# Changelog
## [Unreleased]
## [1.0.1] - 2026-07-17
This release promotes the sealed `+"`v1.0.1-beta.1`"+` contents to stable.
### Changed
- Promote the complete beta release to stable.
### Changes since `+"`v1.0.1-beta.1`"+`
### Fixed
- Stable follow-up.
## [1.0.0] - 2026-07-01
### Added
- Initial release.
`, 0o644)
archiveDir := filepath.Join(repo.root, ".changes", "released", "1.0.1")
if err := os.MkdirAll(archiveDir, 0o755); err != nil {
t.Fatalf("MkdirAll stable archive: %v", err)
}
if err := os.Rename(
filepath.Join(repo.root, ".changes", "1236-stable-followup.md"),
filepath.Join(archiveDir, "1236-stable-followup.md"),
); err != nil {
t.Fatalf("Rename stable release fragment: %v", err)
}
repo.commit(t, "seal stable release notes")
if output, err := repo.runFragmentPolicy(t, sealBase, "HEAD"); err != nil {
t.Fatalf("release fragment policy rejected stable seal: %v\noutput:\n%s", err, output)
}
}
func TestReleaseFragmentPolicyRejectsInvalidActiveFragmentAndWrongArchiveVersion(t *testing.T) {
t.Run("invalid active fragment", func(t *testing.T) {
repo := newChangelogGateRepo(t)
+79
View File
@@ -1895,6 +1895,85 @@ func TestReleasePrepareChangelogRendersAndArchivesPrereleaseFragments(t *testing
}
}
func TestReleasePrepareChangelogRendersAndArchivesStableFragments(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)
releaseCopyFile(t, r.render, filepath.Join(r.root, "scripts", "release", "render-release-fragments.sh"), 0o755)
mustWriteFile(t, filepath.Join(r.root, ".changes", "1236-stable-followup.md"), []byte("---\ncategory: Fixed\n---\n\n- **Stable follow-up** (#1236) — includes a change merged after the beta.\n"), 0o644)
r.commitAndPush(t, "install stable changelog preparation")
cmd := exec.Command(
"sh",
filepath.Join(r.root, "scripts", "release", "prepare-changelog.sh"),
"stable",
"v1.0.1",
"--from-beta",
"v1.0.1-beta.1",
)
cmd.Dir = r.root
cmd.Env = append(os.Environ(), "DWS_RELEASE_DATE=2026-07-11")
output, err := cmd.CombinedOutput()
if err != nil {
t.Fatalf("prepare stable changelog error = %v\noutput:\n%s", err, output)
}
changelog, err := os.ReadFile(filepath.Join(r.root, "CHANGELOG.md"))
if err != nil {
t.Fatalf("ReadFile(CHANGELOG.md) error = %v", err)
}
content := string(changelog)
if !strings.Contains(content, "## [1.0.1] - 2026-07-11") ||
!strings.Contains(content, "promotes the sealed `v1.0.1-beta.1` contents to stable") ||
!strings.Contains(content, "### Changes since `v1.0.1-beta.1`") ||
!strings.Contains(content, "### Fixed") ||
!strings.Contains(content, "Stable follow-up") {
t.Fatalf("prepared stable changelog did not render post-beta fragments:\n%s", changelog)
}
name := "1236-stable-followup.md"
if _, err := os.Stat(filepath.Join(r.root, ".changes", name)); !os.IsNotExist(err) {
t.Fatalf("unconsumed stable release fragment %s still present: %v", name, err)
}
if _, err := os.Stat(filepath.Join(r.root, ".changes", "released", "1.0.1", name)); err != nil {
t.Fatalf("archived stable release fragment %s missing: %v", name, err)
}
}
func TestReleasePrepareChangelogStableWithoutFragmentsKeepsTemplate(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)
releaseCopyFile(t, r.render, filepath.Join(r.root, "scripts", "release", "render-release-fragments.sh"), 0o755)
r.commitAndPush(t, "install stable changelog preparation")
cmd := exec.Command(
"sh",
filepath.Join(r.root, "scripts", "release", "prepare-changelog.sh"),
"stable",
"v1.0.1",
"--from-beta",
"v1.0.1-beta.1",
)
cmd.Dir = r.root
cmd.Env = append(os.Environ(), "DWS_RELEASE_DATE=2026-07-11")
output, err := cmd.CombinedOutput()
if err != nil {
t.Fatalf("prepare stable changelog without fragments error = %v\noutput:\n%s", err, output)
}
changelog, err := os.ReadFile(filepath.Join(r.root, "CHANGELOG.md"))
if err != nil {
t.Fatalf("ReadFile(CHANGELOG.md) error = %v", err)
}
content := string(changelog)
if !strings.Contains(content, "## [1.0.1] - 2026-07-11") ||
!strings.Contains(content, "TODO: summarize the complete user-visible release") ||
strings.Contains(content, "### Changes since") {
t.Fatalf("stable changelog without fragments changed template behavior:\n%s", changelog)
}
if _, err := os.Stat(filepath.Join(r.root, ".changes", "released", "1.0.1")); !os.IsNotExist(err) {
t.Fatalf("stable preparation without fragments created an archive: %v", err)
}
}
func TestReleasePrepareChangelogRejectsInvalidReleaseFragment(t *testing.T) {
r := newReleaseTestRepo(t)
releaseCopyFile(t, r.lib, filepath.Join(r.root, "scripts", "release", "release-lib.sh"), 0o644)