cargoPublish
cargoPublish :: AttrSet → Effect
Deploys package to crates.io, the Rust community’s crate repository.
Example:
effects.cargoPublish {
secretName = "cargo-api-token";
src = ./.;
}
Example secret:
"cargo-api-token": {
"kind": "Secret",
"data": {
"token": "..."
},
"condition": {
"and": [
{ "isOwner": "my-github-org" },
{ "isRepo": "my-site-repo" }
]
}
}
Parameters
secretName
The secret that will be looked up in secrets.json.
The data field must contain a "token" field, with a string value that is a Cargo API token. To make one, navigate to API tokens and use New Token.
extraPublishArgs
Extra arguments to pass to the cargo publish invocation.
src
Example: src = ./.;
Path to the source code of the package to publish.
src is unpacked by the Nixpkgs unpackPhase.
manifestPath
String containing the path to a Cargo.toml, default: Cargo.toml. Relative paths are relative to the unpacked src.
A store path subpath could be passed instead, bypassing unpackPhase.
registryURL
Optional registry to publish to. Defaults to cargo’s default behavior, which is to publish to package.publish or crates.io.
If you use an alternate registry or private registry, you are recommended to store this information in Cargo.toml.
Note that this must be the backing git repository URL, not a web or API URL.
dryRun
Boolean, default false. When true, runs cargo publish --dry-run which packages and verifies the crate(s) without uploading.
When dryRun is true, the secretName is not required.
assertVersions
Verify package versions before publishing. This can be:
-
An empty attribute set
{}(default): no version checking -
A string like
"1.0.0": check that all packages in the workspace have this version -
An attribute set mapping package names to versions:
{ my-crate = "1.0.0"; }
Example for workspace with synchronized versions:
effects.cargoPublish {
src = ./.;
secretName = "cargo-api-token";
assertVersions = "1.0.0"; # All packages must be version 1.0.0
}
Workflow
Initial Setup
-
Enable the module in your
flake.nixwithhercules-ci.cargo-publish.enable = true -
Set the version in
Cargo.tomlto a version that doesn’t exist on crates.io yet (e.g.,0.1.0) -
On each push, Hercules CI runs
cargo publish --dry-runto verify the package is publishable
Releasing a Version
-
Review the version — the version in
Cargo.tomlis probably a patch bump from the last release. Consider whether breaking changes or new features warrant a minor or major bump instead. -
Push a tag matching the version in
Cargo.toml:git tag 0.1.0 git push origin 0.1.0shell -
Hercules CI detects the tag and runs
cargo publish -
Bump the version in
Cargo.tomlto the next version (e.g.,0.1.1) to allow dry-run checks to verify subsequent commits
With assertVersions = true (module) or assertVersions = "0.1.0" (function), the effect verifies that all workspace package versions match the tag name before publishing.
Rate Limits
When publishing a workspace with many crates for the first time, you may hit crates.io rate limits. The registry limits new crate registrations more strictly than updates to existing crates. At the time of writing, crates.io allows a burst of about 5 new packages, then requires a wait of approximately 10 minutes before publishing more.
If you encounter rate limit errors during an initial release:
-
Wait for the rate limit to reset (approximately 10 minutes)
-
Use
extraPublishArgsto publish remaining crates individually:effects.cargoPublish { src = ./.; secretName = "cargo-api-token"; extraPublishArgs = [ "--package" "my-unpublished-crate" ]; }nix -
Run locally with
hci effect runto iterate through remaining crates:hci effect run onPush.default.effects.cargo-publish --pretend-ref refs/tags/0.1.0shell
After the initial release, subsequent version updates are less likely to hit rate limits.