Publishing Rust crates to crates.io
Author: Maciej Wójcik
Email: mwojcik@teonite.com
Copyright © teonite
This document is meant to serve as a general guide for releasing public projects as crates and all the ancillary aspects that come with publishing something that’s meant to be used by other people.
TL;DR
Thanks to great tooling in Rust publishing a crate to crates.io once everything is set up is just a matter of doing the following:
- go back and fill in the docs!
- bump crate version in
Cargo.toml
andCargo.lock
files - run
cargo publish
But before you first publish a new crate you should really at least skim through the stuff below.
Before publishing
Below is a list of a couple steps that should probably be taken before you first publish a new Rust crate.
Docs! Docs! Docs!
Documentation is probably the single most important aspect of releasing code that’s meant to be used by third parties. Fortunately generating documentation is also a part of cargo
tooling. Whenever you publish a new version to crates.io the documentation is also built and published to docs.rs (with a small delay for processing.
To test your documentation run cargo doc --open
to build it and open in your browser.
Another useful cargo
feature is that all the code blocks in your documentation are tested when you run cargo test
. This should prevent your examples from becoming obsolete with subsequent releases.
Some important notes:
- It goes without saying that you should add as much documentation as reasonably possible. At bare minimum you have to document all public APIs that users are meant to interact with.
- In general three slashes (
///
) are used for comments which will be rendered as documentation. Use them to document functions, structs, traits etc. Normal comments (//
) can still be used for further explanations within the source code itself. Other relevant type of documentation comment is//!
which can be used to add module-level docs. - You can use Markdown in all documentation comments.
- Remember to add general crate-level docs in
src/lib.rs
. This part will be used as your docs homepage and for many users this will be the first look into your crate. Aside from README-like description you should also include a small code example which shows how the library is used. For example:\n
- Use
cargo doc --open
to test your documentation and add missing comments to all the public APIs. Try to put yourself in the headspace of a developer trying to actually use your crate.
Fill in crate metadata
Aside from defining the basic stuff like your project’s name and current version, the Cargo.toml
file contains some useful metadata in [package]
section, which enables users to discover your crate easier on crates.io
.
Before publishing you must at least fill in values for description
and license
fields. Other fields are not mandatory but you should fill in some relevant info. For example:
Set up release workflow in GitHub
Each crate version should have a corresponding GitHub release with a changelog. To automate this process add a simple workflow to generate a release for each commit tagged with vX.X.X
:
\
Configuring cargo
There are a couple of steps that need to be performed before you can just run cargo publish
to publish a crate.
- Set up crates.io account. This requires authorizing with your GitHub account.
- Within account settings enter and verify your email address.
- Go to
Account Settings
>API Tokens
and generate a new token. - Go back to your project directory and run
cargo login
. This stores the token locally in~/.cargo/credentials
and allows you to interact with crates.io
That’s it. You should now be able to publish your crate. You can also run cargo publish --dry-run
to check if there are any outstanding issues.
Delegating crate ownership
The user who uploads the crate initially is initially the only one with access to publishing new versions, yanking existing versions etc. To delegate access use the cargo owner
command (note: this can only be done if a crate is already published), for example:
cargo owner --add github-handle
- give access to a specific usercargo owner --add github:org-name:team-name
- give access to a GitHub team within an organization
Release process in GitHub CI
Running cargo publish
can easily be done within the release workflow, but for now we decided to do it manually.