通过 Github Action 将 Python 包发布到 pypi

通过 Github Action 将 Python 包发布到 pypi

Desc

通过 Github Action 将自己的 Python 包自动化发布到 PyPI。实际上 Python 官方在这方面的文档非常齐全,跟着官方教程点点鼠标、复制粘贴就可以完成。比那个什么 NPM 不知道高到哪里去了。

本文简单介绍基于 pyproject.toml 的通过 Github Action 进行打包和发布的大概步骤以及一些注意事项,至于一些细节、个性化的东西请看官方文档。

Reference

前置准备

  • 拥有 Github 账户;
  • 注册 PyPI 账户并开启 2FA(双因素认证);

安装和升级 setuptoolsbuild

只是用于后面调试本地打包和调试 pyproject.toml。实际上使用 Github Action 打包,不需要在本地安装打包工具。

1
2
pip install --upgrade setuptools
pip install --upgrade build

pip 最好也更新一下。

目录结构

根据官方文档 https://packaging.python.org/en/latest/tutorials/packaging-projects/#creating-the-package-files ,使用 pyproject.toml 时,建议将代码放置在 src 目录下。

代码文件较多时,可以分包分成多个文件夹。如果只是小项目代码少,直接放在 src 目录下也是可以的。

<project_name>/
├── LICENSE
├── pyproject.toml
├── README.md
├── src/
│   └── <package_name>/
│   │   ├── __init__.py
│   │   └── <module_name>.py
│   └── <module2_name>.py
│   └── <module3_name>.py
└── tests/

编写 pyproject.toml

1
2
3
4
5
# pyproject.toml

[project]
name = "example_project_name"
version = "0.0.1"

打包只需要 name, version 字段。

其他的字段可根据文档自行添加:

本地调试打包

在项目目录下执行

1
python -m build

即可进行打包。输出的 tar 文件和 wheel 文件会在 dist 中。通过此步骤检查打包是否可以正常运行,及时调整,节省后面调整 CI 的时间。

打包完成后要记得检查 tar 文件里,各种文件是否齐全。设置不当可能一些文件没有打包进来。

配置 Github Action 工作流

创建工作流

本地打包没有问题就可以创建 Github Action 工作流。官方文档 https://packaging.python.org/en/latest/guides/ 里写得挺详细,步骤也很简单,也没有什么 Bug。直接用就可以了。

例如在 .github/workflows/ 目录下创建 publish.yml (记住这个名字,后面要用)。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
name: Publish Python 🐍 distribution 📦 to PyPI

on:
  # 手动触发
  workflow_dispatch:

  # 推送 tag 是 v*.*.*时触发
  push:
    tags:
      - "v*.*.*"

  # 以下是推送到 main 分支时触发
  # push:
  #   branches:
  #     - 'main'

jobs:
  build:
    # 打包
    name: Build distribution 📦
    runs-on: ubuntu-latest

    steps:
      # clone 仓库
      - uses: actions/checkout@v4

      # 设置 Python环境和版本
      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.x"

      # 安装 build
      - name: Install pypa/build
        run: >-
          python3 -m
          pip install
          build
          --user          

      # 打包你的项目
      - name: Build a binary wheel and a source tarball
        run: python3 -m build

      # 将打包得到的文件上传到 artifact
      - name: Store the distribution packages
        uses: actions/upload-artifact@v3
        with:
          name: python-package-distributions
          path: dist/
          retention-days: 1 # 1 天后删除 artifact

  publish-to-pypi:
    # 上传到 PPyPIypi
    name: >-
      Publish Python 🐍 distribution 📦 to PyPI      
    if: startsWith(github.ref, 'refs/tags/') # 只在推送tag时,才发布到 PyPI
    needs:
      - build
    runs-on: ubuntu-latest
    environment:
      name: pypi
      url: https://pypi.org/p/<package-name> # 将 <package-name> with 改成你自己的项目名字
    permissions:
      id-token: write # IMPORTANT: mandatory for trusted publishing

    steps:
      # 从 artifact 下载打包的文件
      - name: Download all the dists
        uses: actions/download-artifact@v3
        with:
          name: python-package-distributions
          path: dist/

      #  通过 pypa/gh-action-pypi-publish 这个 action 发布到 PyPI
      - name: Publish distribution 📦 to PyPI
        uses: pypa/gh-action-pypi-publish@release/v1

官方文档中 https://packaging.python.org/en/latest/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/ ,还有发布到 TestPyPI 和发布 Github Release 的工作流。原理相似的,这里不赘述。

设置 PyPI 的可信发布者

建立工作流后不要着急推送到仓库。先要到 PyPI 中设置可信发布者。

设置 PyPI 的项目名、Github 仓库的拥有者、Github 仓库名、工作流的文件名。 Gitub Action 的环境名可以不设置,但强烈建议设置(strongly encouraged)。

https://pypi.org/manage/account/publishing/

pypi_trusted_publisher

推送到 Github

完成上面的步骤就可以将工作流推送到 Github 上。

根据触发条件触发工作流,测试是否可以正常运行。

ci_publish_to_pypi

End

整个流程下来感觉没什么坑,连 token 都不需要设置。Python 官方的文档教程都很全面和清晰。跟 NPM 比起来,要简便很多。

Built with Hugo
Theme Stack designed by Jimmy