Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions .changeset/config.json
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
{
"$schema": "https://unpkg.com/@changesets/config@3.1.2/schema.json",
"$schema": "https://unpkg.com/@changesets/config@4.0.0/schema.json",
"changelog": [
"@changesets/cli/changelog",
{
Expand DownExpand Up@@ -84,7 +84,5 @@
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": [],
"___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": {
"onlyUpdatePeerDependentsWhenOutOfRange": true
}
"privatePackages": { "version": true, "tag": false }
}
46 changes: 34 additions & 12 deletions .github/workflows/cut-rc.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -486,17 +486,39 @@ jobs:
# cut: the pin bump and the version output are one atomic unit, and there is
# never a main commit carrying a bumped pin but an unversioned tree.
#
# WHAT MAY BE IN IT — re-measured on the 17.0.0 -> 18.0.0-rc.0 train (a full
# local `pnpm run version` in a throwaway clone over 199 pending changesets),
# not assumed. 160 paths:
# 77 modified package.json, 76 modified CHANGELOG.md,
# .changeset/pre.json, the 3 major-boundary paths below, and the 3 doc
# surfaces below. Zero deletions. `.changeset/pre.json` is UNTRACKED on the
# first cut of a train (`changeset pre enter` just created it) and modified
# on later ones; `git add -A` covers both. In PRE mode `changeset version`
# does NOT delete the consumed changesets — it records them in pre.json and
# they are removed at `changeset pre exit` — so a cut never races a lane PR
# over a `.changeset/*.md` file it wants to keep.
# WHAT MAY BE IN IT — re-measured under @changesets/cli v3 on the
# 17.0.0 -> 17.1.0-rc.0 train (a full local `pnpm run version` in a throwaway
# clone over 209 pending changesets), not assumed. 365 staged paths:
# 76 modified package.json, 76 modified CHANGELOG.md, 209 changesets MOVED
# into `.changeset/pre/`, `.changeset/pre.json`, and the 3 doc surfaces
# below. `.changeset/pre.json` is UNTRACKED on the first cut of a train
# (`changeset pre enter` just created it) and modified on later ones;
# `git add -A` covers both.
# The 3 major-boundary paths below did NOT appear on this train and are
# allowed for the train that does move the major — as is the blank
# template's own package.json, which is why the v2 measurement this block
# used to carry counted 77 package.json against this one's 76: that train
# was 17.0.0 -> 18.0.0-rc.0, so `sync-template-versions.mjs` had to rewrite
# the template's `^17.0.0` pins. On a minor train it logs "already pins" and
# writes nothing. The counts move with the SHAPE of the train; the
# allowlist below is what does not have to.
#
# THE CONSUMED CHANGESETS MOVE — new in v3 (changesets#2190), and the one
# thing about a cut that this file's prose used to get wrong. v2 left every
# consumed `.changeset/*.md` on disk and recorded it in `pre.json`; v3 moves
# it to `.changeset/pre/NAME.md` VERBATIM (measured: a moved file diffs
# identical to its original, and git reports all 209 as `R100` renames), and
# `pre.json` is `{"mode","tag"}` only — `changeset version` never rewrites
# it. So in the worktree a cut is 209 deletions plus a new untracked
# `.changeset/pre/` directory, and the claim this block used to make — "a
# cut never races a lane PR over a `.changeset/*.md` file it wants to keep"
# — is FALSE under v3. The cut moves tracked changeset paths, so a lane PR
# that edits or deletes one of them conflicts; the rebase guard further down
# is what catches it, and it already names `.changeset` in its conflict
# surface. What does NOT change is this allowlist: `^\.changeset/` covers
# `.changeset/pre/…` and `git add -A -- … .changeset …` stages the deletions
# and the new directory together (measured: all 365 staged paths accepted,
# nothing tracked left unstaged).
# Three more paths can appear at a major boundary and are allowed for that
# reason, all written by `sync-protocol-version.mjs` /
# `sync-template-versions.mjs`: packages/spec/src/kernel/protocol-version.ts
Expand DownExpand Up@@ -848,7 +870,7 @@ jobs:
echo "### Two things that are expected, not defects"
echo
echo "1. **The standing \`chore: version packages (rc)\` PR (#6208) may look stale.**"
echo " Its changesets were consumed by this cut and are recorded in \`.changeset/pre.json\`."
echo " Its changesets were consumed by this cut and moved to \`.changeset/pre/\` (v3)."
echo " Whether it refreshes now depends on the push credential: pushes made with the"
echo " Actions \`GITHUB_TOKEN\` trigger no workflow runs (GitHub's recursion guard), so"
echo " \`version-pr\` does not fire until some later push to main; with a"
Expand Down
44 changes: 32 additions & 12 deletions .github/workflows/pr-automation.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -383,12 +383,25 @@ jobs:
fi
# Count changesets THIS PR adds (diff against the base commit), NOT
# the whole .changeset directory. A global `find | wc -l` is unsound:
# in pre-release (RC) mode `changeset version` RETAINS every consumed
# .md file, so the directory is permanently non-empty and the gate can
# never go red. #3373 merged a real spec/api-surface fix with no
# changeset while this step happily reported "Found 104 changeset(s)".
# Diffing against the merge base ignores that residue and sees only
# what the PR itself introduced. It has to be the MERGE BASE and not
# it counts main's pending stock, which has nothing to do with what this
# PR wrote. #3373 merged a real spec/api-surface fix with no changeset
# while this step happily reported "Found 104 changeset(s)".
# Diffing against the merge base ignores that stock and sees only what
# the PR itself introduced.
#
# That argument used to be stated in terms of pre-mode RESIDUE — under
# @changesets/cli v2, `changeset version` in pre mode retained every
# consumed .md file, so `.changeset/` was permanently non-empty for the
# whole RC window. v3 moves consumed changesets into `.changeset/pre/`
# instead (changesets#2190), so the root directory is no longer
# permanently non-empty. The unsoundness is unchanged and so is this
# step: a stock count is the wrong question in EVERY repo phase, not just
# a polluted one. What the migration did have to be checked against is
# the counter itself, because a cut now MOVES 209 tracked changeset
# paths: measured on a real v3 cut commit, git reports them as `R100`
# renames, so `--diff-filter=A` credits this PR with 0 of them (still 0
# with `diff.renameLimit=1` forced; only `--no-renames` turns them into
# 209 `A` rows, and nothing here passes it). It has to be the MERGE BASE and not
# the payload's frozen `base.sha` -- see the base-resolution step above
# (#6129); with the frozen sha this count silently included every
# changeset main gained while the PR was open.
Expand DownExpand Up@@ -827,12 +840,19 @@ jobs:
# same #6129 reason one defect along (#7005). This script used to read
# the whole `.changeset` directory with no branch point, so its verdict
# was a function of what main carried rather than of what the author
# wrote. That was invisible while pre-mode held and would have become
# visible all at once at `changeset pre exit`: 171 consumed-but-undeleted
# major changesets sit on main until the post-exit `changeset version`
# removes them, so every unlabelled PR open in that window would have
# gone red listing files it never touched, with `allow-major` -- a label
# meaning "a whole-stack major is intended HERE" -- as its only way out.
# wrote. Under @changesets/cli v2 that was invisible while pre-mode held
# and would have become visible all at once at `changeset pre exit`: 171
# consumed-but-undeleted major changesets sat on main until the post-exit
# `changeset version` removed them, so every unlabelled PR open in that
# window would have gone red listing files it never touched, with
# `allow-major` -- a label meaning "a whole-stack major is intended HERE"
# -- as its only way out. v3 retires that particular detonation: each cut
# moves its consumed changesets into `.changeset/pre/`, which the gate's
# root-only reader does not enumerate, so the root stock stays bounded to
# the unconsumed residue. It retires no line of the fix. `--base` is
# correct because a verdict about what a PR INTRODUCED cannot be computed
# without the fork -- #6129's argument, which never depended on how big
# the stock was.
if: >-
steps.labels.outputs.skip != 'true'
&& steps.labels_settled.outputs.skip != 'true'
Expand Down
13 changes: 8 additions & 5 deletions docs/releases-maintenance.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -303,11 +303,14 @@ rediscovered at 2am:
by itself.

**A stale #6208 after an rc cut is EXPECTED AND HARMLESS — do not "fix" it by hand.**
Its changesets were consumed by the cut and are recorded in `.changeset/pre.json`; the
PR is bookkeeping, it carries no publish capability by construction (`release.yml`
passes the changesets action no `publish:` script), and it regenerates correctly at
the next push to `main` or the next GA cut. Editing or force-refreshing it manually
only risks putting a version commit somewhere the publish lane can reach.
Its changesets were consumed by the cut and MOVED into `.changeset/pre/` — under
`@changesets/cli` v3 that move is what "consumed" looks like on disk, and
`.changeset/pre.json` carries `{"mode","tag"}` and nothing else, so it is not a
record of what was consumed (it was, under v2). The PR is bookkeeping, it carries no
publish capability by construction (`release.yml` passes the changesets action no
`publish:` script), and it regenerates correctly at the next push to `main` or the
next GA cut. Editing or force-refreshing it manually only risks putting a version
commit somewhere the publish lane can reach.

**The runtime image is not built here.** `release.yml`'s `release-integrity` lane runs
on every push to `main` and requests the image once the version is on npm, so it
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -117,7 +117,7 @@
"author": "ObjectStack",
"license": "Apache-2.0",
"devDependencies": {
"@changesets/cli": "^2.31.1",
"@changesets/cli": "^3.0.0",
"@types/node": "^26.1.2",
"@typescript-eslint/parser": "^8.65.0",
"eslint": "^10.8.0",
Expand Down
Loading
Loading