此操作允许您将dist/
目录中的 Python 分发包上传到 PyPI。本文提出了一个简约的使用概述。有关更详细的演练,请查看 PyPA 指南。
如果您对特定操作版本有任何反馈,请在相应的每次发布公告讨论中留下评论。
master
日落master
分支版本已经日落。请将您使用的 GitHub Action 版本从master
更改为release/v1
或使用精确标签,或选择使用完整的 Git 提交 SHA 和 Dependabot。
笔记
目前无法在可重用工作流程中使用可信发布。建议改为创建一个不可重用工作流程,其中包含调用可重用工作流程的作业,然后从该不可重用工作流程中的单独作业执行可信发布步骤。或者,您仍然可以在可重用工作流程中使用用户名/令牌。
笔记
可信发布有时是指其底层技术——OpenID Connect,简称 OIDC。如果您在 PyPI 上下文中看到对“OIDC 发布”的引用,那么这就是他们所指的内容。
这个例子直接跳到当前的最佳实践。如果您想直接使用 API 令牌或安全性较低的用户名和密码,请查看如何指定用户名和密码。
此操作支持 PyPI 的可信发布实现,该实现允许对 PyPI 进行身份验证,而无需手动配置 API 令牌或用户名/密码组合。要使用此操作执行可信发布,您的项目的发布者必须已在 PyPI 上配置。
要进入受信任的发布流程,请使用id-token: write
权限配置此操作的作业,并且无需显式用户名或密码:
# .github/workflows/ci-cd.ymljobs: pypi-publish:name: 将版本上传到 PyPIruns-on: ubuntu-latestenvironment: name: pypi url: https://pypi.org/p/<your-pypi-project -name>permissions: id-token: write # 重要:此权限对于受信任的发布步骤是必需的:# 在此处检索您的发行版- name: 将包发行版发布到 PyPI使用:pypa/gh-action-pypi-publish@release/v1
笔记
专业提示:不要使用分支指针(如unstable/v1
,而是将用于标记版本或 sha1 提交标识符的操作的固定版本。这将使您的工作流程更加安全且可重复性更好,从而使您免受突然和不愉快的意外的影响。
也可以使用其他支持可信发布的索引,例如 TestPyPI:
- 名称:将包分发发布到 TestPyPI 使用:pypa/gh-action-pypi-publish@release/v1 with:repository-url: https://test.pypi.org/legacy/
(不要忘记将环境名称更新为testpypi
或类似名称!)
笔记
专业提示:仅在执行发布的作业中设置id-token: write
权限,而不是全局设置。另外,尝试将构建与发布分开——这可以确保任何恶意注入构建或测试环境的脚本都无法在雷达下提升权限。
一个常见的用例是仅在标记的提交上上传包,为此,请向作业添加过滤器:
if: github.event_name == 'push' &&startsWith(github.ref, 'refs/tags')
重要的
对生成和上传数字证明的支持目前处于实验阶段,并且仅限于使用 PyPI 或 TestPyPI 的可信发布流程。对该功能的支持尚未稳定;下面描述的设置和行为可能会更改,恕不另行通知。
笔记
目前,生成和上传数字证明需要通过可信发布者进行身份验证。
对于所有使用 Trusted Publishing 的项目,现在默认启用为所有分发文件生成签名数字证明并将它们一起上传的功能。要禁用它,请按如下方式设置attestations
:
与:证明:假
使用 Sigstore 为每个分发包创建证明对象,并使用与当前工作流程关联的 GitHub 的 OIDC 令牌提供的身份对它们进行签名。这意味着可信发布身份验证和证明都与同一身份相关联。
此 GitHub Action 与构建包发行版无关。用户负责在运行此操作之前将 dist 放入dist/
文件夹中来准备上传。
重要的
由于此 GitHub Action 基于 docker,因此只能在 GitHub Actions CI/CD 工作流程中基于 GNU/Linux 的作业中使用。这是设计使然,并且由于我们所依赖的许多考虑因素而不太可能改变。
不过,这不应阻止发布特定于平台的分发包。强烈建议将构建特定于操作系统的轮子的作业与发布作业分开。这允许(1)测试即将上传到 PyPI 的完全相同的工件,(2)防止并行不同步作业仅异步发布部分 dist(以防部分作业失败而其他作业成功而结束) PyPI 上的版本不完整)和 (3) 对 PyPI 进行原子上传(当部分 dist 出现在 PyPI 上时,pip 等安装程序将使用该版本进行依赖项解析,但这可能会导致某些环境使用sdists,而其运行时的轮子尚不可用)。
要实现这种编排,请使用actions/upload-artifact
和actions/download-artifact
操作来跨阶段和作业共享构建的 dist。然后,使用needs
设置来排序构建、测试和发布阶段。
为了获得最佳结果,请弄清楚哪种工作流程适合您项目的特定需求。
例如,您可以实现一个并行作业,将每次提交推送到 TestPyPI 或您自己的索引服务器(例如devpi
。为此,您需要 (1) 指定自定义repository-url
值,并 (2) 为每次上传生成唯一的版本号,这样它们就不会产生冲突。如果您使用setuptools_scm
包,则后者是可能的,但您也可以根据与最新标记提交的距离发明自己的解决方案。
您需要为单独的主机创建另一个令牌,然后将其保存为工作中使用的环境下的 GitHub 存储库机密。不过,传递密码会禁用无秘密的可信发布,因此在发布到 TestPyPI 而不是自定义内容时,最好配置它。
在这种情况下,操作调用将如下所示:
- 名称:将包发布到 TestPyPI 使用:pypa/gh-action-pypi-publish@release/v1 with:密码: ${{ Secrets.TEST_PYPI_API_TOKEN }}存储库-url: https://test.pypi.org/legacy/
您可以将dist/
的默认目标目录更改为您喜欢的任何目录。操作调用现在如下所示:
- 名称:将包发布到 PyPI 使用:pypa/gh-action-pypi-publish@release/v1 与:包目录:自定义目录/
建议您在生成文件后立即运行twine check
,但这也会在上传之前运行twine check
。您还可以通过以下方式禁用麻绳检查:
与:验证元数据:假
有时,当您从多个位置发布版本时,您的工作流程可能会遇到竞争条件。例如,当从多个 CI 发布时,甚至在 GitHub Actions CI/CD 中针对涉及同一高级行为的不同事件触发具有相同步骤的工作流程时。
为了方便此用例,您可以使用skip-existing
(默认情况下禁用)设置,如下所示:
与:跳过现有:true
笔记
专业提示:尽可能避免启用此设置。如果您有发布到 PyPI 和 TestPyPI 的步骤,请考虑仅将其用于后者,而前者在重复时会严重失败。
有时, twine upload
可能会失败,并且要使用verbose
设置进行调试,如下所示:
与:详细:真实
您可能想验证 PyPI 上的文件是否是由 CI 脚本自动上传的。它将显示要上传的文件的 SHA256、MD5、BLAKE2-256 值。
与:打印哈希:true
默认用户名值为__token__
。如果您发布到不提供 API 令牌的自定义注册表(例如devpi
),您可能需要指定自定义用户名和密码对。就是这样完成的。
与:用户:guido密码:${{secrets.DEVPI_PASSWORD}}
${{ secrets.DEVPI_PASSWORD }}
中使用的密钥需要在 GitHub 上项目设置下的环境页面上创建。请参阅创建和使用机密。
过去,在发布到 PyPI 时,自动发布的访问范围最安全的方式是使用 PyPI 的 API 令牌功能。例如,可以将其设置为项目范围并在 GitHub 存储库设置中保存为环境绑定的机密,将其命名为${{ secrets.PYPI_API_TOKEN }}
。请参阅创建和使用机密。虽然仍然安全,但现在鼓励通过 API 令牌进行可信发布,作为受支持平台(如 GitHub)上的最佳实践。
本项目中的 Dockerfile 以及相关脚本和文档是根据 BSD 3 条款许可证发布的。