还在手动打包上传 PyPI?GitHub Actions 自动化真香~!
在《Python 代码一键转流程图》一文里,我介绍了我的开源项目 PyFlowchart。过去这段时间里,已经有好几位小伙伴为这个项目提出了建议,或者报告了 Bug 啦。在这几位朋友的帮助下,项目也迭代了几个版本了。之前,这个项目每次版本更新,我都需要做很多写代码意外的麻烦工作:
这个过程非常反人类,release 一个版本要做两个工作。更可怕的是,打包上传 PyPI 的工作十分模版化(鄙人拙作《如何用 pip 安装自己写的包》一文介绍了这个过程)。我觉得作为开发者,不应该把时间浪费在这种套路工作上。
于是我想去了过去我写过一篇叫做《还在手动发博客?GitHub Actions自动化真香》的文章,大致介绍了我是如何利用 GitHub Actions 自动更新博客网站的。所以,今回,我尝试用 GitHub Actions 搭建了一套发布新版本时,自动打包上传 PyPI 的工作流程。
现在,发布新的版本时,就只需在 GitHub 上新建一个 Release。GitHub Actions 会自动帮我完成构建、打包、上传 PyPI 的工作。
本文就介绍如何利用 GitHub Actions 自动发布 Python 包到 PyPI。
(注:我在 PyFlowchart 项目中使用的实现和下文略有不同,我根据需求做了一些修改,如果你感兴趣,可以看一看我的实现:https://github.com/cdfmlr/pyflowchart/tree/master/.github/workflows)
下文翻译自 PyPA 的文章《Publishing package distribution releases using GitHub Actions CI/CD workflows》
原文链接:https://packaging.python.org/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/
GitHub Actions CI/CD 允许在 GitHub 平台上特定的事件发生时自动运行一系列的命令。用这个就可以做设置一个响应 push 事件的工作流程。本文将展示如何当有 git push 时发布一个新的 Python 包发行版(到 PyPI)。我们将使用到 pypa/gh-action-pypi-publish GitHub Action。
注意:这个教程假设你已经有在 GitHub 上有一个 Python 项目,并且你知道如何构建包,并把它发布到 PyPI。
在本文中,我们会把项目上传到 PyPI 和 TestPyPI。所以需要生成两份独立的 token,并把它们保存到 GitHub 的仓库设置中。
我们开始吧!
GitHub Actions CI/CD —project-org/project-repo
之类的,方便辨识。生成 token 后不要关闭浏览器页面—— token 只会显示一次。Settings
选项卡,然后点击左侧边栏里的 Secrets 。PYPI_API_TOKEN
,然后复制粘贴第一步生成的 token。TEST_PYPI_API_TOKEN
。注意:如果你还没有 TestPyPI 账号,你应该注册一个。TestPyPI 和 PyPI 的账号不共通哦。
GitHub CI/CD 工作流程(workflow)是用 YAML 格式的文件储存到仓库的 .github/workflows/
目录里的。
我们创建一个 .github/workflows/publish-to-test-pypi.yml
文件。
我们将从一个有意义的名称开始,然后定义触发 GitHub 运行此工作流程的事件:
name: Publish Python distributions to PyPI and TestPyPI
on: push
现在,我们来为工作(job)添加初始设置。这个过程将执行我们稍后定义的命令。在这里,我们将使用Ubuntu 18.04:
jobs:
build-n-publish:
name: Build and publish Python distributions to PyPI and TestPyPI
runs-on: ubuntu-18.04
然后,在该 build-n-publish
部分下添加以下内容:
steps:
- uses: actions/checkout@master
- name: Set up Python 3.7
uses: actions/setup-python@v1
with:
python-version: 3.7
这些操作会把我们的项目源码下载到 CI 运行容器里,然后安装并激活 Python 3.7 环境。
现在,我们就可以从源码构建 dist 了。在此示例中,我们将使用build
包,所以假设项目里已正确设置 pyproject.toml
(请参见 PEP 517 / PEP 518)。
(注:emmm,其实这里不写 pyproject.toml
问题也不大)
提示:你可以使用任何其他方法来构建发行版,只要将准备好上传的包保存到 dist/
文件夹中即可。
将下面的代码加到 steps
里:
- name: Install pypa/build
run: >-
python -m
pip install
build
--user
- name: Build a binary wheel and a source tarball
run: >-
python -m
build
--sdist
--wheel
--outdir dist/
.
最后,添加如下代码:
- name: Publish distribution to Test PyPI
uses: pypa/gh-action-pypi-publish@master
with:
password: ${{ secrets.TEST_PYPI_API_TOKEN }}
repository_url: https://test.pypi.org/legacy/
- name: Publish distribution to PyPI
if: startsWith(github.ref, 'refs/tags')
uses: pypa/gh-action-pypi-publish@master
with:
password: ${{ secrets.PYPI_API_TOKEN }}
这两个 step 调用了 pypa/gh-action-pypi-publish GitHub Action:
第一个步骤无条件地将 dist/
文件夹的内容上传到TestPyPI。第二个步骤将其内容上传到 PyPI,这一步只会对被打了标签(git tag)的提交执行。
现在,每当你将打了标签(tag)的提交 push 到 GitHub 上时,此工作流程都会将其发布到 PyPI。同时,对于任意 push ,它都会将其打包发布到 TestPyPI,这对于提供 alpha 测试版本以及确保发布渠道保持健康非常有用!
by("CDFMLR", "2021-01-17")
# 啊,今天昆明都下雪了,家里巨冷。。。
# See you ❄️