You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Channel release PR titles previously showed registry-derived prerelease
counters, which could be out of sync with what actually publishes (the
registry is re-queried at publish time and wins). They also degraded
poorly in multi-package cycles: an arbitrary alphabetical lead package
plus `(+N more)`.
Titles, PR bodies, and merge commit messages now only claim what's
derivable from committed state:
- **Wildcard counter** — versions display as `1.2.0-rc.x`; the target
comes from bump files (deterministic), the `.x` is assigned from the
registry at publish. The title can no longer drift, by construction.
- **Package count for multi-package cycles** — `🐸 Versioned release
(next): 4 packages` instead of an arbitrary lead + `(+N more)`.
Single-package cycles keep `name@1.2.0-rc.x`.
- **No registry call in the version-PR job** — the `forDisplay` fetch
(and its offline `-rc.?` fallback) is gone from the release PR path; one
less network dependency and failure mode. `status` and `ci plan` keep
live registry-derived counters (`.?` when offline) since they're
interactive/live output.
- **Consistent wildcard** — the PR check comment and channel `version`
output now use `.x` too (they never queried the registry; `.?`
previously implied a failed lookup rather than "assigned later").
Docs updated where they described the title as "advisory narrative;
registry wins" — the new story is simpler: the title only shows
deterministic state.
All 292 tests pass, including new coverage for `channelDisplayPlan`
(wildcard mapping + unpublishable-package filtering).
Channel release PR titles and bodies now show deterministic versions: targets with a wildcard counter (`1.2.0-rc.x`) derived purely from committed state, instead of registry-derived counters that could drift between PR creation and publish. Multi-package cycles show a package count in the title instead of an arbitrary lead package. The PR check comment and `version` output use the same `.x` wildcard; `status` / `ci plan` still show live registry-derived counters (`.?` when offline).
Copy file name to clipboardExpand all lines: docs/prereleases.md
+5-5Lines changed: 5 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -55,7 +55,7 @@ Rough rule of thumb:
55
55
56
56
-**Branch = channel.** The `next` branch is the `next` channel. Pushing to it produces prerelease publishes on the `@next` dist-tag.
57
57
-**Same flow as main.** Feature PRs land bump files. A "🐸 Versioned prerelease (next)" PR accumulates the cycle. Merging it triggers a prerelease publish.
58
-
-**The release PR moves files, not versions.** Its diff is bump files moving into `.bumpy/next/`. The computed versions appear in the PR title and merge commit message — so `git log` on the channel reads as a release history — but nothing version-shaped is committed.
58
+
-**The release PR moves files, not versions.** Its diff is bump files moving into `.bumpy/next/`. The cycle's target versions appear in the PR title and merge commit message with a wildcard counter (`1.2.0-rc.x`) — so `git log` on the channel reads as a release history — but nothing version-shaped is committed.
59
59
-**Promotion is a merge.**`next` → `main` carries the accumulated bump files forward (and nothing else release-related — versions never diverged). Main's ordinary stable version PR consumes them.
60
60
61
61
---
@@ -166,7 +166,7 @@ When a feature PR merges to `next`:
166
166
167
167
1. `bumpy ci release` runs on the `next` push.
168
168
2. It sees a pending bump file and creates (or updates) a **release PR** — titled something like **"🐸 Versioned prerelease (next): 1.2.0-rc.4"**, targeting `next`, on the branch `bumpy/version-packages-next`.
169
-
3. The PR's diff is **only file moves**: `.bumpy/feature-x.md`→ `.bumpy/next/feature-x.md`. The computed versions live in the PR title and body, and land in git history via the merge commit message.
169
+
3. The PR's diff is **only file moves**: `.bumpy/feature-x.md`→ `.bumpy/next/feature-x.md`. The target versions (with a wildcard counter, e.g. `1.2.0-rc.x`) live in the PR title and body, and land in git history via the merge commit message.
170
170
171
171
When a maintainer merges that PR:
172
172
@@ -178,7 +178,7 @@ When a maintainer merges that PR:
178
178
npm install my-package@next # gets 1.2.0-rc.0
179
179
```
180
180
181
-
> **The PR title is narrative, not state.** Versions are recomputed at publish time and the registry always wins. If reality moved between PR creation and merge (e.g. `main` shipped a stable release that overtakes the cycle's target), publish uses the recomputed versions and warns about the retarget in its logs. Bumpy never reads versions back out of PR titles or commit messages.
181
+
> **The PR title shows targets, not counters.** The title and body display each version as `1.2.0-rc.x` — the target comes from committed bump files (deterministic), while the `.x` counter is assigned from the registry at publish time. This is why the title can never be out of sync with what publishes: everything it claims is derived from committed state. The exact counter lands in the git tag and GitHub release moments after merge. Bumpy never reads versions back out of PR titles or commit messages.
182
182
183
183
To skip the manual merge step, set `versionPr.automerge: true` on the channel — the release PR is created with auto-merge enabled, so each feature merge flows to a prerelease publish once checks pass. The PR (and its file-move commit) still exists, keeping the model intact; you just don't click the button.
184
184
@@ -254,7 +254,7 @@ Instead:
254
254
- **`bumpy status`** on a channel renders the would-be changelog for the whole cycle on demand — the answer to "what has shipped on `@next` so far," including for teams not on GitHub.
255
255
- **The stable `CHANGELOG.md` entry** is written once, at promotion, on `main` — lossless, because it's built from the bump files rather than from intermediate changelogs.
256
256
257
-
There is deliberately no versions index file or per-channel README either — any committed reflection of registry state can go stale and mislead (failed publishes, retargets, resets). The computed versions appear in the release PR title and merge commit message, which are understood as point-in-time narrative; live truth is always `bumpy status`, the dist-tags, and the git tags.
257
+
There is deliberately no versions index file or per-channel README either — any committed reflection of registry state can go stale and mislead (failed publishes, retargets, resets). The release PR title and merge commit message show only what's derivable from committed state (targets with a wildcard counter, `1.2.0-rc.x`); live truth is always `bumpy status`, the dist-tags, and the git tags.
258
258
259
259
---
260
260
@@ -387,7 +387,7 @@ Defaults applied when a field is omitted:
387
387
388
388
- `preid`— defaults to the channel name (e.g., `next` → `1.2.0-next.0`).
389
389
- `tag`— defaults to the channel name (so `@next`).
390
-
- `versionPr.title` — defaults to `<base-title> (<channel>): <computed versions>` — the versions in the title are advisory narrative; the registry wins at publish time.
390
+
- `versionPr.title` — defaults to `<base-title> (<channel>)`. A version summary is appended: `name@1.2.0-rc.x`for a single package, or a package count for several. The `.x` counter is assigned from the registry at publish time, so the title only ever claims what's derivable from committed state.
391
391
- `versionPr.branch`— defaults to `<base-branch>-<channel>` (e.g., `bumpy/version-packages-next`).
@@ -935,7 +920,7 @@ function buildChannelPrPreamble(config: BumpyConfig, channel: ResolvedChannel):
935
920
config.versionPr.preamble,
936
921
'',
937
922
`> 🔀 **Prerelease channel \`${channel.name}\`** — merging this PR publishes the versions below to the \`@${channel.tag}\` dist-tag.`,
938
-
`> The diff only moves bump files into \`.bumpy/${channel.name}/\` — prerelease versions are derived at publish time and never committed. Version numbers shown here are estimates; the registry wins at publish.`,
923
+
`> The diff only moves bump files into \`.bumpy/${channel.name}/\` — prerelease versions are derived at publish time and never committed. The \`.x\` counter is assigned from the registry at publish time.`,
939
924
].join('\n');
940
925
}
941
926
@@ -1037,9 +1022,9 @@ export function formatReleasePlanComment(
1037
1022
constrepo=process.env.GITHUB_REPOSITORY;
1038
1023
constlines: string[]=[];
1039
1024
1040
-
// When targeting a prerelease channel, the version display carries the `-<preid>.?`
1041
-
// suffix (the exact counter is derived from the registry at publish time).
? `**This PR targets the \`${channel.name}\` prerelease channel** — merging it ships these packages as a **prerelease** to the \`@${channel.tag}\` dist-tag, not a stable release.`
@@ -1078,7 +1063,7 @@ export function formatReleasePlanComment(
1078
1063
constinstallHint=examplePkg ? ` (e.g. \`npm i ${examplePkg}@${channel.tag}\`)` : '';
1079
1064
lines.push(
1080
1065
`> 🔀 Published to the \`@${channel.tag}\` dist-tag${installHint}. `+
1081
-
`Prerelease versions are derived at publish time — the \`.?\` counter is filled in from the registry. `+
1066
+
`Prerelease versions are derived at publish time — the \`.x\` counter is filled in from the registry. `+
1082
1067
`Promote to a stable release by merging \`${channel.branch}\` into your base branch.`,
0 commit comments