Tests workflow (coleifer/peewee)
The Tests workflow from coleifer/peewee, explained and optimized by Latchkey.
CI health: D - needs work
Point runs-on at Latchkey and get caching, run de-duplication, job timeouts, self-healing for flaky steps, and up to 58% lower cost, applied automatically.
What it does
This is the Tests workflow from the coleifer/peewee 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: Tests
on: [push]
jobs:
tests:
name: ${{ matrix.peewee-backend }} - ${{ matrix.python-version }}
runs-on: ubuntu-latest
timeout-minutes: 15
services:
mysql:
image: mariadb:latest
env:
MYSQL_ROOT_PASSWORD: peewee
MYSQL_DATABASE: peewee_test
ports:
- 3306:3306
mysql8:
image: mysql:8
env:
MYSQL_ROOT_PASSWORD: peewee
MYSQL_DATABASE: peewee_test
ports:
- 3307:3306
postgres:
image: postgres
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: peewee
POSTGRES_DB: peewee_test
ports:
- 5432:5432
strategy:
fail-fast: false
matrix:
python-version: [3.9, "3.11", "3.13", "3.14"]
peewee-backend:
- "sqlite"
- "postgresql"
- "mysql"
include:
- python-version: "3.8"
peewee-backend: sqlite
- python-version: "3.12"
peewee-backend: sqlite
- python-version: "3.12"
peewee-backend: psycopg3
- python-version: "3.13"
peewee-backend: psycopg3
- python-version: "3.14"
peewee-backend: psycopg3
- python-version: "3.13"
peewee-backend: cysqlite
- python-version: "3.13"
peewee-backend: cockroachdb
- python-version: "3.13"
peewee-backend: mysql8
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: deps
env:
PGUSER: postgres
PGHOST: 127.0.0.1
PGPASSWORD: peewee
run: |
sudo apt-get install libsqlite3-dev
pip install setuptools psycopg2-binary cython pymysql 'apsw' mysql-connector-python sqlcipher3 pysqlite3 'psycopg[binary]' gevent
pip install greenlet aiosqlite aiomysql asyncpg pydantic
python setup.py build_ext -i
psql peewee_test -c 'CREATE EXTENSION hstore;'
- name: crdb
if: ${{ matrix.peewee-backend == 'cockroachdb' }}
run: |
wget -qO- https://binaries.cockroachdb.com/cockroach-v22.2.6.linux-amd64.tgz | tar xz
./cockroach-v22.2.6.linux-amd64/cockroach start-single-node --insecure --background
./cockroach-v22.2.6.linux-amd64/cockroach sql --insecure -e 'create database peewee_test;'
- name: cysqlite
if: ${{ matrix.peewee-backend == 'cysqlite' || matrix.peewee-backend == 'sqlite' }}
run: |
pip install -e 'git+https://github.com/coleifer/cysqlite#egg=cysqlite'
- name: runtests ${{ matrix.peewee-backend }} - ${{ matrix.python-version }}
env:
PEEWEE_TEST_BACKEND: ${{ matrix.peewee-backend }}
PEEWEE_MYSQL_PORT: ${{ matrix.peewee-backend == 'mysql8' && '3307' || '3306' }}
PGUSER: postgres
PGHOST: 127.0.0.1
PGPASSWORD: peewee
CI: 1
run: python runtests.py --mysql-user=root --mysql-password=peewee -s -v2
- name: asyncio stress
if: matrix.peewee-backend == 'postgresql' && matrix.python-version == '3.13'
env:
PGUSER: postgres
PGHOST: 127.0.0.1
PGPASSWORD: peewee
run: python runtests.py -A
stubs:
name: stub checks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.13"
- run: NO_SQLITE=1 pip install . mypy pyright ty typing_extensions
# Fail loudly if a packaging change ever drops the stub from the wheel.
- name: verify stub is packaged
run: python -c "import os,sysconfig;p=os.path.join(sysconfig.get_path('purelib'),'peewee-stubs','__init__.pyi');assert os.path.exists(p),p;print('stub installed at',p)"
- name: stubtest
working-directory: typecheck
run: python -m mypy.stubtest peewee --allowlist stubtest_allowlist.txt
- name: mypy
working-directory: typecheck
run: mypy check_stub.py
- name: pyright
working-directory: typecheck
run: pyright check_stub.py
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: Tests on: [push] concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: tests: name: ${{ matrix.peewee-backend }} - ${{ matrix.python-version }} runs-on: latchkey-small timeout-minutes: 15 services: mysql: image: mariadb:latest env: MYSQL_ROOT_PASSWORD: peewee MYSQL_DATABASE: peewee_test ports: - 3306:3306 mysql8: image: mysql:8 env: MYSQL_ROOT_PASSWORD: peewee MYSQL_DATABASE: peewee_test ports: - 3307:3306 postgres: image: postgres env: POSTGRES_USER: postgres POSTGRES_PASSWORD: peewee POSTGRES_DB: peewee_test ports: - 5432:5432 strategy: fail-fast: false matrix: python-version: [3.9, "3.11", "3.13", "3.14"] peewee-backend: - "sqlite" - "postgresql" - "mysql" include: - python-version: "3.8" peewee-backend: sqlite - python-version: "3.12" peewee-backend: sqlite - python-version: "3.12" peewee-backend: psycopg3 - python-version: "3.13" peewee-backend: psycopg3 - python-version: "3.14" peewee-backend: psycopg3 - python-version: "3.13" peewee-backend: cysqlite - python-version: "3.13" peewee-backend: cockroachdb - python-version: "3.13" peewee-backend: mysql8 steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: cache: 'pip' python-version: ${{ matrix.python-version }} - name: deps env: PGUSER: postgres PGHOST: 127.0.0.1 PGPASSWORD: peewee run: | sudo apt-get install libsqlite3-dev pip install setuptools psycopg2-binary cython pymysql 'apsw' mysql-connector-python sqlcipher3 pysqlite3 'psycopg[binary]' gevent pip install greenlet aiosqlite aiomysql asyncpg pydantic python setup.py build_ext -i psql peewee_test -c 'CREATE EXTENSION hstore;' - name: crdb if: ${{ matrix.peewee-backend == 'cockroachdb' }} run: | wget -qO- https://binaries.cockroachdb.com/cockroach-v22.2.6.linux-amd64.tgz | tar xz ./cockroach-v22.2.6.linux-amd64/cockroach start-single-node --insecure --background ./cockroach-v22.2.6.linux-amd64/cockroach sql --insecure -e 'create database peewee_test;' - name: cysqlite if: ${{ matrix.peewee-backend == 'cysqlite' || matrix.peewee-backend == 'sqlite' }} run: | pip install -e 'git+https://github.com/coleifer/cysqlite#egg=cysqlite' - name: runtests ${{ matrix.peewee-backend }} - ${{ matrix.python-version }} env: PEEWEE_TEST_BACKEND: ${{ matrix.peewee-backend }} PEEWEE_MYSQL_PORT: ${{ matrix.peewee-backend == 'mysql8' && '3307' || '3306' }} PGUSER: postgres PGHOST: 127.0.0.1 PGPASSWORD: peewee CI: 1 run: python runtests.py --mysql-user=root --mysql-password=peewee -s -v2 - name: asyncio stress if: matrix.peewee-backend == 'postgresql' && matrix.python-version == '3.13' env: PGUSER: postgres PGHOST: 127.0.0.1 PGPASSWORD: peewee run: python runtests.py -A stubs: timeout-minutes: 30 name: stub checks runs-on: latchkey-small steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: cache: 'pip' python-version: "3.13" - run: NO_SQLITE=1 pip install . mypy pyright ty typing_extensions # Fail loudly if a packaging change ever drops the stub from the wheel. - name: verify stub is packaged run: python -c "import os,sysconfig;p=os.path.join(sysconfig.get_path('purelib'),'peewee-stubs','__init__.pyi');assert os.path.exists(p),p;print('stub installed at',p)" - name: stubtest working-directory: typecheck run: python -m mypy.stubtest peewee --allowlist stubtest_allowlist.txt - name: mypy working-directory: typecheck run: mypy check_stub.py - name: pyright working-directory: typecheck run: pyright check_stub.py
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.
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
- Network fetches
This workflow runs 2 jobs (13 with the matrix expanded) per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.