name: Python Wheel Build & Test
on:
push:
branches: [main]
paths-ignore:
- '**.md'
- 'docs/**'
- 'mkdocs.yml'
- 'LICENSE'
- '.gitignore'
- '.beads/**'
pull_request:
branches: [main]
paths-ignore:
- '**.md'
- 'docs/**'
- 'mkdocs.yml'
- 'LICENSE'
- '.gitignore'
- '.beads/**'
permissions:
contents: read
env:
PYO3_USE_ABI3_FORWARD_COMPATIBILITY: "1"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build-wheel-smoke:
if: github.event_name == 'pull_request'
name: Build wheel (smoke) on ubuntu-latest py3.12
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v6.0.3
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.12"
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- uses: PyO3/maturin-action@v1
with:
sccache: "true"
manylinux: off
args: --release --out dist -i python3.12
- name: Upload wheels
uses: actions/upload-artifact@v7
with:
name: wheels-smoke-ubuntu-latest-3.12
path: dist
test-wheel-smoke:
if: github.event_name == 'pull_request'
name: Test wheel (smoke) on ubuntu-latest py3.12
needs: build-wheel-smoke
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v6.0.3
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- name: Install uv
uses: astral-sh/setup-uv@v8.2.0
- uses: actions/download-artifact@v8
with:
name: wheels-smoke-ubuntu-latest-3.12
path: dist
- name: Install wheel and test dependencies
shell: bash
run: |
# Install the wheel together with the [test] and [oracle] extras
# from pyproject.toml so test deps stay in sync with the package
# and the pymarc parity oracle executes instead of skipping.
WHEEL=$(ls dist/*.whl | head -1)
uv pip install --system "${WHEEL}[test,oracle]" pytest-rerunfailures
- name: Verify the pymarc oracle is installed
shell: bash
run: |
# The parity tests skip silently when pymarc is missing; fail
# the job here instead so oracle coverage cannot quietly vanish.
# pymarc has no __version__ attribute; read the dist metadata.
python -c "import pymarc, importlib.metadata as m; print('pymarc', m.version('pymarc'))"
- name: Run pytest (core tests, excludes benchmarks)
run: |
pytest tests/python/ -m "not benchmark" -v
build-wheels-pr:
if: github.event_name == 'pull_request' && github.actor != 'dependabot[bot]'
name: Build wheels (PR) on ${{ matrix.os }} py${{ matrix.python-version }}
runs-on: ${{ matrix.os }}
timeout-minutes: 30
strategy:
matrix:
include:
- os: ubuntu-latest
python-version: "3.10"
- os: ubuntu-latest
python-version: "3.14"
- os: macos-latest
python-version: "3.12"
- os: windows-2025
python-version: "3.12"
fail-fast: false
steps:
- uses: actions/checkout@v6.0.3
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- uses: PyO3/maturin-action@v1
with:
sccache: "true"
manylinux: off
args: --release --out dist -i python${{ matrix.python-version }}
- name: Upload wheels
uses: actions/upload-artifact@v7
with:
name: wheels-${{ matrix.os }}-${{ matrix.python-version }}
path: dist
test-wheels-pr:
if: github.event_name == 'pull_request' && github.actor != 'dependabot[bot]'
name: Test wheels (PR) on ${{ matrix.os }} py${{ matrix.python-version }}
needs: build-wheels-pr
runs-on: ${{ matrix.os }}
timeout-minutes: 30
strategy:
matrix:
include:
- os: ubuntu-latest
python-version: "3.10"
- os: ubuntu-latest
python-version: "3.14"
- os: macos-latest
python-version: "3.12"
- os: windows-2025
python-version: "3.12"
fail-fast: false
steps:
- uses: actions/checkout@v6.0.3
- uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install uv
uses: astral-sh/setup-uv@v8.2.0
- uses: actions/download-artifact@v8
with:
name: wheels-${{ matrix.os }}-${{ matrix.python-version }}
path: dist
- name: Install wheel and test dependencies
shell: bash
run: |
# Install the wheel together with the [test] and [oracle] extras
# from pyproject.toml so test deps stay in sync with the package
# and the pymarc parity oracle executes instead of skipping.
WHEEL=$(ls dist/*.whl | head -1)
uv pip install --system "${WHEEL}[test,oracle]" pytest-rerunfailures
- name: Verify the pymarc oracle is installed
shell: bash
run: |
# The parity tests skip silently when pymarc is missing; fail
# the job here instead so oracle coverage cannot quietly vanish.
# pymarc has no __version__ attribute; read the dist metadata.
python -c "import pymarc, importlib.metadata as m; print('pymarc', m.version('pymarc'))"
- name: Run pytest (core tests, excludes benchmarks)
shell: bash
env:
RERUN_FLAGS: ${{ runner.os == 'macOS' && '--reruns 2 --reruns-delay 5' || '' }}
run: pytest tests/python/ -m "not benchmark" -v $RERUN_FLAGS
build-wheels-main:
if: github.event_name == 'push'
name: Build wheels on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
timeout-minutes: 30
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-2025]
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
fail-fast: false
steps:
- uses: actions/checkout@v6.0.3
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- uses: PyO3/maturin-action@v1
with:
sccache: "true"
manylinux: off
args: --release --out dist -i python${{ matrix.python-version }}
- name: Upload wheels
uses: actions/upload-artifact@v7
with:
name: wheels-${{ matrix.os }}-${{ matrix.python-version }}
path: dist
test-wheels-main:
if: github.event_name == 'push'
name: Test wheels on ${{ matrix.os }}
needs: build-wheels-main
runs-on: ${{ matrix.os }}
timeout-minutes: 30
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-2025]
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
fail-fast: false
steps:
- uses: actions/checkout@v6.0.3
- uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install uv
uses: astral-sh/setup-uv@v8.2.0
- uses: actions/download-artifact@v8
with:
name: wheels-${{ matrix.os }}-${{ matrix.python-version }}
path: dist
- name: Install wheel and test dependencies
shell: bash
run: |
# Install the wheel together with the [test] and [oracle] extras
# from pyproject.toml so test deps stay in sync with the package
# and the pymarc parity oracle executes instead of skipping.
WHEEL=$(ls dist/*.whl | head -1)
uv pip install --system "${WHEEL}[test,oracle]" pytest-rerunfailures
- name: Verify the pymarc oracle is installed
shell: bash
run: |
# The parity tests skip silently when pymarc is missing; fail
# the job here instead so oracle coverage cannot quietly vanish.
# pymarc has no __version__ attribute; read the dist metadata.
python -c "import pymarc, importlib.metadata as m; print('pymarc', m.version('pymarc'))"
- name: Run pytest (core tests, excludes benchmarks)
shell: bash
env:
RERUN_FLAGS: ${{ runner.os == 'macOS' && '--reruns 2 --reruns-delay 5' || '' }}
run: pytest tests/python/ -m "not benchmark" -v $RERUN_FLAGS