Repository navigation
fix(release): a v* tag publishes to crates.io, and cut-release.sh --ship cuts the tags - #1081
Merged
Merged
Conversation
…hip cuts the tags PyPI and npm publish from their tags in release.yml; crates.io never did, because publish-crates.yml is dispatch-only and all three of its guards require main. The v* release run now dispatches it on main, as the nightly does. cut-release.sh --ship cuts every product tag on the merged release commit, idempotently, so a release is: cut, merge, ship, approve.
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 free
to 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.
Why
PyPI and npm publish from their tags:
release.ymlruns onv*/node-v*/wasm-v*. crates.io never did.publish-crates.ymlisworkflow_dispatch-only, so every release needed a by-hand dispatch (0.14.1 and 0.15.0 both did) or waited for the nightly. #1079 put the engine bumps intocut-release.sh, but it left the crates.io publish manual.What changed
release.yml: newcrates-publishjob. A finalv*tag push (sameif:aspypi-publish: no rc/dev) dispatchespublish-crates.ymlonmainwithexecute=true. That is the call the nightly makes (release: the coherence check skips the facade, and a public dependency's incompatible move reads as a patch #1073). It doesn't publish from the tag ref directly, because all three of publish-crates' guards requiremain, and crates.io's trusted publisher is bound to that file:if: github.ref == 'refs/heads/main';cratesenvironment's branch policy (main);publish_crates.py's preflight.All three stay as they are. A re-dispatch is harmless, because the publish skips any version crates.io already has.
cut-release.sh X --shipis the post-merge step. On the mergedmainit cuts all three product tags on the release commit and skips any tag that already exists. It refuses to run offmain, whenmainisn'torigin/main, when the head isn't therelease: Xcommit, or when the facade is stamped another version.A release is now:
cut-release.sh X→ merge the PR →cut-release.sh X --ship→ approvepypi/npm. crates.io (the engine crates and the facade) needs no approval: thecratesenvironment has had no reviewer since 2026-09-03.RELEASING.mdand the script's header now describe it; there is a changelogfixedentry.Evidence
cut-release.sh 0.15.0 --shipon a branch exits 1 with--ship runs on main, after the release PR merges.v*tag is its first run. I dispatched 0.15.0's publish by hand (run 38212959062, success). crates.io shows laterite 0.15.0, emit 0.20.4 and validator 0.20.1.actionlint release.ymlshows the same 24 findings before and after, none in the new job.shellcheckis clean.test_version_faithful.py,check_changelog,gen_changelog --check,check_doc_refsand ruff all pass.