From 8047f172f7a3858e5612774de6475446952e1f03 Mon Sep 17 00:00:00 2001 From: Zanie Blue <contact@zanie.dev> Date: Tue, 17 Dec 2024 16:19:58 -0600 Subject: [PATCH] Generate CI matrix at runtime --- .github/workflows/apple.yml | 166 ++---- .github/workflows/linux.yml | 997 +--------------------------------- .github/workflows/windows.yml | 57 +- ci-matrix.py | 191 +++++++ ci-targets.yaml | 322 +++++++++++ 5 files changed, 608 insertions(+), 1125 deletions(-) create mode 100644 ci-matrix.py create mode 100644 ci-targets.yaml diff --git a/.github/workflows/apple.yml b/.github/workflows/apple.yml index deb21c61..05220096 100644 --- a/.github/workflows/apple.yml +++ b/.github/workflows/apple.yml @@ -40,135 +40,39 @@ jobs: name: pythonbuild path: target/release/pythonbuild + generate-matrix: + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: astral-sh/setup-uv@v4 + + - name: Get pull request labels + id: get-labels + run: | + # Convert GitHub labels array to comma-separated string + LABELS=$(echo '${{ toJson(github.event.pull_request.labels.*.name) }}' | jq -r 'join(",")') + echo "labels=$LABELS" >> $GITHUB_OUTPUT + + - name: Generate build matrix + id: set-matrix + run: | + uv run ci-matrix.py --platform darwin --labels "${{ steps.get-labels.outputs.labels }}" > matrix.json && echo "matrix=$(cat matrix.json)" >> $GITHUB_OUTPUT + # Display the matrix for debugging too + cat matrix.json | jq + build: - strategy: - fail-fast: false - matrix: - build: - - target_triple: 'aarch64-apple-darwin' - py: 'cpython-3.9' - options: 'debug' - - target_triple: 'aarch64-apple-darwin' - py: 'cpython-3.9' - options: 'pgo' - - target_triple: 'aarch64-apple-darwin' - py: 'cpython-3.9' - options: 'pgo+lto' - - - target_triple: 'aarch64-apple-darwin' - py: 'cpython-3.10' - options: 'debug' - - target_triple: 'aarch64-apple-darwin' - py: 'cpython-3.10' - options: 'pgo' - - target_triple: 'aarch64-apple-darwin' - py: 'cpython-3.10' - options: 'pgo+lto' - - - target_triple: 'aarch64-apple-darwin' - py: 'cpython-3.11' - options: 'debug' - - target_triple: 'aarch64-apple-darwin' - py: 'cpython-3.11' - options: 'pgo' - - target_triple: 'aarch64-apple-darwin' - py: 'cpython-3.11' - options: 'pgo+lto' - - - target_triple: 'aarch64-apple-darwin' - py: 'cpython-3.12' - options: 'debug' - - target_triple: 'aarch64-apple-darwin' - py: 'cpython-3.12' - options: 'pgo' - - target_triple: 'aarch64-apple-darwin' - py: 'cpython-3.12' - options: 'pgo+lto' - - - target_triple: 'aarch64-apple-darwin' - py: 'cpython-3.13' - options: 'debug' - - target_triple: 'aarch64-apple-darwin' - py: 'cpython-3.13' - options: 'pgo' - - target_triple: 'aarch64-apple-darwin' - py: 'cpython-3.13' - options: 'pgo+lto' - - - target_triple: 'aarch64-apple-darwin' - py: 'cpython-3.13' - options: 'freethreaded+debug' - - target_triple: 'aarch64-apple-darwin' - py: 'cpython-3.13' - options: 'freethreaded+pgo' - - target_triple: 'aarch64-apple-darwin' - py: 'cpython-3.13' - options: 'freethreaded+pgo+lto' - - # macOS on Intel hardware. This is pretty straightforward. We exclude - # noopt because it doesn't provide any compelling advantages over PGO - # or LTO builds. - - target_triple: 'x86_64-apple-darwin' - py: 'cpython-3.9' - options: 'debug' - - target_triple: 'x86_64-apple-darwin' - py: 'cpython-3.9' - options: 'pgo' - - target_triple: 'x86_64-apple-darwin' - py: 'cpython-3.9' - options: 'pgo+lto' - - - target_triple: 'x86_64-apple-darwin' - py: 'cpython-3.10' - options: 'debug' - - target_triple: 'x86_64-apple-darwin' - py: 'cpython-3.10' - options: 'pgo' - - target_triple: 'x86_64-apple-darwin' - py: 'cpython-3.10' - options: 'pgo+lto' - - - target_triple: 'x86_64-apple-darwin' - py: 'cpython-3.11' - options: 'debug' - - target_triple: 'x86_64-apple-darwin' - py: 'cpython-3.11' - options: 'pgo' - - target_triple: 'x86_64-apple-darwin' - py: 'cpython-3.11' - options: 'pgo+lto' - - - target_triple: 'x86_64-apple-darwin' - py: 'cpython-3.12' - options: 'debug' - - target_triple: 'x86_64-apple-darwin' - py: 'cpython-3.12' - options: 'pgo' - - target_triple: 'x86_64-apple-darwin' - py: 'cpython-3.12' - options: 'pgo+lto' - - - target_triple: 'x86_64-apple-darwin' - py: 'cpython-3.13' - options: 'debug' - - target_triple: 'x86_64-apple-darwin' - py: 'cpython-3.13' - options: 'pgo' - - target_triple: 'x86_64-apple-darwin' - py: 'cpython-3.13' - options: 'pgo+lto' - - target_triple: 'x86_64-apple-darwin' - py: 'cpython-3.13' - options: 'freethreaded+debug' - - target_triple: 'x86_64-apple-darwin' - py: 'cpython-3.13' - options: 'freethreaded+pgo' - - target_triple: 'x86_64-apple-darwin' - py: 'cpython-3.13' - options: 'freethreaded+pgo+lto' needs: + - generate-matrix - pythonbuild - runs-on: depot-macos-14 + strategy: + matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }} + fail-fast: false + runs-on: macos-14 + name: ${{ matrix.target_triple }} / ${{ matrix.python }} / ${{ matrix.build_options }} steps: - uses: actions/checkout@v4 with: @@ -187,21 +91,21 @@ jobs: - name: Build run: | - if [ "${{ matrix.build.target_triple }}" = "aarch64-apple-darwin" ]; then + if [ "${{ matrix.target_triple }}" = "aarch64-apple-darwin" ]; then export APPLE_SDK_PATH=/Applications/Xcode_15.2.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk - elif [ "${{ matrix.build.target_triple }}" = "x86_64-apple-darwin" ]; then + elif [ "${{ matrix.target_triple }}" = "x86_64-apple-darwin" ]; then export APPLE_SDK_PATH=/Applications/Xcode_15.2.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk else - echo "unhandled target triple: ${{ matrix.build.target_triple }}" + echo "unhandled target triple: ${{ matrix.target_triple }}" exit 1 fi - ./build-macos.py --target-triple ${{ matrix.build.target_triple }} --python ${{ matrix.build.py }} --options ${{ matrix.build.options }} + ./build-macos.py --target-triple ${{ matrix.target_triple }} --python cpython-${{ matrix.python }} --options ${{ matrix.build_options }} - name: Upload Distributions uses: actions/upload-artifact@v4 with: - name: ${{ matrix.build.py }}-${{ matrix.build.target_triple }}-${{ matrix.build.options }} + name: cpython-${{ matrix.python }}-${{ matrix.target_triple }}-${{ matrix.build_options }} path: dist/* - uses: actions/checkout@v4 diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 14a5cb34..3bac4e77 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -115,981 +115,40 @@ jobs: name: image-${{ matrix.image }} path: build/image-* - build: - strategy: - fail-fast: false - matrix: - build: - # Cross-compiles can't do PGO. - - - target_triple: 'aarch64-unknown-linux-gnu' - py: 'cpython-3.9' - options: 'debug' - - target_triple: 'aarch64-unknown-linux-gnu' - py: 'cpython-3.9' - options: 'noopt' - - target_triple: 'aarch64-unknown-linux-gnu' - py: 'cpython-3.9' - options: 'lto' - - - target_triple: 'aarch64-unknown-linux-gnu' - py: 'cpython-3.10' - options: 'debug' - - target_triple: 'aarch64-unknown-linux-gnu' - py: 'cpython-3.10' - options: 'noopt' - - target_triple: 'aarch64-unknown-linux-gnu' - py: 'cpython-3.10' - options: 'lto' - - - target_triple: 'aarch64-unknown-linux-gnu' - py: 'cpython-3.11' - options: 'debug' - - target_triple: 'aarch64-unknown-linux-gnu' - py: 'cpython-3.11' - options: 'noopt' - - target_triple: 'aarch64-unknown-linux-gnu' - py: 'cpython-3.11' - options: 'lto' - - - target_triple: 'aarch64-unknown-linux-gnu' - py: 'cpython-3.12' - options: 'debug' - - target_triple: 'aarch64-unknown-linux-gnu' - py: 'cpython-3.12' - options: 'noopt' - - target_triple: 'aarch64-unknown-linux-gnu' - py: 'cpython-3.12' - options: 'lto' - - # Cross-compiles can't do PGO and require Python 3.9. - - target_triple: 'armv7-unknown-linux-gnueabi' - py: 'cpython-3.9' - options: 'debug' - - target_triple: 'armv7-unknown-linux-gnueabi' - py: 'cpython-3.9' - options: 'noopt' - - target_triple: 'armv7-unknown-linux-gnueabi' - py: 'cpython-3.9' - options: 'lto' - - - target_triple: 'armv7-unknown-linux-gnueabi' - py: 'cpython-3.10' - options: 'debug' - - target_triple: 'armv7-unknown-linux-gnueabi' - py: 'cpython-3.10' - options: 'noopt' - - target_triple: 'armv7-unknown-linux-gnueabi' - py: 'cpython-3.10' - options: 'lto' - - - target_triple: 'armv7-unknown-linux-gnueabi' - py: 'cpython-3.11' - options: 'debug' - - target_triple: 'armv7-unknown-linux-gnueabi' - py: 'cpython-3.11' - options: 'noopt' - - target_triple: 'armv7-unknown-linux-gnueabi' - py: 'cpython-3.11' - options: 'lto' - - - target_triple: 'armv7-unknown-linux-gnueabi' - py: 'cpython-3.12' - options: 'debug' - - target_triple: 'armv7-unknown-linux-gnueabi' - py: 'cpython-3.12' - options: 'noopt' - - target_triple: 'armv7-unknown-linux-gnueabi' - py: 'cpython-3.12' - options: 'lto' - - # Cross-compiles can't do PGO and require Python 3.9. - - target_triple: 'armv7-unknown-linux-gnueabihf' - py: 'cpython-3.9' - options: 'debug' - - target_triple: 'armv7-unknown-linux-gnueabihf' - py: 'cpython-3.9' - options: 'noopt' - - target_triple: 'armv7-unknown-linux-gnueabihf' - py: 'cpython-3.9' - options: 'lto' - - - target_triple: 'armv7-unknown-linux-gnueabihf' - py: 'cpython-3.10' - options: 'debug' - - target_triple: 'armv7-unknown-linux-gnueabihf' - py: 'cpython-3.10' - options: 'noopt' - - target_triple: 'armv7-unknown-linux-gnueabihf' - py: 'cpython-3.10' - options: 'lto' - - - target_triple: 'armv7-unknown-linux-gnueabihf' - py: 'cpython-3.11' - options: 'debug' - - target_triple: 'armv7-unknown-linux-gnueabihf' - py: 'cpython-3.11' - options: 'noopt' - - target_triple: 'armv7-unknown-linux-gnueabihf' - py: 'cpython-3.11' - options: 'lto' - - - target_triple: 'armv7-unknown-linux-gnueabihf' - py: 'cpython-3.12' - options: 'debug' - - target_triple: 'armv7-unknown-linux-gnueabihf' - py: 'cpython-3.12' - options: 'noopt' - - target_triple: 'armv7-unknown-linux-gnueabihf' - py: 'cpython-3.12' - options: 'lto' - - # Cross-compiles can't do PGO and require Python 3.9. - - target_triple: 's390x-unknown-linux-gnu' - py: 'cpython-3.9' - options: 'debug' - - target_triple: 's390x-unknown-linux-gnu' - py: 'cpython-3.9' - options: 'noopt' - - target_triple: 's390x-unknown-linux-gnu' - py: 'cpython-3.9' - options: 'lto' - - - target_triple: 's390x-unknown-linux-gnu' - py: 'cpython-3.10' - options: 'debug' - - target_triple: 's390x-unknown-linux-gnu' - py: 'cpython-3.10' - options: 'noopt' - - target_triple: 's390x-unknown-linux-gnu' - py: 'cpython-3.10' - options: 'lto' - - - target_triple: 's390x-unknown-linux-gnu' - py: 'cpython-3.11' - options: 'debug' - - target_triple: 's390x-unknown-linux-gnu' - py: 'cpython-3.11' - options: 'noopt' - - target_triple: 's390x-unknown-linux-gnu' - py: 'cpython-3.11' - options: 'lto' - - - target_triple: 's390x-unknown-linux-gnu' - py: 'cpython-3.12' - options: 'debug' - - target_triple: 's390x-unknown-linux-gnu' - py: 'cpython-3.12' - options: 'noopt' - - target_triple: 's390x-unknown-linux-gnu' - py: 'cpython-3.12' - options: 'lto' - - # Cross-compiles can't do PGO and require Python 3.9. - - target_triple: 'ppc64le-unknown-linux-gnu' - py: 'cpython-3.9' - options: 'debug' - - target_triple: 'ppc64le-unknown-linux-gnu' - py: 'cpython-3.9' - options: 'noopt' - - target_triple: 'ppc64le-unknown-linux-gnu' - py: 'cpython-3.9' - options: 'lto' - - - target_triple: 'ppc64le-unknown-linux-gnu' - py: 'cpython-3.10' - options: 'debug' - - target_triple: 'ppc64le-unknown-linux-gnu' - py: 'cpython-3.10' - options: 'noopt' - - target_triple: 'ppc64le-unknown-linux-gnu' - py: 'cpython-3.10' - options: 'lto' - - - target_triple: 'ppc64le-unknown-linux-gnu' - py: 'cpython-3.11' - options: 'debug' - - target_triple: 'ppc64le-unknown-linux-gnu' - py: 'cpython-3.11' - options: 'noopt' - - target_triple: 'ppc64le-unknown-linux-gnu' - py: 'cpython-3.11' - options: 'lto' - - - target_triple: 'ppc64le-unknown-linux-gnu' - py: 'cpython-3.12' - options: 'debug' - - target_triple: 'ppc64le-unknown-linux-gnu' - py: 'cpython-3.12' - options: 'noopt' - - target_triple: 'ppc64le-unknown-linux-gnu' - py: 'cpython-3.12' - options: 'lto' - - - target_triple: 'x86_64-unknown-linux-gnu' - py: 'cpython-3.9' - options: 'debug' - run: true - - target_triple: 'x86_64-unknown-linux-gnu' - py: 'cpython-3.9' - options: 'pgo' - run: true - - target_triple: 'x86_64-unknown-linux-gnu' - py: 'cpython-3.9' - options: 'pgo+lto' - run: true - - - target_triple: 'x86_64-unknown-linux-gnu' - py: 'cpython-3.10' - options: 'debug' - run: true - - target_triple: 'x86_64-unknown-linux-gnu' - py: 'cpython-3.10' - options: 'pgo' - run: true - - target_triple: 'x86_64-unknown-linux-gnu' - py: 'cpython-3.10' - options: 'pgo+lto' - run: true - - - target_triple: 'x86_64-unknown-linux-gnu' - py: 'cpython-3.11' - options: 'debug' - run: true - - target_triple: 'x86_64-unknown-linux-gnu' - py: 'cpython-3.11' - options: 'pgo' - run: true - - target_triple: 'x86_64-unknown-linux-gnu' - py: 'cpython-3.11' - options: 'pgo+lto' - run: true - - - target_triple: 'x86_64-unknown-linux-gnu' - py: 'cpython-3.12' - options: 'debug' - run: true - - target_triple: 'x86_64-unknown-linux-gnu' - py: 'cpython-3.12' - options: 'pgo' - run: true - - target_triple: 'x86_64-unknown-linux-gnu' - py: 'cpython-3.12' - options: 'pgo+lto' - run: true - - - target_triple: 'x86_64_v2-unknown-linux-gnu' - py: 'cpython-3.9' - options: 'debug' - run: true - - target_triple: 'x86_64_v2-unknown-linux-gnu' - py: 'cpython-3.9' - options: 'pgo' - run: true - - target_triple: 'x86_64_v2-unknown-linux-gnu' - py: 'cpython-3.9' - options: 'pgo+lto' - run: true - - - target_triple: 'x86_64_v2-unknown-linux-gnu' - py: 'cpython-3.10' - options: 'debug' - run: true - - target_triple: 'x86_64_v2-unknown-linux-gnu' - py: 'cpython-3.10' - options: 'pgo' - run: true - - target_triple: 'x86_64_v2-unknown-linux-gnu' - py: 'cpython-3.10' - options: 'pgo+lto' - run: true - - - target_triple: 'x86_64_v2-unknown-linux-gnu' - py: 'cpython-3.11' - options: 'debug' - run: true - - target_triple: 'x86_64_v2-unknown-linux-gnu' - py: 'cpython-3.11' - options: 'pgo' - run: true - - target_triple: 'x86_64_v2-unknown-linux-gnu' - py: 'cpython-3.11' - options: 'pgo+lto' - run: true - - - target_triple: 'x86_64_v2-unknown-linux-gnu' - py: 'cpython-3.12' - options: 'debug' - run: true - - target_triple: 'x86_64_v2-unknown-linux-gnu' - py: 'cpython-3.12' - options: 'pgo' - run: true - - target_triple: 'x86_64_v2-unknown-linux-gnu' - py: 'cpython-3.12' - options: 'pgo+lto' - run: true - - - target_triple: 'x86_64_v3-unknown-linux-gnu' - py: 'cpython-3.9' - options: 'debug' - run: true - - target_triple: 'x86_64_v3-unknown-linux-gnu' - py: 'cpython-3.9' - options: 'pgo' - run: true - - target_triple: 'x86_64_v3-unknown-linux-gnu' - py: 'cpython-3.9' - options: 'pgo+lto' - run: true - - - target_triple: 'x86_64_v3-unknown-linux-gnu' - py: 'cpython-3.10' - options: 'debug' - run: true - - target_triple: 'x86_64_v3-unknown-linux-gnu' - py: 'cpython-3.10' - options: 'pgo' - run: true - - target_triple: 'x86_64_v3-unknown-linux-gnu' - py: 'cpython-3.10' - options: 'pgo+lto' - run: true - - - target_triple: 'x86_64_v3-unknown-linux-gnu' - py: 'cpython-3.11' - options: 'debug' - run: true - - target_triple: 'x86_64_v3-unknown-linux-gnu' - py: 'cpython-3.11' - options: 'pgo' - run: true - - target_triple: 'x86_64_v3-unknown-linux-gnu' - py: 'cpython-3.11' - options: 'pgo+lto' - run: true - - - target_triple: 'x86_64_v3-unknown-linux-gnu' - py: 'cpython-3.12' - options: 'debug' - run: true - - target_triple: 'x86_64_v3-unknown-linux-gnu' - py: 'cpython-3.12' - options: 'pgo' - run: true - - target_triple: 'x86_64_v3-unknown-linux-gnu' - py: 'cpython-3.12' - options: 'pgo+lto' - run: true - - # GitHub Actions runners don't support x86-64-v4 so we can't PGO. - - target_triple: 'x86_64_v4-unknown-linux-gnu' - py: 'cpython-3.9' - options: 'debug' - - target_triple: 'x86_64_v4-unknown-linux-gnu' - py: 'cpython-3.9' - options: 'noopt' - - target_triple: 'x86_64_v4-unknown-linux-gnu' - py: 'cpython-3.9' - options: 'lto' - - # GitHub Actions runners don't support x86-64-v4 so we can't PGO. - - target_triple: 'x86_64_v4-unknown-linux-gnu' - py: 'cpython-3.10' - options: 'debug' - - target_triple: 'x86_64_v4-unknown-linux-gnu' - py: 'cpython-3.10' - options: 'noopt' - - target_triple: 'x86_64_v4-unknown-linux-gnu' - py: 'cpython-3.10' - options: 'lto' - - - target_triple: 'x86_64_v4-unknown-linux-gnu' - py: 'cpython-3.11' - options: 'debug' - - target_triple: 'x86_64_v4-unknown-linux-gnu' - py: 'cpython-3.11' - options: 'noopt' - - target_triple: 'x86_64_v4-unknown-linux-gnu' - py: 'cpython-3.11' - options: 'lto' - - - target_triple: 'x86_64_v4-unknown-linux-gnu' - py: 'cpython-3.12' - options: 'debug' - - target_triple: 'x86_64_v4-unknown-linux-gnu' - py: 'cpython-3.12' - options: 'noopt' - - target_triple: 'x86_64_v4-unknown-linux-gnu' - py: 'cpython-3.12' - options: 'lto' - - # musl doesn't support PGO. - - - target_triple: 'x86_64-unknown-linux-musl' - py: 'cpython-3.9' - options: 'debug' - run: true - - target_triple: 'x86_64-unknown-linux-musl' - py: 'cpython-3.9' - options: 'noopt' - run: true - - target_triple: 'x86_64-unknown-linux-musl' - py: 'cpython-3.9' - options: 'lto' - run: true - - - target_triple: 'x86_64-unknown-linux-musl' - py: 'cpython-3.10' - options: 'debug' - run: true - - target_triple: 'x86_64-unknown-linux-musl' - py: 'cpython-3.10' - options: 'noopt' - run: true - - target_triple: 'x86_64-unknown-linux-musl' - py: 'cpython-3.10' - options: 'lto' - run: true - - - target_triple: 'x86_64-unknown-linux-musl' - py: 'cpython-3.11' - options: 'debug' - run: true - - target_triple: 'x86_64-unknown-linux-musl' - py: 'cpython-3.11' - options: 'noopt' - run: true - - target_triple: 'x86_64-unknown-linux-musl' - py: 'cpython-3.11' - options: 'lto' - run: true - - - target_triple: 'x86_64-unknown-linux-musl' - py: 'cpython-3.12' - options: 'debug' - run: true - - target_triple: 'x86_64-unknown-linux-musl' - py: 'cpython-3.12' - options: 'noopt' - run: true - - target_triple: 'x86_64-unknown-linux-musl' - py: 'cpython-3.12' - options: 'lto' - run: true - - - target_triple: 'x86_64_v2-unknown-linux-musl' - py: 'cpython-3.9' - options: 'debug' - run: true - - target_triple: 'x86_64_v2-unknown-linux-musl' - py: 'cpython-3.9' - options: 'noopt' - run: true - - target_triple: 'x86_64_v2-unknown-linux-musl' - py: 'cpython-3.9' - options: 'lto' - run: true - - - target_triple: 'x86_64_v2-unknown-linux-musl' - py: 'cpython-3.10' - options: 'debug' - run: true - - target_triple: 'x86_64_v2-unknown-linux-musl' - py: 'cpython-3.10' - options: 'noopt' - run: true - - target_triple: 'x86_64_v2-unknown-linux-musl' - py: 'cpython-3.10' - options: 'lto' - run: true - - - target_triple: 'x86_64_v2-unknown-linux-musl' - py: 'cpython-3.11' - options: 'debug' - run: true - - target_triple: 'x86_64_v2-unknown-linux-musl' - py: 'cpython-3.11' - options: 'noopt' - run: true - - target_triple: 'x86_64_v2-unknown-linux-musl' - py: 'cpython-3.11' - options: 'lto' - run: true - - - target_triple: 'x86_64_v2-unknown-linux-musl' - py: 'cpython-3.12' - options: 'debug' - run: true - - target_triple: 'x86_64_v2-unknown-linux-musl' - py: 'cpython-3.12' - options: 'noopt' - run: true - - target_triple: 'x86_64_v2-unknown-linux-musl' - py: 'cpython-3.12' - options: 'lto' - run: true - - - target_triple: 'x86_64_v3-unknown-linux-musl' - py: 'cpython-3.9' - options: 'debug' - run: true - - target_triple: 'x86_64_v3-unknown-linux-musl' - py: 'cpython-3.9' - options: 'noopt' - run: true - - target_triple: 'x86_64_v3-unknown-linux-musl' - py: 'cpython-3.9' - options: 'lto' - run: true - - - target_triple: 'x86_64_v3-unknown-linux-musl' - py: 'cpython-3.10' - options: 'debug' - run: true - - target_triple: 'x86_64_v3-unknown-linux-musl' - py: 'cpython-3.10' - options: 'noopt' - run: true - - target_triple: 'x86_64_v3-unknown-linux-musl' - py: 'cpython-3.10' - options: 'lto' - run: true - - - target_triple: 'x86_64_v3-unknown-linux-musl' - py: 'cpython-3.11' - options: 'debug' - run: true - - target_triple: 'x86_64_v3-unknown-linux-musl' - py: 'cpython-3.11' - options: 'noopt' - run: true - - target_triple: 'x86_64_v3-unknown-linux-musl' - py: 'cpython-3.11' - options: 'lto' - run: true - - - target_triple: 'x86_64_v3-unknown-linux-musl' - py: 'cpython-3.12' - options: 'debug' - run: true - - target_triple: 'x86_64_v3-unknown-linux-musl' - py: 'cpython-3.12' - options: 'noopt' - run: true - - target_triple: 'x86_64_v3-unknown-linux-musl' - py: 'cpython-3.12' - options: 'lto' - run: true - - - target_triple: 'x86_64_v4-unknown-linux-musl' - py: 'cpython-3.9' - options: 'debug' - - target_triple: 'x86_64_v4-unknown-linux-musl' - py: 'cpython-3.9' - options: 'noopt' - - target_triple: 'x86_64_v4-unknown-linux-musl' - py: 'cpython-3.9' - options: 'lto' - - - target_triple: 'x86_64_v4-unknown-linux-musl' - py: 'cpython-3.10' - options: 'debug' - - target_triple: 'x86_64_v4-unknown-linux-musl' - py: 'cpython-3.10' - options: 'noopt' - - target_triple: 'x86_64_v4-unknown-linux-musl' - py: 'cpython-3.10' - options: 'lto' - - - target_triple: 'x86_64_v4-unknown-linux-musl' - py: 'cpython-3.11' - options: 'debug' - - target_triple: 'x86_64_v4-unknown-linux-musl' - py: 'cpython-3.11' - options: 'noopt' - - target_triple: 'x86_64_v4-unknown-linux-musl' - py: 'cpython-3.11' - options: 'lto' - - - target_triple: 'x86_64_v4-unknown-linux-musl' - py: 'cpython-3.12' - options: 'debug' - - target_triple: 'x86_64_v4-unknown-linux-musl' - py: 'cpython-3.12' - options: 'noopt' - - target_triple: 'x86_64_v4-unknown-linux-musl' - py: 'cpython-3.12' - options: 'lto' - - needs: - - pythonbuild - - image - runs-on: depot-ubuntu-22.04 + generate-matrix: + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} steps: - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Install Python - uses: actions/setup-python@v5 - with: - python-version: '3.11' + + - name: Set up Python + uses: astral-sh/setup-uv@v4 - - name: Download pythonbuild - uses: actions/download-artifact@v4 - with: - name: pythonbuild - path: build - - - name: Download images - uses: actions/download-artifact@v4 - with: - pattern: image-* - path: build - merge-multiple: true - - - name: Load Docker Images + - name: Get pull request labels + id: get-labels run: | - for f in build/image-*.tar.zst; do - echo "decompressing $f" - zstd -d --rm ${f} - done - - for f in build/image-*.tar; do - echo "loading $f" - docker load --input $f - done - - - name: Build + # Convert GitHub labels array to comma-separated string + LABELS=$(echo '${{ toJson(github.event.pull_request.labels.*.name) }}' | jq -r 'join(",")') + echo "labels=$LABELS" >> $GITHUB_OUTPUT + + - name: Generate build matrix + id: set-matrix run: | - # Do empty target so all generated files are touched. - ./build-linux.py --make-target empty - - # Touch mtimes of all images so they are newer than autogenerated files above. - touch build/image-* - - ./build-linux.py --target-triple ${{ matrix.build.target_triple }} --python ${{ matrix.build.py }} --options ${{ matrix.build.options }} - - - name: Validate Distribution - run: | - chmod +x build/pythonbuild - - if [ -n "${{matrix.build.run}}" ]; then - EXTRA_ARGS="--run" - fi - - build/pythonbuild validate-distribution ${EXTRA_ARGS} dist/*.tar.zst - - - name: Upload Distribution - uses: actions/upload-artifact@v4 - with: - name: ${{ matrix.build.py }}-${{ matrix.build.target_triple }}-${{ matrix.build.options }} - path: dist/* - - - - # GitHub enforces a limit of 256 entries per matrix, which we exceeded above - # so the CPython 3.13 jobs are split out - build-313: - strategy: - fail-fast: false - matrix: - build: - - - target_triple: 'aarch64-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'debug' - - target_triple: 'aarch64-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'noopt' - - target_triple: 'aarch64-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'lto' - - target_triple: 'aarch64-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'freethreaded+debug' - - target_triple: 'aarch64-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'freethreaded+noopt' - - target_triple: 'aarch64-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'freethreaded+lto' - - - target_triple: 'armv7-unknown-linux-gnueabi' - py: 'cpython-3.13' - options: 'debug' - - target_triple: 'armv7-unknown-linux-gnueabi' - py: 'cpython-3.13' - options: 'noopt' - - target_triple: 'armv7-unknown-linux-gnueabi' - py: 'cpython-3.13' - options: 'lto' - - target_triple: 'armv7-unknown-linux-gnueabi' - py: 'cpython-3.13' - options: 'freethreaded+debug' - - target_triple: 'armv7-unknown-linux-gnueabi' - py: 'cpython-3.13' - options: 'freethreaded+noopt' - - target_triple: 'armv7-unknown-linux-gnueabi' - py: 'cpython-3.13' - options: 'freethreaded+lto' - - - target_triple: 'armv7-unknown-linux-gnueabihf' - py: 'cpython-3.13' - options: 'debug' - - target_triple: 'armv7-unknown-linux-gnueabihf' - py: 'cpython-3.13' - options: 'noopt' - - target_triple: 'armv7-unknown-linux-gnueabihf' - py: 'cpython-3.13' - options: 'lto' - - target_triple: 'armv7-unknown-linux-gnueabihf' - py: 'cpython-3.13' - options: 'freethreaded+debug' - - target_triple: 'armv7-unknown-linux-gnueabihf' - py: 'cpython-3.13' - options: 'freethreaded+noopt' - - target_triple: 'armv7-unknown-linux-gnueabihf' - py: 'cpython-3.13' - options: 'freethreaded+lto' - - - target_triple: 's390x-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'debug' - - target_triple: 's390x-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'noopt' - - target_triple: 's390x-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'lto' - - target_triple: 's390x-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'freethreaded+debug' - - target_triple: 's390x-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'freethreaded+noopt' - - target_triple: 's390x-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'freethreaded+lto' - - - target_triple: 'ppc64le-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'debug' - - target_triple: 'ppc64le-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'noopt' - - target_triple: 'ppc64le-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'lto' - - target_triple: 'ppc64le-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'freethreaded+debug' - - target_triple: 'ppc64le-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'freethreaded+noopt' - - target_triple: 'ppc64le-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'freethreaded+lto' - - - target_triple: 'x86_64-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'debug' - run: true - - target_triple: 'x86_64-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'pgo' - run: true - - target_triple: 'x86_64-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'pgo+lto' - run: true - - target_triple: 'x86_64-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'freethreaded+debug' - run: true - - target_triple: 'x86_64-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'freethreaded+pgo' - run: true - - target_triple: 'x86_64-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'freethreaded+pgo+lto' - run: true - - - target_triple: 'x86_64_v2-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'debug' - run: true - - target_triple: 'x86_64_v2-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'pgo' - run: true - - target_triple: 'x86_64_v2-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'pgo+lto' - run: true - - target_triple: 'x86_64_v2-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'freethreaded+debug' - run: true - - target_triple: 'x86_64_v2-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'freethreaded+pgo' - run: true - - target_triple: 'x86_64_v2-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'freethreaded+pgo+lto' - run: true - - - target_triple: 'x86_64_v3-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'debug' - run: true - - target_triple: 'x86_64_v3-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'pgo' - run: true - - target_triple: 'x86_64_v3-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'pgo+lto' - run: true - - target_triple: 'x86_64_v3-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'freethreaded+debug' - run: true - - target_triple: 'x86_64_v3-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'freethreaded+pgo' - run: true - - target_triple: 'x86_64_v3-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'freethreaded+pgo+lto' - run: true - - - target_triple: 'x86_64-unknown-linux-musl' - py: 'cpython-3.13' - options: 'debug' - run: true - - target_triple: 'x86_64-unknown-linux-musl' - py: 'cpython-3.13' - options: 'noopt' - run: true - - target_triple: 'x86_64-unknown-linux-musl' - py: 'cpython-3.13' - options: 'lto' - run: true - # TODO: Free-threaded musl builds are blocked by upgrading LLVM 14 -> 18. - # - target_triple: 'x86_64-unknown-linux-musl' - # py: 'cpython-3.13' - # options: 'freethreaded+debug' - # run: true - # - target_triple: 'x86_64-unknown-linux-musl' - # py: 'cpython-3.13' - # options: 'freethreaded+noopt' - # run: true - # - target_triple: 'x86_64-unknown-linux-musl' - # py: 'cpython-3.13' - # options: 'freethreaded+lto' - # run: true - - - target_triple: 'x86_64_v2-unknown-linux-musl' - py: 'cpython-3.13' - options: 'debug' - run: true - - target_triple: 'x86_64_v2-unknown-linux-musl' - py: 'cpython-3.13' - options: 'noopt' - run: true - - target_triple: 'x86_64_v2-unknown-linux-musl' - py: 'cpython-3.13' - options: 'lto' - run: true - # TODO: Free-threaded musl builds are blocked by upgrading LLVM 14 -> 18. - # - target_triple: 'x86_64_v2-unknown-linux-musl' - # py: 'cpython-3.13' - # options: 'freethreaded+debug' - # run: true - # - target_triple: 'x86_64_v2-unknown-linux-musl' - # py: 'cpython-3.13' - # options: 'freethreaded+noopt' - # run: true - # - target_triple: 'x86_64_v2-unknown-linux-musl' - # py: 'cpython-3.13' - # options: 'freethreaded+lto' - # run: true - - - target_triple: 'x86_64_v4-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'debug' - - target_triple: 'x86_64_v4-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'noopt' - - target_triple: 'x86_64_v4-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'lto' - - target_triple: 'x86_64_v4-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'freethreaded+debug' - - target_triple: 'x86_64_v4-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'freethreaded+noopt' - - target_triple: 'x86_64_v4-unknown-linux-gnu' - py: 'cpython-3.13' - options: 'freethreaded+lto' - - - target_triple: 'x86_64_v3-unknown-linux-musl' - py: 'cpython-3.13' - options: 'debug' - run: true - - target_triple: 'x86_64_v3-unknown-linux-musl' - py: 'cpython-3.13' - options: 'noopt' - run: true - - target_triple: 'x86_64_v3-unknown-linux-musl' - py: 'cpython-3.13' - options: 'lto' - run: true - # TODO: Free-threaded musl builds are blocked by upgrading LLVM 14 -> 18. - # - target_triple: 'x86_64_v3-unknown-linux-musl' - # py: 'cpython-3.13' - # options: 'freethreaded+debug' - # run: true - # - target_triple: 'x86_64_v3-unknown-linux-musl' - # py: 'cpython-3.13' - # options: 'freethreaded+noopt' - # run: true - # - target_triple: 'x86_64_v3-unknown-linux-musl' - # py: 'cpython-3.13' - # options: 'freethreaded+lto' - # run: true - - - target_triple: 'x86_64_v4-unknown-linux-musl' - py: 'cpython-3.13' - options: 'debug' - - target_triple: 'x86_64_v4-unknown-linux-musl' - py: 'cpython-3.13' - options: 'noopt' - - target_triple: 'x86_64_v4-unknown-linux-musl' - py: 'cpython-3.13' - options: 'lto' - # TODO: Free-threaded musl builds are blocked by upgrading LLVM 14 -> 18. - # - target_triple: 'x86_64_v4-unknown-linux-musl' - # py: 'cpython-3.13' - # options: 'freethreaded+debug' - # - target_triple: 'x86_64_v4-unknown-linux-musl' - # py: 'cpython-3.13' - # options: 'freethreaded+noopt' - # - target_triple: 'x86_64_v4-unknown-linux-musl' - # py: 'cpython-3.13' - # options: 'freethreaded+lto' - + uv run ci-matrix.py --platform linux --labels "${{ steps.get-labels.outputs.labels }}" > matrix.json && echo "matrix=$(cat matrix.json)" >> $GITHUB_OUTPUT + # Display the matrix for debugging too + cat matrix.json | jq + + build: needs: + - generate-matrix - pythonbuild - image runs-on: depot-ubuntu-22.04 - - # The above should remain an exact duplicate of the `build` job + strategy: + matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }} + fail-fast: false + name: ${{ matrix.target_triple }} / ${{ matrix.python }} / ${{ matrix.build_options }} steps: - uses: actions/checkout@v4 with: @@ -1133,13 +192,13 @@ jobs: # Touch mtimes of all images so they are newer than autogenerated files above. touch build/image-* - ./build-linux.py --target-triple ${{ matrix.build.target_triple }} --python ${{ matrix.build.py }} --options ${{ matrix.build.options }} + ./build-linux.py --target-triple ${{ matrix.target_triple }} --python cpython-${{ matrix.python }} --options ${{ matrix.build_options }} - name: Validate Distribution run: | chmod +x build/pythonbuild - if [ -n "${{matrix.build.run}}" ]; then + if [ -n "${{ matrix.run }}" ]; then EXTRA_ARGS="--run" fi @@ -1148,5 +207,5 @@ jobs: - name: Upload Distribution uses: actions/upload-artifact@v4 with: - name: ${{ matrix.build.py }}-${{ matrix.build.target_triple }}-${{ matrix.build.options }} + name: cpython-${{ matrix.python }}-${{ matrix.target_triple }}-${{ matrix.build_options }} path: dist/* diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 69999a5c..e92d2b55 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -40,32 +40,39 @@ jobs: name: pythonbuild path: target/release/pythonbuild.exe + generate-matrix: + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: astral-sh/setup-uv@v4 + + - name: Get pull request labels + id: get-labels + run: | + # Convert GitHub labels array to comma-separated string + LABELS=$(echo '${{ toJson(github.event.pull_request.labels.*.name) }}' | jq -r 'join(",")') + echo "labels=$LABELS" >> $GITHUB_OUTPUT + + - name: Generate build matrix + id: set-matrix + run: | + uv run ci-matrix.py --platform windows --labels "${{ steps.get-labels.outputs.labels }}" > matrix.json && echo "matrix=$(cat matrix.json)" >> $GITHUB_OUTPUT + # Display the matrix for debugging too + cat matrix.json | jq + build: + needs: + - generate-matrix + - pythonbuild + runs-on: windows-latest strategy: + matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }} fail-fast: false - matrix: - py: - - 'cpython-3.9' - - 'cpython-3.10' - - 'cpython-3.11' - - 'cpython-3.12' - - 'cpython-3.13' - vcvars: - - 'vcvars32.bat' - - 'vcvars64.bat' - options: - - 'pgo' - - include: - - py: 'cpython-3.13' - vcvars: 'vcvars32.bat' - options: 'freethreaded+pgo' - - py: 'cpython-3.13' - vcvars: 'vcvars64.bat' - options: 'freethreaded+pgo' - - needs: pythonbuild - runs-on: windows-2022 + name: ${{ matrix.target_triple }} / ${{ matrix.python }} / ${{ matrix.build_option }} steps: - uses: actions/checkout@v4 with: @@ -96,7 +103,7 @@ jobs: shell: cmd run: | call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\${{ matrix.vcvars }}" - py.exe -3.9 build-windows.py --python ${{ matrix.py }} --sh c:\cygwin\bin\sh.exe --options ${{ matrix.options }} + py.exe -3.9 build-windows.py --python cpython-${{ matrix.python }} --sh c:\cygwin\bin\sh.exe --options ${{ matrix.build_options }} - name: Validate Distribution run: | @@ -106,5 +113,5 @@ jobs: - name: Upload Distributions uses: actions/upload-artifact@v4 with: - name: ${{ matrix.py }}-${{ matrix.vcvars }}-${{ matrix.options }} + name: cpython-${{ matrix.python }}-${{ matrix.vcvars }}-${{ matrix.build_options }} path: dist/* diff --git a/ci-matrix.py b/ci-matrix.py new file mode 100644 index 00000000..fa9c7c20 --- /dev/null +++ b/ci-matrix.py @@ -0,0 +1,191 @@ +# /// script +# requires-python = ">=3.13" +# dependencies = [ +# "packaging", +# "pyyaml", +# ] +# /// + +import argparse +import json +from typing import Any, Dict, List, Optional, Set + +import yaml +from packaging.version import Version + +CI_TARGETS_YAML = "ci-targets.yaml" + + +def meets_conditional_version(version: str, min_version: str) -> bool: + return Version(version) >= Version(min_version) + + +def parse_labels(labels: Optional[str]) -> Dict[str, Set[str]]: + """Parse labels into a dict of category filters.""" + if not labels: + return {} + + result: Dict[str, Set[str]] = { + "platform": set(), + "python": set(), + "build": set(), + "arch": set(), + "libc": set(), + } + + for label in labels.split(","): + label = label.strip() + if not label or ":" not in label: + continue + category, value = label.split(":", 1) + if category in result: + result[category].add(value) + + return result + + +def should_include_entry(entry: Dict[str, str], filters: Dict[str, Set[str]]) -> bool: + """Check if an entry satisfies the label filters.""" + if filters.get("platform") and entry["platform"] not in filters["platform"]: + return False + + if filters.get("python") and entry["python"] not in filters["python"]: + return False + + if filters.get("arch") and entry["arch"] not in filters["arch"]: + return False + + if filters.get("libc") and entry.get("libc") not in filters["libc"]: + return False + + if filters.get("build"): + build_options = set(entry.get("build_options", "").split("+")) + if not all(f in build_options for f in filters["build"]): + return False + + return True + + +def generate_matrix_entries( + config: Dict[str, Any], + platform_filter: Optional[str] = None, + label_filters: Optional[Dict[str, Set[str]]] = None, +) -> List[Dict[str, str]]: + matrix_entries = [] + + for platform, platform_config in config.items(): + if platform_filter and platform != platform_filter: + continue + + for target_triple, target_config in platform_config.items(): + add_matrix_entries_for_config( + matrix_entries, + target_triple, + target_config, + platform, + ) + + # Apply label filters if present + if label_filters: + matrix_entries = [ + entry + for entry in matrix_entries + if should_include_entry(entry, label_filters) + ] + + return matrix_entries + + +def add_matrix_entries_for_config( + matrix_entries: List[Dict[str, str]], + target_triple: str, + config: Dict[str, Any], + platform: str, +) -> None: + python_versions = config["python_versions"] + build_options = config["build_options"] + arch = config["arch"] + + # Create base entry that will be used for all variants + base_entry = { + "arch": arch, + "target_triple": target_triple, + "platform": platform, + } + + # Add optional fields if they exist + if "arch_variant" in config: + base_entry["arch_variant"] = config["arch_variant"] + if "libc" in config: + base_entry["libc"] = config["libc"] + if "vcvars" in config: + base_entry["vcvars"] = config["vcvars"] + if "run" in config: + base_entry["run"] = str(config["run"]).lower() + + # Process regular build options + for python_version in python_versions: + for build_option in build_options: + entry = base_entry.copy() + entry.update( + { + "python": python_version, + "build_options": build_option, + } + ) + matrix_entries.append(entry) + + # Process conditional build options (e.g., freethreaded) + for conditional in config.get("build_options_conditional", []): + min_version = conditional["minimum-python-version"] + for python_version in python_versions: + if not meets_conditional_version(python_version, min_version): + continue + + for build_option in conditional["options"]: + entry = base_entry.copy() + entry.update( + { + "python": python_version, + "build_options": build_option, + } + ) + matrix_entries.append(entry) + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser( + description="Generate a JSON matrix for building distributions in CI" + ) + parser.add_argument( + "--platform", + choices=["darwin", "linux", "windows"], + help="Filter matrix entries by platform", + ) + parser.add_argument( + "--labels", + help="Comma-separated list of labels to filter by (e.g., 'platform:darwin,python:3.13,build:debug'), all must match.", + ) + return parser.parse_args() + + +def main() -> None: + args = parse_args() + labels = parse_labels(args.labels) + + with open(CI_TARGETS_YAML, "r") as f: + config = yaml.safe_load(f) + + matrix = { + "include": generate_matrix_entries( + config, + args.platform, + labels, + ) + } + + print(json.dumps(matrix)) + + +if __name__ == "__main__": + main() diff --git a/ci-targets.yaml b/ci-targets.yaml new file mode 100644 index 00000000..17d2d0e6 --- /dev/null +++ b/ci-targets.yaml @@ -0,0 +1,322 @@ +# Describes the targets that the CI system will build and test on. + +darwin: + aarch64-apple-darwin: + arch: aarch64 + python_versions: + - "3.9" + - "3.10" + - "3.11" + - "3.12" + - "3.13" + build_options: + - debug + - pgo + - pgo+lto + build_options_conditional: + - options: + - freethreaded+debug + - freethreaded+pgo + - freethreaded+pgo+lto + minimum-python-version: "3.13" + + x86_64-apple-darwin: + arch: x86_64 + python_versions: + - "3.9" + - "3.10" + - "3.11" + - "3.12" + - "3.13" + build_options: + - debug + - pgo + - pgo+lto + build_options_conditional: + - options: + - freethreaded+debug + - freethreaded+pgo + - freethreaded+pgo+lto + minimum-python-version: "3.13" + +linux: + aarch64-unknown-linux-gnu: + arch: aarch64 + libc: gnu + python_versions: + - "3.9" + - "3.10" + - "3.11" + - "3.12" + - "3.13" + build_options: + - debug + - noopt + - lto + build_options_conditional: + - options: + - freethreaded+debug + - freethreaded+noopt + - freethreaded+lto + minimum-python-version: "3.13" + + armv7-unknown-linux-gnueabi: + arch: armv7 + libc: gnu + python_versions: + - "3.9" + - "3.10" + - "3.11" + - "3.12" + - "3.13" + build_options: + - debug + - noopt + - lto + build_options_conditional: + - options: + - freethreaded+debug + - freethreaded+noopt + - freethreaded+lto + minimum-python-version: "3.13" + + armv7-unknown-linux-gnueabihf: + arch: armv7 + libc: gnu + python_versions: + - "3.9" + - "3.10" + - "3.11" + - "3.12" + - "3.13" + build_options: + - debug + - noopt + - lto + build_options_conditional: + - options: + - freethreaded+debug + - freethreaded+noopt + - freethreaded+lto + minimum-python-version: "3.13" + + s390x-unknown-linux-gnu: + arch: s390x + libc: gnu + python_versions: + - "3.9" + - "3.10" + - "3.11" + - "3.12" + - "3.13" + build_options: + - debug + - noopt + - lto + build_options_conditional: + - options: + - freethreaded+debug + - freethreaded+noopt + - freethreaded+lto + minimum-python-version: "3.13" + + ppc64le-unknown-linux-gnu: + arch: ppc64le + libc: gnu + python_versions: + - "3.9" + - "3.10" + - "3.11" + - "3.12" + - "3.13" + build_options: + - debug + - noopt + - lto + build_options_conditional: + - options: + - freethreaded+debug + - freethreaded+noopt + - freethreaded+lto + minimum-python-version: "3.13" + + x86_64-unknown-linux-gnu: + arch: x86_64 + libc: gnu + python_versions: + - "3.9" + - "3.10" + - "3.11" + - "3.12" + - "3.13" + build_options: + - debug + - pgo + - pgo+lto + build_options_conditional: + - options: + - freethreaded+debug + - freethreaded+pgo + - freethreaded+pgo+lto + minimum-python-version: "3.13" + run: true + + x86_64_v2-unknown-linux-gnu: + arch: x86_64 + arch_variant: v2 + libc: gnu + python_versions: + - "3.9" + - "3.10" + - "3.11" + - "3.12" + - "3.13" + build_options: + - debug + - pgo + - pgo+lto + build_options_conditional: + - options: + - freethreaded+debug + - freethreaded+pgo + - freethreaded+pgo+lto + minimum-python-version: "3.13" + run: true + + x86_64_v3-unknown-linux-gnu: + arch: x86_64 + arch_variant: v3 + libc: gnu + python_versions: + - "3.9" + - "3.10" + - "3.11" + - "3.12" + - "3.13" + build_options: + - debug + - pgo + - pgo+lto + build_options_conditional: + - options: + - freethreaded+debug + - freethreaded+pgo + - freethreaded+pgo+lto + minimum-python-version: "3.13" + run: true + + x86_64_v4-unknown-linux-gnu: + arch: x86_64 + arch_variant: v4 + libc: gnu + python_versions: + - "3.9" + - "3.10" + - "3.11" + - "3.12" + - "3.13" + build_options: + - debug + - noopt + - lto + build_options_conditional: + - options: + - freethreaded+debug + - freethreaded+noopt + - freethreaded+lto + minimum-python-version: "3.13" + + x86_64-unknown-linux-musl: + arch: x86_64 + libc: musl + python_versions: + - "3.9" + - "3.10" + - "3.11" + - "3.12" + - "3.13" + build_options: + - debug + - noopt + - lto + run: true + + x86_64_v2-unknown-linux-musl: + arch: x86_64 + arch_variant: v2 + libc: musl + python_versions: + - "3.9" + - "3.10" + - "3.11" + - "3.12" + - "3.13" + build_options: + - debug + - noopt + - lto + run: true + + x86_64_v3-unknown-linux-musl: + arch: x86_64 + arch_variant: v3 + libc: musl + python_versions: + - "3.9" + - "3.10" + - "3.11" + - "3.12" + - "3.13" + build_options: + - debug + - noopt + - lto + run: true + + x86_64_v4-unknown-linux-musl: + arch: x86_64 + arch_variant: v4 + libc: musl + python_versions: + - "3.9" + - "3.10" + - "3.11" + - "3.12" + - "3.13" + build_options: + - debug + - noopt + - lto + +windows: + i686-pc-windows-msvc: + arch: x86 + vcvars: vcvars32.bat + python_versions: + - "3.9" + - "3.10" + - "3.11" + - "3.12" + - "3.13" + build_options: + - pgo + build_options_conditional: + - options: + - freethreaded+pgo + minimum-python-version: "3.13" + + x86_64-pc-windows-msvc: + arch: x86_64 + vcvars: vcvars64.bat + python_versions: + - "3.9" + - "3.10" + - "3.11" + - "3.12" + - "3.13" + build_options: + - pgo + build_options_conditional: + - options: + - freethreaded+pgo + minimum-python-version: "3.13"