diff --git a/scripts/render-github-release-notes.mjs b/scripts/render-github-release-notes.mjs index 85f25bd019bc..71736f035063 100644 --- a/scripts/render-github-release-notes.mjs +++ b/scripts/render-github-release-notes.mjs @@ -230,7 +230,27 @@ function compactReleaseNotes(section, repository, tag) { ].join("\n"); } +export function dedicatedSectionVersionForTag(tag) { + // Correction (vX-N) and alpha tags may carry their own exact changelog + // heading; beta and stable bodies must come from the stable base section. + const taggedVersion = tag.replace(/^v/u, ""); + if (/-beta\.[1-9][0-9]*$/u.test(taggedVersion)) { + return undefined; + } + return /-(?:alpha\.)?[1-9][0-9]*$/u.test(taggedVersion) ? taggedVersion : undefined; +} + export function releaseNotesSectionForTag(changelog, version, tag) { + // Alpha and correction tags prefer their own exact heading when the + // changelog carries one; otherwise they fall back to the base version. + const dedicatedVersion = dedicatedSectionVersionForTag(tag); + if (dedicatedVersion && dedicatedVersion !== version) { + try { + return extractChangelogSection(changelog, dedicatedVersion); + } catch { + // No dedicated section; use the base version below. + } + } try { return extractChangelogSection(changelog, version); } catch (error) { diff --git a/test/scripts/render-github-release-notes.test.ts b/test/scripts/render-github-release-notes.test.ts index 77100a5ac351..b1fedebdd01c 100644 --- a/test/scripts/render-github-release-notes.test.ts +++ b/test/scripts/render-github-release-notes.test.ts @@ -214,6 +214,33 @@ describe("GitHub release-note rendering", () => { ).toThrow("cannot be compacted without a complete contribution record"); }); + it("prefers an alpha tag's exact changelog heading over the Unreleased fallback", () => { + // Shipped alpha tags carry their own heading with no base section, + // matching the tagged CHANGELOG.md shape of v2026.6.20-alpha.1. + const changelog = [ + "# Changelog", + "", + "## 2026.7.1-alpha.2", + "", + "- Alpha-only fix.", + "", + "## 2026.6.11", + "", + "- Previous release.", + "", + ].join("\n"); + const rendered = renderGithubReleaseNotes({ + changelog, + version, + tag: "v2026.7.1-alpha.2", + repository, + }); + + expect(rendered.body).toContain("## 2026.7.1-alpha.2"); + expect(rendered.body).toContain("Alpha-only fix."); + expect(rendered.body).not.toContain("Previous release."); + }); + it("permits the Unreleased fallback only for alpha tags", () => { const changelog = changelogFor("- **PR #123** fix: example.").replace( "## 2026.7.1",