Skip to content

cut-rc.yml refuses every cut since #9064: sync-docs-image-tags.mjs writes three paths outside the enforced release file surface #9518

Description

@os-project-manager

Found while rehearsing #9497 (the @changesets/cli v3 epic, #9465). It is not caused by that migration — it reproduces identically on today's @changesets/cli@2.31.1, so it is filed on its own.

What is broken

cut-rc.yml's "Build the single version commit" step stages an allowlisted set of paths and then asserts that nothing tracked is left modified-but-unstaged:

LEFT="$(git diff --name-only)"
if [ -n "$LEFT" ]; then
echo "::error::tracked files were modified but fall outside the release file surface, so the version commit would be incomplete. Refusing to push."

pnpm run version now ends with node scripts/sync-docs-image-tags.mjs, which rewrites three paths that the staging pathspec does not cover:

content/docs/deployment/self-hosting.mdx
content/docs/upgrading.mdx
docker/README.md

So LEFT is non-empty and the step exits 1. The cut refuses to push — correctly, by its own rule; the rule's input surface just went stale.

Measured

Throwaway clone of origin/main @ 3397d7ec9 (165 pending changesets), .changeset/pre.json absent, then changeset pre enter rc + the full pnpm run version pipeline, then cut-rc.yml's staging + assertions replayed verbatim:

@changesets/cli@2.31.1 (today's pin)
STAGED count: 156
allowlist regex: accepts every staged path
unstaged assertion: TRIPS on:
content/docs/deployment/self-hosting.mdx
content/docs/upgrading.mdx
docker/README.md

sync-docs-image-tags.mjs's own output for the same run:

 docker/README.md
32:6 image-tag: 17.0.0 -> 18.0.0-rc.0
43:3 image-tag: 17.0.0 -> 18.0.0-rc.0
65:45 build-arg: 17.0.0 -> 18.0.0-rc.0
content/docs/deployment/self-hosting.mdx
76:3 image-tag: 17.0.0 -> 18.0.0-rc.0
94:3 image-tag: 17.0.0 -> 18.0.0-rc.0
145:6 image-tag: 17.0.0 -> 18.0.0-rc.0
163:20 npm-pin: 17.0.0 -> 18.0.0-rc.0
content/docs/upgrading.mdx
41:8 image-tag: 17.0.0 -> 18.0.0-rc.0
8 pin(s) across 3 surface(s)

The same replay under @changesets/cli@3.0.0 trips on exactly the same three paths, so the migration neither causes nor cures it.

Why nobody has seen it

sync-docs-image-tags.mjs was added to the version script by #9064 (2026-08-16). v17.0.0 shipped 2026-08-14. No cut has run since the rewriter joined the pipeline, so the assertion has never been reached with these three files dirty. The workflow's allowlist comment still describes a pnpm run version measured on the 17.0.0-rc.5 -> rc.6 train, before the rewriter existed.

release.yml's version-PR lane is unaffected: changesets/action@v1 runs a plain git add ., with no allowlist.

Fix shape

Per #9465 ruling 3 the allowlist follows the measurement. Widen the staging pathspec and the re-check regex in cut-rc.yml to cover the three docs/docker surfaces the version pass legitimately writes — ideally by naming them as the rewriter's declared output rather than by pattern, so the next surface sync-docs-image-tags.mjs learns about fails loudly here again.

Note for whoever takes this: #9498 rewrites this same allowlist for the v3 pre-mode file set. Whichever lands first should carry the other's change or hand it over explicitly — two PRs editing this block is the shape #9465 exists to prevent.

Metadata

Metadata

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions