Update CI and Build Targets for Python 3.14 and Windows/arm64 (#864)

* Update CI and Build Targets

* Add Python 3.14 pre-release support
* Add Windows/arm64 builds
* Update to current GHA runner versions
* Native aarch64 Linux runners
* Fix musllinux 1.2 builds

* musl libyaml build fixes

* add 3.14t wheels w/ freethreading directive, misc CI/build cleanup

* include package version in merged dist artifact filename
This commit is contained in:
Matt Davis 2025-09-25 11:13:58 -07:00 committed by GitHub
parent 69c141adcf
commit d51d8a138f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 155 additions and 78 deletions

View file

@ -38,9 +38,10 @@ env:
jobs:
python_sdist:
name: pyyaml sdist
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
outputs:
artifact_name: ${{ steps.build_sdist.outputs.artifact_name }}
package_version: ${{ steps.build_sdist.outputs.package_version }}
steps:
- name: Checkout PyYAML
uses: actions/checkout@v4
@ -62,6 +63,7 @@ jobs:
python -m build -s .
echo "artifact_name=$(ls ./dist)" >> "$GITHUB_OUTPUT"
echo "package_version=$(ls ./dist | sed -En 's/pyyaml-(.+)\.tar\.gz/\1/p')" >> "$GITHUB_OUTPUT"
- name: Upload sdist artifact
uses: actions/upload-artifact@v4
@ -72,7 +74,7 @@ jobs:
# always upload the sdist artifact- all the wheel build jobs require it
make_linux_libyaml_matrix:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
outputs:
matrix_json: ${{ steps.make_matrix.outputs.matrix_json }}
steps:
@ -85,15 +87,15 @@ jobs:
include:
- { platform: manylinux1, arch: x86_64 }
- { platform: manylinux2014, arch: x86_64 }
- { platform: manylinux2014, arch: aarch64, omit: ${{ env.skip_slow_jobs }} }
- { platform: manylinux2014, arch: s390x, omit: ${{ env.skip_slow_jobs }} }
- { platform: musllinux_1_1, arch: x86_64 }
- { platform: musllinux_1_1, arch: aarch64, omit: ${{ env.skip_slow_jobs }} }
- { platform: manylinux2014, arch: aarch64 }
- { platform: manylinux2014, arch: s390x, omit: ${{ env.skip_ci_redundant_jobs || env.skip_slow_jobs }} }
- { platform: musllinux_1_2, arch: x86_64 }
- { platform: musllinux_1_2, arch: aarch64 }
linux_libyaml:
needs: [make_linux_libyaml_matrix]
name: libyaml ${{ matrix.platform }} ${{ matrix.arch }}
runs-on: ubuntu-22.04
runs-on: ${{ (matrix.arch == 'aarch64') && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }}
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.make_linux_libyaml_matrix.outputs.matrix_json) }}
@ -132,7 +134,7 @@ jobs:
if: steps.cached_libyaml.outputs.cache-hit != 'true'
make_linux_pyyaml_matrix:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
outputs:
matrix_json: ${{ steps.make_matrix.outputs.matrix_json }}
steps:
@ -148,36 +150,45 @@ jobs:
- { platform: manylinux2014, arch: x86_64, spec: cp310, omit: ${{ env.skip_ci_redundant_jobs }} }
- { platform: manylinux2014, arch: x86_64, spec: cp311, omit: ${{ env.skip_ci_redundant_jobs }} }
- { platform: manylinux2014, arch: x86_64, spec: cp312, omit: ${{ env.skip_ci_redundant_jobs }} }
- { platform: manylinux2014, arch: x86_64, spec: cp313 }
- { platform: manylinux2014, arch: aarch64, spec: cp38, omit: ${{ env.skip_ci_redundant_jobs || env.skip_slow_jobs }} }
- { platform: manylinux2014, arch: aarch64, spec: cp39, omit: ${{ env.skip_ci_redundant_jobs || env.skip_slow_jobs }} }
- { platform: manylinux2014, arch: aarch64, spec: cp310, omit: ${{ env.skip_ci_redundant_jobs || env.skip_slow_jobs }} }
- { platform: manylinux2014, arch: aarch64, spec: cp311, omit: ${{ env.skip_ci_redundant_jobs || env.skip_slow_jobs }} }
- { platform: manylinux2014, arch: aarch64, spec: cp312, omit: ${{ env.skip_ci_redundant_jobs || env.skip_slow_jobs }} }
- { platform: manylinux2014, arch: aarch64, spec: cp313, omit: ${{ env.skip_slow_jobs }} }
- { platform: manylinux2014, arch: x86_64, spec: cp313, omit: ${{ env.skip_ci_redundant_jobs }} }
- { platform: manylinux2014, arch: x86_64, spec: cp314 }
- { platform: manylinux2014, arch: x86_64, spec: cp314t }
- { platform: manylinux2014, arch: aarch64, spec: cp38, omit: ${{ env.skip_ci_redundant_jobs }} }
- { platform: manylinux2014, arch: aarch64, spec: cp39, omit: ${{ env.skip_ci_redundant_jobs }} }
- { platform: manylinux2014, arch: aarch64, spec: cp310, omit: ${{ env.skip_ci_redundant_jobs }} }
- { platform: manylinux2014, arch: aarch64, spec: cp311, omit: ${{ env.skip_ci_redundant_jobs }} }
- { platform: manylinux2014, arch: aarch64, spec: cp312, omit: ${{ env.skip_ci_redundant_jobs }} }
- { platform: manylinux2014, arch: aarch64, spec: cp313, omit: ${{ env.skip_ci_redundant_jobs }} }
- { platform: manylinux2014, arch: aarch64, spec: cp314 }
- { platform: manylinux2014, arch: aarch64, spec: cp314t }
- { platform: manylinux2014, arch: s390x, spec: cp38, omit: ${{ env.skip_ci_redundant_jobs || env.skip_slow_jobs }} }
- { platform: manylinux2014, arch: s390x, spec: cp39, omit: ${{ env.skip_ci_redundant_jobs || env.skip_slow_jobs }} }
- { platform: manylinux2014, arch: s390x, spec: cp310, omit: ${{ env.skip_ci_redundant_jobs || env.skip_slow_jobs }} }
- { platform: manylinux2014, arch: s390x, spec: cp311, omit: ${{ env.skip_ci_redundant_jobs || env.skip_slow_jobs }} }
- { platform: manylinux2014, arch: s390x, spec: cp312, omit: ${{ env.skip_ci_redundant_jobs || env.skip_slow_jobs }} }
- { platform: manylinux2014, arch: s390x, spec: cp313, omit: ${{ env.skip_slow_jobs }} }
- { platform: musllinux_1_1, arch: x86_64, spec: cp38, omit: ${{ env.skip_ci_redundant_jobs }} }
- { platform: musllinux_1_1, arch: x86_64, spec: cp39, omit: ${{ env.skip_ci_redundant_jobs }} }
- { platform: musllinux_1_1, arch: x86_64, spec: cp310, omit: ${{ env.skip_ci_redundant_jobs }} }
- { platform: musllinux_1_1, arch: x86_64, spec: cp311, omit: ${{ env.skip_ci_redundant_jobs }} }
- { platform: musllinux_1_1, arch: x86_64, spec: cp312, omit: ${{ env.skip_ci_redundant_jobs }} }
- { platform: musllinux_1_1, arch: x86_64, spec: cp313 }
- { platform: musllinux_1_1, arch: aarch64, spec: cp39, omit: ${{ env.skip_ci_redundant_jobs || env.skip_slow_jobs }} }
- { platform: musllinux_1_1, arch: aarch64, spec: cp310, omit: ${{ env.skip_ci_redundant_jobs || env.skip_slow_jobs }} }
- { platform: musllinux_1_1, arch: aarch64, spec: cp311, omit: ${{ env.skip_ci_redundant_jobs || env.skip_slow_jobs }} }
- { platform: musllinux_1_1, arch: aarch64, spec: cp312, omit: ${{ env.skip_ci_redundant_jobs || env.skip_slow_jobs }} }
- { platform: musllinux_1_1, arch: aarch64, spec: cp313, omit: ${{ env.skip_slow_jobs }} }
- { platform: manylinux2014, arch: s390x, spec: cp313, omit: ${{ env.skip_ci_redundant_jobs || env.skip_slow_jobs }} }
- { platform: manylinux2014, arch: s390x, spec: cp314, omit: ${{ env.skip_slow_jobs }} }
- { platform: manylinux2014, arch: s390x, spec: cp314t, omit: ${{ env.skip_ci_redundant_jobs || env.skip_slow_jobs }} }
- { platform: musllinux_1_2, arch: x86_64, spec: cp38, omit: ${{ env.skip_ci_redundant_jobs }} }
- { platform: musllinux_1_2, arch: x86_64, spec: cp39, omit: ${{ env.skip_ci_redundant_jobs }} }
- { platform: musllinux_1_2, arch: x86_64, spec: cp310, omit: ${{ env.skip_ci_redundant_jobs }} }
- { platform: musllinux_1_2, arch: x86_64, spec: cp311, omit: ${{ env.skip_ci_redundant_jobs }} }
- { platform: musllinux_1_2, arch: x86_64, spec: cp312, omit: ${{ env.skip_ci_redundant_jobs }} }
- { platform: musllinux_1_2, arch: x86_64, spec: cp313, omit: ${{ env.skip_ci_redundant_jobs }} }
- { platform: musllinux_1_2, arch: x86_64, spec: cp314 }
- { platform: musllinux_1_2, arch: x86_64, spec: cp314t }
- { platform: musllinux_1_2, arch: aarch64, spec: cp39, omit: ${{ env.skip_ci_redundant_jobs }} }
- { platform: musllinux_1_2, arch: aarch64, spec: cp310, omit: ${{ env.skip_ci_redundant_jobs }} }
- { platform: musllinux_1_2, arch: aarch64, spec: cp311, omit: ${{ env.skip_ci_redundant_jobs }} }
- { platform: musllinux_1_2, arch: aarch64, spec: cp312, omit: ${{ env.skip_ci_redundant_jobs }} }
- { platform: musllinux_1_2, arch: aarch64, spec: cp313, omit: ${{ env.skip_ci_redundant_jobs }} }
- { platform: musllinux_1_2, arch: aarch64, spec: cp314, omit: ${{ env.skip_slow_jobs }} }
- { platform: musllinux_1_2, arch: aarch64, spec: cp314t, omit: ${{ env.skip_slow_jobs }} }
linux_pyyaml:
needs: [python_sdist, linux_libyaml, make_linux_pyyaml_matrix]
name: pyyaml ${{matrix.spec}}-${{matrix.platform}}_${{matrix.arch}}
runs-on: ubuntu-22.04
runs-on: ${{ (matrix.arch == 'aarch64') && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }}
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.make_linux_pyyaml_matrix.outputs.matrix_json) }}
@ -199,7 +210,7 @@ jobs:
- name: configure docker foreign arch support
uses: docker/setup-qemu-action@v3
if: matrix.arch != 'x86_64'
if: matrix.arch != 'x86_64' && matrix.arch != 'aarch64'
- name: Build/Test/Package
id: build
@ -217,10 +228,9 @@ jobs:
CIBW_MANYLINUX_I686_IMAGE: ${{ matrix.manylinux_img || '' }}
CIBW_MANYLINUX_AARCH64_IMAGE: ${{ matrix.manylinux_img || '' }}
CIBW_MANYLINUX_S390X_IMAGE: ${{ matrix.manylinux_img || '' }}
CIBW_MUSLLINUX_X86_64_IMAGE: ${{ matrix.musllinux_img || 'musllinux_1_1' }}
CIBW_MUSLLINUX_I686_IMAGE: ${{ matrix.musllinux_img || 'musllinux_1_1' }}
CIBW_MUSLLINUX_AARCH64_IMAGE: ${{ matrix.musllinux_img || 'musllinux_1_1' }}
CIBW_PRERELEASE_PYTHONS: 1
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_TEST_COMMAND: cd {project}; pytest
CIBW_TEST_REQUIRES: pytest
run: |
@ -251,22 +261,19 @@ jobs:
if-no-files-found: error
if: ${{ env.skip_artifact_upload != 'true' }}
macos_libyaml:
name: libyaml macos ${{matrix.arch}}
strategy:
matrix:
include:
- arch: x86_64
runs-on: macos-13
run_wrapper: arch -x86_64 bash --noprofile --norc -eo pipefail {0}
runs-on: macos-15-intel # force x86_64 runner
- arch: arm64
deployment_target: '11.0'
run_wrapper: arch -arm64 bash --noprofile --norc -eo pipefail {0}
defaults:
run:
shell: ${{ matrix.run_wrapper || 'arch -x86_64 bash --noprofile --norc -eo pipefail {0}' }}
runs-on: ${{ matrix.runs-on || 'macos-14' }}
shell: ${{ matrix.run_wrapper || 'bash --noprofile --norc -eo pipefail {0}' }}
runs-on: ${{ matrix.runs-on || 'macos-15' }}
steps:
- name: Check cached libyaml state
id: cached_libyaml
@ -281,7 +288,7 @@ jobs:
- name: Build libyaml
env:
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.deployment_target || '10.9' }}
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.deployment_target || '10.13' }}
SDKROOT: ${{ matrix.sdkroot || 'macosx' }}
run: |
set -eux
@ -291,7 +298,7 @@ jobs:
if: steps.cached_libyaml.outputs.cache-hit != 'true'
make_macos_pyyaml_matrix:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
outputs:
matrix_json: ${{ steps.make_matrix.outputs.matrix_json }}
steps:
@ -302,25 +309,40 @@ jobs:
with:
matrix_yaml: |
include:
### x86_64 jobs
- spec: cp38-macosx_x86_64
arch: x86_64
cibw_version: cibuildwheel==2.11.1
runs_on: [macos-13]
runs_on: [macos-15-intel]
omit: ${{ env.skip_ci_redundant_jobs }}
- spec: cp39-macosx_x86_64
runs_on: [macos-13]
arch: x86_64
runs_on: [macos-15-intel]
omit: ${{ env.skip_ci_redundant_jobs }}
- spec: cp310-macosx_x86_64
runs_on: [macos-13]
arch: x86_64
runs_on: [macos-15-intel]
omit: ${{ env.skip_ci_redundant_jobs }}
- spec: cp311-macosx_x86_64
runs_on: [macos-13]
arch: x86_64
runs_on: [macos-15-intel]
omit: ${{ env.skip_ci_redundant_jobs }}
- spec: cp312-macosx_x86_64
runs_on: [macos-13]
arch: x86_64
runs_on: [macos-15-intel]
omit: ${{ env.skip_ci_redundant_jobs }}
- spec: cp313-macosx_x86_64
runs_on: [macos-13]
arch: x86_64
runs_on: [macos-15-intel]
omit: ${{ env.skip_ci_redundant_jobs }}
- spec: cp314-macosx_x86_64
arch: x86_64
runs_on: [macos-15-intel]
- spec: cp314t-macosx_x86_64
arch: x86_64
runs_on: [macos-15-intel]
### arm64 jobs
- spec: cp39-macosx_arm64
deployment_target: '11.0'
arch: arm64
@ -344,12 +366,20 @@ jobs:
- spec: cp313-macosx_arm64
deployment_target: '11.0'
arch: arm64
omit: ${{ env.skip_ci_redundant_jobs }}
- spec: cp314-macosx_arm64
deployment_target: '11.0'
arch: arm64
- spec: cp314t-macosx_arm64
deployment_target: '11.0'
arch: arm64
macos_pyyaml:
needs: [python_sdist, macos_libyaml, make_macos_pyyaml_matrix]
name: pyyaml ${{ matrix.spec }}
runs-on: ${{ matrix.runs_on || 'macos-14' }}
runs-on: ${{ matrix.runs_on || 'macos-15' }}
defaults:
run:
shell: ${{ matrix.run_wrapper || 'bash --noprofile --norc -eo pipefail {0}' }}
@ -368,13 +398,13 @@ jobs:
uses: actions/cache/restore@v4
with:
path: libyaml
key: libyaml_macos_${{ matrix.arch || 'x86_64' }}_${{env.LIBYAML_REF}}
key: libyaml_macos_${{ matrix.arch }}_${{env.LIBYAML_REF}}
fail-on-cache-miss: true
- 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
python-version: '3.11' # as of 2024-05, this has to be < 3.12 since the macos-15 runner image's
# built-in virtualenv/pip are pinned to busted versions that fail on newer Pythons
- name: Build/Test/Package
@ -383,11 +413,10 @@ jobs:
C_INCLUDE_PATH: ../libyaml/include
CIBW_BUILD: ${{matrix.spec}}
CIBW_BUILD_VERBOSITY: 1
CIBW_PRERELEASE_PYTHONS: 1
CIBW_TEST_COMMAND: pytest {package}
CIBW_TEST_REQUIRES: pytest
LIBRARY_PATH: ../libyaml/src/.libs
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.deployment_target || '10.9' }}
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.deployment_target || '10.13' }}
PYYAML_FORCE_CYTHON: 1
PYYAML_FORCE_LIBYAML: 1
SDKROOT: ${{ matrix.sdkroot || 'macosx' }}
@ -417,15 +446,15 @@ jobs:
if-no-files-found: error
if: ${{ env.skip_artifact_upload != 'true' }}
windows_libyaml:
name: libyaml windows ${{ matrix.arch }}
runs-on: ${{ matrix.platform || 'windows-2022' }}
runs-on: ${{ (matrix.arch == 'arm64') && 'windows-11-arm' || 'windows-2022' }}
strategy:
matrix:
include:
- arch: x64
- arch: win32
- arch: arm64
steps:
- name: Get cached libyaml state
id: cached_libyaml
@ -457,7 +486,7 @@ jobs:
popd
make_windows_pyyaml_matrix:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
outputs:
matrix_json: ${{ steps.make_matrix.outputs.matrix_json }}
steps:
@ -468,40 +497,82 @@ jobs:
with:
matrix_yaml: |
include:
### x86_64 jobs
- spec: cp38-win_amd64
arch: x64
- spec: cp39-win_amd64
arch: x64
omit: ${{ env.skip_ci_redundant_jobs }}
- spec: cp310-win_amd64
arch: x64
omit: ${{ env.skip_ci_redundant_jobs }}
- spec: cp311-win_amd64
arch: x64
omit: ${{ env.skip_ci_redundant_jobs }}
- spec: cp312-win_amd64
arch: x64
omit: ${{ env.skip_ci_redundant_jobs }}
- spec: cp313-win_amd64
arch: x64
omit: ${{ env.skip_ci_redundant_jobs }}
- spec: cp314-win_amd64
arch: x64
- spec: cp314t-win_amd64
arch: x64
### arm64 jobs
- spec: cp312-win_arm64
arch: arm64
runs-on: windows-11-arm
omit: ${{ env.skip_ci_redundant_jobs }}
- spec: cp313-win_arm64
arch: arm64
runs-on: windows-11-arm
omit: ${{ env.skip_ci_redundant_jobs }}
- spec: cp314-win_arm64
arch: arm64
runs-on: windows-11-arm
- spec: cp314t-win_arm64
arch: arm64
runs-on: windows-11-arm
### win32 jobs
- spec: cp38-win32
arch: win32
omit: ${{ env.skip_ci_redundant_jobs }}
- spec: cp39-win32
arch: win32
omit: ${{ env.skip_ci_redundant_jobs }}
- spec: cp310-win32
arch: win32
omit: ${{ env.skip_ci_redundant_jobs }}
- spec: cp311-win32
arch: win32
omit: ${{ env.skip_ci_redundant_jobs }}
- spec: cp312-win32
arch: win32
omit: ${{ env.skip_ci_redundant_jobs }}
- spec: cp313-win32
arch: win32
omit: ${{ env.skip_ci_redundant_jobs }}
# no more win32 after 3.13?
windows_pyyaml:
needs: [python_sdist, windows_libyaml, make_windows_pyyaml_matrix]
name: pyyaml ${{matrix.spec}}
@ -527,7 +598,7 @@ jobs:
uses: actions/cache/restore@v4
with:
path: libyaml
key: libyaml_${{'windows'}}_${{ contains(matrix.spec, 'win_amd64') && 'x64' || 'win32' }}_${{env.LIBYAML_REF}}
key: libyaml_${{'windows'}}_${{ matrix.arch }}_${{env.LIBYAML_REF}}
fail-on-cache-miss: true
- name: Install python
@ -544,7 +615,6 @@ jobs:
CIBW_BEFORE_TEST: ls -l {package}
CIBW_TEST_COMMAND: pytest {package}
CIBW_TEST_REQUIRES: pytest
CIBW_PRERELEASE_PYTHONS: 1
#CIBW_CONFIG_SETTINGS: |
# pyyaml_build_config='{"include_dirs": ["libyaml/include"], "library_dirs": ["libyaml/build/Release"], "define": [["YAML_DECLARE_STATIC", 1]], "force": 1}'
run: |
@ -575,16 +645,15 @@ jobs:
merge_artifacts:
needs: [python_sdist, macos_pyyaml, linux_pyyaml, windows_pyyaml]
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps:
- name: merge all artifacts
uses: actions/upload-artifact/merge@v4
with:
name: dist
name: dist-pyyaml-${{ needs.python_sdist.outputs.package_version }}
delete-merged: true
if: ${{ env.skip_artifact_upload != 'true' }}
check:
if: always()
needs:

