This directory contains the planning logic for the Rust crates.io release workflow.
After the repository split, Rust crates are no longer represented by a short hand-maintained list. The release workflow needs to:
core/ and integrations/publish = falseKeeping this logic in a standalone script makes it testable and keeps the workflow YAML readable.
The planner scans:
core/Cargo.tomlcore/core/Cargo.tomlcore/testkit/Cargo.tomlcore/layers/*/Cargo.tomlcore/services/*/Cargo.tomlintegrations/*/Cargo.tomlIt reads local dependencies, build-dependencies, and target-specific variants of those tables to build a dependency graph, then emits a deterministic topological order.
Print the publish order as JSON:
python3 .github/scripts/release_rust/plan.py
Write the same JSON to GitHub Actions output as packages=<json>:
python3 .github/scripts/release_rust/plan.py --github-output
Publish the planned crates:
PACKAGES="$(python3 .github/scripts/release_rust/plan.py)" \ python3 .github/scripts/release_rust/publish.py
Live publishing requires a GitHub Actions job with id-token: write. Dry runs do not request a Trusted Publishing token.
publish.py wraps cargo publish with the release-specific behavior we need:
cargo publish --package <name> so workspace packages publish the intended cratedev-dependencies from the package manifest before publishingbootstrap.py reserves new crate names and audits the complete Rust publish plan. Its discover command reports missing names and existing 0.0.0 placeholders without using credentials. Its apply command uses the protected bootstrap token to:
0.0.0 namespace reservation for every missing nameapache/opendal, release_rust.yml, and the release environment as a placeholder's only Trusted Publishertrustpub_only and reconcile partially completed placeholdersThe verify command reads public crates.io metadata and confirms that all planned crates exist and require Trusted Publishing. The authenticated apply audit is authoritative for ownership and the exact publisher configuration.
Migration of existing crates is independent. bootstrap.py apply refuses to modify an established crate. The rust-bootstrap protected job always runs, including when the plan contains no missing names or placeholders.
Version 0.0.0 only reserves a crates.io namespace. It is not an ASF software release or release artifact.
Run the unit tests with:
python3 -m unittest discover -s .github/scripts/release_rust -p "test_*.py"