refactor(changelog): tier releases by significance, publish routine ones automatically - #79
Merged
Merged
Conversation
…nes automatically The changelog had stalled: the sync opened a PR asking a human to hand-write an entry for every release, so nobody merged it. PR #25 sat open for five weeks and the public page fell seven weeks behind, with 18 entries live still carrying their "curate this, then merge" banner and raw git-cliff bullets. Introduce `significance` (highlight | notable | routine) as the spine. It is derived from the version shape, written into the frontmatter, and overridable by hand — and the page, the nav dot, RSS and the announcer all read the same field, so they can no longer disagree about what a release is worth. Ordering Sort by date, then semver, then url. Date alone was not a total order, so alpha.18 and alpha.19 (same day) fell back to filename order and alpha.18 wore the "latest" badge. Numeric prerelease segments now compare numerically. Page Release notes render inline — no click-through to read what shipped. Runs of routine releases group under one collapsible header; a phase opening (beta.1) or a real release gets the display serif and stands out against them. Rows are no longer Link wrappers, since notes contain PR links and anchors cannot nest; the version in the rail carries the permalink. Automation Routine-only syncs build-verify and push straight to main; anything notable opens a PR. `scripts/check-changelog.mjs` fails CI on an un-curated entry, a bad date, a duplicate version, or an entry below CHANGELOG_MIN_VERSION. The nav dot now tracks the newest non-routine entry instead of pinging for every alpha bump. Announcing Channels follow significance: routine to Discord, notable adds X, highlight adds email. Two brakes before anything posts — ANNOUNCE_ENABLED plus the `announce` environment's required reviewers — and email is only ever drafted in Resend, never sent. It is a reusable workflow called by the sync, because a GITHUB_TOKEN push does not fire workflows and a push trigger alone would have silently never announced a routine release. Generator bugs found while verifying - `${VAR}` in alpha.20's notes compiled as a JSX expression and failed the prerender. Release notes are arbitrary commit text, so they are now escaped. - git-cliff's inline `[**breaking**]` marker was neither detected as breaking nor stripped from the description, so the flag was lost and the markup rendered in the headline. Affected alpha.5, alpha.7 and alpha.8. Content The public changelog now starts at the 1.0 alpha train. The five v0.x entries are removed, alpha.20 through alpha.27 are recovered, and CHANGELOG_MIN_VERSION floors both the sync and the check — the 49 v0.x releases still exist upstream, so a wide backfill would otherwise resurrect them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The changelog had stalled. The sync opened a PR asking a human to hand-write an entry for every release, so nobody merged it: #25 sat open for five weeks, the public page fell seven weeks behind, and 18 live entries still carried their "curate this, then merge" banner above raw git-cliff bullets. The curation gate was a bottleneck, not a quality filter.
The spine
significance: highlight | notable | routine— derived from the version shape, written into the frontmatter, overridable by hand. The page, the nav dot, RSS and the announcer all read the same field, so they can't disagree about what a release is worth.Entering a new prerelease phase (
beta.1,rc.1) counts as notable while later bumps stay routine — so an upcoming beta distinguishes itself with nothing to tag by hand.Ordering
Sort by date → semver → url. Date alone was not a total order:
alpha.18andalpha.19shipped the same day, so the tie fell back to filename order and alpha.18 wore the "latest" badge. Numeric prerelease segments now compare numerically (.9before.10).Page
Release notes render inline — no click-through to read what shipped. Runs of routine releases group under one collapsible header; a phase opening or a real release gets the display serif and stands out against them.
Rows are no longer
Linkwrappers: notes contain PR links and anchors can't nest, so the version in the rail carries the permalink. Per-release pages stay as permalinks for sharing, RSS and search.Automation
mainisn't protected andcreate-pull-requestPRs don't fireon: pull_requestCI, so "auto-merge with required checks" was never actually available — the build in that job is the gate.)scripts/check-changelog.mjsin CI: fails on an un-curated notable entry, a bad date, a duplicate version, or an entry belowCHANGELOG_MIN_VERSION.Announcing
Channels follow significance: routine → Discord, notable → +X, highlight → +email.
Inert until deliberately enabled —
ANNOUNCE_ENABLEDmust betrueand theannounceenvironment takes required reviewers. Email is only ever drafted in Resend, never sent. It's aworkflow_callreusable workflow invoked by the sync, because aGITHUB_TOKENpush doesn't fire workflows and apush:trigger alone would have silently never announced a routine release.Supersedes #29; see the closing comment there for where each of its ideas landed.
Generator bugs found while verifying
${VAR}broke the build.alpha.20's notes containDon't expand ${VAR} inside YAML comments, which MDX compiles as a JS expression —ReferenceError: VAR is not defined, whole build dead. Release notes are arbitrary commit text, so they're now escaped (lib/mdx-escape.mjs).[**breaking**]was dropped and leaked. git-cliff's inline marker was neither detected as breaking nor stripped from the description, so the flag was lost and the raw markup rendered in the headline. Affectedalpha.5,alpha.7,alpha.8.Content
The public changelog now starts at the 1.0 alpha train: the five v0.x entries are gone and
alpha.20–alpha.27are recovered, closing the seven-week gap.CHANGELOG_MIN_VERSIONfloors both the sync and the check — the 49 v0.x releases still exist upstream, so a wide backfill would otherwise resurrect them (verified: a 100-release backfill writes 0 entries).Companion PR: bitrouter/bitrouter#819 does the same cut to the Rust repo's
CHANGELOG.md.Verified
pnpm buildpasses, 126 tests pass,pnpm lint:changelogclean. Feed checked in the browser: 25 releases render notes inline, 3 breaking badges, 0 nested anchors, collapse works and returns thelatestbadge to the group header.Before merging, note
There are currently no notable entries at all — every remaining release is a routine alpha, so
/changelogis one train andLATEST_CHANGELOG_DATEis""(nav dot off). That resolves itself when a beta lands, or sooner by promoting a few alphas withsignificance: notable.Merging adds 8 entries and trips the announce
push:trigger — harmless, sinceANNOUNCE_ENABLEDwon't be set and the 14-day age guard would skip them anyway.🤖 Generated with Claude Code