Skip to content

fix(changesets): stop re-formatting release notes that already shipped - #1739

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-1602-changeset-prettier-off
Sep 7, 2026
Merged

os-zhuang merged 1 commit into
mainfrom
claude/issue-1602-changeset-prettier-off

Conversation

@claude

@claude claude Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Description

changeset version re-printed the whole of CHANGELOG.md through Prettier on every run,
silently rewriting release notes that had already shipped. This sets prettier: false in
.changeset/config.json (option A of the ruling in #1602 comment 5565948014,
maintainer 「同意」), and repairs the one line the generator had already broken.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • CI/CD update

Related Issues

Fixes #1602
Related to #1503 · #1443

Changes Made

  • .changeset/config.json: adds "prettier": false. The generated region becomes
    write-once — the generator no longer re-formats what it already wrote.
  • CHANGELOG.md: repairs one line of the published ## 3.0.0 section back to the
    text the release actually said. This is the single authorised hand-edit of the
    generated region (ruling item 2).
  • .changeset/changeset-version-stops-rewriting-published-notes.md: the changeset.

⚠️ Correction to the ruling's item 2 — the four named lines were not mangled on disk

Ruling item 2 asked for four lines to be repaired: CHANGELOG.md:4176, :4178, :5236,
:5237 on 81a79ee. Re-anchored before editing, they were already correct, and they
still are on this branch's base b760fb08 at the same four line numbers:

4176:     forecast_category map that actually classifies deals") and the English page has
4178:     `stage`, is the single boundary — the same one the _Closing This Quarter_ view
5236:   priced any line is still refused ("Set is_active=false to retire instead"), and
5237:   lines belonging to other deals are never touched. This is deliberately _not_ the

That is the before column of #1602's own table. Those four lines are what the next
run mangles — the card measured them by running changeset version and restoring — so
with prettier: false there is nothing to repair there: they can no longer be reached.
A repo-wide scan for the mangling signature confirms it. One line, and only one, carries
generator damage today:

