Skip to content
Latchkey

test suite workflow (jazzband/django-fsm-log)

The test suite workflow from jazzband/django-fsm-log, 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: jazzband/django-fsm-log.github/workflows/test_suite.ymlLicense MITView source

What it does

This is the test suite workflow from the jazzband/django-fsm-log repository, a real project running GitHub Actions. It is shown here with attribution under its MIT license.

Below, Latchkey shows a faster, safer version produced by its optimization engine.

The workflow

workflow (.yml)
name: test suite
on:
  push:
    branches:
      - master
  pull_request:
jobs:
  pytest:
    runs-on: ubuntu-latest
    env:
      COVERAGE_FILE: coverage-py${{ matrix.python-version }}-dj${{ matrix.django-version }}.coverage
    strategy:
      matrix:
        python-version:
          - "3.10"
          - "3.11"
          - "3.12"
          - "3.13"
          - "3.14"
        django-version:
          - "4.2"
          - "5.0"
          - "5.1"
          - "5.2"
          - "6.0"
        exclude:
          - django-version: 4.2
            python-version: 3.12
          - django-version: 4.2
            python-version: 3.13
          - django-version: 4.2
            python-version: 3.14
          - django-version: 5.0
            python-version: 3.14
          - django-version: 5.1
            python-version: 3.14
          - django-version: 6.0
            python-version: 3.10
          - django-version: 6.0
            python-version: 3.11
    steps:
      - uses: actions/checkout@v6
      - name: Set up Python ${{ matrix.python-version }}
        uses: astral-sh/setup-uv@v7
        with:
          enable-cache: true
          cache-dependency-glob: "pyproject.toml"
          cache-suffix: ${{ matrix.python-version }}
      - name: Install Python
        run: uv python install ${{ matrix.python-version }}
        env:
          UV_PYTHON_PREFERENCE: only-managed
      - run: uv sync --all-groups
      - run: uv run --with 'django~=${{ matrix.django-version }}.0' pytest --cov
        env:
          DJANGO_SETTINGS_MODULE: tests.settings
          PYTHONPATH: "."
      - name: Save coverage file
        uses: actions/upload-artifact@v6
        with:
          name: ${{ env.COVERAGE_FILE }}
          path: ${{ env.COVERAGE_FILE }}
          include-hidden-files: true

  codecov:
    needs: pytest
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: astral-sh/setup-uv@v7
        with:
          enable-cache: true
      - run: uv python install 3.13
      - uses: actions/download-artifact@v7
        with:
          pattern: "*.coverage"
          merge-multiple: true
      - name: Combine coverage
        run: |
          uv run coverage combine --keep ./*.coverage
          uv run coverage report
          uv run coverage xml
      - name: Upload coverage to Codecov
        uses: codecov/codecov-action@v5

  lint: # redundant with pre-commit-ci, but we want to make the linters a part of strict status checks.
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: astral-sh/setup-uv@v7
        with:
          enable-cache: true
      - run: uv python install 3.13
      - run: uv sync --group dev
      - run: uvx ruff check
      - run: uvx ruff format --check

  check:
    runs-on: ubuntu-latest
    if: always()
    needs:
      - pytest
      - lint
    steps:
      - name: Decide whether the needed jobs succeeded or failed
        uses: re-actors/alls-green@release/v1
        with:
          jobs: ${{ toJSON(needs) }}

The same workflow, on Latchkey

Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.

name: test suite
on:
  push:
    branches:
      - master
  pull_request:
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true
 
jobs:
  pytest:
    timeout-minutes: 30
    runs-on: latchkey-small
    env:
      COVERAGE_FILE: coverage-py${{ matrix.python-version }}-dj${{ matrix.django-version }}.coverage
    strategy:
      matrix:
        python-version:
          - "3.10"
          - "3.11"
          - "3.12"
          - "3.13"
          - "3.14"
        django-version:
          - "4.2"
          - "5.0"
          - "5.1"
          - "5.2"
          - "6.0"
        exclude:
          - django-version: 4.2
            python-version: 3.12
          - django-version: 4.2
            python-version: 3.13
          - django-version: 4.2
            python-version: 3.14
          - django-version: 5.0
            python-version: 3.14
          - django-version: 5.1
            python-version: 3.14
          - django-version: 6.0
            python-version: 3.10
          - django-version: 6.0
            python-version: 3.11
    steps:
      - uses: actions/checkout@v6
      - name: Set up Python ${{ matrix.python-version }}
        uses: astral-sh/setup-uv@v7
        with:
          enable-cache: true
          cache-dependency-glob: "pyproject.toml"
          cache-suffix: ${{ matrix.python-version }}
      - name: Install Python
        run: uv python install ${{ matrix.python-version }}
        env:
          UV_PYTHON_PREFERENCE: only-managed
      - run: uv sync --all-groups
      - run: uv run --with 'django~=${{ matrix.django-version }}.0' pytest --cov
        env:
          DJANGO_SETTINGS_MODULE: tests.settings
          PYTHONPATH: "."
      - name: Save coverage file
        uses: actions/upload-artifact@v6
        with:
          name: ${{ env.COVERAGE_FILE }}
          path: ${{ env.COVERAGE_FILE }}
          include-hidden-files: true
 
  codecov:
    timeout-minutes: 30
    needs: pytest
    runs-on: latchkey-small
    steps:
      - uses: actions/checkout@v6
      - uses: astral-sh/setup-uv@v7
        with:
          enable-cache: true
      - run: uv python install 3.13
      - uses: actions/download-artifact@v7
        with:
          pattern: "*.coverage"
          merge-multiple: true
      - name: Combine coverage
        run: |
          uv run coverage combine --keep ./*.coverage
          uv run coverage report
          uv run coverage xml
      - name: Upload coverage to Codecov
        uses: codecov/codecov-action@v5
 
  lint: # redundant with pre-commit-ci, but we want to make the linters a part of strict status checks.
    timeout-minutes: 30
    runs-on: latchkey-small
    steps:
      - uses: actions/checkout@v6
      - uses: astral-sh/setup-uv@v7
        with:
          enable-cache: true
      - run: uv python install 3.13
      - run: uv sync --group dev
      - run: uvx ruff check
      - run: uvx ruff format --check
 
  check:
    timeout-minutes: 30
    runs-on: latchkey-small
    if: always()
    needs:
      - pytest
      - lint
    steps:
      - name: Decide whether the needed jobs succeeded or failed
        uses: re-actors/alls-green@release/v1
        with:
          jobs: ${{ toJSON(needs) }}
 

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.

This workflow runs 4 jobs (28 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