From 3ee4c49e3ca9c341f7d02734d9ba078ffaa459aa Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Mon, 5 Oct 2026 03:58:31 +0200 Subject: [PATCH] docs(release): fold each beta into one changelog entry for the series Each beta now rewrites the series' single entry to cover the previous stable release to the release source, describing current behavior rather than adding a per-beta entry. Promotion renames the entry to the stable heading. --- docs/release.md | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/docs/release.md b/docs/release.md index 26af0182eb..cdac451f23 100644 --- a/docs/release.md +++ b/docs/release.md @@ -95,7 +95,7 @@ release push as the changelog and version commit. There are two supported release paths: 1. **Direct stable release**: you are ready to ship the resolved release source to everyone immediately (default `origin/main`). -2. **Beta flow**: release candidates on the `beta` channel. Each beta carries its own changelog entry, publishes npm only on the explicit `beta` dist-tag, and stays behind the Stable/Beta switch on `/download`. +2. **Beta flow**: release candidates on the `beta` channel. Each beta folds into the series' single changelog entry, publishes npm only on the explicit `beta` dist-tag, and stays behind the Stable/Beta switch on `/download`. Paseo has one linear release track even though npm dist-tags are independent pointers. The npm invariant is: @@ -194,7 +194,7 @@ npm run release:promote # Promote X.Y.Z-beta.N to stable X.Y.Z - Desktop assets now come from the Electron package at `packages/desktop` - Require the Linux artifact CI checks with both restricted and usable user namespaces to pass before publication; see [packaged desktop smoke](testing.md#packaged-desktop-smoke). Keep the installed-package and AppImage checks together. - Beta releases use Electron's `beta` update channel. Users on the stable channel only receive stable releases; users on the beta channel receive beta releases and the final stable release when it is published. -- **Each beta carries its own changelog entry.** `Release Notes Sync` mirrors the matching `## X.Y.Z-beta.N` entry into that prerelease body. Promotion collapses every beta entry for the version into one final stable entry. See the Changelog policy section. +- **A beta series has one changelog entry.** Each beta folds into it and renames its heading to the new `## X.Y.Z-beta.N`, which `Release Notes Sync` mirrors into that prerelease body. Promotion renames it to the stable heading. See the Changelog policy section. Use the beta path when you need to: @@ -414,7 +414,7 @@ The GitHub Release body is populated automatically by the `Release Notes Sync` w - Homebrew, the Play Store, the App Store, and `app.paseo.sh` have no beta. The Beta view drops those rows, and the whole Web section, rather than showing an inert "stable only" placeholder. When a surface gains a beta path — say a public TestFlight link — add its row back in `packages/website/src/routes/download.tsx`. - The default download target only moves when you publish the final stable release tag like `v0.1.41`. - The public `/changelog` page renders `CHANGELOG.md` as-is, so the in-flight `-beta.N` entry shows there once it lands on `main` — that's intended, it's where beta users check what's coming. Only the **default download target** stays pinned to the latest stable; the download links read GitHub's releases API, not the changelog, so a `-beta.N` heading on top never affects them. -- The download page's "What's new" link deep-links the **minor group** anchor (`/changelog#release-0.3`), not the exact entry: promotion collapses the beta entries into one stable entry, so the minor group remains the durable target. A version with no entry in the bundled changelog — a tag whose changelog commit hasn't redeployed the site yet — links the plain `/changelog` instead of a dead anchor. +- The download page's "What's new" link deep-links the **minor group** anchor (`/changelog#release-0.3`), not the exact entry: the beta entry is renamed on each beta and on promotion, so the minor group remains the durable target. A version with no entry in the bundled changelog — a tag whose changelog commit hasn't redeployed the site yet — links the plain `/changelog` instead of a dead anchor. - The website itself is deployed by `Deploy Website` (Cloudflare Workers), which redeploys on the `release: published` event emitted when a stable draft is published and on pushes to `main` that touch `CHANGELOG.md` or `packages/website/**`. Its job condition excludes beta prereleases. ## Fixing a failed release build @@ -521,17 +521,20 @@ No prefix (`v`), no extra text. `Release Notes Sync` matches the `## X.Y.Z` (or ## Changelog policy -- `CHANGELOG.md` includes stable releases and every entry in the current beta series. +- `CHANGELOG.md` holds stable releases and at most one entry for the current beta series. - The first beta of a version inserts a top entry like `## 0.1.60-beta.1 - YYYY-MM-DD`. -- Each subsequent beta inserts a new top entry with the next beta number. Its notes cover the changes since the previous beta tag. -- Stable promotion replaces every beta entry for that version with one `## 0.1.60 - YYYY-MM-DD` entry. -- The promoted stable entry covers the full diff from the previous stable tag and collapses internal iterations across the beta series. +- Each subsequent beta rewrites that entry in place: the heading becomes the new beta number and date, and the body describes the full change from the previous stable release to this beta. Never add a second beta entry. +- The entry is a list of changes, not of PRs. When a later beta reverts, reworks, or follows up on something an earlier beta added, rewrite the bullet to the current behavior or delete it. A stable user never saw the earlier beta behavior, so fixes to it are not "Fixed" bullets. +- Anything that already shipped to stable through a patch release on an older line stays out of the beta entry. +- Stable promotion renames the entry to `## 0.1.60 - YYYY-MM-DD` after a final review. + +Older prerelease bodies on GitHub keep the notes they were synced with; `Release Notes Sync` only writes the release whose tag matches the top entry. ## Changelog ownership - **The agent running the release writes the changelog entry — beta or stable.** The release context and final wording stay with that agent. - **Commit history is only an index of the changes. Never draft the changelog from commit subjects or diffs alone.** For every PR in the release range, read the full PR description and every issue it links to before deciding what changed, why users care, or how changes should be grouped. Use the implementation only to verify the resulting understanding. -- For the first beta or a direct stable release, draft from the previous stable tag to the release source. For later betas, draft from the previous beta tag to the release source. Promotion replaces the beta series with one entry drafted from the previous stable tag to the release source. Review the result against the changelog policy below, show it to the user, and wait for approval before committing it. +- Every entry, beta or stable, is drafted from the previous stable release to the release source. For a later beta, read the PRs since the previous beta tag, then rework the existing entry so each bullet still describes current behavior. Review the result against the changelog policy below, show it to the user, and wait for approval before committing it. ## Changelog wording @@ -563,7 +566,7 @@ that changed, the failure that was fixed, or the capability that was added? If t claims a general improvement, rewrite it with the concrete change. - **Use the entry's release scope.** Include changes within the matching range in **Changelog scope**. -- **Collapse internal iterations within that scope.** Present a feature added and fixed in one range as working. A later beta can describe a fix to behavior delivered in an earlier beta; promotion folds the complete beta series into the final stable behavior. +- **Collapse internal iterations within that scope.** Present a feature added and fixed in one range as working. - **Cut low-signal entries.** "Toolbar buttons have consistent sizing" is too granular. Combine small polish items or drop them. ## Changelog conciseness @@ -631,12 +634,7 @@ Use `git diff ..` as the review input. T Changelog scope follows the release being described: -- **First beta**: `previous stable tag → release source` -- **Later beta**: `previous beta tag → release source` -- **Direct stable release**: `previous stable tag → release source` -- **Stable promotion**: replace the full beta series with one entry covering `previous stable tag → release source` - -Each beta entry records what its testers receive. Promotion produces the single stable record for the full jump from one stable version to the next. +Every entry covers `previous stable release → release source`: first beta, later beta, direct stable release, and promotion alike. The beta entry always reads as the stable entry would if the beta were promoted today. ## Completion checklist @@ -644,7 +642,7 @@ Each beta entry records what its testers receive. Promotion produces the single - [ ] The resolved release source is the intended commit (default `origin/main`) and its existing CI is green - [ ] Every PR in the release range has been opened, and its full description and every linked issue have been read before drafting the changelog -- [ ] Add a new `CHANGELOG.md` entry for this beta (heading `## X.Y.Z-beta.N - YYYY-MM-DD`), review it against the changelog policy, get approval, and commit it before cutting the release +- [ ] Fold this beta into the series' single `CHANGELOG.md` entry (heading `## X.Y.Z-beta.N - YYYY-MM-DD`, previous stable → release source), review it against the changelog policy, get approval, and commit it before cutting the release - [ ] The diff from the previous stable to the resolved release source is classified as patch or minor, with the target version and rationale approved - [ ] Release preparation stayed local until the approved release command pushed the complete branch and tag - [ ] `npm run release:beta:patch`, `npm run release:beta:minor`, or `npm run release:beta:next` completes successfully @@ -667,7 +665,7 @@ Each beta entry records what its testers receive. Promotion produces the single - [ ] Every PR in the release range has been opened, and its full description and every linked issue have been read before drafting the changelog - [ ] Ensure the approved release inputs are committed locally and the git worktree is clean before running any release command - [ ] Ensure local `npm run typecheck` passes on that exact commit before running any release command -- [ ] Update `CHANGELOG.md` with user-facing release notes (features, fixes — not refactors). Promotion replaces every `## X.Y.Z-beta.N` entry in the series with one `## X.Y.Z - YYYY-MM-DD` entry covering the full release +- [ ] Update `CHANGELOG.md` with user-facing release notes (features, fixes — not refactors). Promotion renames the series' `## X.Y.Z-beta.N` entry to `## X.Y.Z - YYYY-MM-DD` and re-checks it covers the full release - [ ] Verify the changelog heading follows strict `## X.Y.Z - YYYY-MM-DD` format - [ ] Release preparation stayed local until the approved release command pushed the complete branch and tag - [ ] `npm run release:patch`, `npm run release:minor`, or `npm run release:promote` completes successfully