Rust crate release
Rust crate release 是 Rust library crate 发布到 crates.io 时的媒介合同:一个明确的源码版本必须先通过 manifest、package 和 dry-run 检查,再以同一 source SHA 形成 crates.io package、不可变 Git tag 和 GitHub Release 三面一致的 release unit。
- 运维
- 工具
目录
Definition
Rust crate release 是 Rust library crate 发布到 crates.io 时的媒介合同:一个明确的源码版本必须先通过 manifest、package 和 dry-run 检查,再以同一 source SHA 形成 crates.io package、不可变 Git tag 和 GitHub Release 三面一致的 release unit。它回答“这个 crate 版本怎样安全、可复核地出现在公开 registry 和 GitHub”,不回答 PR 如何表达 intent、哪些 check 是 required、何时触发 workflow,或失败通知发往哪里。
Topic 的输入是一个确定的源码版本和其公开 registry 目标。它适用于公开 crates.io library crate,包括从零到一的 bootstrap、Trusted Publisher/OIDC 迁移、后续版本和发布失败后的幂等恢复;私有 registry、binary application 或完整产品 deployment 需要另外的交付合同。
When to use
当仓库的 Cargo.toml 是可发布 library crate,且目标是 crates.io 时使用。若改动涉及 crate metadata、package 内容、版本策略、cargo publish、GitHub release/tag 绑定、registry 可见性或发布凭据迁移,就应命中本 Topic。仅有 GitHub Release 而没有 crates.io package,或只发布内部 artifact,不足以使用本 Topic。
不要因为仓库存在 label-gate.yml、.github/quality-gates.json 或通知 workflow 就把它们纳入本 Topic 的核心;这些分别属于 PR label release、Quality gates 和 Release failure notification。本 Topic 只接收一个已经确定的源码版本,不规定 label、channel、触发方式、manual-dispatch 输入、签名 intent、required checks、branch protection 或通知策略。
Habits / defaults
- 先从干净、已验证的提交确定 source SHA,检查
Cargo.toml的 package version、name、license、repository、readme 和cargo metadata,再执行cargo package --locked;检查包内文件清单后,对尚未存在的版本执行cargo publish --locked --dry-run。dry-run 通过不等于 registry 已发布,仍需做 post-publish 查询。 - 首发有明确的 bootstrap 例外:Trusted Publisher 只能在 crate 已经存在首个版本后配置。owner 从已验证源码提交用最小权限、短生命周期 crates.io token 发布一次;确认
https://crates.io/api/v1/crates/<crate>/<version>可见后立即撤销 token,再在 crates.io 配置 GitHub Trusted Publisher,并完成一次 OIDC exchange smoke check。后续版本只走rust-lang/crates-io-auth-action@v1等 OIDC 路径,不保留长寿命 token fallback。 - 每个正式或 prerelease 版本都必须把
crate@version、release/<version>tag 和同 tag GitHub Release 绑定到同一个 source SHA。prerelease 可以使用 Cargo 合法的-beta.N或-dev.N版本,但 tag、Release class 和 registry version 必须保持同一语义;不要为此引入type:*、channel:*或其他 label 编排。 - 发布前检查 registry 是否已有该版本,发布后确认 registry 可见且未被 yank,并保存能够连接 source SHA、版本和三面公开地址的 release receipt。已有版本不可再次
cargo publish;yank、超时或 workflow 重跑都不能改变这个不重发约束。 - recovery 先按精确版本查询 crates.io、Git tag 和 GitHub Release,判断缺失面和 source SHA 是否一致,再只补齐缺失的公开面。crate 已存在时不得再次 publish;若已有 tag 指向不同 SHA、Release 不是同一 tag,或状态无法证明一致,应停止并人工处理。
fusb302-rs的0.2.2只提供了精确 tag 查询加 bounded retry 的局部 recovery 证据,不规定所有仓库的重试时长。
Reference implementations
projects/fusb302-rs.md:完整记录0.1.0owner bootstrap、0.2.0/0.2.1OIDC 发布、0.2.2recovery,以及release.yml的 manifest/package/registry 检查。- Cargo 的 publishing contract:
cargo package、cargo publish --dry-run、package 文件清单和已发布版本不可覆盖/删除,见https://doc.rust-lang.org/cargo/reference/publishing.html。 - crates.io Trusted Publishing 的迁移边界和 GitHub OIDC action,见
https://blog.rust-lang.org/2025/07/11/crates-io-development-update-2025-07/;registry token scope 和撤销原则见https://blog.rust-lang.org/inside-rust/2023/05/09/api-token-scopes/。
Failure modes
- 首发前就假设 Trusted Publisher 可用,或把长期
CARGO_REGISTRY_TOKEN留在 CI,会让从零到一流程无法启动或扩大凭据暴露面;首发必须由 owner 做一次最小 token bootstrap,随后撤销并迁移 OIDC。 - 没有先查 registry 就重跑
cargo publish,会把 crates.io 的永久版本约束变成重复发布错误。看到版本已存在时,应检查其 tag、GitHub Release 和 source SHA,走 recovery 而不是重发。 - 只验证 GitHub Release 或移动 tag,未验证 package 内容和 crates.io 版本,会形成无法证明同源的半个 release unit。三面任一绑定不同 SHA 都应阻断公开完成状态。
- 把
cargo package的.cargo_vcs_info.json当成完整 provenance,或把 dry-run 当成 registry visibility,会高估证据;需要同时保存 manifest/package、source SHA、精确 tag 和 registry 查询结果。 - 将
PR label release的 label、Quality gates的 required checks、具体 trigger/manual input、签名 intent、branch protection 或Release failure notification的 transport 写进本 Topic,会破坏职责边界。它们只能作为相邻 Topic 引用或项目编排事实。 - 把
0.2.2的 GitHub Release 列表短暂不可见误写成固定发布流程,会导致不必要的全局等待或重复操作;项目可以采用精确 tag 查询和 bounded retry,但默认合同仍是查询后补齐且不重发。
Evidence index
projects/fusb302-rs.mdskills/style-playbook/references/data/topics/rust-crate-release.jsonskills/style-rust-crate-release/SKILL.md.github/workflows/release.ymlscripts/release_surfaces.pyscripts/registry_state.pyhttps://doc.rust-lang.org/cargo/reference/publishing.htmlhttps://doc.rust-lang.org/cargo/reference/registry-authentication.htmlhttps://blog.rust-lang.org/2025/07/11/crates-io-development-update-2025-07/