tree: 4d2615f01ae4f96990a828a2482b11ed29647035 [search]
  1. bootstrap.py
  2. plan.py
  3. publish.py
  4. README.md
  5. test_bootstrap.py
  6. test_plan.py
  7. test_publish.py
  8. test_trusted_publishing.py
  9. trusted_publishing.py
.github/scripts/release_rust/README.md

Rust release helpers

These scripts define and publish the crates.io package set for Apache Reqsign.

Publish plan

plan.py reads cargo metadata --no-deps, selects workspace packages that can publish to crates.io, and orders them by non-dev local dependencies using Python's TopologicalSorter.

python3 .github/scripts/release_rust/plan.py

The release workflow first runs the complete workspace dry run:

cargo publish --workspace --dry-run

It then runs publish.py. The publisher uploads one package at a time, requests and revokes a fresh GitHub OIDC-derived crates.io token for every attempt, retries crates.io rate limits, and treats an already-published matching name/version as a completed step. Individual uploads use --no-verify because the workflow has already verified the complete package set from the same commit.

Live publishing requires the release GitHub environment and a job with id-token: write. It never reads a long-lived crates.io token.

Bootstrap crate names

Trusted Publishing cannot create the first version of a crate. bootstrap.py reserves new names and audits the complete publish plan:

  • discover reports missing names and existing 0.0.0 placeholders without credentials.
  • apply authenticates every existing crate before any write, publishes a dependency-free 0.0.0 namespace reservation for each missing name, configures the exact apache/reqsign, release.yml, release Trusted Publisher, enables trustpub_only, and performs a final authenticated audit.
  • verify checks public crate metadata and trustpub_only. It cannot verify ownership or the exact Trusted Publisher because those APIs require authentication.

The protected rust-bootstrap job audits the complete plan before any write, including when no names are missing. It never changes an established crate. Existing crates must be migrated independently before the workflow can succeed.

Published crate metadata may still reference the former repository URL or the former project name in a 0.0.0 placeholder description. The audit accepts that historical metadata, but every Trusted Publisher must target apache/reqsign. New placeholders and releases use the current project name and repository URL.

Version 0.0.0 is an irreversible namespace reservation. It is not an ASF software release and contains no implementation.

The local dispatch helper uses GitHub REST API version 2026-03-10 to obtain the exact workflow run ID, then checks its commit and waits for completion.

These are repository-specific scripts: run them with normal Python (without -O or PYTHONOPTIMIZE, which disable assertions). Cargo and crates.io response fields are used directly; unexpected package or publisher state fails an assertion. Failed API requests stop the run; rerun after resolving the failure. Only Cargo publish rate limits and public metadata propagation are retried.

Tests

python3 -m unittest discover \
  -s .github/scripts/release_rust \
  -p "test_*.py"