You need a crates.io account (sign in via GitHub) and an API token:
cargo login
# Paste your token from https://crates.io/settings/tokens
crates.io requires certain fields. Here's a minimal example:
[package]
name = "my-crate"
version = "0.1.0"
edition = "2024"
authors = ["Your Name <you@example.com>"]
description = "A short description of what your crate does"
license = "MIT"
repository = "https://github.com/you/my-crate"
keywords = ["relevant", "keywords"]
categories = ["science"]
readme = "README.md"
description and license (or license-file) fields are required for publishing. Without them, cargo publish will fail.Always verify before publishing:
cargo publish --dry-run
This checks:
cargo publish
Follow Semantic Versioning:
| Change | Version Bump | Example |
|---|---|---|
| Bug fix, no API change | Patch | 0.6.0 → 0.6.1 |
| New feature, backward compatible | Minor | 0.6.0 → 0.7.0 |
| Breaking API change | Major | 0.7.0 → 1.0.0 |
For pre-1.0 crates (common in early development), minor bumps signal new features and patch bumps signal fixes. Breaking changes in 0.x are expected.
Pair every crates.io publish with a GitHub release for visibility:
# Read version from Cargo.toml
VERSION=$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)"/\1/')
# Create release with auto-generated notes
gh release create "$VERSION" \
--title "v$VERSION" \
--generate-notes \
--target main
cargo publish refuses to run with uncommitted changes:
# If you see "dirty" errors, ensure Cargo.lock is committed
cargo check # regenerates Cargo.lock if needed
git add Cargo.lock
git commit -m "update Cargo.lock"
--allow-dirty. Fix the root cause instead — it's usually a stale Cargo.lock.Before every publish:
cargo testcargo doc --no-depsCargo.tomlCHANGELOG.md updated (if you maintain one)cargo publish --dry-runmainIf you publish a broken version:
cargo yank --version 0.5.0
# To undo:
cargo yank --version 0.5.0 --undo
Yanked versions still work for existing Cargo.lock files but won't be picked up by new projects.
When managing several related crates, a version-checking script helps catch drift:
#!/bin/bash
# Compare local versions against crates.io
for dir in rfconversions touchstone gainlineup linkbudget; do
LOCAL=$(grep '^version' "$dir/Cargo.toml" | head -1 | sed 's/.*"\(.*\)"/\1/')
REMOTE=$(cargo search "$dir" --limit 1 2>/dev/null | head -1 | sed 's/.*= "\(.*\)".*/\1/')
if [ "$LOCAL" != "$REMOTE" ]; then
echo "⚠️ $dir: local=$LOCAL remote=$REMOTE"
else
echo "✅ $dir: $LOCAL (up to date)"
fi
done
This pattern scales well — run it before release days to see what needs publishing.