在 crates.io 上发布

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

发布 crate 时请小心,因为发布是永久性的。版本永远不能被覆盖,代码也不能被删除。但是,可以发布的版本数量没有限制。

首次发布前

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

然后运行 cargo login 命令。

$ cargo login

然后根据提示输入指定的 token。

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

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

注意cargo logout 命令可用于从 credentials.toml 中删除 token。如果你不再需要将其存储在本地机器上,这会很有用。

发布新 crate 前

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

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

最好也包含一些 keywords(关键词)和 categories(分类),尽管它们不是必需的。

如果你正在发布一个库,你可能还需要查阅 Rust API Guidelines(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",
]

上传 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 网页界面。为此,有一些子命令用于管理 crate。

cargo yank

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

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

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

Yanked 版本(被撤回的版本)的语义是,不能针对该版本创建新的依赖,但所有现有依赖仍然有效。 crates.io 的主要目标之一是作为 crates 的永久存档,随时间不会改变,允许删除版本会违背这个目标。本质上,yank 意味着所有拥有 Cargo.lock 的包不会损坏,而将来生成的 Cargo.lock 文件将不会列出被 yank 的版本。

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 请求任何权限,因为我们实际上从未将用户的 token 用于除登录以外的任何事情。然而,为了代表你查询团队成员资格,我们现在需要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 应用设置页面,检查 Authorized OAuth Apps(已授权的 OAuth 应用)选项卡中是否列出了 crates.io。如果未列出,你应该前往 https://crates.io/ 并授权它。然后返回 GitHub 的应用设置页面,点击列表中的 crates.io 应用,确保你或你的组织在“Organization access”(组织访问)列表中带有绿色勾选标记。如果有一个标有 Grant(授予)或 Request(请求)的按钮,你应该授予访问权限或请求组织所有者这样做。