目录

GitHub Actions:二进制轮子

构建二进制轮子稍微复杂一些,但仍然可以使用 GHA 有效地完成。本文档将介绍 cibuildwheel 在项目中的使用。我们将重点关注下面的 GHA。

轮子构建应该很少发生,因此您需要将其限制在发布时,以及可能很少移动的分支或其他特殊标签(例如,如果您主要更新其他分支,则为 stable)。您可能偶尔需要手动触发轮子构建。

name: Wheels

on:
  workflow_dispatch:
  release:
    types:
      - published
    pull_request:
      paths:
        - .github/workflows/cd.yml

这将在发布时运行。如果您使用开发分支,则可以包含 pull_request: branches: [stable],因为它很少更改。GitHub Actions 也有 一个 workflow_dispatch 选项,它允许您在 GUI 中点击一个按钮来触发构建,这非常适合在发布之前测试轮子;您可以从“工件”中下载它们。您甚至可以定义可以在 GUI 中设置并在 CI 中访问的变量!最后,如果您在 PR 中更改了工作流程本身,则也重新构建轮子。

有用建议

由于这些变量将被所有作业使用,因此您可以将它们放在 pyproject.toml 文件中,以便它们可以在任何地方使用(甚至在 Linux 和 Windows 上本地使用)

[tool.cibuildwheel]
test-extras = "test"
test-command = "pytest {project}/tests"
# Optional
build-verbosity = 1

test-extras 将导致 pip install 使用 [test]test-command 将使用 pytest 运行您的测试。您还可以设置构建详细程度(pip 中的 -v),如果您需要的话。

创建 SDist

您可能不应该忘记创建 SDist!一个简单的作业,就像之前一样,就可以工作

make_sdist:
  name: Make SDist
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4
      with:
        fetch-depth: 0 # Optional, use if you use setuptools_scm
        submodules: true # Optional, use if you have submodules

    - name: Build SDist
      run: pipx run build --sdist

    - uses: actions/upload-artifact@v4
      with:
        name: cibw-sdist
        path: dist/*.tar.gz

您可以改为通过 pip 安装 build 并使用 python -m build --sdist。您还可以使用 pipx run build==<version> 固定版本。

核心作业(3 个主要操作系统)

核心工作在这里完成

build_wheels:
  name: Wheel on ${{ matrix.os }}
  runs-on: ${{ matrix.os }}
  strategy:
    fail-fast: false
    matrix:
      os: [ubuntu-latest, windows-latest, macos-13, macos-14]

  steps:
    - uses: actions/checkout@v4
      with:
        fetch-depth: 0
        submodules: true

    - uses: pypa/cibuildwheel@v2.21

    - name: Upload wheels
      uses: actions/upload-artifact@v4
      with:
        name: cibw-wheels-${{ matrix.os }}
        path: wheelhouse/*.whl

这里需要注意几点。首先,它能够工作的原因之一是您遵循了前面部分的建议,并且您的包可以很好地构建成一个轮子,而无需奇怪的自定义(如果您 *真的* 需要它们,请查看 CIBW_BEFORE_BUILDCIBW_ENVIRONMENT)。

这列出了所有三个操作系统;如果您不支持 Windows,则可以在这里将其删除。如果您更希望为 macOS 创建 universal2 轮子,则可以删除 Intel (macos-13) 或 Apple Silicon (macos-14) 作业,并将 CIBW_ARCHS_MACOS 设置为 "universal2"。您还可以将 CIBW_TEST_SKIP 设置为 "*universal2:arm64",如果从 Intel 构建以确认您理解您无法从 Intel 测试 Apple Silicon。如果您愿意,也可以从 pyproject.toml 文件中执行此操作。

构建步骤几乎完全通过环境变量控制,这使得在 CI 中设置起来更容易(通常)。这里主要需要的变量通常是 CIBW_BUILD,用于选择要构建的平台 - 请参阅 此处的文档 以获取所有标识符。请注意,ARM 和其他备用架构需要模拟,因此此处未显示(会增加一个额外步骤)。

您还可以选择不同的基础镜像(默认值为 manylinux2014)。如果您想要不同的受支持镜像,请设置 CIBW_MANYLINUX_X86_64_IMAGECIBW_MANYLINUX_I686_IMAGE 等。如果您始终需要特定镜像,则可以在 pyproject.toml 文件中设置。

您可以通过指定 build[uv] 构建前端选项并在运行程序上预安装 uv 来加快构建速度。

发布

upload_all:
  needs: [build_wheels, make_sdist]
  environment: pypi
  permissions:
    id-token: write
    attestations: write
    contents: read

  runs-on: ubuntu-latest
  if: github.event_name == 'release' && github.event.action == 'published'
  steps:
    - uses: actions/download-artifact@v4
      with:
        pattern: cibw-*
        path: dist
        merge-multiple: true

    - name: Generate artifact attestations
      uses: actions/attest-build-provenance@v1.4.3
      with:
        subject-path: "dist/*"

    - uses: pypa/gh-action-pypi-publish@release/v1

当您在 Web UI 中进行 GitHub 发布时,我们会发布到 PyPI。您只需要告诉 PyPI 哪个组织、哪个仓库、哪个工作流程,并设置 pypi 环境以允许 GitHub 推送。如果这是您第一次发布软件包,请访问 PyPI 受信任发布者文档,了解有关准备 PyPI 以接受您的初始软件包发布的说明。

我们还生成工件证明,这可以让用户验证工件是否在您的操作中构建。

如果您有多个作业,则需要从上面收集工件。如果您只有一个作业,则可以将其合并到一个作业中,就像我们为纯 Python 轮子所做的那样,使用 dist 而不是 wheelhouse。如果您从多个位置上传,则可以设置 skip_existing(但通常最好不要尝试从两个位置上传相同的文件 - 例如,您可以欺骗 Travis 避免 sdist)。

其他架构

在 Travis 上,cibuildwheel 甚至能够原生创建 ARM 和 PowerPC 构建。IBM Z 构建也可用,但处于测试阶段。但是,由于 Travis CI 最近大幅减少了对开源的支持,因此在 GHA 或 Azure 上模拟这些架构可能更好。也许可以看看 Cirrus CI,它有一些难以找到的架构。