tests workflow (mujocolab/mjlab)
The tests workflow from mujocolab/mjlab, 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 tests workflow from the mujocolab/mjlab 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
name: tests
on:
push:
branches: [main]
paths-ignore:
- '**.md'
- '**.rst'
- 'docs/**'
- 'Makefile'
- 'LICENSE'
- 'scripts/benchmarks/**'
pull_request:
branches: [main]
paths-ignore:
- '**.md'
- '**.rst'
- 'docs/**'
- 'Makefile'
- 'LICENSE'
- 'scripts/benchmarks/**'
env:
UV_FROZEN: "1"
jobs:
lint-format:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
version: "0.9.27"
- name: Run lint
run: uvx ruff@0.14.14 check --diff
- name: Run format
run: uvx ruff@0.14.14 format --diff
tests:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"]
resolution: ["locked"]
# Also test against a fresh resolve of the latest compatible
# dependencies so a new upstream release breaks a PR instead of a
# release.
include:
- python-version: "3.13"
resolution: "unlocked"
steps:
- uses: actions/checkout@v6
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
python-version: ${{ matrix.python-version }}
enable-cache: true
version: "0.9.27"
- name: Restore Warp kernel cache
uses: actions/cache@v4
with:
path: ~/.cache/warp
key: warp-kernels-${{ runner.os }}-${{ runner.arch }}-${{ matrix.python-version }}-${{ matrix.resolution }}-${{ hashFiles('uv.lock', 'mjlab/**/*.py') }}
restore-keys: |
warp-kernels-${{ runner.os }}-${{ runner.arch }}-${{ matrix.python-version }}-${{ matrix.resolution }}-
- name: Test with python ${{ matrix.python-version }} (locked deps)
if: matrix.resolution == 'locked'
run: uv run --extra cpu pytest
- name: Test with python ${{ matrix.python-version }} (latest deps)
if: matrix.resolution == 'unlocked'
env:
UV_FROZEN: "0"
run: uv run --extra cpu --upgrade pytest
pyright:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v6
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
python-version: ${{ matrix.python-version }}
enable-cache: true
version: "0.9.27"
- name: Test with python ${{ matrix.python-version }}
run: uv run --extra cpu pyright
ty-check:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v6
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
python-version: ${{ matrix.python-version }}
enable-cache: true
version: "0.9.27"
- name: Type check with python ${{ matrix.python-version }}
run: uv run --extra cpu ty check
stubs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
version: "0.9.27"
- name: Sync environment
run: uv sync --extra cpu
- name: Regenerate MuJoCo stubs
run: bash typings/generate_mujoco_stubs.sh
- name: Verify stubs are up to date
run: |
if ! git diff --exit-code typings/mujoco; then
echo "::error::MuJoCo type stubs are out of date. Run 'make stubs' and commit the result."
exit 1
fi
# Mirrors the release smoke test: build the artifacts and import mjlab from an
# isolated, freshly resolved install, so packaging and clean-install issues
# surface on the PR instead of at publish time.
smoke-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
version: "0.9.27"
- name: Install Python 3.13
run: uv python install 3.13
- name: Build
run: uv build
# MUJOCO_GL=disable so `import mujoco` skips its GL backend import; the
# runner has no GL libraries and the smoke test does not render.
- name: Smoke test (wheel)
run: uv run --isolated --no-project --with dist/*.whl tests/smoke_test.py
env:
MUJOCO_GL: disable
- name: Smoke test (source distribution)
run: uv run --isolated --no-project --with dist/*.tar.gz tests/smoke_test.py
env:
MUJOCO_GL: disable
The same workflow, on Latchkey
Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.
name: tests on: push: branches: [main] paths-ignore: - '**.md' - '**.rst' - 'docs/**' - 'Makefile' - 'LICENSE' - 'scripts/benchmarks/**' pull_request: branches: [main] paths-ignore: - '**.md' - '**.rst' - 'docs/**' - 'Makefile' - 'LICENSE' - 'scripts/benchmarks/**' env: UV_FROZEN: "1" concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: lint-format: timeout-minutes: 30 runs-on: latchkey-small steps: - name: Checkout repository uses: actions/checkout@v6 - name: Setup uv uses: astral-sh/setup-uv@v7 with: enable-cache: true version: "0.9.27" - name: Run lint run: uvx ruff@0.14.14 check --diff - name: Run format run: uvx ruff@0.14.14 format --diff tests: timeout-minutes: 30 runs-on: latchkey-small strategy: fail-fast: false matrix: python-version: ["3.10", "3.11", "3.12", "3.13"] resolution: ["locked"] # Also test against a fresh resolve of the latest compatible # dependencies so a new upstream release breaks a PR instead of a # release. include: - python-version: "3.13" resolution: "unlocked" steps: - uses: actions/checkout@v6 - name: Setup uv uses: astral-sh/setup-uv@v7 with: python-version: ${{ matrix.python-version }} enable-cache: true version: "0.9.27" - name: Restore Warp kernel cache uses: actions/cache@v4 with: path: ~/.cache/warp key: warp-kernels-${{ runner.os }}-${{ runner.arch }}-${{ matrix.python-version }}-${{ matrix.resolution }}-${{ hashFiles('uv.lock', 'mjlab/**/*.py') }} restore-keys: | warp-kernels-${{ runner.os }}-${{ runner.arch }}-${{ matrix.python-version }}-${{ matrix.resolution }}- - name: Test with python ${{ matrix.python-version }} (locked deps) if: matrix.resolution == 'locked' run: uv run --extra cpu pytest - name: Test with python ${{ matrix.python-version }} (latest deps) if: matrix.resolution == 'unlocked' env: UV_FROZEN: "0" run: uv run --extra cpu --upgrade pytest pyright: timeout-minutes: 30 runs-on: latchkey-small strategy: matrix: python-version: ["3.10", "3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v6 - name: Setup uv uses: astral-sh/setup-uv@v7 with: python-version: ${{ matrix.python-version }} enable-cache: true version: "0.9.27" - name: Test with python ${{ matrix.python-version }} run: uv run --extra cpu pyright ty-check: timeout-minutes: 30 runs-on: latchkey-small strategy: matrix: python-version: ["3.10", "3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v6 - name: Setup uv uses: astral-sh/setup-uv@v7 with: python-version: ${{ matrix.python-version }} enable-cache: true version: "0.9.27" - name: Type check with python ${{ matrix.python-version }} run: uv run --extra cpu ty check stubs: timeout-minutes: 30 runs-on: latchkey-small steps: - uses: actions/checkout@v6 - name: Setup uv uses: astral-sh/setup-uv@v7 with: enable-cache: true version: "0.9.27" - name: Sync environment run: uv sync --extra cpu - name: Regenerate MuJoCo stubs run: bash typings/generate_mujoco_stubs.sh - name: Verify stubs are up to date run: | if ! git diff --exit-code typings/mujoco; then echo "::error::MuJoCo type stubs are out of date. Run 'make stubs' and commit the result." exit 1 fi # Mirrors the release smoke test: build the artifacts and import mjlab from an # isolated, freshly resolved install, so packaging and clean-install issues # surface on the PR instead of at publish time. smoke-test: timeout-minutes: 30 runs-on: latchkey-small steps: - uses: actions/checkout@v6 - name: Setup uv uses: astral-sh/setup-uv@v7 with: enable-cache: true version: "0.9.27" - name: Install Python 3.13 run: uv python install 3.13 - name: Build run: uv build # MUJOCO_GL=disable so `import mujoco` skips its GL backend import; the # runner has no GL libraries and the smoke test does not render. - name: Smoke test (wheel) run: uv run --isolated --no-project --with dist/*.whl tests/smoke_test.py env: MUJOCO_GL: disable - name: Smoke test (source distribution) run: uv run --isolated --no-project --with dist/*.tar.gz tests/smoke_test.py env: MUJOCO_GL: disable
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.
1 third-party action is referenced by a movable tag. Pin it to the commit SHA (Latchkey resolves and applies this automatically) so a repointed tag cannot change what runs.
This workflow runs 6 jobs (15 with the matrix expanded) per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.