Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/wheel_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env bash
# Smoke first to fail fast, then the full suite, against the installed
# cppjit. Run from the repository (or cibuildwheel test-sources) root;
# shared by the cibuildwheel test phase and the relocation and sdist jobs.
set -e
export CPPINTEROP_EXTRA_INTERPRETER_ARGS=-std=c++20
python -X faulthandler .github/wheel_smoke.py
cd test
make -j"$(python -c 'import os; print(os.cpu_count())')" PYTHON=python
python -m pytest -ra
135 changes: 78 additions & 57 deletions .github/workflows/wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,18 @@ name: Wheels
# linux mounts it into the build container, the same manylinux_2_28 image
# the toolchain was built on.

# Every code PR and every push to main builds one python per platform
# with the full suite inside; the `build-wheels` label switches a PR to
# the full python list plus the sdist install test. Schedule, tags, and
# dispatch always build the full list.
on:
workflow_dispatch:
pull_request:
paths:
- '.github/workflows/wheels.yml'
- '.github/wheel_smoke.py'
- '.github/wheel_contents_check.py'
- 'pyproject.toml'
- 'CMakeLists.txt'
- 'cmake/**'
- 'src/interop/**'
- 'python/cppjit/_cpython_cppjit.py'
types: [opened, synchronize, reopened, labeled]
paths-ignore:
- 'README.md'
push:
branches: [main]
tags: ['v*']
schedule:
- cron: '30 4 * * 1'
Expand All @@ -32,10 +31,14 @@ concurrency:
jobs:
wheels:
name: wheels ${{ matrix.label }}
# A labeled event re-runs the workflow only for build-wheels itself;
# jobs without a needs edge to this one repeat the guard by alias.
if: &label-guard ${{ github.event.action != 'labeled' || github.event.label.name == 'build-wheels' }}
strategy:
fail-fast: false
matrix:
include:
# One row per shipped wheel; test-relocation reuses this list.
include: &platforms
- { os: ubuntu-24.04, label: manylinux-x86_64, arch: x86_64 }
- { os: ubuntu-24.04-arm, label: manylinux-aarch64, arch: aarch64 }
- { os: macos-26, label: macosx-arm64, arch: arm64 }
Expand All @@ -62,6 +65,17 @@ jobs:
RECIPE_PATH: ${{ steps.llvm.outputs.path }}
run: sudo mv "$RECIPE_PATH" /opt/llvm

# The inverse of test-sdist's full-run condition: plain PRs and
# main pushes build one python; schedule, dispatch, tags, and PRs
# labeled build-wheels fall through to pyproject's full list.
- name: Build one python unless a full run is requested
if: >-
${{ !(github.event_name == 'schedule'
|| github.event_name == 'workflow_dispatch'
|| startsWith(github.ref, 'refs/tags/')
|| contains(github.event.pull_request.labels.*.name, 'build-wheels')) }}
run: echo 'CIBW_BUILD=cp314-*' >> "$GITHUB_ENV"

- uses: pypa/cibuildwheel@v4.2.0

