Skip to content
Latchkey

Run tests workflow (vas3k/vas3k.club)

The Run tests workflow from vas3k/vas3k.club, explained and optimized by Latchkey.

A

CI health: A - excellent

Point runs-on at Latchkey and get caching, self-healing for flaky steps, and up to 58% lower cost, applied automatically.

Grade your own workflow free or run it on Latchkey →
Source: vas3k/vas3k.club.github/workflows/tests.ymlLicense MITView source

What it does

This is the Run tests workflow from the vas3k/vas3k.club 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: Run tests

on:
  pull_request:
  workflow_call:

concurrency:
  # For pull requests, cancel all currently-running jobs for this workflow
  # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#concurrency
  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
  cancel-in-progress: ${{ github.event_name == 'pull_request' }}

permissions:
  contents: read

jobs:
  lint:
    runs-on: ubuntu-latest
    timeout-minutes: 5
    steps:

      - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0

      - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
        id: setup-python
        with:
          python-version: '3.12'

      - uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
        with:
          enable-cache: false

      - name: Install requirements
        run: |
          uv pip install --system flake8

      - name: run flake8
        run: |
          # stop the build if there are Python syntax errors or undefined names
          flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
          # exit-zero treats all errors as warnings.
          flake8 . --count --exit-zero --statistics

  frontend-test:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0

      - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
        with:
          node-version: '22'
          cache: 'npm'
          cache-dependency-path: frontend/package-lock.json

      - name: Install dependencies
        working-directory: ./frontend
        run: npm ci

      - name: Run frontend tests
        working-directory: ./frontend
        run: npm run test:ci

      - name: Upload coverage report
        if: always()
        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
        with:
          name: frontend-coverage
          path: frontend/coverage/
          retention-days: 14

  test:
    runs-on: ubuntu-latest
    timeout-minutes: 15
    services:
      postgres:
        image: postgres:14-alpine
        env:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
          POSTGRES_DB: vas3k_club
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 5432:5432
      redis:
        image: redis:6-alpine
        env:
          ALLOW_EMPTY_PASSWORD: yes
        ports:
          - 6379:6379

    steps:
      - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0

      - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
        id: setup-python
        with:
          python-version: '3.12'

      - uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
        with:
          enable-cache: true
          cache-dependency-glob: "**/Pipfile.lock"

      - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
        with:
          node-version: '22'

      - name: Cache webpack build
        uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
        id: cache-webpack
        with:
          path: |
            frontend/static/dist
            frontend/webpack-stats.json
          key: ${{ runner.os }}-webpack-${{ hashFiles('frontend/package*.json', 'frontend/webpack*.js', 'frontend/static/js/**', 'frontend/static/css/**') }}
          restore-keys: |
            ${{ runner.os }}-webpack-

      - name: Webpack build
        if: steps.cache-webpack.outputs.cache-hit != 'true'
        working-directory: ./frontend
        run: |
          node -v
          npm -v
          npm ci
          npm run build

      - name: Install pip dependencies
        run: |
          uv pip install --system pipenv
          pipenv requirements --dev > requirements.txt
          uv pip install --system -r requirements.txt

      - name: Run tests
        env:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
          POSTGRES_DB: vas3k_club
          POSTGRES_HOST: localhost
          REDIS_DB: 0
          REDIS_HOST: localhost
          PYTHONUNBUFFERED: 1
          TESTS_RUN: da
        run: |
          make test-ci

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: Run tests
 
on:
  pull_request:
  workflow_call:
 
concurrency:
  # For pull requests, cancel all currently-running jobs for this workflow
  # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#concurrency
  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
  cancel-in-progress: ${{ github.event_name == 'pull_request' }}
 
permissions:
  contents: read
 
jobs:
  lint:
    runs-on: latchkey-small
    timeout-minutes: 5
    steps:
 
      - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
 
      - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
        id: setup-python
        with:
          python-version: '3.12'
 
      - uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
        with:
          enable-cache: false
 
      - name: Install requirements
        run: |
          uv pip install --system flake8
 
      - name: run flake8
        run: |
          # stop the build if there are Python syntax errors or undefined names
          flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
          # exit-zero treats all errors as warnings.
          flake8 . --count --exit-zero --statistics
 
  frontend-test:
    runs-on: latchkey-small
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
 
      - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
        with:
          node-version: '22'
          cache: 'npm'
          cache-dependency-path: frontend/package-lock.json
 
      - name: Install dependencies
        working-directory: ./frontend
        run: npm ci
 
      - name: Run frontend tests
        working-directory: ./frontend
        run: npm run test:ci
 
      - name: Upload coverage report
        if: always()
        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
        with:
          name: frontend-coverage
          path: frontend/coverage/
          retention-days: 14
 
  test:
    runs-on: latchkey-small
    timeout-minutes: 15
    services:
      postgres:
        image: postgres:14-alpine
        env:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
          POSTGRES_DB: vas3k_club
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 5432:5432
      redis:
        image: redis:6-alpine
        env:
          ALLOW_EMPTY_PASSWORD: yes
        ports:
          - 6379:6379
 
    steps:
      - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
 
      - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
        id: setup-python
        with:
          python-version: '3.12'
 
      - uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
        with:
          enable-cache: true
          cache-dependency-glob: "**/Pipfile.lock"
 
      - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
        with:
          cache: 'npm'
          node-version: '22'
 
      - name: Cache webpack build
        uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
        id: cache-webpack
        with:
          path: |
            frontend/static/dist
            frontend/webpack-stats.json
          key: ${{ runner.os }}-webpack-${{ hashFiles('frontend/package*.json', 'frontend/webpack*.js', 'frontend/static/js/**', 'frontend/static/css/**') }}
          restore-keys: |
            ${{ runner.os }}-webpack-
 
      - name: Webpack build
        if: steps.cache-webpack.outputs.cache-hit != 'true'
        working-directory: ./frontend
        run: |
          node -v
          npm -v
          npm ci
          npm run build
 
      - name: Install pip dependencies
        run: |
          uv pip install --system pipenv
          pipenv requirements --dev > requirements.txt
          uv pip install --system -r requirements.txt
 
      - name: Run tests
        env:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
          POSTGRES_DB: vas3k_club
          POSTGRES_HOST: localhost
          REDIS_DB: 0
          REDIS_HOST: localhost
          PYTHONUNBUFFERED: 1
          TESTS_RUN: da
        run: |
          make test-ci
 

What changed

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 3 jobs per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.

Actions used in this workflow