Python Tests workflow (joke2k/faker)
The Python Tests workflow from joke2k/faker, 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 Python Tests workflow from the joke2k/faker 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
name: Python Tests
on:
push:
branches:
- master
pull_request:
types: [opened, synchronize, reopened]
permissions:
contents: read
jobs:
flake8:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Setup pip cache
uses: actions/cache@v6
id: pipcache
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('setup.py') }}
restore-keys: |
${{ runner.os }}-pip-flake8
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install flake8
- name: Lint with flake8
uses: liskin/gh-problem-matcher-wrap@v4
with:
linters: flake8
run: flake8 --extend-ignore=E203 faker tests
checkmanifest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Setup pip cache
uses: actions/cache@v6
id: pipcache
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('setup.py') }}
restore-keys: |
${{ runner.os }}-pip-checkmanifest
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install tox
- name: Check manifest
run: tox
env:
TOXENV: checkmanifest
test_class_order:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.x'
- name: Check Test* class order in test files
run: python scripts/check_test_class_order.py
isort:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Setup pip cache
uses: actions/cache@v6
id: pipcache
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('setup.py') }}
restore-keys: |
${{ runner.os }}-pip-isort
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install isort
- name: Import order checking with isort
uses: liskin/gh-problem-matcher-wrap@v4
with:
linters: isort
run: isort --check --diff .
black:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Setup pip cache
uses: actions/cache@v6
id: pipcache
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('setup.py') }}
restore-keys: |
${{ runner.os }}-pip-black
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install tox
- name: Formatting with black
run: tox
env:
TOXENV: black
doc8:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Setup pip cache
uses: actions/cache@v6
id: pipcache
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('setup.py') }}
restore-keys: |
${{ runner.os }}-pip-pep8
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install tox
- name: Doc formatting
run: tox
env:
TOXENV: doc8
typing:
runs-on: ubuntu-latest
strategy:
matrix:
python:
- "3.10"
- "3.11"
- "3.12"
- "3.13"
- "3.14"
steps:
- uses: actions/checkout@v7
- name: Setup pip cache
uses: actions/cache@v6
id: pipcache
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('setup.py') }}
restore-keys: |
${{ runner.os }}-pip-typing
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python }}
- name: Install dependencies
run: |
python -m pip install "mypy<2"
- name: Static type checking with mypy
uses: liskin/gh-problem-matcher-wrap@v4
with:
linters: mypy
run: mypy --install-types --non-interactive --config mypy.ini faker
test_ubuntu:
runs-on: ubuntu-latest
needs: [flake8, isort, black, doc8, checkmanifest, typing, test_class_order]
strategy:
matrix:
python:
- "3.10"
- "3.11"
- "3.12"
- "3.13"
- "3.14"
- "pypy-3.11"
steps:
- uses: actions/checkout@v7
- name: Setup pip cache
uses: actions/cache@v6
id: pipcache
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('setup.py') }}
restore-keys: |
${{ runner.os }}-pip-test_ubuntu
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python }}
- name: Install system dependencies
run: sudo apt-get update && sudo apt-get install -y libjpeg-dev
- name: Install Tox and any other packages
run: python -m pip install tox
- name: pytest
uses: liskin/gh-problem-matcher-wrap@v4
with:
linters: pytest
run: tox -e py
env:
COVERALLS_PARALLEL: true
COVERALLS_FLAG_NAME: run-ubuntu-${{ matrix.python }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COVERALLS_SERVICE_NAME: github
test_windows:
runs-on: windows-latest
needs: [flake8, isort, black, doc8, checkmanifest, typing, test_class_order]
strategy:
matrix:
python:
- "3.10"
- "3.11"
- "3.12"
- "3.13"
- "3.14"
arch: ["x86", "x64"]
steps:
- uses: actions/checkout@v7
- name: Setup pip cache
uses: actions/cache@v6
id: pipcache
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('setup.py') }}
restore-keys: |
${{ runner.os }}-pip-test_windows
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python }}
- name: Install Tox and any other packages
run: python -m pip install tox
- name: Run Tox
# Run tox using the version of Python in `PATH`
run: tox -e py
test_alpine:
runs-on: ubuntu-latest
needs: [flake8, isort, black, doc8, checkmanifest, typing, test_class_order]
steps:
- uses: actions/checkout@v7
- name: Setup pip cache
uses: actions/cache@v6
id: pipcache
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('setup.py') }}
restore-keys: |
${{ runner.os }}-pip-test_alpine
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.12'
- name: Install dependencies
run: |
python -m pip install tox==3.27.1 setuptools
- name: Run tests
run: tox
env:
TOXENV: alpine
TEST_ALPINE: 1
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: Python Tests on: push: branches: - master pull_request: types: [opened, synchronize, reopened] permissions: contents: read concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: flake8: timeout-minutes: 30 runs-on: latchkey-small steps: - uses: actions/checkout@v7 - name: Setup pip cache uses: actions/cache@v6 id: pipcache with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('setup.py') }} restore-keys: | ${{ runner.os }}-pip-flake8 - name: Set up Python uses: actions/setup-python@v6 with: cache: 'pip' python-version: '3.x' - name: Install dependencies run: | python -m pip install flake8 - name: Lint with flake8 uses: liskin/gh-problem-matcher-wrap@v4 with: linters: flake8 run: flake8 --extend-ignore=E203 faker tests checkmanifest: timeout-minutes: 30 runs-on: latchkey-small steps: - uses: actions/checkout@v7 - name: Setup pip cache uses: actions/cache@v6 id: pipcache with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('setup.py') }} restore-keys: | ${{ runner.os }}-pip-checkmanifest - name: Set up Python uses: actions/setup-python@v6 with: cache: 'pip' python-version: '3.x' - name: Install dependencies run: | python -m pip install tox - name: Check manifest run: tox env: TOXENV: checkmanifest test_class_order: timeout-minutes: 30 runs-on: latchkey-small steps: - uses: actions/checkout@v7 - name: Set up Python uses: actions/setup-python@v6 with: cache: 'pip' python-version: '3.x' - name: Check Test* class order in test files run: python scripts/check_test_class_order.py isort: timeout-minutes: 30 runs-on: latchkey-small steps: - uses: actions/checkout@v7 - name: Setup pip cache uses: actions/cache@v6 id: pipcache with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('setup.py') }} restore-keys: | ${{ runner.os }}-pip-isort - name: Set up Python uses: actions/setup-python@v6 with: cache: 'pip' python-version: '3.x' - name: Install dependencies run: | python -m pip install isort - name: Import order checking with isort uses: liskin/gh-problem-matcher-wrap@v4 with: linters: isort run: isort --check --diff . black: timeout-minutes: 30 runs-on: latchkey-small steps: - uses: actions/checkout@v7 - name: Setup pip cache uses: actions/cache@v6 id: pipcache with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('setup.py') }} restore-keys: | ${{ runner.os }}-pip-black - name: Set up Python uses: actions/setup-python@v6 with: cache: 'pip' python-version: '3.x' - name: Install dependencies run: | python -m pip install tox - name: Formatting with black run: tox env: TOXENV: black doc8: timeout-minutes: 30 runs-on: latchkey-small steps: - uses: actions/checkout@v7 - name: Setup pip cache uses: actions/cache@v6 id: pipcache with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('setup.py') }} restore-keys: | ${{ runner.os }}-pip-pep8 - name: Set up Python uses: actions/setup-python@v6 with: cache: 'pip' python-version: '3.x' - name: Install dependencies run: | python -m pip install tox - name: Doc formatting run: tox env: TOXENV: doc8 typing: timeout-minutes: 30 runs-on: latchkey-small strategy: matrix: python: - "3.10" - "3.11" - "3.12" - "3.13" - "3.14" steps: - uses: actions/checkout@v7 - name: Setup pip cache uses: actions/cache@v6 id: pipcache with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('setup.py') }} restore-keys: | ${{ runner.os }}-pip-typing - name: Set up Python uses: actions/setup-python@v6 with: cache: 'pip' python-version: ${{ matrix.python }} - name: Install dependencies run: | python -m pip install "mypy<2" - name: Static type checking with mypy uses: liskin/gh-problem-matcher-wrap@v4 with: linters: mypy run: mypy --install-types --non-interactive --config mypy.ini faker test_ubuntu: timeout-minutes: 30 runs-on: latchkey-small needs: [flake8, isort, black, doc8, checkmanifest, typing, test_class_order] strategy: matrix: python: - "3.10" - "3.11" - "3.12" - "3.13" - "3.14" - "pypy-3.11" steps: - uses: actions/checkout@v7 - name: Setup pip cache uses: actions/cache@v6 id: pipcache with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('setup.py') }} restore-keys: | ${{ runner.os }}-pip-test_ubuntu - name: Setup Python uses: actions/setup-python@v6 with: cache: 'pip' python-version: ${{ matrix.python }} - name: Install system dependencies run: sudo apt-get update && sudo apt-get install -y libjpeg-dev - name: Install Tox and any other packages run: python -m pip install tox - name: pytest uses: liskin/gh-problem-matcher-wrap@v4 with: linters: pytest run: tox -e py env: COVERALLS_PARALLEL: true COVERALLS_FLAG_NAME: run-ubuntu-${{ matrix.python }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} COVERALLS_SERVICE_NAME: github test_windows: timeout-minutes: 30 runs-on: windows-latest needs: [flake8, isort, black, doc8, checkmanifest, typing, test_class_order] strategy: matrix: python: - "3.10" - "3.11" - "3.12" - "3.13" - "3.14" arch: ["x86", "x64"] steps: - uses: actions/checkout@v7 - name: Setup pip cache uses: actions/cache@v6 id: pipcache with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('setup.py') }} restore-keys: | ${{ runner.os }}-pip-test_windows - name: Setup Python uses: actions/setup-python@v6 with: cache: 'pip' python-version: ${{ matrix.python }} - name: Install Tox and any other packages run: python -m pip install tox - name: Run Tox # Run tox using the version of Python in `PATH` run: tox -e py test_alpine: timeout-minutes: 30 runs-on: latchkey-small needs: [flake8, isort, black, doc8, checkmanifest, typing, test_class_order] steps: - uses: actions/checkout@v7 - name: Setup pip cache uses: actions/cache@v6 id: pipcache with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('setup.py') }} restore-keys: | ${{ runner.os }}-pip-test_alpine - name: Set up Python uses: actions/setup-python@v6 with: cache: 'pip' python-version: '3.12' - name: Install dependencies run: | python -m pip install tox==3.27.1 setuptools - name: Run tests run: tox env: TOXENV: alpine TEST_ALPINE: 1
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.
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 10 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.