Skip to content
Latchkey

CI workflow (samuelcolvin/dirty-equals)

The CI workflow from samuelcolvin/dirty-equals, 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: samuelcolvin/dirty-equals.github/workflows/ci.ymlLicense MITView source

What it does

This is the CI workflow from the samuelcolvin/dirty-equals 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: CI

on:
  push:
    branches:
      - main
    tags:
      - "**"
  pull_request: {}

env:
  COLUMNS: 150
  UV_PYTHON: 3.12
  UV_FROZEN: "1"

jobs:
  lint:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - uses: astral-sh/setup-uv@v6
        with:
          enable-cache: true

      - run: uv sync --all-groups

      - uses: actions/cache@v4
        with:
          path: ~/.cache/pre-commit
          key: pre-commit|${{ env.UV_PYTHON }}|${{ hashFiles('.pre-commit-config.yaml') }}

      - run: uvx pre-commit run --color=always --all-files --verbose
        env:
          SKIP: no-commit-to-branch

  test:
    name: test ${{ matrix.python-version }} on ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu, macos]
        python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
        # test pypy on ubuntu only to speed up CI, no reason why macos X pypy should fail separately
        include:
          - os: "ubuntu"
            python-version: "pypy-3.9"
          - os: "ubuntu"
            python-version: "pypy-3.10"

    runs-on: ${{ matrix.os }}-latest

    env:
      UV_PYTHON: ${{ matrix.python-version }}
      OS: ${{ matrix.os }}

    steps:
      - uses: actions/checkout@v4

      - uses: astral-sh/setup-uv@v6
        with:
          enable-cache: true

      - run: make test

      - run: uv run coverage xml

      - uses: codecov/codecov-action@v3
        with:
          file: ./coverage.xml
          env_vars: PYTHON,OS

  docs:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: astral-sh/setup-uv@v6
        with:
          enable-cache: true

      - run: uv sync --group docs

      - name: install mkdocs-material-insiders
        if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')
        run: uv pip install https://files.scolvin.com/${MKDOCS_TOKEN}/mkdocs_material-9.4.2+insiders.4.42.0-py3-none-any.whl
        env:
          MKDOCS_TOKEN: ${{ secrets.mkdocs_token }}

      - run: uv run --no-sync mkdocs build --strict

      - name: store docs site
        uses: actions/upload-artifact@v4
        with:
          name: docs
          path: site

  check: # This job does nothing and is only used for the branch protection
    if: always()
    needs: [lint, test, docs]
    runs-on: ubuntu-latest

    steps:
      - name: Decide whether the needed jobs succeeded or failed
        uses: re-actors/alls-green@release/v1
        id: all-green
        with:
          jobs: ${{ toJSON(needs) }}

  publish_docs:
    needs: [check]
    if: "success() && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/'))"
    runs-on: ubuntu-latest

    steps:
      - name: checkout docs-site
        uses: actions/checkout@v4
        with:
          ref: docs-site

      - uses: actions/checkout@v4

      - uses: astral-sh/setup-uv@v6
        with:
          enable-cache: true

      - run: uv sync --group docs

      - name: install mkdocs-material-insiders
        run: uv pip install https://files.scolvin.com/${MKDOCS_TOKEN}/mkdocs_material-9.4.2+insiders.4.42.0-py3-none-any.whl
        env:
          MKDOCS_TOKEN: ${{ secrets.mkdocs_token }}

      - run: uv run --no-sync mkdocs build --strict

      - name: Set git credentials
        run: |
          git config --global user.name "${{ github.actor }}"
          git config --global user.email "${{ github.actor }}@users.noreply.github.com"

      - run: uv run --no-sync mike deploy -b docs-site dev --push
        if: github.ref == 'refs/heads/main'

      - name: check version
        if: "startsWith(github.ref, 'refs/tags/')"
        id: check-version
        uses: samuelcolvin/check-python-version@v5
        with:
          version_file_path: "dirty_equals/version.py"

      - run: uv run --no-sync mike deploy -b docs-site ${{ steps.check-version.outputs.VERSION_MAJOR_MINOR }} latest --update-aliases --push
        if: "startsWith(github.ref, 'refs/tags/') && !fromJSON(steps.check-version.outputs.IS_PRERELEASE)"

  deploy:
    needs: [check]
    if: "success() && startsWith(github.ref, 'refs/tags/')"
    runs-on: ubuntu-latest
    environment: release

    permissions:
      id-token: write

    steps:
      - uses: actions/checkout@v4

      - uses: astral-sh/setup-uv@v6
        with:
          enable-cache: true

      - name: install
        run: pip install -U build

      - name: check version
        id: check-version
        uses: samuelcolvin/check-python-version@v5
        with:
          version_file_path: "dirty_equals/version.py"

      - run: uv build

      - run: uv publish --trusted-publishing always

The same workflow, on Latchkey

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

name: CI
 
on:
  push:
    branches:
      - main
    tags:
      - "**"
  pull_request: {}
 
