From ffb96207379d1eb882c125cb2de6bd669324b9d3 Mon Sep 17 00:00:00 2001 From: Lachlan Collins <1667261+lachlancollins@users.noreply.github.com> Date: Tue, 17 Mar 2026 14:48:51 +1100 Subject: [PATCH 1/9] WIP: use @changesets/get-release-plan --- .changeset/curly-bugs-rescue.md | 5 + .github/changeset-preview/action.yml | 4 + .github/changeset-preview/package.json | 5 + .../preview-changeset-versions.mjs | 150 +++++------------- packages/publish-config/package.json | 3 + 5 files changed, 61 insertions(+), 106 deletions(-) create mode 100644 .changeset/curly-bugs-rescue.md create mode 100644 .github/changeset-preview/package.json diff --git a/.changeset/curly-bugs-rescue.md b/.changeset/curly-bugs-rescue.md new file mode 100644 index 00000000..e0745b8b --- /dev/null +++ b/.changeset/curly-bugs-rescue.md @@ -0,0 +1,5 @@ +--- +'@tanstack/eslint-config': minor +--- + +test diff --git a/.github/changeset-preview/action.yml b/.github/changeset-preview/action.yml index 8a32dde8..0248f810 100644 --- a/.github/changeset-preview/action.yml +++ b/.github/changeset-preview/action.yml @@ -3,6 +3,10 @@ description: Generates comment on a PR showing expected version impact runs: using: composite steps: + - name: Install dependencies + shell: bash + run: npm install + working-directory: ${{ github.action_path }} - name: Preview version bumps shell: bash run: node ${{ github.action_path }}/preview-changeset-versions.mjs --output /tmp/changeset-preview.md diff --git a/.github/changeset-preview/package.json b/.github/changeset-preview/package.json new file mode 100644 index 00000000..d388a203 --- /dev/null +++ b/.github/changeset-preview/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "@changesets/get-release-plan": "^4.0.15" + } +} diff --git a/.github/changeset-preview/preview-changeset-versions.mjs b/.github/changeset-preview/preview-changeset-versions.mjs index 2569314c..2058dc42 100644 --- a/.github/changeset-preview/preview-changeset-versions.mjs +++ b/.github/changeset-preview/preview-changeset-versions.mjs @@ -13,69 +13,18 @@ * revert the changes it makes. */ -import { execSync } from 'node:child_process' -import { readdirSync, readFileSync, writeFileSync } from 'node:fs' -import { join, resolve } from 'node:path' +import { writeFileSync } from 'node:fs' +import { resolve } from 'node:path' import { parseArgs } from 'node:util' +import getReleasePlan from '@changesets/get-release-plan' const ROOT = resolve(import.meta.dirname, '..', '..') -const PACKAGES_DIR = join(ROOT, 'packages') - -function readPackageVersions() { - const versions = new Map() - for (const dir of readdirSync(PACKAGES_DIR, { withFileTypes: true })) { - if (!dir.isDirectory()) continue - const pkgPath = join(PACKAGES_DIR, dir.name, 'package.json') - try { - const pkg = JSON.parse(readFileSync(pkgPath, 'utf8')) - if (pkg.name && pkg.version && pkg.private !== true) { - versions.set(pkg.name, pkg.version) - } - } catch { - // skip packages without a valid package.json - } - } - return versions -} - -function readChangesetEntries() { - const changesetDir = join(ROOT, '.changeset') - const explicit = new Map() - for (const file of readdirSync(changesetDir)) { - if (file === 'config.json' || file === 'README.md' || !file.endsWith('.md')) - continue - const content = readFileSync(join(changesetDir, file), 'utf8') - const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/) - if (!frontmatterMatch) continue - for (const line of frontmatterMatch[1].split('\n')) { - const match = line.match(/^['"]?([^'"]+)['"]?\s*:\s*(major|minor|patch)/) - if (match) { - const [, name, bump] = match - const existing = explicit.get(name) - // keep the highest bump if a package appears in multiple changesets - if (!existing || bumpRank(bump) > bumpRank(existing)) { - explicit.set(name, bump) - } - } - } - } - return explicit -} - function bumpRank(bump) { return bump === 'major' ? 3 : bump === 'minor' ? 2 : 1 } -function bumpType(oldVersion, newVersion) { - const [oMaj, oMin] = oldVersion.split('.').map(Number) - const [nMaj, nMin] = newVersion.split('.').map(Number) - if (nMaj > oMaj) return 'major' - if (nMin > oMin) return 'minor' - return 'patch' -} - -function main() { +async function main() { const { values } = parseArgs({ args: process.argv.slice(2), options: { @@ -85,10 +34,10 @@ function main() { allowPositionals: false, }) - // 1. Read explicit changeset entries - const explicit = readChangesetEntries() + const releasePlan = await getReleasePlan(ROOT) + const releases = releasePlan.releases - if (explicit.size === 0) { + if (releases.length === 0) { const msg = 'No changeset entries found. Merging this PR will not cause a version bump for any packages.\n' process.stdout.write(msg) @@ -99,42 +48,18 @@ function main() { return } - // 2. Snapshot current versions - const before = readPackageVersions() - - // 3. Temporarily swap changeset config to skip changelog generation - // (the GitHub changelog plugin requires a token we don't need for previews) - const configPath = join(ROOT, '.changeset', 'config.json') - const originalConfig = readFileSync(configPath, 'utf8') - try { - const config = JSON.parse(originalConfig) - config.changelog = false - writeFileSync(configPath, JSON.stringify(config, null, 2)) - - // 4. Run changeset version - execSync('pnpm changeset version', { cwd: ROOT, stdio: 'pipe' }) - } finally { - // Always restore the original config - writeFileSync(configPath, originalConfig) - } - - // 5. Read new versions - const after = readPackageVersions() - // 6. Diff const bumps = [] - for (const [name, newVersion] of after) { - const oldVersion = before.get(name) - if (!oldVersion || oldVersion === newVersion) continue - const bump = bumpType(oldVersion, newVersion) - const source = explicit.has(name) ? explicit.get(name) : 'dependency' - bumps.push({ name, oldVersion, newVersion, bump, source }) + for (const release of releases) { + if (release.oldVersion === release.newVersion) continue + const reason = release.changesets.length !== 0 ? 'direct' : 'indirect' + bumps.push({ ...release, reason }) } // Sort: major first, then minor, then patch; within each group alphabetical bumps.sort( (a, b) => - bumpRank(b.bump) - bumpRank(a.bump) || a.name.localeCompare(b.name), + bumpRank(b.type) - bumpRank(a.type) || a.name.localeCompare(b.name), ) // 7. Build markdown @@ -145,41 +70,54 @@ function main() { 'No version changes detected. Merging this PR will not cause a version bump for any packages.', ) } else { - const explicitBumps = bumps.filter((b) => b.source !== 'dependency') - const dependencyBumps = bumps.filter((b) => b.source === 'dependency') + const majorBumps = bumps.filter((b) => b.type === 'major') + const minorBumps = bumps.filter((b) => b.type === 'minor') + const patchBumps = bumps.filter((b) => b.type === 'patch') + const directBumps = bumps.filter((b) => b.reason === 'direct') + const indirectBumps = bumps.filter((b) => b.reason === 'indirect') lines.push( - `**${explicitBumps.length}** package(s) bumped directly, **${dependencyBumps.length}** bumped as dependents.`, + `**${directBumps.length}** package(s) bumped directly, **${indirectBumps.length}** bumped as dependents.`, ) lines.push('') - if (explicitBumps.length > 0) { - lines.push('### Direct bumps') + if (majorBumps.length > 0) { + lines.push('### Major bumps') lines.push('') - lines.push('| Package | Bump | Version |') + lines.push('| Package | Version | Reason |') lines.push('| --- | --- | --- |') - for (const b of explicitBumps) { + for (const b of majorBumps) { lines.push( - `| \`${b.name}\` | **${b.bump}** | ${b.oldVersion} → ${b.newVersion} |`, + `| \`${b.name}\` | ${b.oldVersion} → ${b.newVersion} |${b.reason} |`, ) } lines.push('') } - if (dependencyBumps.length > 0) { - lines.push( - '
', - `Dependency bumps (${dependencyBumps.length})`, - '', - '| Package | Bump | Version |', - '| --- | --- | --- |', - ) - for (const b of dependencyBumps) { + if (minorBumps.length > 0) { + lines.push('### Minor bumps') + lines.push('') + lines.push('| Package | Version | Reason |') + lines.push('| --- | --- | --- |') + for (const b of minorBumps) { lines.push( - `| \`${b.name}\` | ${b.bump} | ${b.oldVersion} → ${b.newVersion} |`, + `| \`${b.name}\` | ${b.oldVersion} → ${b.newVersion} |${b.reason} |`, ) } - lines.push('', '
') + lines.push('') + } + + if (patchBumps.length > 0) { + lines.push('### Patch bumps') + lines.push('') + lines.push('| Package | Version | Reason |') + lines.push('| --- | --- | --- |') + for (const b of patchBumps) { + lines.push( + `| \`${b.name}\` | ${b.oldVersion} → ${b.newVersion} |${b.reason} |`, + ) + } + lines.push('') } } diff --git a/packages/publish-config/package.json b/packages/publish-config/package.json index 98ed6258..213badf2 100644 --- a/packages/publish-config/package.json +++ b/packages/publish-config/package.json @@ -48,5 +48,8 @@ "@types/jsonfile": "catalog:", "@types/semver": "catalog:", "type-fest": "catalog:" + }, + "peerDependencies": { + "@tanstack/eslint-config": ">=0.4.0" } } From 08b7eacf5904558b4108428691e24a12794a0b77 Mon Sep 17 00:00:00 2001 From: Lachlan Collins <1667261+lachlancollins@users.noreply.github.com> Date: Tue, 17 Mar 2026 14:52:01 +1100 Subject: [PATCH 2/9] Tweak reason --- .github/changeset-preview/preview-changeset-versions.mjs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/changeset-preview/preview-changeset-versions.mjs b/.github/changeset-preview/preview-changeset-versions.mjs index 2058dc42..87c4e4cc 100644 --- a/.github/changeset-preview/preview-changeset-versions.mjs +++ b/.github/changeset-preview/preview-changeset-versions.mjs @@ -52,7 +52,7 @@ async function main() { const bumps = [] for (const release of releases) { if (release.oldVersion === release.newVersion) continue - const reason = release.changesets.length !== 0 ? 'direct' : 'indirect' + const reason = release.changesets.length !== 0 ? 'Changeset' : 'Dependent' bumps.push({ ...release, reason }) } @@ -73,8 +73,8 @@ async function main() { const majorBumps = bumps.filter((b) => b.type === 'major') const minorBumps = bumps.filter((b) => b.type === 'minor') const patchBumps = bumps.filter((b) => b.type === 'patch') - const directBumps = bumps.filter((b) => b.reason === 'direct') - const indirectBumps = bumps.filter((b) => b.reason === 'indirect') + const directBumps = bumps.filter((b) => b.reason === 'Changeset') + const indirectBumps = bumps.filter((b) => b.reason === 'Dependent') lines.push( `**${directBumps.length}** package(s) bumped directly, **${indirectBumps.length}** bumped as dependents.`, From 40e32a3f8cb08a8f44e6881417fed368b6ac2316 Mon Sep 17 00:00:00 2001 From: Lachlan Collins <1667261+lachlancollins@users.noreply.github.com> Date: Tue, 17 Mar 2026 14:56:03 +1100 Subject: [PATCH 3/9] Add colours --- .changeset/curly-bugs-rescue.md | 2 +- .changeset/thin-mugs-judge.md | 5 +++++ .github/changeset-preview/preview-changeset-versions.mjs | 6 +++--- packages/publish-config/package.json | 3 --- packages/vite-config/package.json | 1 + pnpm-lock.yaml | 3 +++ 6 files changed, 13 insertions(+), 7 deletions(-) create mode 100644 .changeset/thin-mugs-judge.md diff --git a/.changeset/curly-bugs-rescue.md b/.changeset/curly-bugs-rescue.md index e0745b8b..c642002f 100644 --- a/.changeset/curly-bugs-rescue.md +++ b/.changeset/curly-bugs-rescue.md @@ -1,5 +1,5 @@ --- -'@tanstack/eslint-config': minor +'@tanstack/publish-config': minor --- test diff --git a/.changeset/thin-mugs-judge.md b/.changeset/thin-mugs-judge.md new file mode 100644 index 00000000..02602fdd --- /dev/null +++ b/.changeset/thin-mugs-judge.md @@ -0,0 +1,5 @@ +--- +'@tanstack/typedoc-config': major +--- + +TEST diff --git a/.github/changeset-preview/preview-changeset-versions.mjs b/.github/changeset-preview/preview-changeset-versions.mjs index 87c4e4cc..be8550d2 100644 --- a/.github/changeset-preview/preview-changeset-versions.mjs +++ b/.github/changeset-preview/preview-changeset-versions.mjs @@ -82,7 +82,7 @@ async function main() { lines.push('') if (majorBumps.length > 0) { - lines.push('### Major bumps') + lines.push('### 🟥 Major bumps') lines.push('') lines.push('| Package | Version | Reason |') lines.push('| --- | --- | --- |') @@ -95,7 +95,7 @@ async function main() { } if (minorBumps.length > 0) { - lines.push('### Minor bumps') + lines.push('### 🟨 Minor bumps') lines.push('') lines.push('| Package | Version | Reason |') lines.push('| --- | --- | --- |') @@ -108,7 +108,7 @@ async function main() { } if (patchBumps.length > 0) { - lines.push('### Patch bumps') + lines.push('### 🟩 Patch bumps') lines.push('') lines.push('| Package | Version | Reason |') lines.push('| --- | --- | --- |') diff --git a/packages/publish-config/package.json b/packages/publish-config/package.json index 213badf2..98ed6258 100644 --- a/packages/publish-config/package.json +++ b/packages/publish-config/package.json @@ -48,8 +48,5 @@ "@types/jsonfile": "catalog:", "@types/semver": "catalog:", "type-fest": "catalog:" - }, - "peerDependencies": { - "@tanstack/eslint-config": ">=0.4.0" } } diff --git a/packages/vite-config/package.json b/packages/vite-config/package.json index 7c60fc37..b02f8c7c 100644 --- a/packages/vite-config/package.json +++ b/packages/vite-config/package.json @@ -41,6 +41,7 @@ "node": ">=18" }, "dependencies": { + "@tanstack/publish-config": "workspace:*", "vite-plugin-dts": "catalog:", "vite-plugin-externalize-deps": "catalog:", "vite-tsconfig-paths": "catalog:" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5fa72d3a..6eb8ac91 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -343,6 +343,9 @@ importers: packages/vite-config: dependencies: + '@tanstack/publish-config': + specifier: workspace:* + version: link:../publish-config vite-plugin-dts: specifier: 'catalog:' version: 4.2.3(@types/node@25.3.3)(rollup@4.59.0)(typescript@6.0.1-rc)(vite@8.0.0(@types/node@25.3.3)(esbuild@0.27.3)(jiti@2.6.1)(yaml@2.8.2)) From fc7831d1bf4067cd59dffa532a1acf59a23327d2 Mon Sep 17 00:00:00 2001 From: Lachlan Collins <1667261+lachlancollins@users.noreply.github.com> Date: Tue, 17 Mar 2026 14:57:00 +1100 Subject: [PATCH 4/9] Don't double log --- .github/changeset-preview/upsert-pr-comment.mjs | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/changeset-preview/upsert-pr-comment.mjs b/.github/changeset-preview/upsert-pr-comment.mjs index 7d106302..cb914c6c 100644 --- a/.github/changeset-preview/upsert-pr-comment.mjs +++ b/.github/changeset-preview/upsert-pr-comment.mjs @@ -111,8 +111,6 @@ async function main() { const rawBody = await fsp.readFile(bodyPath, 'utf8') const body = `${args.marker}\n## 🚀 Changeset Version Preview\n\n${rawBody}` - process.stdout.write(body) - const comments = await listIssueComments({ apiUrl: args.apiUrl, token: args.token, From caaae74c0a5e45692921a94526840e0ddda24c72 Mon Sep 17 00:00:00 2001 From: Lachlan Collins <1667261+lachlancollins@users.noreply.github.com> Date: Tue, 17 Mar 2026 15:02:10 +1100 Subject: [PATCH 5/9] Sort by name only --- .github/changeset-preview/preview-changeset-versions.mjs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/changeset-preview/preview-changeset-versions.mjs b/.github/changeset-preview/preview-changeset-versions.mjs index be8550d2..44c36c0b 100644 --- a/.github/changeset-preview/preview-changeset-versions.mjs +++ b/.github/changeset-preview/preview-changeset-versions.mjs @@ -56,11 +56,7 @@ async function main() { bumps.push({ ...release, reason }) } - // Sort: major first, then minor, then patch; within each group alphabetical - bumps.sort( - (a, b) => - bumpRank(b.type) - bumpRank(a.type) || a.name.localeCompare(b.name), - ) + bumps.sort((a, b) => a.name.localeCompare(b.name)) // 7. Build markdown const lines = [] @@ -117,7 +113,6 @@ async function main() { `| \`${b.name}\` | ${b.oldVersion} → ${b.newVersion} |${b.reason} |`, ) } - lines.push('') } } From 7870635ec1246c4130085d7c82d3e0233a7d6802 Mon Sep 17 00:00:00 2001 From: Lachlan Collins <1667261+lachlancollins@users.noreply.github.com> Date: Tue, 17 Mar 2026 15:06:09 +1100 Subject: [PATCH 6/9] Update sorting --- .changeset/curly-bugs-rescue.md | 2 +- .../changeset-preview/preview-changeset-versions.mjs | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.changeset/curly-bugs-rescue.md b/.changeset/curly-bugs-rescue.md index c642002f..4b83e6d4 100644 --- a/.changeset/curly-bugs-rescue.md +++ b/.changeset/curly-bugs-rescue.md @@ -1,5 +1,5 @@ --- -'@tanstack/publish-config': minor +'@tanstack/publish-config': patch --- test diff --git a/.github/changeset-preview/preview-changeset-versions.mjs b/.github/changeset-preview/preview-changeset-versions.mjs index 44c36c0b..2db91562 100644 --- a/.github/changeset-preview/preview-changeset-versions.mjs +++ b/.github/changeset-preview/preview-changeset-versions.mjs @@ -20,8 +20,8 @@ import getReleasePlan from '@changesets/get-release-plan' const ROOT = resolve(import.meta.dirname, '..', '..') -function bumpRank(bump) { - return bump === 'major' ? 3 : bump === 'minor' ? 2 : 1 +function reasonRank(reason) { + return reason === 'Changeset' ? 2 : 1 } async function main() { @@ -56,7 +56,12 @@ async function main() { bumps.push({ ...release, reason }) } - bumps.sort((a, b) => a.name.localeCompare(b.name)) + // Order by reason and name + bumps.sort( + (a, b) => + reasonRank(b.reason) - reasonRank(a.reason) || + a.name.localeCompare(b.name), + ) // 7. Build markdown const lines = [] From c6927ee063f3ab2eb024d4db32d9bc4d1de3e09b Mon Sep 17 00:00:00 2001 From: Lachlan Collins <1667261+lachlancollins@users.noreply.github.com> Date: Tue, 17 Mar 2026 15:07:35 +1100 Subject: [PATCH 7/9] Fix spacing --- .github/changeset-preview/preview-changeset-versions.mjs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/changeset-preview/preview-changeset-versions.mjs b/.github/changeset-preview/preview-changeset-versions.mjs index 2db91562..6cb67b32 100644 --- a/.github/changeset-preview/preview-changeset-versions.mjs +++ b/.github/changeset-preview/preview-changeset-versions.mjs @@ -89,7 +89,7 @@ async function main() { lines.push('| --- | --- | --- |') for (const b of majorBumps) { lines.push( - `| \`${b.name}\` | ${b.oldVersion} → ${b.newVersion} |${b.reason} |`, + `| \`${b.name}\` | ${b.oldVersion} → ${b.newVersion} | ${b.reason} |`, ) } lines.push('') @@ -102,7 +102,7 @@ async function main() { lines.push('| --- | --- | --- |') for (const b of minorBumps) { lines.push( - `| \`${b.name}\` | ${b.oldVersion} → ${b.newVersion} |${b.reason} |`, + `| \`${b.name}\` | ${b.oldVersion} → ${b.newVersion} | ${b.reason} |`, ) } lines.push('') @@ -115,7 +115,7 @@ async function main() { lines.push('| --- | --- | --- |') for (const b of patchBumps) { lines.push( - `| \`${b.name}\` | ${b.oldVersion} → ${b.newVersion} |${b.reason} |`, + `| \`${b.name}\` | ${b.oldVersion} → ${b.newVersion} | ${b.reason} |`, ) } } From 0632a6d5ecf459bb63d4d64d15db13ce57572f7b Mon Sep 17 00:00:00 2001 From: Lachlan Collins <1667261+lachlancollins@users.noreply.github.com> Date: Tue, 17 Mar 2026 22:09:31 +1100 Subject: [PATCH 8/9] Undo temp changes --- .changeset/curly-bugs-rescue.md | 5 ----- .changeset/thin-mugs-judge.md | 5 ----- packages/vite-config/package.json | 1 - pnpm-lock.yaml | 3 --- 4 files changed, 14 deletions(-) delete mode 100644 .changeset/curly-bugs-rescue.md delete mode 100644 .changeset/thin-mugs-judge.md diff --git a/.changeset/curly-bugs-rescue.md b/.changeset/curly-bugs-rescue.md deleted file mode 100644 index 4b83e6d4..00000000 --- a/.changeset/curly-bugs-rescue.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/publish-config': patch ---- - -test diff --git a/.changeset/thin-mugs-judge.md b/.changeset/thin-mugs-judge.md deleted file mode 100644 index 02602fdd..00000000 --- a/.changeset/thin-mugs-judge.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/typedoc-config': major ---- - -TEST diff --git a/packages/vite-config/package.json b/packages/vite-config/package.json index b02f8c7c..7c60fc37 100644 --- a/packages/vite-config/package.json +++ b/packages/vite-config/package.json @@ -41,7 +41,6 @@ "node": ">=18" }, "dependencies": { - "@tanstack/publish-config": "workspace:*", "vite-plugin-dts": "catalog:", "vite-plugin-externalize-deps": "catalog:", "vite-tsconfig-paths": "catalog:" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6eb8ac91..5fa72d3a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -343,9 +343,6 @@ importers: packages/vite-config: dependencies: - '@tanstack/publish-config': - specifier: workspace:* - version: link:../publish-config vite-plugin-dts: specifier: 'catalog:' version: 4.2.3(@types/node@25.3.3)(rollup@4.59.0)(typescript@6.0.1-rc)(vite@8.0.0(@types/node@25.3.3)(esbuild@0.27.3)(jiti@2.6.1)(yaml@2.8.2)) From 369af434aec0e43b731f826b53f12adfe62b35fa Mon Sep 17 00:00:00 2001 From: Lachlan Collins <1667261+lachlancollins@users.noreply.github.com> Date: Tue, 17 Mar 2026 22:12:36 +1100 Subject: [PATCH 9/9] Update description --- .../changeset-preview/preview-changeset-versions.mjs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/.github/changeset-preview/preview-changeset-versions.mjs b/.github/changeset-preview/preview-changeset-versions.mjs index 6cb67b32..fd631853 100644 --- a/.github/changeset-preview/preview-changeset-versions.mjs +++ b/.github/changeset-preview/preview-changeset-versions.mjs @@ -1,16 +1,7 @@ #!/usr/bin/env node /** - * Preview the version bumps that `changeset version` will produce. - * - * Workflow: - * 1. Snapshot every workspace package's current version - * 2. Run `changeset version` (mutates package.json files) - * 3. Diff against the snapshot - * 4. Print a markdown summary (or write to --output file) - * - * This script is meant to run in CI on a disposable checkout — it does NOT - * revert the changes it makes. + * Uses `@changesets/get-release-plan` to get the version bumps and formats it as markdown. */ import { writeFileSync } from 'node:fs'