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_BUILD
和 CIBW_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_IMAGE
、CIBW_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,它有一些难以找到的架构。