CI workflow (pyro-ppl/numpyro)
The CI workflow from pyro-ppl/numpyro, explained and optimized by Latchkey.
CI health: C - fair
Point runs-on at Latchkey and get run de-duplication, job timeouts, SHA-pinned actions, self-healing for flaky steps, and up to 58% lower cost, applied automatically.
What it does
This is the CI workflow from the pyro-ppl/numpyro repository, a real project running GitHub Actions. It is shown here with attribution under its Apache-2.0 license.
Below, Latchkey shows a faster, safer version produced by its optimization engine.
The workflow
# adapted from https://github.com/actions/starter-workflows/blob/master/ci/python-package.yml
name: CI
on:
push:
branches: [master]
pull_request:
branches: [master]
env:
PYTEST_ADDOPTS: "--cov=numpyro --cov-append --cov-report=lcov"
jobs:
prek:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: prek check
uses: j178/prek-action@v1
with:
extra-args: --all-files --skip ruff --skip ruff-format
lint:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.11", "3.14"]
steps:
- uses: actions/checkout@v6
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
sudo apt install -y pandoc gsfonts
uv sync \
--upgrade \
--extra cpu \
--group ci \
--group docs \
--group test
uv pip freeze
- name: Lint with ty and ruff
run: |
uv run make lint
- name: Build documentation
run: |
uv run make docs
- name: Test documentation
run: |
uv run make doctest
uv run python -m doctest -v README.md
test-modeling:
runs-on: ubuntu-latest
needs: [lint, prek]
strategy:
matrix:
python-version: ["3.11", "3.14"]
env:
UV_PYTHON: ${{ matrix.python-version }}
steps:
- uses: actions/checkout@v6
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
sudo apt install -y graphviz
uv sync \
--upgrade \
--extra cpu \
--group ci \
--group dev \
--group test
uv pip freeze
- name: Test with pytest
run: |
CI=1 uv run pytest -vs -k "not test_example" --durations=100 --ignore=test/infer/ --ignore=test/contrib/
- name: Test x64
run: |
JAX_ENABLE_X64=1 uv run pytest -vs test/test_distributions.py -k "powerLaw or Dagum"
- name: Test tracer leak
if: matrix.python-version == '3.14'
env:
JAX_CHECK_TRACER_LEAKS: 1
run: |
uv run pytest -vs \
test/infer/test_mcmc.py::test_chain_inside_jit \
test/infer/test_mcmc.py::test_chain_jit_args_smoke \
test/infer/test_mcmc.py::test_model_with_multiple_exec_paths \
test/infer/test_mcmc.py::test_reuse_mcmc_run
uv run pytest -vs test/test_distributions.py::test_mean_var -k Gompertz
- name: Coveralls
if: github.repository == 'pyro-ppl/numpyro' && matrix.python-version == '3.14'
uses: coverallsapp/github-action@v2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
parallel: true
flag-name: test-modeling
file: coverage.lcov
test-inference:
runs-on: ubuntu-latest
needs: [lint, prek]
strategy:
matrix:
python-version: ["3.11", "3.14"]
env:
UV_PYTHON: ${{ matrix.python-version }}
steps:
- uses: actions/checkout@v6
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
python-version: ${{ matrix.python-version }}
- name: Set up Python ${{ matrix.python-version }}
run: uv python install ${{ matrix.python-version }}
- name: Install dependencies
run: |
uv sync \
--upgrade \
--extra cpu \
--group ci \
--group dev \
--group test
uv pip freeze
- name: Test with pytest
run: |
uv run pytest -vs --durations=20 test/contrib --ignore=test/contrib/stochastic_support/test_dcc.py
uv run pytest -vs --durations=20 test/infer --ignore=test/infer/test_mcmc.py --ignore=test/contrib/test_nested_sampling.py
uv run pytest -vs --durations=20 test/infer/test_mcmc.py
- name: Test x64
run: |
JAX_ENABLE_X64=1 uv run pytest -vs test/infer/test_mcmc.py -k x64
- name: Test chains
run: |
XLA_FLAGS="--xla_force_host_platform_device_count=2" uv run pytest -vs test/contrib/stochastic_support/test_dcc.py
XLA_FLAGS="--xla_force_host_platform_device_count=2" uv run pytest -vs test/contrib/test_tfp.py -k "chain"
XLA_FLAGS="--xla_force_host_platform_device_count=2" uv run pytest -vs test/infer/test_hmc_gibbs.py -k "chain"
XLA_FLAGS="--xla_force_host_platform_device_count=2" uv run pytest -vs test/infer/test_mcmc.py -k "chain or pmap or vmap"
- name: Test custom prng
run: |
JAX_ENABLE_CUSTOM_PRNG=1 uv run pytest -vs test/infer/test_mcmc.py
- name: Test nested sampling
run: |
JAX_ENABLE_X64=1 uv run pytest -vs test/contrib/test_nested_sampling.py
- name: Coveralls
if: github.repository == 'pyro-ppl/numpyro' && matrix.python-version == '3.14'
uses: coverallsapp/github-action@v2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
parallel: true
flag-name: test-inference
file: coverage.lcov
examples:
runs-on: ubuntu-latest
needs: [lint, prek]
strategy:
matrix:
python-version: ["3.14"]
env:
UV_PYTHON: ${{ matrix.python-version }}
steps:
- uses: actions/checkout@v6
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
update-path: true
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
uv sync \
--upgrade \
--extra cpu \
--group ci \
--group dev \
--group examples \
--group test
uv pip freeze
- name: Test with pytest
run: |
CI=1 XLA_FLAGS="--xla_force_host_platform_device_count=2" uv run pytest -vs -k test_example
- name: Coveralls
if: github.repository == 'pyro-ppl/numpyro' && matrix.python-version == '3.14'
uses: coverallsapp/github-action@v2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
parallel: true
flag-name: examples
file: coverage.lcov
finish:
needs: [test-modeling, test-inference, examples]
runs-on: ubuntu-latest
if: github.repository == 'pyro-ppl/numpyro'
steps:
- name: Coveralls finished
uses: coverallsapp/github-action@v2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
parallel-finished: true
carryforward: "test-modeling,test-inference,examples"
The same workflow, on Latchkey
Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.
# adapted from https://github.com/actions/starter-workflows/blob/master/ci/python-package.yml name: CI on: push: branches: [master] pull_request: branches: [master] env: PYTEST_ADDOPTS: "--cov=numpyro --cov-append --cov-report=lcov" concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: prek: timeout-minutes: 30 runs-on: latchkey-small steps: - uses: actions/checkout@v6 - name: prek check uses: j178/prek-action@v1 with: extra-args: --all-files --skip ruff --skip ruff-format lint: timeout-minutes: 30 runs-on: latchkey-small strategy: matrix: python-version: ["3.11", "3.14"] steps: - uses: actions/checkout@v6 - name: Install uv uses: astral-sh/setup-uv@v7 with: enable-cache: true python-version: ${{ matrix.python-version }} - name: Install dependencies run: | sudo apt install -y pandoc gsfonts uv sync \ --upgrade \ --extra cpu \ --group ci \ --group docs \ --group test uv pip freeze - name: Lint with ty and ruff run: | uv run make lint - name: Build documentation run: | uv run make docs - name: Test documentation run: | uv run make doctest uv run python -m doctest -v README.md test-modeling: timeout-minutes: 30 runs-on: latchkey-small needs: [lint, prek] strategy: matrix: python-version: ["3.11", "3.14"] env: UV_PYTHON: ${{ matrix.python-version }} steps: - uses: actions/checkout@v6 - name: Install uv uses: astral-sh/setup-uv@v7 with: enable-cache: true python-version: ${{ matrix.python-version }} - name: Install dependencies run: | sudo apt install -y graphviz uv sync \ --upgrade \ --extra cpu \ --group ci \ --group dev \ --group test uv pip freeze - name: Test with pytest run: | CI=1 uv run pytest -vs -k "not test_example" --durations=100 --ignore=test/infer/ --ignore=test/contrib/ - name: Test x64 run: | JAX_ENABLE_X64=1 uv run pytest -vs test/test_distributions.py -k "powerLaw or Dagum" - name: Test tracer leak if: matrix.python-version == '3.14' env: JAX_CHECK_TRACER_LEAKS: 1 run: | uv run pytest -vs \ test/infer/test_mcmc.py::test_chain_inside_jit \ test/infer/test_mcmc.py::test_chain_jit_args_smoke \ test/infer/test_mcmc.py::test_model_with_multiple_exec_paths \ test/infer/test_mcmc.py::test_reuse_mcmc_run uv run pytest -vs test/test_distributions.py::test_mean_var -k Gompertz - name: Coveralls if: github.repository == 'pyro-ppl/numpyro' && matrix.python-version == '3.14' uses: coverallsapp/github-action@v2 with: github-token: ${{ secrets.GITHUB_TOKEN }} parallel: true flag-name: test-modeling file: coverage.lcov test-inference: timeout-minutes: 30 runs-on: latchkey-small needs: [lint, prek] strategy: matrix: python-version: ["3.11", "3.14"] env: UV_PYTHON: ${{ matrix.python-version }} steps: - uses: actions/checkout@v6 - name: Install uv uses: astral-sh/setup-uv@v7 with: enable-cache: true python-version: ${{ matrix.python-version }} - name: Set up Python ${{ matrix.python-version }} run: uv python install ${{ matrix.python-version }} - name: Install dependencies run: | uv sync \ --upgrade \ --extra cpu \ --group ci \ --group dev \ --group test uv pip freeze - name: Test with pytest run: | uv run pytest -vs --durations=20 test/contrib --ignore=test/contrib/stochastic_support/test_dcc.py uv run pytest -vs --durations=20 test/infer --ignore=test/infer/test_mcmc.py --ignore=test/contrib/test_nested_sampling.py uv run pytest -vs --durations=20 test/infer/test_mcmc.py - name: Test x64 run: | JAX_ENABLE_X64=1 uv run pytest -vs test/infer/test_mcmc.py -k x64 - name: Test chains run: | XLA_FLAGS="--xla_force_host_platform_device_count=2" uv run pytest -vs test/contrib/stochastic_support/test_dcc.py XLA_FLAGS="--xla_force_host_platform_device_count=2" uv run pytest -vs test/contrib/test_tfp.py -k "chain" XLA_FLAGS="--xla_force_host_platform_device_count=2" uv run pytest -vs test/infer/test_hmc_gibbs.py -k "chain" XLA_FLAGS="--xla_force_host_platform_device_count=2" uv run pytest -vs test/infer/test_mcmc.py -k "chain or pmap or vmap" - name: Test custom prng run: | JAX_ENABLE_CUSTOM_PRNG=1 uv run pytest -vs test/infer/test_mcmc.py - name: Test nested sampling run: | JAX_ENABLE_X64=1 uv run pytest -vs test/contrib/test_nested_sampling.py - name: Coveralls if: github.repository == 'pyro-ppl/numpyro' && matrix.python-version == '3.14' uses: coverallsapp/github-action@v2 with: github-token: ${{ secrets.GITHUB_TOKEN }} parallel: true flag-name: test-inference file: coverage.lcov examples: timeout-minutes: 30 runs-on: latchkey-small needs: [lint, prek] strategy: matrix: python-version: ["3.14"] env: UV_PYTHON: ${{ matrix.python-version }} steps: - uses: actions/checkout@v6 - name: Install uv uses: astral-sh/setup-uv@v7 with: enable-cache: true update-path: true python-version: ${{ matrix.python-version }} - name: Install dependencies run: | uv sync \ --upgrade \ --extra cpu \ --group ci \ --group dev \ --group examples \ --group test uv pip freeze - name: Test with pytest run: | CI=1 XLA_FLAGS="--xla_force_host_platform_device_count=2" uv run pytest -vs -k test_example - name: Coveralls if: github.repository == 'pyro-ppl/numpyro' && matrix.python-version == '3.14' uses: coverallsapp/github-action@v2 with: github-token: ${{ secrets.GITHUB_TOKEN }} parallel: true flag-name: examples file: coverage.lcov finish: timeout-minutes: 30 needs: [test-modeling, test-inference, examples] runs-on: latchkey-small if: github.repository == 'pyro-ppl/numpyro' steps: - name: Coveralls finished uses: coverallsapp/github-action@v2 with: github-token: ${{ secrets.GITHUB_TOKEN }} parallel-finished: true carryforward: "test-modeling,test-inference,examples"
What changed
- Run on Latchkey managed runners with one line (
runs-on), which apply the fixes below automatically and self-heal transient failures. This example useslatchkey-small; pick the runner size that fits the job. - Cancel superseded runs when a branch or PR gets a newer push.
- Add a job timeout so a hung step cannot burn hours of runner time.
3 third-party actions are referenced by a movable tag. Pin them to the commit SHA (Latchkey resolves and applies this automatically) so a repointed tag cannot change what runs.
What Latchkey heals here
This workflow has steps that commonly fail on transient issues (network, registries, flaky browsers). On Latchkey managed runners they are detected, retried, and self-healed instead of failing your build:
- Dependency installs
This workflow runs 6 jobs (9 with the matrix expanded) per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.