fix(scripts): move released-changesets ledger out of .changeset/

@changesets/read treats every directory inside .changeset/ as a legacy
v1 changeset and tries to read changes.md from it, which made
`changeset version` fail with ENOENT on .changeset/.released/changes.md.
Move the per-branch ledger to .changeset-released/ at the repo root.
This commit is contained in:
Zoltan Kochan
2026-05-07 00:15:34 +02:00
parent 997a8ca9bf
commit 306fefbb1d
3 changed files with 10 additions and 4 deletions

View File

@@ -8,6 +8,8 @@ Fixes are cherry-picked between `main` and `release/*` branches, so the same cha
The ledger prevents that double-application. Each branch only writes to its own file, so cross-branch merges are conflict-free; the wrapper around `changeset version` reads the union of every file when deciding what to skip.
The directory lives at the repo root (sibling of `.changeset/`) rather than inside `.changeset/` because `@changesets/read` treats every directory inside `.changeset/` as a legacy v1 changeset and tries to read `changes.md` from it.
## How it gets updated
`pnpm bump` runs the wrapper at `__utils__/scripts/src/bump.ts`, which:

View File

@@ -1,9 +1,13 @@
// Wrapper around `changeset version` that prevents cherry-picked changesets
// from being applied twice when a release branch is merged back into main.
// Maintains a per-branch ledger at .changeset/.released/<branch>.txt of
// Maintains a per-branch ledger at .changeset-released/<branch>.txt of
// consumed changeset ids; before running `changeset version` it hides any
// changeset whose id is already in the union of those files. See
// .changeset/.released/README.md for the full explanation.
// .changeset-released/README.md for the full explanation.
//
// The ledger lives outside `.changeset/` because `@changesets/read` treats
// every directory inside `.changeset/` as a legacy v1 changeset and tries to
// read `changes.md` from it.
import { execSync } from 'node:child_process'
import fs from 'node:fs'
@@ -105,7 +109,7 @@ function detectCurrentBranch (cwd: string): string {
function main (): void {
const repoRoot = path.resolve(import.meta.dirname, '../../..')
const changesetDir = path.join(repoRoot, '.changeset')
const releasedDir = path.join(changesetDir, '.released')
const releasedDir = path.join(repoRoot, '.changeset-released')
const branch = detectCurrentBranch(repoRoot)
console.log(`Branch: ${branch}`)

View File

@@ -81,7 +81,7 @@ describe('appendReleased', () => {
})
test('creates the released directory if missing', () => {
const nested = path.join(dir, 'nested', '.released')
const nested = path.join(dir, 'nested', 'released')
appendReleased(nested, 'main', ['foo'])
expect(fs.readFileSync(path.join(nested, 'main.txt'), 'utf8')).toBe('foo\n')
})