09-发布到 crates.io
6 分钟阅读
译文 · 基于 The Cargo Book
发布到 crates.io
原文链接: https://doc.rust-lang.org/cargo/reference/publishing.html
一旦你有了想与世界分享的库,就可以把它发布到 crates.io!发布 crate 是指将特定版本上传并托管在 crates.io 上。
发布 crate 时请谨慎,因为发布通常是永久性的。版本永远无法被覆盖,代码也无法删除。不过,可以发布的版本数量没有限制。
首次发布之前
首先,你需要一个 crates.io 账户来获取 API token。为此,访问首页并通过 GitHub 账户登录(目前必须)。你还需要在账户设置页面提供并验证邮箱地址。完成后创建 API token,务必复制它。一旦离开该页面,你将无法再次看到它。
然后运行 cargo login 命令。
| |
在提示处粘贴指定的 token。
| |
该命令会告知 Cargo 你的 API token,并将其本地存储在 ~/.cargo/credentials.toml 中。注意,此 token 是机密,不应与任何人共享。若因任何原因泄露,应立即撤销。
注意:可以使用
cargo logout命令从credentials.toml中移除 token。若本地机器不再需要存储它,这会很有用。
发布新 crate 之前
请记住,crates.io 上的 crate 名称按先到先得分配。一旦名称被占用,就不能用于另一个 crate。
查看可在 Cargo.toml 中指定的元数据,以确保你的 crate 更容易被发现!发布前,请确保已填写以下字段:
最好也包含一些 keywords 与 categories,尽管它们不是必需的。
若你发布的是库,可能还想参考 Rust API 指南。
打包 crate
下一步是打包你的 crate 并上传到 crates.io。为此我们将使用 cargo publish 子命令。该命令执行以下步骤:
- 对包执行一些验证检查。
- 将源代码压缩为
.crate文件。 - 将
.crate文件解压到临时目录并验证它能编译。 - 将
.crate文件上传到 crates.io。 - 注册表会在添加之前对上传的包执行一些额外检查。
建议先运行 cargo publish --dry-run(或等价的 cargo package),以确保发布前没有警告或错误。这会执行上面列出的前三个步骤。
| |
你可以在 target/package 目录中检查生成的 .crate 文件。crates.io 目前对 .crate 文件有 10MB 大小限制。你可能想检查 .crate 文件的大小,以确保没有意外打包构建包所不需要的大型资源,例如测试数据、网站文档或代码生成内容。可用以下命令检查包含了哪些文件:
| |
打包时,Cargo 会自动忽略版本控制系统忽略的文件,但若想指定额外要忽略的文件集,可在清单中使用 exclude 键:
| |
若你更愿意显式列出要包含的文件,Cargo 也支持 include 键,一旦设置,会覆盖 exclude 键:
| |
上传 crate
准备好发布时,使用 cargo publish 命令上传到 crates.io:
| |
就是这样,你已经发布了第一个 crate!
发布已有 crate 的新版本
要发布新版本,请更改 Cargo.toml 清单中指定的version 值。请记住提供兼容性变更指南的 SemVer 规则。然后按上文所述运行 cargo publish 上传新版本。
建议: 考虑完整的发布流程,并尽可能自动化。
每个版本应包含:
代表不同工作流的第三方工具示例包括(按字母顺序):
更多内容参见 crates.io。
管理基于 crates.io 的 crate
crate 的管理主要通过命令行 cargo 工具完成,而不是 crates.io Web 界面。为此,有几个子命令用于管理 crate。
cargo yank
有时你发布的某个版本最终因某种原因损坏(语法错误、忘记包含某个文件等)。对于这类情况,Cargo 支持对 crate 的某个版本进行「yank(撤回)」。
| |
yank 不会删除任何代码。此功能并非用于删除意外上传的密钥等。若发生这种情况,你必须立即重置这些密钥。
被 yank 版本的语义是:不能再针对该版本创建新依赖,但所有现有依赖继续有效。crates.io 的主要目标之一是作为不随时间变化的 crate 永久归档,允许删除版本会与此目标相悖。本质上,yank 意味着所有带有 Cargo.lock 的包不会损坏,而未来生成的任何 Cargo.lock 文件都不会列出被 yank 的版本。
cargo owner
crate 通常由不止一人开发,或者主要维护者可能随时间变化!crate 的所有者是唯一允许发布新版本的人,但所有者可以指定额外所有者。
| |
传给这些命令的所有者 ID 必须是 GitHub 用户名或 GitHub 团队。
若向 --add 给出用户名,该用户会被邀请为「具名」所有者,拥有对该 crate 的完整权限。除了能够发布或 yank 版本外,他们还有能力添加或移除所有者,包括让他们成为所有者的那个所有者。毋庸置疑,你不应让不完全信任的人成为具名所有者。要成为具名所有者,用户必须之前已登录过 crates.io。
若向 --add 给出团队名,该团队会被邀请为「团队」所有者,对 crate 的权限受限。虽然他们有权发布或 yank 版本,但没有添加或移除所有者的能力。除了更便于管理所有者群体外,团队在所有者变得恶意时也稍更安全一些。
团队的语法目前是 github:org:team(见上面的例子)。要邀请团队成为所有者,必须是该团队的成员。移除团队所有者则无此限制。
GitHub 权限
团队成员身份不是 GitHub 提供简单公开访问的内容,使用时你很可能会遇到如下消息:
It looks like you don’t have permission to query a necessary property from GitHub to complete this request. You may need to re-authenticate on crates.io to grant permission to read GitHub org memberships.
这基本上是「你试图查询团队,而五层成员访问控制中的某一层拒绝了此请求」的统称。这并非夸张。GitHub 对团队访问控制的支持是企业级的。
最可能的原因只是你上次登录发生在该功能添加之前。我们最初在验证用户时向 GitHub 请求了零权限,因为实际上除了登录外从未使用过用户的 token。但为了代你查询团队成员身份,我们现在需要 read:org 作用域。
你可以自由拒绝该作用域,团队引入之前能工作的一切仍会继续工作。但你将永远无法把团队添加为所有者,或以团队所有者身份发布 crate。若你尝试这样做,会得到上面的错误。若你尝试发布一个你根本不拥有、但恰好有团队的 crate,也可能看到此错误。
若你改变主意,或只是不确定 crates.io 是否有足够权限,可以随时前往 https://crates.io/ 重新认证,若 crates.io 尚未拥有它想要的全部作用域,系统会提示你授权。
查询 GitHub 的另一个障碍是组织可能主动拒绝第三方访问。要检查这一点,可以访问:
| |
其中 :org 是组织名称(例如 rust-lang)。你可能看到类似:

你可以选择显式将 crates.io 从组织的黑名单中移除,或直接按「Remove Restrictions」按钮以允许所有第三方应用访问此数据。
或者,当 crates.io 请求 read:org 作用域时,你可以通过按名称旁的「Grant Access」按钮,显式白名单允许 crates.io 查询相关组织:

排查 GitHub 团队访问错误
尝试将 GitHub 团队添加为 crate 所有者时,你可能看到如下错误:
| |
此时,你应前往 GitHub 应用设置页面,检查 crates.io 是否列在 Authorized OAuth Apps 选项卡中。若没有,应前往 https://crates.io/ 进行授权。然后回到 GitHub 上的应用设置页面,点击列表中的 crates.io 应用,确保你或你的组织在「Organization access」列表中带有绿色对勾。若有标为 Grant 或 Request 的按钮,你应授予访问权限,或请求组织所有者这样做。