CHANGELOG.md:1135 (inside ## 3.0.0)
- ... / status / due*date / owner_id / related_to*\*,没有任何重复字段。
+ ... / status / due_date / owner_id / related_to_*,没有任何重复字段。

Proved to be the generator's damage rather than the author's text: the changeset that
produced that paragraph, .changeset/activities-recurring-example.md as authored at
3ec9feba, says due_date / owner_id / related_to_*. The 3.0.0 generation emitted
due*date and related_to*\*. It does not appear in the card's table because it is
already a Prettier fixed point, so a further run leaves it alone — it is damage that has
shipped and stays shipped until repaired by hand.

The repair is squarely inside the ruling's authorisation and its stated reason ("published
release text is never silently rewritten — this repairs a silent rewrite back to what was
published"); only the line number moved. No other line of the generated region is touched.

Testing

Both probes ran on a throwaway worktree, were restored, and the restore is proven by blob
hash. ⛔ Neither run's output is committed.

Before — Prettier on (config sets no key), tree at b760fb08:

$ pnpm changeset version      -> exit 0
$ git diff --numstat CHANGELOG.md
4917    4    CHANGELOG.md
$ git diff -U0 CHANGELOG.md | grep '^-[^-]'
-    forecast_category map that actually classifies deals") and the English page has
-    `stage`, is the single boundary — the same one the _Closing This Quarter_ view
-  priced any line is still refused ("Set is_active=false to retire instead"), and
-  lines belonging to other deals are never touched. This is deliberately _not_ the

and what replaced them, at their new positions in the rewritten file:

9089:     forecast*category map that actually classifies deals") and the English page has
9091:     `stage`, is the single boundary — the same one the \_Closing This Quarter* view
10149:   priced any line is still refused ("Set is*active=false to retire instead"), and
10150:   lines belonging to other deals are never touched. This is deliberately \_not* the

Exactly the four rewrites #1602 tabulated, reproduced independently. Restore:
git hash-object CHANGELOG.md = 877ec8d4… = git rev-parse HEAD:CHANGELOG.md,
git diff HEAD empty.

After — prettier: false, tree at this branch's commit 465dad24:

$ pnpm changeset version      -> exit 0
$ git diff --numstat CHANGELOG.md
4806    0    CHANGELOG.md
$ git diff -U0 CHANGELOG.md | grep '^@@'
@@ -2,0 +3,4806 @@
$ git diff -U0 CHANGELOG.md | grep -c '^-[^-]'
0

One hunk, zero deletions — a pure prepend of the new section under the # Changelog
title. The pre-existing region is byte-identical, not merely diff-clean:

sha256(old file from line 3 on)          = d60fab5699e084561991cc0b37f9b77f9bfbf41985c6b105987e2ab135b29c0c
sha256(new file from line 4809 on)       = d60fab5699e084561991cc0b37f9b77f9bfbf41985c6b105987e2ab135b29c0c
cmp -> identical

Restore: git hash-object CHANGELOG.md = 4e301190… = git rev-parse HEAD:CHANGELOG.md,
git diff HEAD empty, git status clean.

pnpm verify — green, run in two locked calls on the shared box, in the chain's own
order (validate → typecheck → lint → lint:i18n-gate → hygiene → hygiene:tokens, then
build → test):

os-verify-lock: VERDICT command-exit 0 · held the lock 38s
os-verify-lock: VERDICT command-exit 0 · held the lock 238s (3m58s)

 Test Files  161 passed (161)
      Tests  3416 passed | 1 skipped (3417)
  • Unit tests pass (pnpm test)
  • Linting passes (pnpm lint)
  • Build succeeds (pnpm build)
  • pnpm validate, pnpm lint:i18n-gate, pnpm hygiene, pnpm hygiene:tokens pass

Ruling item 3 — the stranded preamble at :9007 stays where it is

The ruling permits moving it "if the dev judges it a one-hunk change". It is not one. The
preamble is a single line ~9,000 lines below the title, so moving it is a deletion hunk at
:9007 and an insertion hunk at :2 — two hunks by construction. It also sits inside the
generated ## 3.0.0 region (which ends at :9008, immediately above the
## Pre-3.0.0 hand-written history heading), so moving it would be a second hand-edit
of that region, and the ruling authorises exactly one. Left alone, and said so — the
remaining half of #1443's observation is still open.

Checklist — the changeset, and why 'hotcrm': patch rather than empty frontmatter

There is no scripts/check-changeset-* in this repo; the decision source is
.github/workflows/changeset-check.yml plus the split already in .changeset/ (148
entries: 76 with empty frontmatter, 72 versioned). The documented boundary in the
empty-frontmatter entries is "ships nothing to HotCRM users; no src/ metadata changed".

This one ships something to users: CHANGELOG.md is the artifact HotCRM publishes,
and the repaired line is text a reader of the 3.0.0 notes has already been given. HotCRM
is the reference implementation other marketplace apps fork, so a release note naming
due*date — a column that does not exist — is precisely the error that gets copied.
The release-notes reader is entitled to be told it was wrong and is now right. Hence a
versioned patch entry, matching the repo's other corrections-to-published-prose entries.

  • I have added a changeset
  • I have performed a self-review of my own code
  • My changes generate no new warnings
  • New and existing unit tests pass locally with my changes

Additional Notes

⚠️ #1503 / dependabot PR #1264 inherit this. @changesets/cli 3.x replaces the
prettier key with format, so the key this PR sets stops existing at the bump. #1264
must not merge until #1503 sets the off-equivalent under the new name; otherwise this
fix is silently undone and the next release re-mangles the four lines above.


Generated by Claude Code

`changeset version` re-printed the whole of `CHANGELOG.md` through Prettier on
every run, because Prettier is on unless a project turns it off and
`.changeset/config.json` never set the key. Prettier re-pairs emphasis
delimiters across a paragraph, so an underscore inside a field name pairs with
the underscore of a nearby italic span and both are re-emitted with the wrong
delimiters. The command exits 0 and the churn hides inside a several-thousand
line addition.

Set `prettier: false`, so a release section is written once and is never
re-formatted afterwards.

It had already cost the repo one shipped line: the generated 3.0.0 notes say
the renewal task writes `due*date` and `related_to*\*`, where the changeset
that produced them (`.changeset/activities-recurring-example.md`, authored at
3ec9feb) said `due_date` and `related_to_*`. That line is repaired back to
what the release actually said — the one hand-edit of the generated region the
#1602 ruling authorises, because the generator is what broke it.

Measured on a throwaway copy, not read out of the docs: with Prettier on,
`changeset version` rewrites four further lines of the shipped 3.0.0 section
(`forecast_category` -> `forecast*category`, `is_active` -> `is*active`, and
the italic spans either side of them); with `prettier: false` the entire
pre-existing file comes back byte-identical.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TezFG8ZMrNH6n5VTNpPpdH
@vercel

vercel Bot commented Sep 7, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
hotcrm Ignored Ignored Sep 7, 2026 11:34am UTC

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation configuration Build and app configuration files labels Sep 7, 2026
@os-zhuang
os-zhuang marked this pull request as ready for review September 7, 2026 14:10
@os-zhuang
os-zhuang added this pull request to the merge queue Sep 7, 2026
Merged via the queue into main with commit e735d00 Sep 7, 2026
10 checks passed
os-zhuang pushed a commit that referenced this pull request Sep 7, 2026
#1739 landed on main as a squash (e735d00), so this branch's own copy of it
(465dad2) is no longer an ancestor of main and the two sides collide.

One file conflicted: `.changeset/config.json`. Both sides edit the formatter
switch. main writes `prettier: false`; under @changesets/cli 3.x that key is
removed — it is accepted in silence, produces no warning, and formatting falls
back to its `format: "auto"` default, which is exactly the re-mangling of
published release notes that #1739 set out to stop. This branch's `format: false`
is what carries #1739's intent forward, so it is what the merge keeps, together
with `privatePackages: { version: true, tag: false }` and the `$schema` bump to
@changesets/config@4.0.0.

Verified against the installed @changesets/config 4.0.0 rather than by reading:
`readConfig()` on the merged tree resolves `format: false` and
`privatePackages: {version: true, tag: false}` with no errors and no warnings.
The control — main's side of the hunk through the same 4.0.0 validator — resolves
`format: "auto"` and `privatePackages: {version: false, tag: false}`, silently.

CHANGELOG.md and `.changeset/changeset-version-stops-rewriting-published-notes.md`
merged clean and byte-identical to main: #1739's `due_date` / `related_to_*`
repair is present exactly once, and there is one changeset for that fix, not two.
pnpm-lock.yaml did not conflict (main never touched it) and stays as the branch
resolved it; `pnpm install --frozen-lockfile` reports the lockfile up to date.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TezFG8ZMrNH6n5VTNpPpdH
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

configuration Build and app configuration files documentation Improvements or additions to documentation

Projects

None yet

2 participants