View file

@ -2,6 +2,14 @@
set -eux
# build the requested version of libyaml locally
echo "::group::fetch libyaml ${LIBYAML_REF}"
git config --global advice.detachedHead false
git clone --branch "$LIBYAML_REF" "$LIBYAML_REPO" libyaml
pushd libyaml
git reset --hard "$LIBYAML_REF"
echo "::endgroup::"
# ensure the prove testing tool is available
echo "::group::ensure build/test prerequisites"
if ! command -v prove; then
@ -12,14 +20,14 @@ if ! command -v prove; then
exit 1
fi
fi
echo "::endgroup::"
# build the requested version of libyaml locally
echo "::group::fetch libyaml ${LIBYAML_REF}"
git config --global advice.detachedHead false
git clone --branch "$LIBYAML_REF" "$LIBYAML_REPO" libyaml
pushd libyaml
git reset --hard "$LIBYAML_REF"
# hack to fix up locally musl1.2 libtool macros
if grep -m 1 alpine /etc/os-release; then
if ! grep -E 'AC_CONFIG_MACRO_DIRS\(\[m4])' configure.ac; then
echo 'AC_CONFIG_MACRO_DIRS([m4])' >> configure.ac
ACLOCAL_PATH=/usr/local/share/libtool/ libtoolize
fi
fi
echo "::endgroup::"
echo "::group::autoconf libyaml w/ static only"

View file

@ -1,7 +1,6 @@
[build-system]
requires = [
"setuptools", # FIXME: declare min/max setuptools versions?
"wheel",
"Cython; python_version < '3.13'",
"Cython>=3.0; python_version >= '3.13'"
]

View file

@ -1,3 +1,4 @@
# cython: freethreading_compatible = True
import yaml