CI workflow (ubernostrum/django-registration)
The CI workflow from ubernostrum/django-registration, explained and optimized by Latchkey.
CI health: F - at risk
Point runs-on at Latchkey and get caching, 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 CI workflow from the ubernostrum/django-registration 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: CI
on:
push:
branches: [ trunk ]
pull_request:
workflow_dispatch:
env:
FORCE_COLOR: "1"
PIP_DISABLE_PIP_VERSION_CHECK: "1"
PIP_NO_PYTHON_VERSION_WARNING: "1"
permissions: { }
jobs:
build-package:
name: Build and verify package
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
- uses: hynek/build-and-inspect-python-package@v2
id: baipp
outputs:
python-versions: ${{ steps.baipp.outputs.supported_python_classifiers_json_array }}
tests:
name: Tests on Python ${{ matrix.python-version }}
needs: build-package
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ${{ fromJson(needs.build-package.outputs.python-versions) }}
steps:
- name: Download pre-built packages
uses: actions/download-artifact@v4
with:
name: Packages
path: dist
- run: tar xf dist/*.tar.gz --strip-components=1
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
allow-prereleases: true
- name: Install test runner
run: |
python -VV
python -Im site
python -Im pip install --upgrade nox
python -Im nox --version
- name: Run tests
run: "python -Im nox --non-interactive --error-on-external-run --tag tests --python ${{ matrix.python-version }}"
- name: Upload coverage data
uses: actions/upload-artifact@v4
with:
name: coverage-data-${{ matrix.python-version }}
path: .coverage.*
include-hidden-files: true
if-no-files-found: ignore
coverage:
name: Combine and check coverage
needs: tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- uses: actions/download-artifact@v4
with:
pattern: coverage-data-*
merge-multiple: true
- name: Combine coverage & fail under 100%
run: |
python -Im pip install --upgrade "coverage[toml]"
coverage combine
coverage html --skip-covered --skip-empty
# Report and write to summary.
coverage report --format=markdown >> $GITHUB_STEP_SUMMARY
# Report again and fail if under 100%.
coverage report --fail-under=100
- name: Upload HTML report if check failed.
uses: actions/upload-artifact@v4
with:
name: html-report
path: htmlcov
if: ${{ failure() }}
docs:
name: Check documentation
needs: build-package
runs-on: ubuntu-latest
steps:
- name: Download pre-built packages
uses: actions/download-artifact@v4
with:
name: Packages
path: dist
- run: tar xf dist/*.tar.gz --strip-components=1
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Set up test runner
run: |
python -VV
python -Im site
python -Im pip install --upgrade nox
python -Im nox --version
- name: Run documentation checks
run: "python -Im nox --non-interactive --error-on-external-run --tag docs"
lint-format:
name: Lint code and check formatting
needs: build-package
runs-on: ubuntu-latest
steps:
- name: Download pre-built packages
uses: actions/download-artifact@v4
with:
name: Packages
path: dist
- run: tar xf dist/*.tar.gz --strip-components=1
- uses: actions/setup-python@v5
with:
python-version: "3.13"
- name: Set up test runner
run: |
python -VV
python -Im site
python -Im pip install --upgrade nox
python -Im nox --version
- name: Check code formatting
run: "python -Im nox --non-interactive --error-on-external-run --tag formatters --python 3.13"
- name: Lint code
run: "python -Im nox --non-interactive --error-on-external-run --tag linters --python 3.13"
check-package:
name: Additional package checks
needs: build-package
runs-on: ubuntu-latest
steps:
- name: Download pre-built packages
uses: actions/download-artifact@v4
with:
name: Packages
path: dist
- run: tar xf dist/*.tar.gz --strip-components=1
- uses: actions/setup-python@v5
with:
python-version: "3.13"
- name: Set up test runner
run: |
python -VV
python -Im site
python -Im pip install --upgrade nox
python -Im nox --version
- name: Check package
run: "python -Im nox --non-interactive --error-on-external-run --tag packaging --python 3.13"
required-checks-pass:
name: Ensure required checks pass for branch protection
if: always()
needs:
- check-package
- coverage
- docs
- lint-format
runs-on: ubuntu-latest
steps:
- name: Decide whether the jobs succeeded or failed
uses: re-actors/alls-green@release/v1
with:
jobs: ${{ toJSON(needs) }}
The same workflow, on Latchkey
Estimated ~20% faster on cache hits, plus fewer wasted runs and a safer supply chain. Added and changed lines are highlighted.
--- name: CI on: push: branches: [ trunk ] pull_request: workflow_dispatch: env: FORCE_COLOR: "1" PIP_DISABLE_PIP_VERSION_CHECK: "1" PIP_NO_PYTHON_VERSION_WARNING: "1" permissions: { } concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: build-package: timeout-minutes: 30 name: Build and verify package runs-on: latchkey-small steps: - uses: actions/checkout@v4 with: fetch-depth: 0 persist-credentials: false - uses: hynek/build-and-inspect-python-package@v2 id: baipp outputs: python-versions: ${{ steps.baipp.outputs.supported_python_classifiers_json_array }} tests: timeout-minutes: 30 name: Tests on Python ${{ matrix.python-version }} needs: build-package runs-on: latchkey-small strategy: fail-fast: false matrix: python-version: ${{ fromJson(needs.build-package.outputs.python-versions) }} steps: - name: Download pre-built packages uses: actions/download-artifact@v4 with: name: Packages path: dist - run: tar xf dist/*.tar.gz --strip-components=1 - uses: actions/setup-python@v5 with: cache: 'pip' python-version: ${{ matrix.python-version }} allow-prereleases: true - name: Install test runner run: | python -VV python -Im site python -Im pip install --upgrade nox python -Im nox --version - name: Run tests run: "python -Im nox --non-interactive --error-on-external-run --tag tests --python ${{ matrix.python-version }}" - name: Upload coverage data uses: actions/upload-artifact@v4 with: name: coverage-data-${{ matrix.python-version }} path: .coverage.* include-hidden-files: true if-no-files-found: ignore coverage: timeout-minutes: 30 name: Combine and check coverage needs: tests runs-on: latchkey-small steps: - uses: actions/checkout@v4 with: persist-credentials: false - uses: actions/setup-python@v5 with: cache: 'pip' python-version: "3.12" - uses: actions/download-artifact@v4 with: pattern: coverage-data-* merge-multiple: true - name: Combine coverage & fail under 100% run: | python -Im pip install --upgrade "coverage[toml]" coverage combine coverage html --skip-covered --skip-empty # Report and write to summary. coverage report --format=markdown >> $GITHUB_STEP_SUMMARY # Report again and fail if under 100%. coverage report --fail-under=100 - name: Upload HTML report if check failed. uses: actions/upload-artifact@v4 with: name: html-report path: htmlcov if: ${{ failure() }} docs: timeout-minutes: 30 name: Check documentation needs: build-package runs-on: latchkey-small steps: - name: Download pre-built packages uses: actions/download-artifact@v4 with: name: Packages path: dist - run: tar xf dist/*.tar.gz --strip-components=1 - uses: actions/setup-python@v5 with: cache: 'pip' python-version: "3.12" - name: Set up test runner run: | python -VV python -Im site python -Im pip install --upgrade nox python -Im nox --version - name: Run documentation checks run: "python -Im nox --non-interactive --error-on-external-run --tag docs" lint-format: timeout-minutes: 30 name: Lint code and check formatting needs: build-package runs-on: latchkey-small steps: - name: Download pre-built packages uses: actions/download-artifact@v4 with: name: Packages path: dist - run: tar xf dist/*.tar.gz --strip-components=1 - uses: actions/setup-python@v5 with: cache: 'pip' python-version: "3.13" - name: Set up test runner run: | python -VV python -Im site python -Im pip install --upgrade nox python -Im nox --version - name: Check code formatting run: "python -Im nox --non-interactive --error-on-external-run --tag formatters --python 3.13" - name: Lint code run: "python -Im nox --non-interactive --error-on-external-run --tag linters --python 3.13" check-package: timeout-minutes: 30 name: Additional package checks needs: build-package runs-on: latchkey-small steps: - name: Download pre-built packages uses: actions/download-artifact@v4 with: name: Packages path: dist - run: tar xf dist/*.tar.gz --strip-components=1 - uses: actions/setup-python@v5 with: cache: 'pip' python-version: "3.13" - name: Set up test runner run: | python -VV python -Im site python -Im pip install --upgrade nox python -Im nox --version - name: Check package run: "python -Im nox --non-interactive --error-on-external-run --tag packaging --python 3.13" required-checks-pass: timeout-minutes: 30 name: Ensure required checks pass for branch protection if: always() needs: - check-package - coverage - docs - lint-format runs-on: latchkey-small steps: - name: Decide whether the jobs succeeded or failed uses: re-actors/alls-green@release/v1 with: jobs: ${{ toJSON(needs) }}
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.
- Cache dependency installs on the setup step so they are served from cache.
- Add a job timeout so a hung step cannot burn hours of runner time.
2 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:
- Dependency installs
This workflow runs 7 jobs per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.