Repository navigation
Rust releases: skip versions crates.io already has, fail closed on every release git command (#211) - #216
Conversation
Adding .gitkeep for PR creation (default mode). This file will be removed when the task is complete. Issue: #211
…eached main command-stream's $ resolves on a non-zero exit, so a failed fetch, rebase, add or commit fell through like the rejected push did before #215. All of them now go through checked() in scripts/release-git.mjs, and after the push the version commit must be an ancestor of a freshly fetched origin/main. Run 38359465127 showed the defect left after #215: main had 0.23.0, the minor bump picked 0.24.0, which crates.io already had from an older tree, and the publish step turned into a green no-op. The Rust bump now skips every version crates.io has, and rust.yml fails when the version the run committed was already published before the publish step. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The 0.24.0 entry on main was never published (crates.io had 0.24.0 from 2026-10-10); it is annotated, and a minor fragment makes the next release 0.25.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Working session summaryI've finished the fix for #211 and marked PR #216 ready for review. All 34 CI checks pass, and the full local JS suite passes (1247 tests, 0 failures). What I found: PR #215 had already fixed the deploy key, and in the first release run after it (38359465127) the version commit did reach main. But the bump went from 0.23.0 to 0.24.0, a version crates.io already had from an older build on 2026-10-10. Publishing was skipped as "already published" and the job still ended green. So the CPU-penalty fixes (PR #208) and OOM-attribution fixes (PR #210) still weren't on crates.io. What the PR changes:
Partly done outside this PR: while I was working, someone ran a manual release that published Still unconfirmed: a fully automatic release from start to finish. Only the first release run on main after this merges can show that. Not done as suggested: the issue proposed failing a run if changelog fragments remain on main afterwards. A PR merged during the release could add a new fragment and make that fail for no real reason. The check that the version commit reached main covers the same failure, and the case study explains this. This summary was automatically extracted from the AI working session output. |
🤖 Solution Draft LogThis log file contains the complete execution trace of the AI solution draft process. 💰 Cost: $2.811051📊 Context and tokens usage:
Total: (142 new + 108.3K cache writes + 5.5M cache reads) input tokens, 42.4K output tokens, $2.811051 cost 🤖 Models used:
📎 Log file uploaded as Gist (2253KB)Now working session is ended, feel free to review and add any feedback on the solution draft. |
|
Fixes #211.
What was still broken after #215
PR #215 (
secrets: inherit) fixed the deploy key. In the first release run after it, 38359465127, the key arrives and the push lands, but nothing was published:rust/Cargo.tomlon main was 0.23.0. crates.io has had 0.24.0 since 2026-10-10T18:58Z, built from an older tree. The minor bump picked 0.24.0 again, and the self-healing publish step turned that into a green no-op. The fragments 204/208/210/211 were consumed into a## [0.24.0]changelog entry that crates.io does not contain. Acceptance criteria 1 and 2 were therefore still unmet.Changes
scripts/release-git.mjs,nextUnpublishedVersion()keeps bumping until crates.io returns 404, and fails closed on any other status. For 0.23.0 with a minor bump and 0.24.0 taken, the result is 0.25.0.$resolves on a non-zero exit. Fix #211: Rust release jobs get the deploy key (secrets: inherit); a rejected push fails the release #215 checked onlygit push. Now every git and version command inversion-and-commit.mjs(fetch, rebase, add, commit, push,changeset version, instant bump) goes throughchecked().verifyCommitOnRemote()fetches main and requires the commit to be an ancestor oforigin/main. Ancestry is used instead of comparing heads, because another merge may land right after the push.publish-to-crates.mjsemitspublished_before_run=trueonly when the version existed before it tried to publish. A retry that finds its own upload does not emit it. In bothauto-releaseandmanual-release,rust.ymlfails the job when the run committed that version itself.start-command@0.25.0(commit 69c82b4, crates.io 2026-10-13T07:11:48Z). Its tree includes PR fix: restore observed CPU quotas and recover penalty monitors #208 and PR fix: attribute Docker OOM exits after the last cgroup sample #210. The## [0.24.0]entry is annotated as not on crates.io, and the 0.25.0 entry says it ships those changes.rust/changelog.d/211.mdis a patch fragment for the automation fix.docs/case-studies/issue-211/.Not implemented: the "fragments remain on main" check
A PR merged during a release run can legitimately add a new fragment, so that check would fail spuriously. The ancestry check verifies the same thing directly: the commit that removed the fragments is on main.
How to reproduce
bun experiments/issue-211-rejected-push.mjspushes to a bare remote whosepre-receivehook rejects the push. Output:{ threw: false, code: 1, stderr: "remote: GH013: ..." }.node experiments/issue-211-version-and-commit-e2e.mjsruns the realversion-and-commit.mjswith a fake crates.io that already has 0.24.0:Error: git push origin main failed with exit code 1, noversion_committed.New version: 0.25.0,Verified <sha> is on origin/main, and remote main getsrust-v0.25.0.Tests
js/test/release-git.mjs(new): rejected push reproduction,checked()throwing, the ancestry check failing for a rejected push and passing after main moves on, version skipping (0.23.0 + minor with 0.24.0 taken → 0.25.0), and failing closed on HTTP 503.js/test/publish-to-crates.mjs:published_before_runis set only for a version that already existed.bun run check,actionlintandzizmorpass locally. zizmor reports the same findings as before.Status of the acceptance criteria
start-command@0.25.0(manual release,[Rust] 0.25.0) contains the PR fix: restore observed CPU quotas and recover penalty monitors #208 and PR fix: attribute Docker OOM exits after the last cgroup sample #210 fixes, giving parity with npm.git pushby Fix #211: Rust release jobs get the deploy key (secrets: inherit); a rejected push fails the release #215 and is extended here to every release command plus an ancestry check.