Skip to content
Latchkey

CI workflow (pyro-ppl/numpyro)

The CI workflow from pyro-ppl/numpyro, explained and optimized by Latchkey.

C

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.

Grade your own workflow free or run it on Latchkey →
Source: pyro-ppl/numpyro.github/workflows/ci.ymlLicense Apache-2.0View source

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

workflow (.yml)
# 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

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:

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.

Actions used in this workflow