Repository navigation
Commit 365fe5e
fix(release): the stable cut folds each prerelease section into the stable section instead of copying it (#26156)
<!-- claude-projects-attribution: {"github_login":"os-steve"} -->
_Requested by **Steve** · [project
thread](https://claude.ai/code/project/chan_01FdL1XeUyvVNxLreh3F4Qi9?thread=cmsg_01FdL1XeUyvVNxLreh3F4Qi9DjkzyES5iJcSWAVHScrQBe)_
Fixes #26079
Clause-②: no
Metadata-protocol: none
Ruling-ref: 6417011624 (batch #397 item 3, letter A′, maintainer 「同意」)
## What this does
On the stable cut out of pre mode (`changeset pre exit`, then `pnpm run
version`), the changelog generator now **folds** every `X.Y.Z-next.N`
section of the cycle into the `X.Y.Z` section instead of leaving it as a
second copy below it. Today that cut re-applies every changeset the
prereleases consumed, so the stable section repeats each prerelease
section verbatim (18.0.0 left `packages/spec/CHANGELOG.md` with about
4,076 duplicated long lines).
Ruled scope, kept: only `scripts/changeset-changelog.mjs` changes
behaviour; its pins go into the self-test CI already runs for it (`node
scripts/release-pending-publish.mjs --self-test`, lint.yml), the file
surface the seat widened on the claim. ⛔ No `files` change in any
`package.json` — `CHANGELOG.md` keeps shipping (AGENTS.md, Documentation
Guardrails). ⛔ No existing CHANGELOG text is rewritten by this PR, and
the generator never touches an older cycle (#25919 A 「存量不横扫」). No
workflow change, no new gate.
## Timing — when the fold runs, and on what
The generator API (`getReleaseLine` / `getDependencyReleaseLine`) hands
out one line at a time and is told neither the package nor the version,
and `@changesets/apply-release-plan` writes every `CHANGELOG.md` only
after all lines are generated. So:
1. **Armed on the first generated line**, and only when
`.changeset/pre.json` says `"mode": "exit"` (the stable cut; the version
pass itself deletes that file later). An rc cut (`mode: "pre"`) and a
normal cut (no `pre.json`) arm nothing.
2. **Snapshot at arming:** each tracked `*CHANGELOG.md` whose top `##
VERSION` is a prerelease (read from the first 64 KiB only).
3. **Run when the `changeset version` process exits 0** (a
`process.once('exit')` handler; a failed version pass folds nothing).
For each snapshotted file whose top is now a new stable section sitting
directly above the old top, the prerelease sections between that stable
section and the next stable one below are dropped — each one only if
every changeset entry it carries is found in the new stable section
(compared without the commit prefix). Dependency-bump entries (`Updated
dependencies`, `pkg@X.Y.Z-next.N`) are superseded by the stable
section's own. A section holding an entry the stable section does not
reproduce (amended in place by a docs PR, say) stays, with a
`::warning::` naming it.
What may fold is fixed by the file as it stood before the cut, never by
a version guess, so every stable section and every older cycle's
prerelease sections are kept byte for byte. One plain line reports the
count: `changeset-changelog: the stable cut folded N prerelease
section(s) in M CHANGELOG(s) into their stable section.`
## Evidence
- `node scripts/release-pending-publish.mjs --self-test` at `2f44043a`:
`✓ release-pending-publish self-test: 136 cases across 34 batteries
pass.` Three new batteries (floor 31 → 34): a prerelease section folds
(4 cases); the stable section is kept whole, and so is every older
cycle, and a section with an entry the stable section lacks stays (5
cases); armed only on an exit-mode cut, for the files whose top was a
prerelease, folded after the write (3 cases).
- **End to end through the real CLI** (`@changesets/cli` 3.0.3,
throwaway repo, two fixed packages, this generator): `pre enter next` →
version (`1.2.0-next.0`) → version (`1.2.0-next.1`) → `pre exit` →
version (`1.2.0`). Result: `## 1.2.0` (all three entries, each naming
the commit that added its changeset), then the untouched `## 1.1.0` /
`## 1.1.0-next.0`; the run printed `folded 4 prerelease section(s) in 2
CHANGELOG(s)`. The rc cuts in between folded nothing.
- **Control leg**, same history, the generator at `origin/main`
`95294be3`: the stable cut leaves 5 sections (`1.2.0`, `1.2.0-next.1`,
`1.2.0-next.0`, `1.1.0`, `1.1.0-next.0`), 37 + 36 lines, against 3
sections and 23 + 22 lines with this change.
## Confidence gap from the card
No downstream tooling reads an installed CHANGELOG's prerelease section:
- This repo: the CHANGELOG readers (`check:release-notes`,
`check:release-page-status`, `check-release-section-coverage.mjs`) read
`## N.x.y` headings for majors / GA versions; the stable heading the
fold keeps is what they count.
- `objectstack-ai/hotcrm` at `9464673`: no script reads
`node_modules/@objectstack/*/CHANGELOG.md`; one code comment cites the
`17.0.0` heading of installed CHANGELOGs, a stable heading.
- `objectstack-ai/cloud`: NOT MEASURED — not readable from this session.
## Gates
`node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` at `2f44043a` derives 33 commands; all 33
exit 0, and `--ran` reconciles `33 derived, 33 run, 0 NOT-MEASURED, 0
UNRUN`. CI families outside the derivation are read from this PR's
check-runs.
## Acceptance notes
- The fold applies at the next stable cut out of pre mode; nothing in
the tree changes on merge. Rollback is reverting this PR before that
cut.
- `skip-changeset`: the diff is repository tooling under `scripts/`,
which no package's `files` ships.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01PbYqgMPfuTjR2CMEqrjHVL)_
Co-authored-by: Claude <noreply@anthropic.com>1 parent d98d3e2 commit 365fe5e
2 files changed
Lines changed: 253 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
19 | 51 | | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
20 | 55 | | |
21 | 56 | | |
22 | 57 | | |
23 | 58 | | |
24 | 59 | | |
25 | 60 | | |
26 | 61 | | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
27 | 68 | | |
28 | | - | |
29 | | - | |
30 | | - | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
31 | 77 | | |
32 | 78 | | |
33 | 79 | | |
34 | 80 | | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1489 | 1489 | | |
1490 | 1490 | | |
1491 | 1491 | | |
| 1492 | + | |
| 1493 | + | |
| 1494 | + | |
1492 | 1495 | | |
1493 | | - | |
| 1496 | + | |
1494 | 1497 | | |
1495 | 1498 | | |
1496 | 1499 | | |
| |||
2023 | 2026 | | |
2024 | 2027 | | |
2025 | 2028 | | |
| 2029 | + | |
| 2030 | + | |
| 2031 | + | |
| 2032 | + | |
| 2033 | + | |
| 2034 | + | |
| 2035 | + | |
| 2036 | + | |
| 2037 | + | |
| 2038 | + | |
| 2039 | + | |
| 2040 | + | |
| 2041 | + | |
| 2042 | + | |
| 2043 | + | |
| 2044 | + | |
| 2045 | + | |
| 2046 | + | |
| 2047 | + | |
| 2048 | + | |
| 2049 | + | |
| 2050 | + | |
| 2051 | + | |
| 2052 | + | |
| 2053 | + | |
| 2054 | + | |
| 2055 | + | |
| 2056 | + | |
| 2057 | + | |
| 2058 | + | |
| 2059 | + | |
| 2060 | + | |
| 2061 | + | |
| 2062 | + | |
| 2063 | + | |
| 2064 | + | |
| 2065 | + | |
| 2066 | + | |
| 2067 | + | |
| 2068 | + | |
| 2069 | + | |
| 2070 | + | |
| 2071 | + | |
| 2072 | + | |
| 2073 | + | |
| 2074 | + | |
| 2075 | + | |
| 2076 | + | |
| 2077 | + | |
| 2078 | + | |
| 2079 | + | |
| 2080 | + | |
| 2081 | + | |
| 2082 | + | |
| 2083 | + | |
| 2084 | + | |
| 2085 | + | |
| 2086 | + | |
| 2087 | + | |
| 2088 | + | |
| 2089 | + | |
| 2090 | + | |
| 2091 | + | |
| 2092 | + | |
| 2093 | + | |
2026 | 2094 | | |
2027 | 2095 | | |
2028 | 2096 | | |
| |||
0 commit comments