Skip to content

Stop the release job formatting its own tree, and gate formatting instead - #11

Merged
brentrager merged 2 commits into
mainfrom
fix/format-check
Aug 20, 2026
Merged

brentrager merged 2 commits into
mainfrom
fix/format-check

Conversation

@brentrager

Copy link
Copy Markdown
Contributor

What broke

The 0.2.1 release published to npm and PyPI, then died on crates.io (run 32401070715):

error: 1 files in the working directory contain changes that were not yet committed into git:
rust/audit/Cargo.toml
to proceed despite this and include the uncommitted changes, pass the `--allow-dirty` flag

release.yml had a step that ran pnpm format — write mode — and nothing committed the result. main was not format-clean (this repo has never had a format check anywhere), so the formatter reliably dirtied the tree before cargo publish ran.

That is the entire reason --allow-dirty existed. Removing it in #7 didn't cause this; it revealed it. And the flag was masking it blindly: --allow-dirty would publish whatever the formatter happened to rewrite, unreviewed.

Collateral: the crates.io step aborting killed the rest of the job, so the Go tag and the NuGet push for 0.2.1 never ran. 0.2.1 is on npm + PyPI only. I have not hand-published anything — the next release restores all five to lockstep (see below).

The fix

  • release.yml formats nothing. It runs pnpm format:check. A write-mode formatter in a release pipeline can only dirty the tree; formatting is a gate, not a release side effect.
  • pr-checks.yml gains the same gate. There was no format check in either workflow, which is how main drifted out of format at all.
  • New scripts: format:check (oxfmt --check + ruff format --check + the existing rust:fmt:check / go:fmt:check) and python:format-check. Added to check-all too.
  • The repo is formatted once so the gate is green from the start. That is the bulk of this diff: oxfmt reflows markdown tables in README.md, reindents spec/parity-corpus.json from 4-space to 2-space, and reflows some TOML/package.json key order. No content or semantic change — every suite still passes, corpus loaders included (they parse JSON, not bytes).

The part that would have bitten again

pnpm run version now ends with pnpm format.

That is not decoration. I simulated it: a changesets-generated CHANGELOG.md is not oxfmt-clean, so adding format:check alone would have redded every future release PR — the same self-inflicted break, one step further down the pipeline. Folding the format into the version lifecycle works because that lifecycle's output is already committed by the changesets action (the Spec A fix from #7).

Verified end to end with a scratch changeset:

$ pnpm run version      # changeset version && sync-versions && format
$ pnpm format:check     # clean
$ pnpm version:check    # All manifests are at 0.3.0

Both gates pass on exactly the tree a release PR will contain, in both the version run and the subsequent publish run.

Verification

format:check, version:check, tsc --noEmit, oxlint (0 errors), pnpm test (51 TS · 63 Python · 21 Rust · 9 Go), dotnet test (31) all green on the reformatted tree.

No changeset: no published code changes, only formatting and CI configuration.

🤖 Generated with Claude Code

https://claude.ai/code/session_0152bbE1veqfG1SVJdyLCBxC

@changeset-bot

changeset-bot Bot commented Aug 20, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 5564e9d

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Brent and others added 2 commits August 20, 2026 14:18
…tead

The 0.2.1 release published to npm and PyPI and then FAILED on crates.io:

    error: 1 files in the working directory contain changes that were not
    yet committed into git: rust/audit/Cargo.toml

Cause: release.yml ran `pnpm format` — WRITE mode — as a step, and nothing
committed the result. main was not format-clean, so the formatter dirtied the
tree, and `cargo publish` refused. That is the only thing `--allow-dirty` was
ever masking, and it was masking it blindly: the flag would have shipped
whatever the formatter happened to change.

Because that job aborted, the Go tag and the NuGet push never ran either, so
0.2.1 exists on npm + PyPI only. The next release restores lockstep across all
five; nothing is published by hand here.

- release.yml formats nothing. It runs `pnpm format:check`.
- pr-checks.yml gains the same gate — the repo had NO format check at all,
  which is how main drifted out of format in the first place.
- New `format:check` (oxfmt --check + ruff format --check + the existing
  rust/go check scripts) and `python:format-check`.
- The repo is formatted once, so the gate is green from the start.
- `pnpm run version` now ends with `pnpm format`. Verified necessary, not
  decorative: a changesets-generated CHANGELOG.md is NOT oxfmt-clean, so
  format:check would have redded every release PR — the same self-inflicted
  break in a new place. Simulated the full lifecycle (`changeset version` ->
  sync -> format) and confirmed both format:check and version:check pass on
  the resulting tree at 0.3.0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0152bbE1veqfG1SVJdyLCBxC
The new format:check gate immediately caught its own motivating case: release
#10 appended a changesets-generated 0.3.0 entry to CHANGELOG.md, and that
output is not oxfmt-clean. Exactly what the `pnpm run version` change in this
PR prevents from recurring — this commit clears the one already on main.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0152bbE1veqfG1SVJdyLCBxC
@brentrager
brentrager merged commit dc82811 into main Aug 20, 2026
1 check passed
@brentrager
brentrager deleted the fix/format-check branch August 20, 2026 18:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant