feat(release): scaffold the blog post in its published shape

`release:notes:blog` used to emit the notes as a type-grouped inventory with
area prefixes and the highlight sections buried after the feature list; the
v0.23 post shipped in exactly that form and had to be restructured after
publication. The scaffold now starts from the shape the posts end up in:
a "What changed" table with one row per highlight, one `##` section per
highlight ahead of everything else, breaking changes on their own, the
remaining features folded into reader-facing themed sections instead of
conventional-commit scopes, Performance, every remaining fix under a Spoiler
grouped by theme, and the before-updating alert, Thanks and Download cards
(including the compare link to the previous version). Only the components a
post uses are imported.

The blog renderer moves to `release-notes-blog.mjs`; `release-notes-render.mjs`
keeps the GitHub/CHANGELOG renderers and exports the shared text helpers.
Editorial work stays editorial and is marked with TODOs: which fixes deserve
promotion out of the spoiler, one-line bullets, lead-ins, intro and thanks.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
4grayandClaude Fable 5.1 committed 2026-09-03 20:57:15 +02:00
1 parent fa9084fca3
commit 81ce8e8c90
8 files changed
+693 -161

No files matched your search

+30 -2
View File
@@ -91,8 +91,9 @@ Highlights drive three behaviors:
dropping from the tail of the grouped list, which is ordered breaking →
feature → fix → perf so the least consequential go first. A breaking change
is never dropped there either.
- **The blog scaffold** uses the highlight as a ready `###` heading instead of
emitting `TODO headline (<area>)`.
- **The blog scaffold** gives each highlight a row in the opening "What
changed" table and its own `##` section ahead of everything else, instead of
emitting `TODO headline (<area>)`. Shape below.
Prose fields keep `#`. `parseFrontmatterLine` strips trailing `# comment` text
only from closed-vocabulary fields (`type`, `area`, `issues`, `screenshot`),
@@ -106,6 +107,33 @@ Both announcement formats then print an explanation on stderr, leave stdout
empty, and exit 0 — the same shape `extract-changelog-section.mjs --public`
already uses for its empty public body.
## Blog scaffold shape
`renderBlogScaffold` (`tools/release/release-notes-blog.mjs`) emits the shape
the published posts end up in, so the editor starts from the form rather than
from the inventory — the v0.23 post shipped as the raw type-grouped list with
area prefixes and had to be restructured after publication. In order:
narrative intro (TODO) → `ReleaseMeta` → `## What changed` (a `ChangeTable`
with one row per highlight; the theme is the default area label, the impact a
TODO) → the "About the screenshots" alert when any note names a screenshot →
one `##` section per highlight or screenshot note, with a `StatusPill`
matching the note type → `## Breaking changes` → the remaining features folded
into themed `##` sections → `## Performance` → `## Everything else`, holding
every remaining fix under a `Spoiler` grouped by theme → the before-updating
alert → `## Thanks` → `## Download` link cards (release tag, full notes, the
compare link when a previous version is known, all releases).
Themes come from `BLOG_THEMES`: a conventional-commit `area` says nothing to a
reader ("matching", "window-controls", "electron-backend"), so notes fold into
reader-facing headings ("Stalker portals", "Live TV, EPG and M3U"). An unmapped
area lands in "Other changes" rather than failing; add it to the map when it
recurs. Two defaults are deliberately dumb: every non-highlighted fix goes into
the spoiler, and every bullet keeps its full note body. Promoting the fixes
users will notice, compressing bullets to one line and writing the bold
lead-ins is the editorial pass, and the scaffold marks where with `TODO`. Only
the components the post actually uses are imported, so an MDX build never
fails on an unused import.
## Highlight cards
`tools/release/highlight-cards.mjs` plans and lays out;