在 crates.io 上发布

一旦你有一个想要与世界分享的库,就到了在 crates.io 上发布的时候了!发布 crate 是指将特定版本上传到 crates.io 上托管。

发布 crate 时请注意,因为发布是永久性的。版本永远无法覆盖,代码也无法删除。但是,发布的版本数量没有限制。

首次发布之前

首先,你需要一个 crates.io 上的帐户来获取 API 令牌。为此,请访问主页并通过 GitHub 帐户登录(目前是必需的)。你还需要在帐户设置页面上提供并验证你的电子邮件地址。完成之后,创建一个 API 令牌,确保复制它。一旦离开该页面,你将无法再次看到它。

然后运行 cargo login 命令。

$ cargo login

然后在提示符中输入指定的令牌。

please paste the API Token found on https://crates.io/me below
abcdefghijklmnopqrstuvwxyz012345

此命令会通知 Cargo 你的 API 令牌,并将其本地存储在你的 ~/.cargo/credentials.toml 中。请注意,此令牌是秘密的,不应与任何人分享。如果出于任何原因泄漏,你应该立即撤销它。

注意:可以使用 cargo logout 命令从 credentials.toml 中删除令牌。如果你不再需要将其存储在本地计算机上,这将非常有用。

发布新 crate 之前

请记住,crates.io 上的 crate 名称是按照先到先得的原则分配的。一旦某个 crate 名称被占用,就不能用于另一个 crate。

查看 Cargo.toml 中可以指定的 元数据,以确保你的 crate 更容易被发现!在发布之前,请确保你已填写以下字段

最好还包括一些 keywordscategories,尽管它们不是必需的。

如果你正在发布库,你可能还需要参考 Rust API 指南

打包 crate

下一步是将你的 crate 打包并上传到 crates.io。为此,我们将使用 cargo publish 子命令。此命令执行以下步骤

  1. 对你的包执行一些验证检查。
  2. 将你的源代码压缩成 .crate 文件。
  3. .crate 文件解压缩到临时目录并验证它是否可以编译。
  4. .crate 文件上传到 crates.io
  5. 注册表会在添加上传的包之前对其执行一些额外的检查。

建议你首先运行 cargo publish --dry-run (或等效的 cargo package)以确保在发布之前没有任何警告或错误。这将执行上面列出的前三个步骤。

$ cargo publish --dry-run

你可以在 target/package 目录中检查生成的 .crate 文件。crates.io 目前对 .crate 文件的大小限制为 10MB。你可能需要检查 .crate 文件的大小,以确保你没有意外地打包了构建包不需要的大型资源,例如测试数据、网站文档或代码生成。你可以使用以下命令检查包含哪些文件

$ cargo package --list

Cargo 会在打包时自动忽略版本控制系统忽略的文件,但如果你想指定要忽略的额外文件集,可以使用清单中的 exclude

[package]
# ...
exclude = [
    "public/assets/*",
    "videos/*",
]

如果你宁愿显式列出要包含的文件,Cargo 还支持 include 键,如果设置了该键,它将覆盖 exclude

[package]
# ...
include = [
    "**/*.rs",
    "Cargo.toml",
]

上传 crate

当你准备好发布时,请使用 cargo publish 命令上传到 crates.io

$ cargo publish

就是这样,你现在已经发布了你的第一个 crate!

发布现有 crate 的新版本

为了发布新版本,请更改 Cargo.toml 清单中指定的 version。请记住 SemVer 规则,该规则提供了有关什么是兼容更改的指南。然后运行 cargo publish (如上所述)以上传新版本。

建议: 考虑完整的发布过程并自动化你可以做的事情。

每个版本都应包括

  • 一个更改日志条目,最好是 手动整理,尽管生成的更改日志也比没有好
  • 一个指向已发布提交的 git 标签

代表不同工作流程的第三方工具示例包括(按字母顺序排列)

有关更多信息,请参见 crates.io

管理基于 crates.io 的 crate

crate 的管理主要通过命令行 cargo 工具完成,而不是通过 crates.io Web 界面。为此,有一些子命令可以管理 crate。

cargo yank

有时你可能会发布一个实际上由于某种原因而损坏的 crate 版本(语法错误、忘记包含文件等)。对于这种情况,Cargo 支持“撤回”crate 的版本。

$ cargo yank --version 1.0.1
$ cargo yank --version 1.0.1 --undo

撤回不会删除任何代码。此功能并非旨在删除意外上传的机密信息。如果发生这种情况,你必须立即重置这些机密信息。

