Skip to content
Latchkey

Django application workflow (HackSoftware/Django-Styleguide-Example)

The Django application workflow from HackSoftware/Django-Styleguide-Example, explained and optimized by Latchkey.

C

CI health: C - fair

Point runs-on at Latchkey and get run de-duplication, job timeouts, self-healing for flaky steps, and up to 58% lower cost, applied automatically.

Grade your own workflow free or run it on Latchkey →
Source: HackSoftware/Django-Styleguide-Example.github/workflows/django.ymlLicense MITView source

What it does

This is the Django application workflow from the HackSoftware/Django-Styleguide-Example 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: Django application
on: [push]
jobs:
  docker_build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Build docker
        run: docker compose build
      - name: Run ruff
        run: docker compose run django ruff check styleguide_example/
      - name: Run mypy
        run: docker compose run django mypy --config mypy.ini styleguide_example/
      - name: Run tests
        run: docker compose run django py.test

  build:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:latest
        env:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
          POSTGRES_DB: github_actions
        ports:
          - 5432:5432
        # needed because the postgres container does not provide a healthcheck
        options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: 3.12.4
          cache: "pip"
          cache-dependency-path: |
            requirements/local.txt
            requirements/base.txt
      # This is a more aggresive cache.
      # The one above caches the wheel files, but still runs the installation for them
      # While the cache below caches the entire Python directory.
      - name: Cache pip
        uses: actions/cache@v4
        with:
          path: /opt/hostedtoolcache/Python/3.12.4/x64/ # This path is specific to Ubuntu
          key: python-${{ hashFiles('requirements/local.txt') }}-${{ hashFiles('requirements/base.txt') }}
      - name: Install dependencies
        run: pip install -r requirements/local.txt
      - name: Run ruff
        run: ruff check .
      - name: Type check
        run: mypy --config mypy.ini styleguide_example/
      - name: Run tests
        run: pytest

  deploy_to_heroku:
    runs-on: ubuntu-latest
    needs: build
    if: false
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: "0"
      - name: Deploy to Heroku
        env:
          HEROKU_API_KEY: ${{ secrets.HEROKU_API_KEY }}
          HEROKU_APP_NAME: "hacksoft-styleguide-example"
        run: git push --force https://heroku:$HEROKU_API_KEY@git.heroku.com/$HEROKU_APP_NAME.git origin/master:master

The same workflow, on Latchkey

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

name: Django application
on: [push]
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true
 
jobs:
  docker_build:
    timeout-minutes: 30
    runs-on: latchkey-small
    steps:
      - uses: actions/checkout@v4
      - name: Build docker
        run: docker compose build
      - name: Run ruff
        run: docker compose run django ruff check styleguide_example/
      - name: Run mypy
        run: docker compose run django mypy --config mypy.ini styleguide_example/
      - name: Run tests
        run: docker compose run django py.test
 
  build:
    timeout-minutes: 30
    runs-on: latchkey-small
    services:
      postgres:
        image: postgres:latest
        env:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
          POSTGRES_DB: github_actions
        ports:
          - 5432:5432
        # needed because the postgres container does not provide a healthcheck
        options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: 3.12.4
          cache: "pip"
          cache-dependency-path: |
            requirements/local.txt
            requirements/base.txt
      # This is a more aggresive cache.
      # The one above caches the wheel files, but still runs the installation for them
      # While the cache below caches the entire Python directory.
      - name: Cache pip
        uses: actions/cache@v4
        with:
          path: /opt/hostedtoolcache/Python/3.12.4/x64/ # This path is specific to Ubuntu
          key: python-${{ hashFiles('requirements/local.txt') }}-${{ hashFiles('requirements/base.txt') }}
      - name: Install dependencies
        run: pip install -r requirements/local.txt
      - name: Run ruff
        run: ruff check .
      - name: Type check
        run: mypy --config mypy.ini styleguide_example/
      - name: Run tests
        run: pytest
 
  deploy_to_heroku:
    timeout-minutes: 30
    runs-on: latchkey-small
    needs: build
    if: false
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: "0"
      - name: Deploy to Heroku
        env:
          HEROKU_API_KEY: ${{ secrets.HEROKU_API_KEY }}
          HEROKU_APP_NAME: "hacksoft-styleguide-example"
        run: git push --force https://heroku:$HEROKU_API_KEY@git.heroku.com/$HEROKU_APP_NAME.git origin/master:master
 

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