diff --git a/docs/changelog.mdx b/docs/changelog.mdx index 5e5770e7b6..09290a516a 100644 --- a/docs/changelog.mdx +++ b/docs/changelog.mdx @@ -2897,7 +2897,7 @@ BeginFrame timing. Percentage-based canary rollouts land, so a change can ship to a stable slice of installs instead of all-or-nothing — decided locally and offline, with two inert @@ -4218,7 +4218,7 @@ HyperFrames now uses a 0–10 recommendation scale for feedback, keeps canvas z- `hyperframes publish` now returns a stable public URL: re-publishing updates the same link in place, and a `--space` flag plus a committable project file let a whole team publish to one shared URL. This release also keeps preview review sessions alive across reloads and tags HeyGen API calls with an `X-HeyGen-Client-Source` header. @@ -6054,7 +6054,7 @@ Adds slideshow support end-to-end: a player-side controller state machine and `< Brings the AI Studio (Pacific) SDK integration surface online — object-valued font/image variables, elastic timing with word-alignment, element insertion, and keyframe animation ops — all on the acorn GSAP writer, now gated behind the cutover flag with recast kept as the default. Also adds a slideshow schema/parser/lint rule and phase-1 image-alpha hit-testing, so clicks on transparent image pixels fall through to the layer behind. @@ -6815,7 +6815,7 @@ Completes the playbackRate fix across all media duration resolution sites — vi Fixes media elements with custom playback rates being clipped to the raw source duration instead of the rate-adjusted timeline duration. Also adds a release tag monotonicity guard. diff --git a/scripts/draft-changelog.test.ts b/scripts/draft-changelog.test.ts index df3227bb8f..50d62ae102 100644 --- a/scripts/draft-changelog.test.ts +++ b/scripts/draft-changelog.test.ts @@ -7,6 +7,7 @@ import { parseCommit, renderCommitBullet, renderMdxCommitBullet, + renderTags, shouldSkipCommit, type RawCommit, } from "./draft-changelog.ts"; @@ -149,3 +150,25 @@ describe("skipped release tags", () => { assert.deepEqual(findSkippedReleaseTags(TAGS, "0.8.50", "0.8.52"), ["0.8.51"]); }); }); + +describe("release tags", () => { + it("names Release once, even when a commit is scoped to the release itself", () => { + const commits = [ + "fix(studio-server): inject page tags (#1)", + "docs(release): list the changes v1.2.3 also shipped (#2)", + "fix(core): wait for a loading video (#3)", + "fix(studio): open at Fit (#4)", + ].map((subject) => parseCommit(commit(subject))); + + assert.deepEqual(renderTags(commits), ["Release", "Studio Server", "Core", "Studio"]); + }); + + it("names Release once whatever the case of the release scope", () => { + const commits = [ + "chore(RELEASE): cut v1.2.3 (#5)", + "fix(core): wait for a loading video (#6)", + ].map((subject) => parseCommit(commit(subject))); + + assert.deepEqual(renderTags(commits), ["Release", "Core"]); + }); +}); diff --git a/scripts/draft-changelog.ts b/scripts/draft-changelog.ts index b30988a58c..e8fb84bf63 100644 --- a/scripts/draft-changelog.ts +++ b/scripts/draft-changelog.ts @@ -447,8 +447,13 @@ export function renderMdxCommitBullet(commit: ParsedCommit) { return `- ${scope}${escapeForMdx(capitalize(commit.summary))} (${links.join(", ")}).`; } -function renderTags(commits: ParsedCommit[]) { - return ["Release", ...uniqueScopeTags(commits).slice(0, 3)]; +export function renderTags(commits: ParsedCommit[]) { + return [ + "Release", + ...uniqueScopeTags(commits) + .filter((tag) => tag.toLowerCase() !== "release") + .slice(0, 3), + ]; } function uniqueScopeTags(commits: ParsedCommit[]) {