env:
  COLUMNS: 150
  UV_PYTHON: 3.12
  UV_FROZEN: "1"
 
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true
 
jobs:
  lint:
    timeout-minutes: 30
    runs-on: latchkey-small
 
    steps:
      - uses: actions/checkout@v4
 
      - uses: astral-sh/setup-uv@v6
        with:
          enable-cache: true
 
      - run: uv sync --all-groups
 
      - uses: actions/cache@v4
        with:
          path: ~/.cache/pre-commit
          key: pre-commit|${{ env.UV_PYTHON }}|${{ hashFiles('.pre-commit-config.yaml') }}
 
      - run: uvx pre-commit run --color=always --all-files --verbose
        env:
          SKIP: no-commit-to-branch
 
  test:
    timeout-minutes: 30
    name: test ${{ matrix.python-version }} on ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu, macos]
        python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
        # test pypy on ubuntu only to speed up CI, no reason why macos X pypy should fail separately
        include:
          - os: "ubuntu"
            python-version: "pypy-3.9"
          - os: "ubuntu"
            python-version: "pypy-3.10"
 
    runs-on: ${{ matrix.os }}-latest
 
    env:
      UV_PYTHON: ${{ matrix.python-version }}
      OS: ${{ matrix.os }}
 
    steps:
      - uses: actions/checkout@v4
 
      - uses: astral-sh/setup-uv@v6
        with:
          enable-cache: true
 
      - run: make test
 
      - run: uv run coverage xml
 
      - uses: codecov/codecov-action@v3
        with:
          file: ./coverage.xml
          env_vars: PYTHON,OS
 
  docs:
    timeout-minutes: 30
    runs-on: latchkey-small
    steps:
      - uses: actions/checkout@v4
 
      - uses: astral-sh/setup-uv@v6
        with:
          enable-cache: true
 
      - run: uv sync --group docs
 
      - name: install mkdocs-material-insiders
        if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')
        run: uv pip install https://files.scolvin.com/${MKDOCS_TOKEN}/mkdocs_material-9.4.2+insiders.4.42.0-py3-none-any.whl
        env:
          MKDOCS_TOKEN: ${{ secrets.mkdocs_token }}
 
      - run: uv run --no-sync mkdocs build --strict
 
      - name: store docs site
        uses: actions/upload-artifact@v4
        with:
          name: docs
          path: site
 
  check: # This job does nothing and is only used for the branch protection
    timeout-minutes: 30
    if: always()
    needs: [lint, test, docs]
    runs-on: latchkey-small
 
    steps:
      - name: Decide whether the needed jobs succeeded or failed
        uses: re-actors/alls-green@release/v1
        id: all-green
        with:
          jobs: ${{ toJSON(needs) }}
 
  publish_docs:
    timeout-minutes: 30
    needs: [check]
    if: "success() && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/'))"
    runs-on: latchkey-small
 
    steps:
      - name: checkout docs-site
        uses: actions/checkout@v4
        with:
          ref: docs-site
 
      - uses: actions/checkout@v4
 
      - uses: astral-sh/setup-uv@v6
        with:
          enable-cache: true
 
      - run: uv sync --group docs
 
      - name: install mkdocs-material-insiders
        run: uv pip install https://files.scolvin.com/${MKDOCS_TOKEN}/mkdocs_material-9.4.2+insiders.4.42.0-py3-none-any.whl
        env:
          MKDOCS_TOKEN: ${{ secrets.mkdocs_token }}
 
      - run: uv run --no-sync mkdocs build --strict
 
      - name: Set git credentials
        run: |
          git config --global user.name "${{ github.actor }}"
          git config --global user.email "${{ github.actor }}@users.noreply.github.com"
 
      - run: uv run --no-sync mike deploy -b docs-site dev --push
        if: github.ref == 'refs/heads/main'
 
      - name: check version
        if: "startsWith(github.ref, 'refs/tags/')"
        id: check-version
        uses: samuelcolvin/check-python-version@v5
        with:
          version_file_path: "dirty_equals/version.py"
 
      - run: uv run --no-sync mike deploy -b docs-site ${{ steps.check-version.outputs.VERSION_MAJOR_MINOR }} latest --update-aliases --push
        if: "startsWith(github.ref, 'refs/tags/') && !fromJSON(steps.check-version.outputs.IS_PRERELEASE)"
 
  deploy:
    timeout-minutes: 30
    needs: [check]
    if: "success() && startsWith(github.ref, 'refs/tags/')"
    runs-on: latchkey-small
    environment: release
 
    permissions:
      id-token: write
 
    steps:
      - uses: actions/checkout@v4
 
      - uses: astral-sh/setup-uv@v6
        with:
          enable-cache: true
 
      - name: install
        run: pip install -U build
 
      - name: check version
        id: check-version
        uses: samuelcolvin/check-python-version@v5
        with:
          version_file_path: "dirty_equals/version.py"
 
      - run: uv build
 
      - run: uv publish --trusted-publishing always
 

What changed

4 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:

This workflow runs 6 jobs (17 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