From 5f677a7989a5f42ad3524ef0f54ac847826979d4 Mon Sep 17 00:00:00 2001 From: Silia Taider Date: Fri, 21 Aug 2026 14:58:47 +0200 Subject: [PATCH 1/2] [ci][wheels] Build and test wheels on macOS (arm64) --- .../workflows/cibuildwheel-impl/action.yml | 5 ++- .github/workflows/python_wheel_build.yml | 39 ++++++++++++++----- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/.github/workflows/cibuildwheel-impl/action.yml b/.github/workflows/cibuildwheel-impl/action.yml index e005211ed17e6..81c2238ad412e 100644 --- a/.github/workflows/cibuildwheel-impl/action.yml +++ b/.github/workflows/cibuildwheel-impl/action.yml @@ -4,6 +4,9 @@ inputs: build-tag: description: 'The tag for this build' required: true + artifact-name: + description: 'The name of the artifact to upload' + required: true runs: using: "composite" @@ -16,6 +19,6 @@ runs: - name: Upload wheel uses: actions/upload-artifact@v6 with: - name: ${{ inputs.build-tag }} + name: ${{ inputs.artifact-name }} path: wheelhouse/* retention-days: 1 diff --git a/.github/workflows/python_wheel_build.yml b/.github/workflows/python_wheel_build.yml index 0e24ca5d33d10..b817fb7146e52 100644 --- a/.github/workflows/python_wheel_build.yml +++ b/.github/workflows/python_wheel_build.yml @@ -24,28 +24,49 @@ jobs: (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')) || contains(github.event.pull_request.labels.*.name, 'build-python-wheels') - runs-on: ubuntu-latest + runs-on: ${{ matrix.config.runner }} strategy: fail-fast: false matrix: - target: [cp310-manylinux_x86_64, cp311-manylinux_x86_64, cp312-manylinux_x86_64, cp313-manylinux_x86_64, cp314-manylinux_x86_64] - name: ${{ matrix.target }} + python: [cp310, cp311, cp312, cp313, cp314] + config: + - runner: macos-15 + platform: macosx_arm64 + deployment_target: "15.0" + - runner: macos-26 + platform: macosx_arm64 + deployment_target: "26.0" + - runner: ubuntu-latest + platform: manylinux_x86_64 + deployment_target: "" + name: ${{ matrix.python }}-${{ matrix.config.platform }}-${{ matrix.config.runner }} steps: - uses: actions/checkout@v6 with: ref: ${{ github.event.inputs.ref }} - uses: ./.github/workflows/cibuildwheel-impl + env: + MACOSX_DEPLOYMENT_TARGET: ${{ matrix.config.deployment_target }} with: - build-tag: ${{ matrix.target }} + build-tag: ${{ matrix.python }}-${{ matrix.config.platform }} + artifact-name: ${{ matrix.python }}-${{ matrix.config.platform }}-${{ matrix.config.runner }} test-wheels: needs: build-wheels - runs-on: ubuntu-latest + runs-on: ${{ matrix.test_config.runner }} strategy: fail-fast: false matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] - name: test-wheel-cp${{ matrix.python-version }} + python: ["3.10", "3.11", "3.12", "3.13", "3.14"] + test_config: + # each runner tests the wheel built on it + - runner: macos-15 + wheel_name_pattern: "macosx_15" + - runner: macos-26 + wheel_name_pattern: "macosx_26" + - runner: ubuntu-latest + wheel_name_pattern: "manylinux" + name: test-cp${{ matrix.python }}-${{ matrix.test_config.wheel_name_pattern }} steps: - uses: actions/checkout@v6 with: @@ -59,13 +80,13 @@ jobs: - name: Setup Python uses: actions/setup-python@v5 with: - python-version: ${{ matrix.python-version }} + python-version: ${{ matrix.python }} - name: Install produced wheel run: | ls -R wheels PY_VER=$(python -c "import sys; print(f'cp{sys.version_info.major}{sys.version_info.minor}')") - WHEEL=$(ls wheels/*${PY_VER}*.whl | head -n 1) + WHEEL=$(ls wheels/*${PY_VER}*${{ matrix.test_config.wheel_name_pattern }}*.whl | head -n 1) echo "Python version: ${PY_VER}, installing wheel: ${WHEEL}" pip install "$WHEEL" From eac9489f026a0cc4a27315fcfe69201de426aa69 Mon Sep 17 00:00:00 2001 From: siliataider Date: Tue, 25 Aug 2026 16:51:52 +0200 Subject: [PATCH 2/2] [ci][wheels] Force ROOT_BATCH in Python tutorials --- test/wheels/test_tutorials.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/wheels/test_tutorials.py b/test/wheels/test_tutorials.py index c3222f17f0b62..4703ec5355fc0 100644 --- a/test/wheels/test_tutorials.py +++ b/test/wheels/test_tutorials.py @@ -56,6 +56,9 @@ def test_tutorial(tutorial): env = dict(**os.environ) # force matplotlib to use a non-GUI backend env["MPLBACKEND"] = "Agg" + # Tell tutorials that block on GUI input (e.g. Draw(block=True)) + # not to wait for interactive input + env["ROOT_BATCH"] = "1" print("Test env:", env) try: result = subprocess.run(