CFFI CI #376
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: CFFI CI | |
on: | |
push: | |
pull_request: | |
types: [ opened, synchronize, reopened ] | |
schedule: | |
- cron: '0 12 * * 1' | |
workflow_dispatch: | |
inputs: | |
skip_artifact_upload: | |
description: Skip (most) job artifact uploads? | |
type: boolean | |
default: true | |
skip_ci_redundant_jobs: | |
description: Skip CI redundant jobs? | |
type: boolean | |
default: true | |
skip_slow_jobs: | |
description: Skip slow/emulated jobs? | |
type: boolean | |
default: true | |
env: | |
skip_ci_redundant_jobs: ${{ (github.event_name == 'workflow_dispatch' && inputs.skip_ci_redundant_jobs) || (github.event_name == 'pull_request' || github.event_name == 'push') }} | |
skip_slow_jobs: ${{ (github.event_name == 'workflow_dispatch' && inputs.skip_slow_jobs) || (github.event_name == 'pull_request' || github.event_name == 'push') }} | |
skip_artifact_upload: ${{ (github.event_name == 'workflow_dispatch' && inputs.skip_artifact_upload) || github.event_name != 'workflow_dispatch' }} | |
jobs: | |
python_sdist: | |
runs-on: ubuntu-24.04 | |
outputs: | |
sdist_artifact_name: ${{ steps.build_sdist.outputs.sdist_artifact_name }} | |
package_version: ${{ steps.build_sdist.outputs.package_version }} | |
steps: | |
- name: clone repo | |
uses: actions/checkout@v4 | |
- name: install python | |
uses: actions/setup-python@v5 | |
with: | |
python-version: 3.x | |
- name: build sdist | |
id: build_sdist | |
run: | | |
rm -rf dist/ | |
python -m pip install build | |
python -m build --sdist | |
echo "sdist_artifact_name=$(ls ./dist)" >> "$GITHUB_OUTPUT" | |
echo "package_version=$(ls ./dist | sed -En 's/cffi-(.+)\.tar\.gz/\1/p')" >> "$GITHUB_OUTPUT" | |
- name: upload sdist artifact | |
uses: actions/upload-artifact@v4 | |
with: | |
name: ${{ steps.build_sdist.outputs.sdist_artifact_name }} | |
path: dist/${{ steps.build_sdist.outputs.sdist_artifact_name }} | |
if-no-files-found: error | |
# always upload the sdist artifact- all the wheel build jobs require it | |
make_linux_matrix: | |
runs-on: ubuntu-24.04 | |
outputs: | |
matrix_json: ${{ steps.make_matrix.outputs.matrix_json }} | |
steps: | |
- uses: actions/checkout@v4 | |
- name: make a matrix | |
id: make_matrix | |
uses: ./.github/actions/dynamatrix | |
with: | |
matrix_yaml: | | |
include: | |
# x86_64 manylinux | |
- { spec: cp39-manylinux_x86_64, arch: x86_64, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp310-manylinux_x86_64, arch: x86_64, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp311-manylinux_x86_64, arch: x86_64, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp312-manylinux_x86_64, arch: x86_64, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp313-manylinux_x86_64, arch: x86_64, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp314-manylinux_x86_64, arch: x86_64, cibw_version: cibuildwheel~=3.0b1 } | |
# FIXME: need to run tests with PYTHON_GIL=0 on this build to actually test sans-GIL, but breaks packaging tests that use the wrong `virtualenv` script wrapper | |
- { spec: cp314t-manylinux_x86_64, skip_artifact_upload: 'true', cibw_version: cibuildwheel~=3.0b1 } | |
# x86_64 musllinux | |
- { spec: cp39-musllinux_x86_64, arch: x86_64, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp310-musllinux_x86_64, arch: x86_64, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp311-musllinux_x86_64, arch: x86_64, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp312-musllinux_x86_64, arch: x86_64, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp313-musllinux_x86_64, arch: x86_64, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp314-musllinux_x86_64, arch: x86_64, cibw_version: cibuildwheel~=3.0b1 } | |
# i686 manylinux | |
- { spec: cp39-manylinux_i686, arch: i686, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp310-manylinux_i686, arch: i686, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp311-manylinux_i686, arch: i686, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp312-manylinux_i686, arch: i686, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp313-manylinux_i686, arch: i686 } | |
# omit i686 releases > 3.13 | |
# i686 musllinux | |
- { spec: cp39-musllinux_i686, arch: i686, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp310-musllinux_i686, arch: i686, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp311-musllinux_i686, arch: i686 } | |
# omit i686 releases after 3.11 | |
# aarch64 manylinux | |
- { spec: cp39-manylinux_aarch64, arch: aarch64 } | |
- { spec: cp310-manylinux_aarch64, arch: aarch64, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp311-manylinux_aarch64, arch: aarch64, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp312-manylinux_aarch64, arch: aarch64, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp313-manylinux_aarch64, arch: aarch64, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp314-manylinux_aarch64, arch: aarch64, cibw_version: cibuildwheel~=3.0b1 } | |
# aarch64 musllinux | |
- { spec: cp39-musllinux_aarch64, arch: aarch64, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp310-musllinux_aarch64, arch: aarch64, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp311-musllinux_aarch64, arch: aarch64, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp312-musllinux_aarch64, arch: aarch64, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp313-musllinux_aarch64, arch: aarch64, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp314-musllinux_aarch64, arch: aarch64, cibw_version: cibuildwheel~=3.0b1 } | |
# ppc64le manylinux | |
- { spec: cp39-manylinux_ppc64le, arch: ppc64le, test_args: '{package}/src/c', omit: ${{ env.skip_slow_jobs }} } | |
- { spec: cp310-manylinux_ppc64le, arch: ppc64le, test_args: '{package}/src/c', omit: ${{ env.skip_slow_jobs || env.skip_ci_redundant_jobs }} } | |
- { spec: cp311-manylinux_ppc64le, arch: ppc64le, test_args: '{package}/src/c', omit: ${{ env.skip_slow_jobs || env.skip_ci_redundant_jobs }} } | |
- { spec: cp312-manylinux_ppc64le, arch: ppc64le, test_args: '{package}/src/c', omit: ${{ env.skip_slow_jobs || env.skip_ci_redundant_jobs }} } | |
- { spec: cp313-manylinux_ppc64le, arch: ppc64le, test_args: '{package}/src/c', omit: ${{ env.skip_slow_jobs || env.skip_ci_redundant_jobs }} } | |
- { spec: cp314-manylinux_ppc64le, arch: ppc64le, omit: ${{ env.skip_slow_jobs }}, cibw_version: cibuildwheel~=3.0b1 } | |
# s390x manylinux | |
- { spec: cp39-manylinux_s390x, arch: s390x, test_args: '{package}/src/c', omit: ${{ env.skip_slow_jobs }} } | |
- { spec: cp310-manylinux_s390x, arch: s390x, test_args: '{package}/src/c', omit: ${{ env.skip_slow_jobs || env.skip_ci_redundant_jobs }} } | |
- { spec: cp311-manylinux_s390x, arch: s390x, test_args: '{package}/src/c', omit: ${{ env.skip_slow_jobs || env.skip_ci_redundant_jobs }} } | |
- { spec: cp312-manylinux_s390x, arch: s390x, test_args: '{package}/src/c', omit: ${{ env.skip_slow_jobs || env.skip_ci_redundant_jobs }} } | |
- { spec: cp313-manylinux_s390x, arch: s390x, test_args: '{package}/src/c', omit: ${{ env.skip_slow_jobs || env.skip_ci_redundant_jobs }} } | |
- { spec: cp314-manylinux_s390x, arch: s390x, omit: ${{ env.skip_slow_jobs }}, cibw_version: cibuildwheel~=3.0b1 } | |
linux: | |
needs: [python_sdist, make_linux_matrix] | |
runs-on: ${{ (matrix.arch == 'aarch64') && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }} | |
strategy: | |
fail-fast: false | |
matrix: ${{ fromJSON(needs.make_linux_matrix.outputs.matrix_json) }} | |
steps: | |
- name: fetch sdist artifact | |
id: fetch_sdist | |
uses: actions/download-artifact@v4 | |
with: | |
name: ${{ needs.python_sdist.outputs.sdist_artifact_name }} | |
- name: configure docker foreign arch support | |
uses: docker/setup-qemu-action@v3 | |
if: matrix.arch != 'x86_64' && matrix.arch != 'i686' && matrix.arch != 'aarch64' | |
- name: build/test wheels | |
id: build | |
env: | |
CFLAGS: -Dffi_call=cffistatic_ffi_call # override name for ffi_call to break hard if we linked against someone else's libffi | |
CIBW_ARCHS_LINUX: all | |
CIBW_BUILD: ${{ matrix.spec }} | |
CIBW_BEFORE_BUILD: | | |
set -eux && \ | |
curl -L -O https://github.com/libffi/libffi/archive/v3.4.6.tar.gz && \ | |
tar zxf v3.4.6.tar.gz && cd libffi-3.4.6 && \ | |
((command -v apk && apk add libtool) || true) && \ | |
./autogen.sh && \ | |
./configure --without-gcc-arch --disable-docs --with-pic --enable-shared=no && \ | |
make install && \ | |
cd .. && \ | |
rm -rf libffi-3.4.6 | |
CIBW_ENVIRONMENT_PASS_LINUX: CFLAGS # ensure that the build container can see our overridden build config | |
CIBW_MANYLINUX_X86_64_IMAGE: ${{ matrix.manylinux_img || '' }} | |
CIBW_MANYLINUX_I686_IMAGE: ${{ matrix.manylinux_img || '' }} | |
CIBW_MANYLINUX_AARCH64_IMAGE: ${{ matrix.manylinux_img || '' }} | |
CIBW_MANYLINUX_PPC64LE_IMAGE: ${{ matrix.manylinux_img || '' }} | |
CIBW_MANYLINUX_S390X_IMAGE: ${{ matrix.manylinux_img || '' }} | |
CIBW_MUSLLINUX_X86_64_IMAGE: ${{ matrix.musllinux_img || 'musllinux_1_2' }} | |
CIBW_MUSLLINUX_I686_IMAGE: ${{ matrix.musllinux_img || 'musllinux_1_2' }} | |
CIBW_MUSLLINUX_AARCH64_IMAGE: ${{ matrix.musllinux_img || 'musllinux_1_2' }} | |
CIBW_ENABLE: cpython-prerelease cpython-freethreading | |
CIBW_TEST_REQUIRES: pytest setuptools # 3.12+ no longer includes distutils, just always ensure setuptools is present | |
CIBW_TEST_COMMAND: PYTHONUNBUFFERED=1 python -m pytest ${{ matrix.test_args || '{project}' }} # default to test all | |
run: | | |
set -eux | |
mkdir cffi | |
tar zxf ${{ steps.fetch_sdist.outputs.download-path }}/cffi*.tar.gz --strip-components=1 -C cffi | |
python -m pip install --upgrade "${{ matrix.cibw_version || 'cibuildwheel' }}" | |
# actually build libffi + wheel (using env tweaks above) | |
python -m cibuildwheel --output-dir dist ./cffi | |
echo "artifact_name=$(ls ./dist/)" >> "$GITHUB_OUTPUT" | |
- name: upload artifacts | |
uses: actions/upload-artifact@v4 | |
with: | |
name: ${{ steps.build.outputs.artifact_name }} | |
path: dist/*.whl | |
if-no-files-found: error | |
if: ${{ (matrix.skip_artifact_upload != 'true') && (env.skip_artifact_upload != 'true') }} | |
make_macos_matrix: | |
runs-on: ubuntu-24.04 | |
outputs: | |
matrix_json: ${{ steps.make_matrix.outputs.matrix_json }} | |
steps: | |
- uses: actions/checkout@v4 | |
- name: make a matrix | |
id: make_matrix | |
uses: ./.github/actions/dynamatrix | |
with: | |
matrix_yaml: | | |
include: | |
# x86_64 macos | |
- { spec: cp39-macosx_x86_64, runs_on: [macos-13], omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp310-macosx_x86_64, runs_on: [macos-13], omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp311-macosx_x86_64, runs_on: [macos-13], omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp312-macosx_x86_64, runs_on: [macos-13], omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp313-macosx_x86_64, runs_on: [macos-13], omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp314-macosx_x86_64, runs_on: [macos-13], cibw_version: cibuildwheel~=3.0b1 } | |
# arm64 macos | |
- { spec: cp39-macosx_arm64, deployment_target: '11.0', run_wrapper: 'arch -arm64 bash --noprofile --norc -eo pipefail {0}', omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp310-macosx_arm64, deployment_target: '11.0', run_wrapper: 'arch -arm64 bash --noprofile --norc -eo pipefail {0}', omit: ${{ env.skip_ci_redundant_jobs}} } | |
- { spec: cp311-macosx_arm64, deployment_target: '11.0', run_wrapper: 'arch -arm64 bash --noprofile --norc -eo pipefail {0}', omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp312-macosx_arm64, deployment_target: '11.0', run_wrapper: 'arch -arm64 bash --noprofile --norc -eo pipefail {0}', omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp313-macosx_arm64, deployment_target: '11.0', run_wrapper: 'arch -arm64 bash --noprofile --norc -eo pipefail {0}', omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp314-macosx_arm64, deployment_target: '11.0', run_wrapper: 'arch -arm64 bash --noprofile --norc -eo pipefail {0}', cibw_version: cibuildwheel~=3.0b1 } | |
macos: | |
needs: [python_sdist, make_macos_matrix] | |
defaults: | |
run: | |
shell: ${{ matrix.run_wrapper || 'bash --noprofile --norc -eo pipefail {0}' }} | |
runs-on: ${{ matrix.runs_on || 'macos-14' }} | |
strategy: | |
fail-fast: false | |
matrix: ${{ fromJSON(needs.make_macos_matrix.outputs.matrix_json) }} | |
steps: | |
- name: fetch sdist artifact | |
id: fetch_sdist | |
uses: actions/download-artifact@v4 | |
with: | |
name: ${{ needs.python_sdist.outputs.sdist_artifact_name }} | |
- name: install python | |
uses: actions/setup-python@v5 | |
with: | |
python-version: '3.11' # as of 2024-05, this has to be < 3.12 since the macos-13 runner image's | |
# built-in virtualenv/pip are pinned to busted versions that fail on newer Pythons | |
- name: build wheel prereqs | |
run: | | |
set -eux | |
python3 -m pip install --user --upgrade "${{ matrix.cibw_version || 'cibuildwheel' }}" | |
brew uninstall --ignore-dependencies libffi 2>&1 || true | |
- name: build/test wheels | |
id: build | |
env: | |
CIBW_BUILD: ${{ matrix.spec }} | |
CIBW_ENABLE: cpython-prerelease | |
CIBW_TEST_REQUIRES: pytest setuptools | |
CIBW_TEST_COMMAND: pip install pip --upgrade; cd {project}; PYTHONUNBUFFERED=1 pytest | |
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.deployment_target || '10.13' }} | |
SDKROOT: ${{ matrix.sdkroot || 'macosx' }} | |
run: | | |
set -eux | |
mkdir cffi | |
tar zxf ${{ steps.fetch_sdist.outputs.download-path }}/cffi*.tar.gz --strip-components=1 -C cffi | |
python3 -m cibuildwheel --output-dir dist cffi | |
echo "artifact_name=$(ls ./dist/)" >> "$GITHUB_OUTPUT" | |
- name: upload artifacts | |
uses: actions/upload-artifact@v4 | |
with: | |
name: ${{ steps.build.outputs.artifact_name }} | |
path: dist/*.whl | |
if-no-files-found: error | |
if: ${{ env.skip_artifact_upload != 'true' }} | |
make_windows_matrix: | |
runs-on: ubuntu-24.04 | |
outputs: | |
matrix_json: ${{ steps.make_matrix.outputs.matrix_json }} | |
steps: | |
- uses: actions/checkout@v4 | |
- name: make a matrix | |
id: make_matrix | |
uses: ./.github/actions/dynamatrix | |
with: | |
matrix_yaml: | | |
include: | |
# x86_64 windows | |
- { spec: cp39-win_amd64, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp310-win_amd64, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp311-win_amd64, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp312-win_amd64, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp313-win_amd64, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp314-win_amd64, cibw_version: cibuildwheel~=3.0b1 } | |
# x86 windows | |
- { spec: cp39-win32, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp310-win32, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp311-win32, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp312-win32, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp313-win32, omit: ${{ env.skip_ci_redundant_jobs }} } | |
- { spec: cp314-win32, cibw_version: cibuildwheel~=3.0b1 } | |
# arm64 windows | |
- { spec: cp311-win_arm64, runs_on: windows-11-arm, omit: ${{ env.skip_ci_redundant_jobs }}, cibw_version: cibuildwheel~=3.0b1 } | |
- { spec: cp312-win_arm64, runs_on: windows-11-arm, omit: ${{ env.skip_ci_redundant_jobs }}, cibw_version: cibuildwheel~=3.0b1 } | |
- { spec: cp313-win_arm64, runs_on: windows-11-arm, omit: ${{ env.skip_ci_redundant_jobs }}, cibw_version: cibuildwheel~=3.0b1 } | |
- { spec: cp314-win_arm64, runs_on: windows-11-arm, cibw_version: cibuildwheel~=3.0b1 } | |
windows: | |
needs: [python_sdist, make_windows_matrix] | |
runs-on: ${{ matrix.runs_on || 'windows-2022' }} | |
strategy: | |
fail-fast: false | |
matrix: ${{ fromJSON(needs.make_windows_matrix.outputs.matrix_json) }} | |
steps: | |
- name: fetch sdist artifact | |
id: fetch_sdist | |
uses: actions/download-artifact@v4 | |
with: | |
name: ${{ needs.python_sdist.outputs.sdist_artifact_name }} | |
- name: Install python | |
uses: actions/setup-python@v5 | |
with: | |
python-version: 3.x | |
- name: build/test wheels | |
id: build | |
env: | |
CIBW_BUILD: ${{ matrix.spec }} | |
CIBW_ENABLE: cpython-prerelease | |
CIBW_TEST_REQUIRES: pytest setuptools | |
CIBW_TEST_COMMAND: ${{ matrix.test_cmd || 'python -m pytest {package}/src/c' }} | |
# FIXME: /testing takes ~45min on Windows and has some failures... | |
# CIBW_TEST_COMMAND='python -m pytest {package}/src/c {package}/testing' | |
run: | | |
set -eux | |
mkdir cffi | |
tar zxf cffi*.tar.gz --strip-components=1 -C cffi | |
python -m pip install --upgrade pip | |
pip install "${{ matrix.cibw_version || 'cibuildwheel'}}" | |
python -m cibuildwheel --output-dir dist cffi | |
echo "artifact_name=$(ls ./dist/)" >> "$GITHUB_OUTPUT" | |
shell: bash | |
- name: upload artifacts | |
uses: actions/upload-artifact@v4 | |
with: | |
name: ${{ steps.build.outputs.artifact_name }} | |
path: dist/*.whl | |
if-no-files-found: error | |
if: ${{ env.skip_artifact_upload != 'true' }} | |
merge_artifacts: | |
needs: [python_sdist, linux, macos, windows] | |
runs-on: ubuntu-24.04 | |
steps: | |
- name: merge all artifacts | |
uses: actions/upload-artifact/merge@v4 | |
with: | |
name: dist-cffi-${{ needs.python_sdist.outputs.package_version }} | |
delete-merged: true | |
if: ${{ env.skip_artifact_upload != 'true' }} | |
check: | |
if: always() | |
needs: [python_sdist, linux, macos, windows, merge_artifacts] | |
runs-on: ubuntu-24.04 | |
steps: | |
- name: Verify all previous jobs succeeded (provides a single check to sample for gating purposes) | |
uses: re-actors/alls-green@release/v1 | |
with: | |
jobs: ${{ toJSON(needs) }} |