Skip to content
Latchkey

Test workflow (django-commons/django-simple-history)

The Test workflow from django-commons/django-simple-history, 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: django-commons/django-simple-history.github/workflows/test.ymlLicense BSD-3-ClauseView source

What it does

This is the Test workflow from the django-commons/django-simple-history repository, a real project running GitHub Actions. It is shown here with attribution under its BSD-3-Clause license.

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

The workflow

workflow (.yml)
---
name: Test

on: [push, pull_request]

jobs:
  build:
    name: build (Python ${{ matrix.python-version }}, Django ${{ matrix.django-version }})
    runs-on: ubuntu-latest

    strategy:
      fail-fast: false
      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', '6.1', 'main']

        exclude:
          # Exclude py3.10 and py3.11 for Django > 5.2
          # and py3.14 for Django < 5.2
          - python-version: '3.10'
            django-version: 'main'
          - python-version: '3.10'
            django-version: '6.1'
          - python-version: '3.11'
            django-version: '6.1'
          - python-version: '3.10'
            django-version: '6.0'
          - python-version: '3.11'
            django-version: '6.0'
          - python-version: '3.11'
            django-version: 'main'
          - python-version: '3.14'
            django-version: '4.2'
          - python-version: '3.14'
            django-version: '5.0'
          - python-version: '3.14'
            django-version: '5.1'

    services:

      postgres:
        image: postgres:latest
        env:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
          POSTGRES_DB: github_actions
        ports:
          - 5432:5432
        # needed because the postgres container does not provide a healthcheck
        options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5

      mysql:
        image: mysql:latest
        env:
          MYSQL_DATABASE: mysql
          MYSQL_ROOT_PASSWORD: mysql
        ports:
          - 3306:3306
        options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3

      mariadb:
        image: mariadb:latest
        env:
          MARIADB_DATABASE: mariadb
          MARIADB_ROOT_PASSWORD: mariadb
        ports:
          - 3307:3306
        options: --health-cmd="mariadb-admin ping" --health-interval=10s --health-timeout=5s --health-retries=3

    steps:
      - uses: actions/checkout@v7

      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v6
        with:
          python-version: ${{ matrix.python-version }}
          cache: 'pip'
          cache-dependency-path: |
            pyproject.toml
            tox.ini
            requirements/*.txt
          allow-prereleases: true

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements/tox.txt

      - name: Tox tests
        run: |
          tox -v
        env:
          DJANGO: ${{ matrix.django-version }}

      - name: Upload coverage
        uses: codecov/codecov-action@v7
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
          name: Python ${{ matrix.python-version }}, Django ${{ matrix.django-version }}


  generated_file_checks:
    name: Check generated files
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v7

      - name: Install gettext
        run: |
          sudo apt-get update
          sudo apt-get install -y gettext

      - name: Set up newest stable Python version
        uses: actions/setup-python@v6
        with:
          python-version: 3.x
          cache: 'pip'
          # Invalidate the cache when this file updates, as the dependencies' versions
          # are pinned in the step below
          cache-dependency-path: '.github/workflows/test.yml'

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          # Install this project in editable mode, so that its package metadata can be queried
          pip install --editable .
          # Install the latest minor version of Django we support
          pip install "Django>=6.0,<6.1"

      - name: Check translation files are updated
        run: python -m simple_history.tests.generated_file_checks.check_translations

The same workflow, on Latchkey

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

---
name: Test
 
on: [push, pull_request]
 
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true
 
jobs:
  build:
    timeout-minutes: 30
    name: build (Python ${{ matrix.python-version }}, Django ${{ matrix.django-version }})
    runs-on: latchkey-small
 
    strategy:
      fail-fast: false
      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', '6.1', 'main']
 
        exclude:
          # Exclude py3.10 and py3.11 for Django > 5.2
          # and py3.14 for Django < 5.2
          - python-version: '3.10'
            django-version: 'main'
          - python-version: '3.10'
            django-version: '6.1'
          - python-version: '3.11'
            django-version: '6.1'
          - python-version: '3.10'
            django-version: '6.0'
          - python-version: '3.11'
            django-version: '6.0'
          - python-version: '3.11'
            django-version: 'main'
          - python-version: '3.14'
            django-version: '4.2'
          - python-version: '3.14'
            django-version: '5.0'
          - python-version: '3.14'
            django-version: '5.1'
 
    services:
 
      postgres:
        image: postgres:latest
        env:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
          POSTGRES_DB: github_actions
        ports:
          - 5432:5432
        # needed because the postgres container does not provide a healthcheck
        options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
 
      mysql:
        image: mysql:latest
        env:
          MYSQL_DATABASE: mysql
          MYSQL_ROOT_PASSWORD: mysql
        ports:
          - 3306:3306
        options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
 
      mariadb:
        image: mariadb:latest
        env:
          MARIADB_DATABASE: mariadb
          MARIADB_ROOT_PASSWORD: mariadb
        ports:
          - 3307:3306
        options: --health-cmd="mariadb-admin ping" --health-interval=10s --health-timeout=5s --health-retries=3
 
    steps:
      - uses: actions/checkout@v7
 
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v6
        with:
          python-version: ${{ matrix.python-version }}
          cache: 'pip'
          cache-dependency-path: |
            pyproject.toml
            tox.ini
            requirements/*.txt
          allow-prereleases: true
 
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements/tox.txt
 
      - name: Tox tests
        run: |
          tox -v
        env:
          DJANGO: ${{ matrix.django-version }}
 
      - name: Upload coverage
        uses: codecov/codecov-action@v7
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
          name: Python ${{ matrix.python-version }}, Django ${{ matrix.django-version }}
 
 
  generated_file_checks:
    timeout-minutes: 30
    name: Check generated files
    runs-on: latchkey-small
 
    steps:
      - uses: actions/checkout@v7
 
      - name: Install gettext
        run: |
          sudo apt-get update
          sudo apt-get install -y gettext
 
      - name: Set up newest stable Python version
        uses: actions/setup-python@v6
        with:
          python-version: 3.x
          cache: 'pip'
          # Invalidate the cache when this file updates, as the dependencies' versions
          # are pinned in the step below
          cache-dependency-path: '.github/workflows/test.yml'
 
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          # Install this project in editable mode, so that its package metadata can be queried
          pip install --editable .
          # Install the latest minor version of Django we support
          pip install "Django>=6.0,<6.1"
 
      - name: Check translation files are updated
        run: python -m simple_history.tests.generated_file_checks.check_translations
 

What changed

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.

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 2 jobs (36 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