History

Drop release-notes archiving — single rolling next.md (#493)

Other CLIs in this space don't archive release notes per-version into the repo: - opencode generates GitHub Releases bodies from git log + AI at release time; nothing committed. - codex uses git-cliff against conventional commits; root CHANGELOG.md redirects to GitHub Releases. - openclaw appends to a single CHANGELOG.md with a `## Unreleased` section (no rename ritual). We were the outlier with the rename-`next.md`-to-`v<version>.md` post-release ritual. It was easy to forget and didn't add value: historical release bodies are already preserved on GitHub Releases (durable, indexed, linkable).

Rhys Sullivan committed 6 months ago

Commit 4d0709b1 parent d8be39b3 files · +29 −29Browse files

Unified · Split

3 files
  1. .skills/cli-release/SKILL.md +12 −10
  2. RELEASING.md +13 −12
  3. apps/cli/src/release.ts +4 −7
.skills/cli-release/SKILL.md+12−10
@@ -37,10 +37,11 @@ The owner doesn't want GitHub's auto-generated "PR title by @user" list. Release · 36 unmodified lines
3737 **`apps/cli/release-notes/next.md` is the canonical user-facing changelog.** Per-package workspace `CHANGELOG.md` files were removed in late 2026 — they were empty stubs and changesets does not regenerate them under `changelog: false`. Don't create them.
3838
3939 ### How it's wired
40−`apps/cli/src/release.ts:198` picks the notes file in this order:
41−1. `apps/cli/release-notes/v<version>.md` (archived per release)
42−2. `apps/cli/release-notes/next.md` (rolling draft)
43−3. Fall back to `gh release create --generate-notes`
40+`apps/cli/src/release.ts` reads `apps/cli/release-notes/next.md` and uses
41+its contents as the GitHub Release body. If the file is missing or empty,
42+falls back to `gh release create --generate-notes`. There's no
43+per-version archive in the repo — historical release bodies live on
44+GitHub Releases (durable, indexed, linkable).
4445
4546 ### Writing conventions
4647 Structure release-notes files as:
@@ -83,12 +84,13 @@ Do not `Thanks` maintainers, bots, or the repo owner — the lint script rejects · 36 unmodified lines
8384 - The `.changeset/*.md` body can be a one-liner pointing at the release-notes section it expands; users read the GitHub release body, not the changeset.
8485 - Frontmatter is `"executor": patch` (or `minor`/`major` if owner says so).
8586
86−### Post-release archival (manual)
87−After a release publishes, rename `apps/cli/release-notes/next.md` → `apps/cli/release-notes/v<version>.md` and commit on `main` (or in a small follow-up PR). This:
88−- Preserves the historical notes file-by-version (matches `release.ts`'s preferred lookup path).
89−- Resets `next.md` absence so the next cycle starts from a blank file — no chance of last release's content leaking into the next one.
90−
91−`release.ts` falls back to `next.md` if `v<version>.md` is missing, so skipping the rename won't break a publish; it just leaves stale content in `next.md` for the next release.
87+### Starting a new release cycle
88+There's no post-release rename step. When you start work on the next
89+release, replace the existing `next.md` content with new entries — the
90+previous cycle's content is already preserved on the matching `vX.Y.Z`
91+GitHub Release page, so overwriting locally is safe. If `next.md` content
92+looks stale (i.e. mentions features already shipped), that's the signal
93+to clear it.
9294
9395 ## Beta release flow
9496
RELEASING.md+13−12
@@ -54,18 +54,19 @@ To pack the `@executor-js/*` library packages without publishing: · 53 unmodified lines
5454
5555 ## Release notes
5656
57−User-facing release notes live in `apps/cli/release-notes/`:
58−
59−- `next.md` — rolling draft for the next release. **This is the single
60− source of truth users see.** Edit it whenever you ship a user-visible
61− change.
62−- `v<version>.md` — archived per-release snapshots. After a release
63− publishes, rename `next.md` to `v<version>.md` so the next cycle starts
64− blank.
65−
66−`apps/cli/src/release.ts` reads `v<tag>.md` first, falls back to
67−`next.md`, and only invokes `gh release create --generate-notes` if both
68−are absent.
57+User-facing release notes live at `apps/cli/release-notes/next.md` —
58+one rolling file. **This is the single source of truth users see.** Edit
59+it whenever you ship a user-visible change.
60+
61+`apps/cli/src/release.ts` reads `next.md` and uses its contents as the
62+GitHub Release body. If the file is missing or empty it falls back to
63+`gh release create --generate-notes` (auto-generated from PR titles).
64+
65+There's no per-version archive in the repo — historical release bodies
66+live on GitHub Releases (durable, indexed, linkable). When you start a
67+new release cycle, replace the existing `next.md` content with your new
68+entries; the previous cycle's content is already preserved on the
69+matching `vX.Y.Z` release page.
6970
7071 ### Authoring rules
7172
apps/cli/src/release.ts+4−7
@@ -195,13 +195,10 @@ const syncGitHubRelease = async (input: { · 194 unmodified lines
195195 return;
196196 }
197197
198− const versionedNotes = resolve(cliRoot, "release-notes", `${input.tag}.md`);
199− const fallbackNotes = resolve(cliRoot, "release-notes", "next.md");
200− const notesFile = existsSync(versionedNotes)
201− ? versionedNotes
202− : existsSync(fallbackNotes)
203− ? fallbackNotes
204− : null;
198+ // Single rolling release-notes file. Historical release bodies live on
199+ // GitHub Releases — we don't archive per-version copies in the repo.
200+ const notesPath = resolve(cliRoot, "release-notes", "next.md");
201+ const notesFile = existsSync(notesPath) ? notesPath : null;
205202
206203 const args = [
207204 "release",