CI/CD pipeline for a Python backend: GitHub Actions with PostgreSQL and Redis

Backend Live Coding November 13, 2026 yaml

Stages: lint/format → type check → tests with a real PostgreSQL (not SQLite, because it behaves differently) → security scan (pip-audit, image scan) → build the image tagged with the commit SHA → deploy to staging → smoke tests → production with rolling o

yaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# ======================================================================
# Q: Describe a CI/CD pipeline.
#
# Stages: lint/format → type check → tests with a real PostgreSQL (not SQLite,
# because it behaves differently) → security scan (pip-audit, image scan) →
# build the image tagged with the commit SHA → deploy to staging → smoke tests →
# production with rolling or blue/green. Migrations run as a separate step
# before the new code and are backward compatible, so the old and new code work
# together during the rolling deploy.
# ======================================================================

# .github/workflows/ci.yml
jobs:
  test:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:16
        env: { POSTGRES_PASSWORD: test }
        ports: ['5432:5432']
        options: --health-cmd pg_isready
      redis:
        image: redis:7
        ports: ['6379:6379']
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with: { python-version: '3.12' }
      - run: pip install -r requirements-dev.txt
      - run: ruff check . && ruff format --check .
      - run: mypy app
      - run: alembic upgrade head && alembic check     # model == migrations
      - run: pytest --cov=app --cov-fail-under=80
      - run: pip-audit                                  # known CVEs