- name: Assert the build left the checkout clean
Expand All @@ -76,8 +90,54 @@ jobs:
path: wheelhouse/*.whl
if-no-files-found: error

# Relocation: each wheel installs and runs the full suite away from its
# build machine. The linux image starts bare (g++ because the JIT reads
# the host's C++ standard library headers). The label guard reaches
# this job through needs.
test-relocation:
name: test relocation (${{ matrix.label }})
needs: wheels
strategy:
fail-fast: false
matrix:
include: *platforms
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v7
with:
persist-credentials: false

- uses: actions/download-artifact@v8
with:
name: wheels-${{ matrix.label }}
path: dist

- name: Install the cp314 wheel and run the suite on python:3.14-slim
if: runner.os == 'Linux'
run: |
docker run --rm -v "$PWD":/src -w /src -e PYTHONSAFEPATH=1 \
-e DEBIAN_FRONTEND=noninteractive python:3.14-slim bash -ec '
apt-get -qq update && apt-get -qq -y install g++ make libeigen3-dev libboost-dev
pip install dist/cppjit-*cp314*.whl -r requirements.txt
bash .github/wheel_test.sh'

- uses: actions/setup-python@v7
if: runner.os == 'macOS'
with:
python-version: '3.14'

- name: Install the cp314 wheel and run the suite
if: runner.os == 'macOS'
env:
PYTHONSAFEPATH: '1'
run: |
brew install eigen boost
pip install dist/cppjit-*cp314*.whl -r requirements.txt
bash .github/wheel_test.sh

sdist:
name: sdist
if: *label-guard
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v7
Expand All @@ -95,48 +155,17 @@ jobs:
path: dist/*.tar.gz
if-no-files-found: error

# Run the full suite on a plain runner, outside the manylinux
# container the wheel was built in.
test-wheel:
name: test wheel (full suite)
needs: wheels
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v7
with:
persist-credentials: false

- uses: actions/setup-python@v7
with:
python-version: '3.12'

- uses: actions/download-artifact@v8
with:
name: wheels-manylinux-x86_64
path: wheelhouse

- name: Install the test suite's native deps
# test_eigen/test_boost need them; the CI cells install the same pair.
run: sudo apt-get -q update && sudo apt-get -y install libeigen3-dev libboost-dev

- name: Install the wheel and the test requirements
run: python -m pip install wheelhouse/cppjit-*cp312*.whl -r requirements.txt

- name: Smoke the wheel outside pytest
run: python -X faulthandler .github/wheel_smoke.py

- name: Run the test suite against the installed wheel
env:
CPPINTEROP_EXTRA_INTERPRETER_ARGS: -std=c++20
run: |
cd test
make -j$(nproc) PYTHON=python
python -m pytest -ra

# Build from the sdist and run the full suite against the install.
# PR source-build coverage lives in ci.yml; this job rides the full
# runs (schedule/tag/dispatch and the build-wheels label).
test-sdist:
name: test sdist (build + full suite)
needs: sdist
if: >-
${{ github.event_name == 'schedule'
|| github.event_name == 'workflow_dispatch'
|| startsWith(github.ref, 'refs/tags/')
|| contains(github.event.pull_request.labels.*.name, 'build-wheels') }}
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v7
Expand Down Expand Up @@ -173,13 +202,5 @@ jobs:
--config-settings=cmake.define.Clang_DIR="$RECIPE_PATH/lib/cmake/clang"
-r requirements.txt

- name: Smoke the install outside pytest
run: python -X faulthandler .github/wheel_smoke.py

- name: Run the test suite against the sdist install
env:
CPPINTEROP_EXTRA_INTERPRETER_ARGS: -std=c++20
run: |
cd test
make -j$(nproc) PYTHON=python
python -m pytest -ra
run: bash .github/wheel_test.sh
7 changes: 4 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,22 @@ archs = ["auto64"]
build-verbosity = 1
audit-requires = ["twine"]
audit-command = "twine check {wheel}"
test-sources = ["test", "requirements.txt", ".github/wheel_smoke.py"]
test-command = "python .github/wheel_smoke.py"
test-sources = ["test", "requirements.txt", ".github/wheel_smoke.py", ".github/wheel_test.sh"]
# smoke + full suite; the script is shared with the relocation and sdist jobs
test-command = "bash .github/wheel_test.sh"
# imports must resolve from the installed wheel, not the checkout
test-environment = { PYTHONSAFEPATH = "1" }

[tool.cibuildwheel.linux]
manylinux-x86_64-image = "manylinux_2_28"
manylinux-aarch64-image = "manylinux_2_28"
before-test = "python -m pip install -r {project}/requirements.txt"
# /opt/llvm is staged on the runner by wheels.yml.
container-engine = { name = "docker", create-args = ["--volume=/opt/llvm:/opt/llvm"], disable-host-mount = true }
environment = { CMAKE_ARGS = "-DLLVM_DIR=/opt/llvm/lib/cmake/llvm -DClang_DIR=/opt/llvm/lib/cmake/clang" }

[tool.cibuildwheel.macos]
before-test = "brew install eigen boost && python -m pip install -r {project}/requirements.txt"
test-command = "python .github/wheel_smoke.py && cd test && make -j$(sysctl -n hw.ncpu) PYTHON=python && CPPINTEROP_EXTRA_INTERPRETER_ARGS=-std=c++20 python -m pytest -ra"
environment = { CMAKE_ARGS = "-DLLVM_DIR=/opt/llvm/lib/cmake/llvm -DClang_DIR=/opt/llvm/lib/cmake/clang", MACOSX_DEPLOYMENT_TARGET = "14.0" }

[tool.pytest.ini_options]
Expand Down
Loading