Uh oh!
There was an error while loading. Please reload this page.
Sync manifest versions during the bump, not after publish, and guard it - #186
Merged
Conversation
🦋 Changeset detectedLatest commit: 456ad51 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
`ci:publish` ran `pnpm build && changeset publish && pnpm version:sync`. The sync happened AFTER the publish, mutating manifests in a CI workspace that was then discarded — so every git tag shipped stale version constants, and `cargo publish --allow-dirty` existed only to paper over the dirt. On a repo publishing 4.4.0 to npm, this is what the manifests actually said: package.json 4.4.0 python/pyproject.toml 3.2.3 python/uv.lock 3.2.3 rust/logger/Cargo.toml/.lock 3.1.2 go/version.go 3.2.3 dotnet/…/SmooAI.Logger.csproj 4.1.0 The sync moves into the changesets `version` lifecycle, whose working tree the action commits, so the bumped manifests land in the release commit. cargo publish drops --allow-dirty and gains --locked (verified: cargo check --locked and cargo package both clean after the sync). python/uv.lock joins the synced set. It was missed before and is not cosmetic: `poe install-dev` runs `uv sync --locked`, which errors outright when the lock disagrees with pyproject.toml — so syncing pyproject alone would have broken dev installs. sync-versions also rewrites go.mod's /vN suffix on a major bump, which is the other half of the tag-resolution fix. The new check:versions guard fails — never warns — when any manifest disagrees. It runs in PR checks and again inside the release tagging step, which is the only point where the post-bump version that becomes the tag exists. Verified red by hand-setting go/version.go to 9.9.9. check-go-module is folded into it rather than kept alongside: both now read the same scripts/versioned-files.mjs, so the guard cannot drift from the syncer. A hand-copied second list is precisely the failure mode this change is about. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0152bbE1veqfG1SVJdyLCBxC
brentragerforce-pushed
the
fix/version-sync
branch
from
August 20, 2026 18:27
92f0359 to
456ad51CompareUh oh!
There was an error while loading. Please reload this page.
brentrager added a commit
that referenced
this pull request
Aug 20, 2026
…189) The release that bumped package.json to 4.5.1 ran from the commit BEFORE the version-sync fix (#186) landed, so it used the old plain `changeset version` with no sync. The next release run then hit the new guard and stopped, exactly as designed: check-versions: FAILED — manifests disagree with package.json (4.5.1) - python/pyproject.toml is at 4.5.0, expected 4.5.1 (package.json) ... (all six) That is the guard working, not a regression — main genuinely carries a package.json bump that never reached the other five manifests. This is the last bump that can happen: from here `changeset version` runs `changeset version && node scripts/sync-versions.mjs`, and the changesets action commits the whole working tree, so the manifests ride along in the bump commit. No changeset on purpose. 4.5.1 was never published — the failing guard skipped every publish step — so merging this lets the release finish 4.5.1 consistently across npm, PyPI, crates.io, the Go tag and NuGet. Adding a changeset would bump to 4.5.2 and strand 4.5.1 in the changelog with nothing published under it. Verified: `uv sync --locked` and `cargo check --locked` both clean at 4.5.1. Claude-Session: https://claude.ai/code/session_0152bbE1veqfG1SVJdyLCBxC Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
brentrager added a commit
that referenced
this pull request
Aug 20, 2026
Dropping `cargo publish --allow-dirty` (#186) surfaced what the flag had been hiding for who knows how long: error: 1 files in the working directory contain changes that were not yet committed into git: rust/logger/README.md The dirt comes from release.yml's own `Format` step. It runs `pnpm format`, which REWRITES files and then never commits them — so `cargo publish` a few steps later stares at a dirty tree. `--allow-dirty` existed to shrug that off, which meant every published crate silently carried uncommitted reformatting. main is format-drifted across seven files: .claude/settings.json (4-space vs oxfmt's 2), README.md (94 lines), CHANGELOG.md, package.json (devDependencies unsorted, peerDependencies out of position), a Python test, a TS spec, and rust/logger/README.md. Nothing checked: PR checks run oxlint but never a formatter check, and `pnpm format:check` did not exist. Three changes: 1. Commit the formatting. `pnpm format` is now a no-op on main. 2. Add `format:check` (oxfmt + ruff + cargo fmt + gofmt) and run it in PR checks, so this cannot drift again. Verified red by hand-breaking both a markdown file and a TS file. 3. release.yml's `Format` step becomes `Format check` — check, never rewrite. A release pipeline that mutates the tree and discards the result is exactly the thing that made `--allow-dirty` look necessary. Also: `changeset version` writes CHANGELOG.md and package.json, and oxfmt wants both formatted differently, so the version lifecycle now ends with `oxfmt --write CHANGELOG.md package.json`. Without it the very next release PR would land unformatted and break `cargo publish --locked` all over again. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0152bbE1veqfG1SVJdyLCBxC
brentrager added a commit
that referenced
this pull request
Aug 20, 2026
#192) * Commit the formatting, and stop the release from dirtying its own tree Dropping `cargo publish --allow-dirty` (#186) surfaced what the flag had been hiding for who knows how long: error: 1 files in the working directory contain changes that were not yet committed into git: rust/logger/README.md The dirt comes from release.yml's own `Format` step. It runs `pnpm format`, which REWRITES files and then never commits them — so `cargo publish` a few steps later stares at a dirty tree. `--allow-dirty` existed to shrug that off, which meant every published crate silently carried uncommitted reformatting. main is format-drifted across seven files: .claude/settings.json (4-space vs oxfmt's 2), README.md (94 lines), CHANGELOG.md, package.json (devDependencies unsorted, peerDependencies out of position), a Python test, a TS spec, and rust/logger/README.md. Nothing checked: PR checks run oxlint but never a formatter check, and `pnpm format:check` did not exist. Three changes: 1. Commit the formatting. `pnpm format` is now a no-op on main. 2. Add `format:check` (oxfmt + ruff + cargo fmt + gofmt) and run it in PR checks, so this cannot drift again. Verified red by hand-breaking both a markdown file and a TS file. 3. release.yml's `Format` step becomes `Format check` — check, never rewrite. A release pipeline that mutates the tree and discards the result is exactly the thing that made `--allow-dirty` look necessary. Also: `changeset version` writes CHANGELOG.md and package.json, and oxfmt wants both formatted differently, so the version lifecycle now ends with `oxfmt --write CHANGELOG.md package.json`. Without it the very next release PR would land unformatted and break `cargo publish --locked` all over again. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0152bbE1veqfG1SVJdyLCBxC * Add the changeset Needed for its own sake (this changes package.json scripts) and to unstick the release: crates.io, NuGet and the Go tag stalled at 4.5.0 while npm and PyPI reached 4.5.2, and the downstream publish steps only fire when changesets reports it published something — which needs a version bump. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0152bbE1veqfG1SVJdyLCBxC --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The sync ran after the publish. It mutated manifests in a CI workspace that was then discarded, so nothing it wrote was ever committed. Two consequences, both live in this repo today:
4.4.0on npm,git show origin/main:go/version.gosays3.2.3.cargo publish --allow-dirtyexists only to paper over the dirt — the comment above it says so outright.The actual state of
mainbefore this PR:package.jsonpython/pyproject.tomlpython/uv.lockrust/logger/Cargo.toml+Cargo.lockgo/version.godotnet/…/SmooAI.Logger.csprojFive languages, four different versions, none of them the published one. This is also how the
/v3Go module bug survived:sync-versions.mjsnever looked atgo.modat all.Fix
versionlifecycle."version": "changeset version && node scripts/sync-versions.mjs", withversion: pnpm run versiononchangesets/action. The action commits the working tree afterversion, so the synced manifests land in the release commit.ci:publishno longer syncs.cargo publishdrops--allow-dirty, gains--locked.python/uv.lockjoins the synced set. Missed before, and not cosmetic:poe install-devrunsuv sync --locked, which errors when the lock disagrees withpyproject.toml— syncingpyproject.tomlalone would have broken dev installs outright.sync-versions.mjsrewritesgo.mod's/vNsuffix on a major bump, the other half of the tag-resolution fix.The guard
New
check:versionsfails — never warns — when any manifest disagrees withpackage.json, includinggo.mod's major. It runs in two places:pr-checks.yml+ release pre-flightscripts/check-go-module.mjsis folded into it, not kept alongside. Both now read onescripts/versioned-files.mjs, so the guard cannot drift from the syncer — a hand-copied second list is exactly the failure mode this change is about. All six of the go-module spec's cases carried over intocheck-versions.spec.ts.Verification
The guard, run on
mainbefore syncing — this is the bug, printed:After
node scripts/sync-versions.mjs:check-versions: OK (all manifests at 4.4.0).go/version.goto9.9.9→ exit 1 with exactly that one line. Restored → green.cargo check --locked --all-targetsandcargo packageclean after the sync, so--lockedon publish is safe.uv sync --locked --group devresolvessmooai-logger==4.4.0.scripts/check-versions.spec.ts: 8 cases, including the real 4.3.0-vs-3.2.3 skew and all four Go-module cases.Note on this PR's own diff
It contains a one-time version bump of five manifests from 3.x/4.1.0 to 4.4.0 — that is the accumulated skew being closed, not a release. The next changeset release will bump them together from here on.
🤖 Generated with Claude Code
https://claude.ai/code/session_0152bbE1veqfG1SVJdyLCBxC