Publishing crates to crates.io
Publishing a crate to crates.io
Section titled “Publishing a crate to crates.io”Vox uses cargo-hakari for workspace build optimization. Publishing external crates requires a few extra steps to satisfy crates.io closure requirements.
Checklist
Section titled “Checklist”-
Mark the crate publishable in
docs/src/architecture/layers.toml:my-crate = { layer = 1, publishable = true } -
Run the publishability gate:
Terminal window cargo run -p vox-arch-checkRule 18 must pass — no
publish = falsedeps in the workspace-crate closure. If it fires, either mark each flagged dep publishable (and add it to this pipeline) or remove it from the crate’s dependencies. -
Remove
workspace-hackfrom the crate’sCargo.toml:# Remove this line from crates intended for external publishing:# workspace-hack = { workspace = true }workspace-hackis a build-optimization-only dep managed by hakari. It has no code — only feature flags.cargo publishcannot resolve it (our repo version is 0.6.0; no matching version on crates.io). Removing it has no effect on crate behaviour. -
Add a version to each workspace path-dep that is in this crate’s closure (in the root
Cargo.toml[workspace.dependencies]section):my-dep = { path = "crates/my-dep", version = "0.6.0" } -
Verify name availability:
Terminal window cargo search my-crate --limit 5crates.io has no namespaces — use a
vox-prefix to avoid collisions. Record the decision incontracts/reports/crates-io-names.v1.json. -
Add publish metadata to the crate’s
Cargo.toml:readme = "README.md"keywords = ["..."] # max 5, snake_casecategories = ["..."] # must match https://crates.io/category_slugslicense,repository,version,authorsare inherited from the workspace. Add aREADME.md(becomes the crates.io front page). -
Dry-run:
Terminal window cargo publish -p my-crate --dry-runIf this fails with “no matching package named X”, the dep
Xis not yet on crates.io. Publish it first (leaf-first ordering). -
Publish leaf-first — each crate must be on crates.io before its dependents can publish:
Terminal window cargo publish -p my-leaf-crate # publish deps firstcargo publish -p my-crate # then the crateEvery
cargo publish(without--dry-run) is irreversible — crates.io allows yanking but not deletion. Requirescargo loginwith a maintainer token. Never run from CI.
Current publishable crates (leaf-first order)
Section titled “Current publishable crates (leaf-first order)”| Crate | Status | Notes |
|---|---|---|
vox-crypto | prepared, ready to publish | no workspace deps |
vox-mesh-types | prepared | no workspace deps |
vox-scaling-policy | prepared | requires vox-mesh-types live |
vox-bounded-fs | prepared | requires vox-scaling-policy live |
vox-secrets | prepared | requires vox-crypto + vox-bounded-fs live |
See also
Section titled “See also”contracts/reports/crates-io-names.v1.json— approved published namescontracts/reports/closure-budgets.v1.json— Rule 19 dep-closure budgetsdocs/src/architecture/layers.toml—publishable = trueregistry