Test workflow (django-commons/django-simple-history)
The Test workflow from django-commons/django-simple-history, 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 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
---
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
- 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.
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 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.