Rust Crates Publishing
Quick Start
Add a publish job to your release workflow that runs on tags and requires CARGO_REGISTRY_TOKEN:
publish-crates:
name: Publish to crates.io
needs: release
runs-on: ubuntu-latest
timeout-minutes: 15
if: ${{ !contains(github.ref, '-') }} # skip pre-releases
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
- name: Publish to crates.io
if: ${{ env.CARGO_REGISTRY_TOKEN != '' }}
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: cargo publish --all-features
Workflow
- Ensure crate metadata is ready:
Cargo.tomlversion, license, README, repository. - Confirm tag matches version (ex: tag
v1.2.3->package.version = "1.2.3"). - Add a release workflow that builds artifacts first, then publishes.
- Gate publish on tags and non-pre-release tags.
- Require
CARGO_REGISTRY_TOKENsecret; skip publish if missing. - Dry-run locally:
cargo publish --dry-run.
Release Trigger Pattern
Use tag triggers and allow manual dispatch:
on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
tag:
description: 'Tag to release (e.g., v0.1.0)'
required: true
type: string
Workspace Publishing
- Publish dependency crates first, then the top-level crate.
- Use
cargo publish -p crate_namefor each crate.
cargo publish -p core-crate --all-features
cargo publish -p cli-crate --all-features
Guardrails
- Never publish from PRs or forks; only from tags on the main repo.
- Use
--lockedin CI if lockfiles are committed. - Avoid
publish = falsein[package]for crates meant to ship.
Validation
cargo packagecargo publish --dry-runcargo package --list(verify included files)- Ensure CI can reach crates.io (no network restrictions).
Notes
CARGO_REGISTRY_TOKENshould be a crates.io API token with publish scope.- Skip publish for pre-releases by checking tag contains
-. - Keep publish job last (
needs: release) to avoid partial releases.
Troubleshooting
HTTP 401/token rejected: confirm token scope and repo secret name.version already uploaded: bumppackage.versionand retag.readme not found: setreadme = "README.md"inCargo.toml.
Deep Dive
- Advanced publishing edge cases:
references/ADVANCED.md