Repository navigation
Commit 24d350b
fix(release): a changeset a revert restored is credited to the commit that first added it in the CHANGELOG (#25669)
<!-- claude-projects-attribution: {"github_login":"os-elon-musk"} -->
_Requested by **Elon** · [project
thread](https://claude.ai/code/project/chan_01WedDzV26nniwxv7jC88B9D?thread=cmsg_01WedDzV26nniwxv7jC88B9D8YtQfsG3aDPvEyQz2wfMbk)_
Part of #25638
Clause-②: no
Metadata-protocol: none
## What happens today
`.changeset/config.json` named `@changesets/cli/changelog`. It stamps
each entry with the commit `@changesets/git` returns: the **newest**
commit that added the changeset file. #25605 (`3937697`) reverted the
unpublished first 18.1.0 cut (`74fa3cb6d`), which re-added the 260
changesets that cut had consumed. The re-cut (#25606, `e649c2d91e`)
therefore credited all 260 to the revert: 260 of 265 distinct entries,
and 6000 `- Updated dependencies [3937697]` lines, across 79 CHANGELOGs.
## The fix (a): future cuts
- `.changeset/config.json` loads `../scripts/changeset-changelog.mjs`
(resolved from `.changeset/`, as `@changesets/apply-release-plan`
resolves it). It is the stock generator's two functions with each
changeset's `commit` replaced by `createChangelogAttribution`. The line
format is the stock one byte for byte.
- `createChangelogAttribution` lives in
`scripts/release-pending-publish.mjs`, beside `annotate-shipped`, which
already knows reverted cuts (#25607). One `git log --no-renames
--diff-filter=AD --name-status -- .changeset/` pass indexes every add
and delete. An add whose blob is exactly the blob the previous delete
removed is a **restoration**. The walk passes over it, and over that
delete, to the add before. A changeset written afresh under a name a
published cut consumed has other bytes and keeps its own add. A
changeset the walk cannot find as an add keeps the stock commit.
- Shallow clones (the version-PR job checks out at depth 1): the clone
is deepened, in `annotate-shipped`'s bounded rounds, to the last version
commit (every delete that matters lies after it), then further while a
restoration's first add is still beyond the boundary. A shallow boundary
commit diffs against nothing and seems to add every file it carries, so
its adds are never trusted.
- It never stops the version pass. Anything it cannot decide (history
out of reach, not a git repo, any error) keeps the stock commit, with
one `::warning::changeset-changelog:` line. A restoring commit is named
once, as a plain line.
- `annotate-shipped`'s fetch is factored into a shared `deepenBy`
helper. Its reasons and behaviour are unchanged, and its batteries pass
unchanged.
## Not in this pull: the 18.1.0 amendment (b)
The seat split the card. After this merges, the same branch restarts
from `main` and regenerates the 18.1.0 amendment with this generator as
its own pull (`Fixes #25638`). The method, already run once against this
branch's generator (that commit is reverted here):
- The 18.1.0 sections are **regenerated, not hand-edited**: the cut
re-run on `e649c2d91e^` (`8801f2bb37`, the tree #25606 cut) with this
generator (`annotate-shipped`, then `changeset version`), and the
resulting CHANGELOGs copied.
- Compared with `e649c2d91e`, every changed line differs **only in its
7-hex commit**. With hashes normalised, all 79 files are identical.
`main` has not touched any CHANGELOG since `e649c2d91e`.
- 265 distinct entries, none naming `3937697`. The eight **Shipped in
18.0.0** entries name `6b9e6df 7cacad5 950f949 9a06f0b abd5acd de9cd1f
df8bb40 e5b3de0`, exactly the adding commits #25607 measured. The five
post-revert changesets keep `a57643d 9f39094 4a25192 4395cbc cb38a8c`.
- The same re-cut from a **depth-1 clone** (annotate-shipped deepened it
by 700 commits) produced byte-identical CHANGELOGs.
- The published tarballs are not touched. ⛔ No republish of 18.1.0.
## Evidence
- `node scripts/release-pending-publish.mjs --self-test`: 124 cases
across 31 batteries pass, two of them new:
- *add → version → revert → re-cut*: the fixture first proves the stock
lookup names the revert for every restored changeset. Then `a`/`b` name
their own adds, and `l`, a leak added before the 1.0.0 cut, names its
own add. `n`, rewritten under a consumed name, keeps its second add, and
`c`, landed after the revert, is untouched. The re-cut runs through
`scripts/changeset-changelog.mjs`'s own
`getReleaseLine`/`getDependencyReleaseLine`.
- *shallow clone*: bounded deepening reaches each first add, including
past a graft commit that only seems to add `l`. With deepening off, or
outside a repository, the stock commit stays with one warning and
nothing throws.
- Ablations, each reverted after: dropping the blob-equality test fails
the reused-name case. Dropping the boundary guard fails the
shallow-clone case.
- `dispatch-gates --commands`: 108 derived, all 108 run and exit 0 (two
after `pnpm build`, which they need first); `--ran` reconciles 108 of
108, 0 not measured. That run covered the combined diff before the
split, a superset of this one.
- `check:commit-card-trailers --range origin/main..HEAD` and
`check-nul-bytes` pass.
## Tier and surface
- 339 changed lines: `.changeset/config.json`,
`scripts/changeset-changelog.mjs`,
`scripts/release-pending-publish.mjs`. No governed path.
- ⛔ `release.yml` and the root `version` script are **not** touched. The
generator is reached through `.changeset/config.json` (loaded by
`@changesets/apply-release-plan` through `import()`), and its self-test
rides the `release-pending-publish.mjs --self-test` step lint.yml
already runs.
## Acceptance notes
- The 18.1.0 amendment is the second pull, by the method above.
- `unconsumedChangesets` (the `unconsumed` report) still names the
newest add. It reads changesets a version commit left pending, which a
revert does not produce, so it was left alone. Noted, not filed.
`skip-changeset`: `scripts/` and `.changeset/config.json` publish
nothing from any released package.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01X36HeTaoAfX2pS589N9FYP
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 384bb7b commit 24d350b
3 files changed
Lines changed: 331 additions & 8 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
0 commit comments