Skip to content

Test workflow

Test workflow #2223

Workflow file for this run

name: Test workflow
permissions:
contents: read
checks: write
on:
push:
branches:
- main
pull_request:
branches:
- "**"
schedule:
- cron: "23 3 * * 0"
workflow_dispatch:
concurrency:
group: ${{ github.ref }}-${{ github.workflow }}
cancel-in-progress: true
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v7
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.13"
- name: Run focused Ruff checks
run: |
python -m pip install --upgrade pip
python -m pip install "ruff>=0.8,<1.0"
ruff check .
minimal-install:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v7
- name: Install system build dependencies (when binary not available)
run: |
retry() {
for attempt in 1 2 3; do
"$@" && return 0
echo "Command failed on attempt ${attempt}; retrying..."
sleep $((attempt * 20))
done
"$@"
}
disable_unavailable_apt_sources() {
sudo rm -f \
/etc/apt/sources.list.d/azure-cli.list \
/etc/apt/sources.list.d/azure-cli.sources \
/etc/apt/sources.list.d/microsoft-prod.list \
/etc/apt/sources.list.d/microsoft-prod.sources
}
disable_unavailable_apt_sources
retry sudo apt-get update
retry sudo apt-get install -y \
gfortran pkg-config ninja-build \
libopenblas-dev liblapack-dev \
libfftw3-dev libhealpix-cxx-dev
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.13"
- name: Install default package and run public smoke check
run: |
python -m pip install --upgrade pip
python -m pip install .
python - <<'PY'
import pyrecest
from pyrecest.backend import array, diag
from pyrecest.filters import KalmanFilter
kf = KalmanFilter((array([0.0, 1.0]), diag(array([1.0, 1.0]))))
print(f"Imported pyrecest {pyrecest.__version__}; initial estimate={kf.get_point_estimate()}")
PY
docs:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v7
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.13"
- name: Install documentation dependencies
run: |
retry() {
for attempt in 1 2 3; do
"$@" && return 0
echo "Command failed on attempt ${attempt}; retrying..."
sleep $((attempt * 20))
done
"$@"
}
python -m pip install --upgrade pip
retry python -m pip install poetry
poetry env use python
retry poetry install --only docs --no-root
- name: Build documentation
run: poetry run mkdocs build --strict
env:
PYTHONPATH: ${{ github.workspace }}/src
- name: Check backend API matrix documentation
run: poetry run python scripts/check_backend_api_matrix.py
env:
PYTHONPATH: ${{ github.workspace }}/src
package:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v7
- name: Install system build dependencies (when binary not available)
run: |
retry() {
for attempt in 1 2 3; do
"$@" && return 0
echo "Command failed on attempt ${attempt}; retrying..."
sleep $((attempt * 20))
done
"$@"
}
disable_unavailable_apt_sources() {
sudo rm -f \
/etc/apt/sources.list.d/azure-cli.list \
/etc/apt/sources.list.d/azure-cli.sources \
/etc/apt/sources.list.d/microsoft-prod.list \
/etc/apt/sources.list.d/microsoft-prod.sources
}
disable_unavailable_apt_sources
retry sudo apt-get update
retry sudo apt-get install -y \
gfortran pkg-config ninja-build \
libopenblas-dev liblapack-dev \
libfftw3-dev libhealpix-cxx-dev
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.13"
- name: Build distributions and validate local release metadata
run: |
retry() {
for attempt in 1 2 3; do
"$@" && return 0
echo "Command failed on attempt ${attempt}; retrying..."
sleep $((attempt * 20))
done
"$@"
}
python -m pip install --upgrade pip
retry python -m pip install build twine
python scripts/check_release_consistency.py --local-only
python -m build
python -m twine check dist/*
- name: Smoke-test default wheel in a clean environment
run: |
python -m venv /tmp/pyrecest-default-wheel
/tmp/pyrecest-default-wheel/bin/python -m pip install --upgrade pip
/tmp/pyrecest-default-wheel/bin/python -m pip install dist/*.whl
/tmp/pyrecest-default-wheel/bin/python - <<'PY'
import pyrecest
from pyrecest.filters import KalmanFilter
print(f"Installed pyrecest {pyrecest.__version__}")
print(f"Resolved baseline filter {KalmanFilter.__name__}")
PY
- name: Install built wheel and smoke-run public examples
run: |
python -m pip install dist/*.whl
python - <<'PY'
import pyrecest
print(f"Installed pyrecest {pyrecest.__version__}")
PY
python scripts/check_minimal_imports.py
python examples/basic/kalman_filter.py
python examples/basic/gaussian_multiplication.py
python scripts/run_scenario.py scenarios/linear_gaussian_cv_1d/config.toml --expected scenarios/linear_gaussian_cv_1d/expected.json
python benchmarks/basic_regressions.py --output benchmark-results.json
python scripts/check_benchmark_regression.py \
benchmark-results.json \
benchmarks/baselines/basic_regressions-linux-py313.json
python scripts/check_benchmark_results.py benchmark-results.json --baseline benchmarks/baselines/basic_regressions.json
- name: Upload benchmark result artifact
uses: actions/upload-artifact@v7
with:
name: package-benchmark-results
path: benchmark-results.json
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- backend: numpy
python-version: "3.11"
- backend: numpy
python-version: "3.12"
- backend: numpy
python-version: "3.13"
- backend: numpy
python-version: "3.14"
- backend: pytorch
python-version: "3.11"
- backend: pytorch
python-version: "3.12"
- backend: pytorch
python-version: "3.13"
- backend: jax
python-version: "3.11"
- backend: jax
python-version: "3.12"
- backend: jax
python-version: "3.13"
permissions:
checks: write
pull-requests: write
steps:
- name: Check out repository
uses: actions/checkout@v7
- name: Install system build dependencies (when binary not available)
run: |
retry() {
for attempt in 1 2 3; do
"$@" && return 0
echo "Command failed on attempt ${attempt}; retrying..."
sleep $((attempt * 20))
done
"$@"
}
disable_unavailable_apt_sources() {
sudo rm -f \
/etc/apt/sources.list.d/azure-cli.list \
/etc/apt/sources.list.d/azure-cli.sources \
/etc/apt/sources.list.d/microsoft-prod.list \
/etc/apt/sources.list.d/microsoft-prod.sources
}
disable_unavailable_apt_sources
retry sudo apt-get update
retry sudo apt-get install -y \
gfortran pkg-config ninja-build \
libopenblas-dev liblapack-dev \
libfftw3-dev libhealpix-cxx-dev
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
retry() {
for attempt in 1 2 3; do
"$@" && return 0
echo "Command failed on attempt ${attempt}; retrying..."
sleep $((attempt * 20))
done
"$@"
}
python -m pip install --upgrade pip
retry python -m pip install poetry
poetry env use python
case "${{ matrix.backend }}" in
numpy)
retry poetry install --with dev --extras "healpy_support"
;;
pytorch)
retry poetry install --with dev --extras "healpy_support"
retry poetry run python -m pip install \
--index-url https://download.pytorch.org/whl/cpu \
--extra-index-url https://pypi.org/simple \
"torch>=2.4,<3.0"
;;
jax)
retry poetry install --with dev --extras "healpy_support jax_support"
;;
*)
echo "Unsupported backend: ${{ matrix.backend }}" >&2
exit 1
;;
esac
- name: Run tests
run: |
if [ "${{ matrix.backend }}" = "jax" ]; then
export JAX_ENABLE_X64=True
fi
export PYRECEST_BACKEND=${{ matrix.backend }}
poetry run python -m pytest \
--rootdir . \
-v \
--strict-config \
--junitxml=junit_test_results_${{ matrix.backend }}.xml \
--cov=pyrecest \
--cov-report=term-missing \
--cov-report=xml:coverage_${{ matrix.backend }}_${{ matrix.python-version }}.xml \
./tests
env:
PYTHONPATH: ${{ github.workspace }}/src
- name: Upload test result artifact
uses: actions/upload-artifact@v7
with:
name: ${{ matrix.backend }}-${{ matrix.python-version }}-test-results
path: junit_test_results_${{ matrix.backend }}.xml
- name: Upload coverage artifact
uses: actions/upload-artifact@v7
with:
name: ${{ matrix.backend }}-${{ matrix.python-version }}-coverage
path: coverage_${{ matrix.backend }}_${{ matrix.python-version }}.xml
full-test:
runs-on: ubuntu-latest
if: ${{ github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' }}
strategy:
fail-fast: false
matrix:
backend: [numpy, pytorch, jax]
python-version: ["3.11", "3.12", "3.13", "3.14"]
permissions:
checks: write
pull-requests: write
steps:
- name: Check out repository
uses: actions/checkout@v7
- name: Install system build dependencies (when binary not available)
run: |
retry() {
for attempt in 1 2 3; do
"$@" && return 0
echo "Command failed on attempt ${attempt}; retrying..."
sleep $((attempt * 20))
done
"$@"
}
disable_unavailable_apt_sources() {
sudo rm -f \
/etc/apt/sources.list.d/azure-cli.list \
/etc/apt/sources.list.d/azure-cli.sources \
/etc/apt/sources.list.d/microsoft-prod.list \
/etc/apt/sources.list.d/microsoft-prod.sources
}
disable_unavailable_apt_sources
retry sudo apt-get update
retry sudo apt-get install -y \
gfortran pkg-config ninja-build \
libopenblas-dev liblapack-dev \
libfftw3-dev libhealpix-cxx-dev
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
retry() {
for attempt in 1 2 3; do
"$@" && return 0
echo "Command failed on attempt ${attempt}; retrying..."
sleep $((attempt * 20))
done
"$@"
}
python -m pip install --upgrade pip
retry python -m pip install poetry
poetry env use python
case "${{ matrix.backend }}" in
numpy)
retry poetry install --with dev --extras "healpy_support"
;;
pytorch)
retry poetry install --with dev --extras "healpy_support"
retry poetry run python -m pip install \
--index-url https://download.pytorch.org/whl/cpu \
--extra-index-url https://pypi.org/simple \
"torch>=2.4,<3.0"
;;
jax)
retry poetry install --with dev --extras "healpy_support jax_support"
;;
*)
echo "Unsupported backend: ${{ matrix.backend }}" >&2
exit 1
;;
esac
- name: Run full backend matrix
run: |
if [ "${{ matrix.backend }}" = "jax" ]; then
export JAX_ENABLE_X64=True
fi
export PYRECEST_BACKEND=${{ matrix.backend }}
poetry run python -m pytest --rootdir . -v --strict-config --junitxml=junit_test_results_${{ matrix.backend }}.xml ./tests
env:
PYTHONPATH: ${{ github.workspace }}/src
- name: Upload test result artifact
uses: actions/upload-artifact@v7
with:
name: full-${{ matrix.backend }}-${{ matrix.python-version }}-test-results
path: junit_test_results_${{ matrix.backend }}.xml
publish-results:
needs: [test, full-test]
runs-on: ubuntu-latest
if: always() && (needs.test.result != 'skipped' || needs.full-test.result != 'skipped')
permissions:
checks: write
pull-requests: write
steps:
- name: Download all test result artifacts
uses: actions/download-artifact@v8
with:
path: test-results
- name: Publish test results
uses: EnricoMi/publish-unit-test-result-action@v2
with:
comment_mode: off
compare_to_earlier_commit: false
github_token: ${{ github.token }}
files: |
test-results/*/junit_test_results_*.xml