在 crates.io 上发布

当你有一个想要与全世界分享的库时,就可以将它发布到 crates.io 上了!发布一个包是指将特定版本上传到 crates.io 上托管。

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

首次发布前的准备工作

首先,你需要在 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 中删除令牌。如果你不再需要将令牌存储在本地计算机上,这将非常有用。

发布新包前的准备工作

请记住,crates.io 上的包名称采用先到先得的分配方式。一旦一个包名被占用,就不能再用于其他包。

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

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

如果你要发布一个库,你可能还想参考Rust API 指南

打包包

下一步是打包你的包并将其上传到 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",
]

上传包

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

$ cargo publish

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

发布现有包的新版本

要发布新版本,请更改 Cargo.toml 清单中指定的version。请记住语义化版本规则,它提供了关于什么是兼容更改的指南。然后按照上述说明运行 cargo publish 以上传新版本。

**建议:** 考虑完整的发布流程,并尽可能地自动化。

每个版本都应该包含:

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

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

更多信息,请参阅 crates.io

管理基于 crates.io 的包

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

cargo yank

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

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

撤销**不会**删除任何代码。例如,此功能不用于删除意外上传的密钥。如果发生这种情况,你必须立即重置这些密钥。

撤销版本的语义是不能创建任何新的依赖于该版本的依赖项,但所有现有的依赖项将继续工作。crates.io 的主要目标之一是充当一个不会随时间变化的永久性包存档,而允许删除版本将违背这一目标。本质上,撤销意味着所有具有 Cargo.lock 的包都不会损坏,而任何将来生成的 Cargo.lock 文件都不会列出已撤销的版本。

cargo owner

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

$ 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,但该 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 是否列在“已授权的 OAuth 应用程序”选项卡中。如果未列出,则应转到 https://crates.io/ 并对其进行授权。然后返回 GitHub 上的应用程序设置页面,单击列表中的 crates.io 应用程序,并确保您或您的组织列在“组织访问权限”列表中,并带有绿色复选标记。如果有标记为“授予”或“请求”的按钮,您应该授予访问权限或请求组织所有者这样做。