撤回版本的语义是不能针对该版本创建新的依赖项,但所有现有依赖项继续工作。crates.io 的主要目标之一是充当 crate 的永久存档,不会随时间更改,而允许删除版本将违背此目标。本质上,撤回意味着所有具有 Cargo.lock 的包都不会中断,而生成的任何未来的 Cargo.lock 文件都不会列出撤回的版本。

cargo owner

一个 crate 通常由多个人开发,或者主要维护者可能会随着时间的推移而更改!crate 的所有者是唯一允许发布 crate 新版本的人,但所有者可以指定其他所有者。

$ cargo owner --add github-handle
$ cargo owner --remove github-handle
$ cargo owner --add github:rust-lang:owners
$ cargo owner --remove github:rust-lang:owners

提供给这些命令的所有者 ID 必须是 GitHub 用户名或 GitHub 团队。

如果将用户名提供给 --add,则该用户将受邀作为“命名”所有者,拥有 crate 的完全权限。除了能够发布或撤回 crate 版本外,他们还有权添加或删除所有者,包括使其成为所有者的所有者。不用说,你不应该让那些你不完全信任的人成为命名所有者。为了成为命名所有者,用户必须先前已登录 crates.io

如果将团队名称提供给 --add,则该团队将受邀作为“团队”所有者,对 crate 拥有受限的权利。虽然他们有权发布或撤回 crate 版本,但他们没有添加或删除所有者的能力。除了更方便地管理所有者组之外,团队还可以更好地防止所有者变得恶意。

团队的语法当前为 github:org:team(请参见上面的示例)。为了邀请团队作为所有者,必须是该团队的成员。删除团队作为所有者没有此类限制。

GitHub 权限

团队成员资格不是 GitHub 提供简单的公共访问权限的功能,你可能会在处理它们时遇到以下消息

看起来你没有权限从 GitHub 查询必要的属性来完成此请求。你可能需要在 crates.io 上重新进行身份验证,以授予读取 GitHub 组织成员资格的权限。

这基本上是“你尝试查询团队,并且五级成员资格访问控制之一拒绝了此操作”的统称。这绝非夸张。GitHub 对团队访问控制的支持是企业级的。

最可能的原因是,你上次登录是在添加此功能之前。我们最初在对用户进行身份验证时没有从 GitHub 请求任何权限,因为我们实际上从未使用用户的令牌进行任何操作,只是让他们登录。但是,为了代表你查询团队成员资格,我们现在需要 read:org 范围

你可以自由拒绝我们此范围,并且团队引入之前的所有功能都将继续工作。但是,你将永远无法添加团队作为所有者,或以团队所有者的身份发布 crate。如果你尝试执行此操作,将收到上述错误。如果你尝试发布一个你根本不拥有,但恰好有团队的 crate 时,也可能会看到此错误。

如果你改变主意,或者只是不确定 crates.io 是否具有足够的权限,你始终可以转到 https://crates.io/ 并重新进行身份验证,如果 crates.io 没有所有它想要的范围,则会提示你输入权限。

查询 GitHub 的另一个障碍是,组织可能正在主动拒绝第三方访问。要检查这一点,你可以转到

https://github.com/organizations/:org/settings/oauth_application_policy

其中 :org 是组织的名称(例如,rust-lang)。你可能会看到类似以下内容

Organization Access Control

在这里,你可以选择显式地从组织的黑名单中删除 crates.io,或者只需按“删除限制”按钮,以允许所有第三方应用程序访问此数据。

或者,当 crates.io 请求 read:org 范围时,你可以通过按其名称旁边的“授予访问权限”按钮来显式地将 crates.io 查询相关组织列入白名单

Authentication Access Control

解决 GitHub 团队访问错误

尝试添加 GitHub 团队作为 crate 所有者时,你可能会看到类似以下内容的错误

error: failed to invite owners to crate <crate_name>: api errors (status 200 OK): could not find the github team org/repo

在这种情况下,你应该前往 GitHub 应用程序设置页面,检查 crates.io 是否列在 Authorized OAuth Apps 选项卡中。如果没有,你应该前往 https://crates.io/ 并授权它。然后返回 GitHub 上的应用程序设置页面,点击列表中的 crates.io 应用程序,确保你或你的组织在“组织访问权限”列表中显示为一个绿色对勾。如果有一个标记为 GrantRequest 的按钮,你应该授予访问权限或请求组织所有者授予访问权限。