Skip to content

Modernize project structure for better OSS contribution experience #277

Modernize project structure for better OSS contribution experience

Modernize project structure for better OSS contribution experience #277

Workflow file for this run

name: Build and upload to PyPI
on:
push:
branches:
- main
tags:
- v*
pull_request:
branches:
- main
jobs:
unit_tests:
if: github.event_name == 'pull_request'
name: Unit tests on ${{ matrix.os }} / Python ${{ matrix.python }}
runs-on: ${{ matrix.os }}
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
# Pairwise coverage: All OS × Python pairs covered with 7 combinations
include:
- os: ubuntu-latest
python: '3.8'
- os: ubuntu-latest
python: '3.12'
- os: macos-14
python: '3.9'
- os: macos-14
python: '3.13'
- os: windows-latest
python: '3.10'
- os: windows-latest
python: '3.11'
- os: windows-latest
python: '3.14'
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip build
- name: Build and install
run: python -m pip install -e ".[dev]"
- name: Run tests
run: python -m pytest tests -vv
build_wheels:
# Skip wheel builds on PRs - only build on main branch and tags
if: github.event_name != 'pull_request'
name: Build wheels on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
timeout-minutes: 90
strategy:
# Ensure that a wheel builder finishes even if another fails
fail-fast: false
matrix:
include:
# Window 64 bit
# Note: Python 3.6 and 3.7 dropped due to pybind11 v2.13.6 requiring Python >=3.7
# and Python 3.7 being EOL (June 2023). Minimum supported version is now Python 3.8.
- os: windows-latest
python: 38
platform_id: win_amd64
arch: AMD64
- os: windows-latest
python: 39
platform_id: win_amd64
arch: AMD64
- os: windows-latest
python: 310
platform_id: win_amd64
arch: AMD64
- os: windows-latest
python: 311
platform_id: win_amd64
arch: AMD64
- os: windows-latest
python: 312
platform_id: win_amd64
arch: AMD64
- os: windows-latest
python: 313
platform_id: win_amd64
arch: AMD64
- os: windows-latest
python: 314
platform_id: win_amd64
arch: AMD64
# Linux 64 bit manylinux2014
# Python 3.6 and 3.7 dropped (see Windows section comment)
- os: ubuntu-latest
python: 38
platform_id: manylinux_x86_64
manylinux_image: manylinux2014
arch: x86_64
- os: ubuntu-latest
python: 39
platform_id: manylinux_x86_64
manylinux_image: manylinux2014
arch: x86_64
- os: ubuntu-latest
python: 310
platform_id: manylinux_x86_64
manylinux_image: manylinux2014
arch: x86_64
- os: ubuntu-latest
python: 311
platform_id: manylinux_x86_64
manylinux_image: manylinux2014
arch: x86_64
- os: ubuntu-latest
python: 312
platform_id: manylinux_x86_64
manylinux_image: manylinux2014
arch: x86_64
- os: ubuntu-latest
python: 313
platform_id: manylinux_x86_64
manylinux_image: manylinux_2_28
arch: x86_64
- os: ubuntu-latest
python: 314
platform_id: manylinux_x86_64
manylinux_image: manylinux_2_28
arch: x86_64
# Linux 64 bit aarch64
# Python 3.6 and 3.7 dropped (see Windows section comment)
- os: ubuntu-latest
python: 38
platform_id: manylinux_aarch64
manylinux_image: manylinux2014
arch: aarch64
- os: ubuntu-latest
python: 39
platform_id: manylinux_aarch64
manylinux_image: manylinux2014
arch: aarch64
- os: ubuntu-latest
python: 310
platform_id: manylinux_aarch64
manylinux_image: manylinux2014
arch: aarch64
- os: ubuntu-latest
python: 311
platform_id: manylinux_aarch64
manylinux_image: manylinux2014
arch: aarch64
- os: ubuntu-latest
python: 312
platform_id: manylinux_aarch64
manylinux_image: manylinux2014
arch: aarch64
- os: ubuntu-latest
python: 313
platform_id: manylinux_aarch64
manylinux_image: manylinux_2_28
arch: aarch64
- os: ubuntu-latest
python: 314
platform_id: manylinux_aarch64
manylinux_image: manylinux_2_28
arch: aarch64
# MacOS x86_64
# Python 3.6 and 3.7 dropped (see Windows section comment)
- os: macos-13
python: 38
platform_id: macosx_x86_64
macosx_deployment_target: 10.14
arch: x86_64
- os: macos-13
python: 39
platform_id: macosx_x86_64
macosx_deployment_target: 10.14
arch: x86_64
- os: macos-13
python: 310
platform_id: macosx_x86_64
macosx_deployment_target: 10.14
arch: x86_64
- os: macos-13
python: 311
platform_id: macosx_x86_64
macosx_deployment_target: 10.14
arch: x86_64
- os: macos-13
python: 312
platform_id: macosx_x86_64
macosx_deployment_target: 10.14
arch: x86_64
- os: macos-13
python: 313
platform_id: macosx_x86_64
macosx_deployment_target: 10.14
arch: x86_64
- os: macos-13
python: 314
platform_id: macosx_x86_64
macosx_deployment_target: 10.14
arch: x86_64
# Linux musllinux x86_64 (Alpine Linux)
# Note: cibuildwheel 3.x auto-selects appropriate musllinux images
- os: ubuntu-latest
python: 38
platform_id: musllinux_x86_64
arch: x86_64
- os: ubuntu-latest
python: 39
platform_id: musllinux_x86_64
arch: x86_64
- os: ubuntu-latest
python: 310
platform_id: musllinux_x86_64
arch: x86_64
- os: ubuntu-latest
python: 311
platform_id: musllinux_x86_64
arch: x86_64
- os: ubuntu-latest
python: 312
platform_id: musllinux_x86_64
arch: x86_64
- os: ubuntu-latest
python: 313
platform_id: musllinux_x86_64
arch: x86_64
- os: ubuntu-latest
python: 314
platform_id: musllinux_x86_64
arch: x86_64
# Linux musllinux aarch64 (Alpine Linux ARM64)
# Note: cibuildwheel 3.x auto-selects appropriate musllinux images
- os: ubuntu-latest
python: 38
platform_id: musllinux_aarch64
arch: aarch64
- os: ubuntu-latest
python: 39
platform_id: musllinux_aarch64
arch: aarch64
- os: ubuntu-latest
python: 310
platform_id: musllinux_aarch64
arch: aarch64
- os: ubuntu-latest
python: 311
platform_id: musllinux_aarch64
arch: aarch64
- os: ubuntu-latest
python: 312
platform_id: musllinux_aarch64
arch: aarch64
- os: ubuntu-latest
python: 313
platform_id: musllinux_aarch64
arch: aarch64
- os: ubuntu-latest
python: 314
platform_id: musllinux_aarch64
arch: aarch64
# MacOS arm64
- os: macos-14
python: 38
platform_id: macosx_arm64
macosx_deployment_target: 11.7
arch: arm64
- os: macos-14
python: 39
platform_id: macosx_arm64
macosx_deployment_target: 11.7
arch: arm64
- os: macos-14
python: 310
platform_id: macosx_arm64
macosx_deployment_target: 11.7
arch: arm64
- os: macos-14
python: 311
platform_id: macosx_arm64
macosx_deployment_target: 11.7
arch: arm64
- os: macos-14
python: 312
platform_id: macosx_arm64
macosx_deployment_target: 11.7
arch: arm64
- os: macos-14
python: 313
platform_id: macosx_arm64
macosx_deployment_target: 11.7
arch: arm64
- os: macos-14
python: 314
platform_id: macosx_arm64
macosx_deployment_target: 11.7
arch: arm64
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- uses: actions/setup-python@v5
name: Install Python
with:
python-version: '3.10'
- name: Set up QEMU
if: runner.os == 'Linux'
uses: docker/setup-qemu-action@v3
with:
platforms: all
- name: Build wheels
uses: pypa/cibuildwheel@v3.2.1
env:
CIBW_MANYLINUX_X86_64_IMAGE: ${{ matrix.manylinux_image }}
CIBW_MANYLINUX_AARCH64_IMAGE: ${{ matrix.manylinux_image }}
CIBW_BUILD: cp${{ matrix.python }}-${{ matrix.platform_id }}
CIBW_BEFORE_BUILD: pip install pybind11
CIBW_TEST_COMMAND: python {project}/tests/_ci_test_runner.py
CIBW_TEST_COMMAND_WINDOWS: python {project}\tests\_ci_test_runner.py
CIBW_TEST_REQUIRES: pytest numpy
CIBW_TEST_SKIP: ${{ github.event_name == 'pull_request' && '*' || '' }}
CIBW_BUILD_VERBOSITY: 1
CIBW_ARCHS: ${{ matrix.arch }}
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.macosx_deployment_target }}
CIBW_ENVIRONMENT: CIBW_PLATFORM_ID=${{ matrix.platform_id }}
- uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.platform_id }}-py${{ matrix.python }}
path: ./wheelhouse/*.whl
overwrite: true
build_sdist:
# Skip sdist builds on PRs - only build on main branch and tags
if: github.event_name != 'pull_request'
name: Build source distribution
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- uses: actions/setup-python@v5
name: Install Python
with:
python-version: '3.10'
- name: Build sdist
run: python setup.py sdist
- uses: actions/upload-artifact@v4
with:
name: sdist
path: dist/*.tar.gz
overwrite: true
upload_pypi:
needs: [build_wheels, build_sdist]
runs-on: ubuntu-latest
# upload to PyPI on every tag starting with 'v'
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/v')
steps:
- uses: actions/download-artifact@v4
with:
pattern: '*'
path: dist
merge-multiple: true
- uses: pypa/gh-action-pypi-publish@v1.13.0
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}