diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9d020930..a4ef18d0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -84,7 +84,33 @@ jobs: run: djlint frontend/templates/ --lint # ══════════════════════════════════════════════════════════════════════════ - # Stage 2a: Dependency Vulnerability Scan (runs in parallel with lint) + # Stage 1: Mypy type-checking (runs in parallel with lint & html-lint) + # ══════════════════════════════════════════════════════════════════════════ + + mypy: + name: Mypy + runs-on: ubuntu-latest + # No needs — runs immediately in Stage 1 alongside Ruff and HTML lint + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install Dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements-dev.txt + + - name: Run Mypy + run: mypy app/ + + # ══════════════════════════════════════════════════════════════════════════ + # Stage 2: Dependency Vulnerability Scan (parallel background track — + # does NOT block tests; still gates build/deploy) # ══════════════════════════════════════════════════════════════════════════ dependency-scan: @@ -109,14 +135,15 @@ jobs: run: pip-audit -r requirements-dev.txt --desc on # ══════════════════════════════════════════════════════════════════════════ - # Stage 2b: Quick Tests (unit + basic integration — fast fail gate) + # Stage 3: Quick Tests (unit + basic integration — fast fail gate; + # starts as soon as Stage 1 static analysis passes) # ══════════════════════════════════════════════════════════════════════════ test-quick: name: Quick Tests runs-on: ubuntu-latest timeout-minutes: 15 - needs: [lint, html-lint, dependency-scan] + needs: [lint, html-lint, mypy] services: redis: image: redis:7 @@ -176,7 +203,8 @@ jobs: coverage.xml # ══════════════════════════════════════════════════════════════════════════ - # Stage 2c: Integration Tests (Docker containers, external services) + # Stage 4: Integration Tests (Docker containers, external services; + # only runs if Quick Tests pass) # ══════════════════════════════════════════════════════════════════════════ test-integration: @@ -232,29 +260,9 @@ jobs: name: test-results-integration path: junit-integration.xml - mypy: - name: Mypy - runs-on: ubuntu-latest - needs: [lint, html-lint, dependency-scan] # Wait for lint, HTML a11y lint, and dependency scan before running type checks - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install Dependencies - run: | - python -m pip install --upgrade pip - pip install -r requirements-dev.txt - - - name: Run Mypy - run: mypy app/ - # ══════════════════════════════════════════════════════════════════════════ - # Stage 3: Build & Push Docker Image (only after all Stage 2 jobs pass) + # Stage 5: Build & Push Docker Image (only on push to main/develop/tags; + # gates on ALL prior stages including dependency scan) # ══════════════════════════════════════════════════════════════════════════ build: @@ -317,7 +325,7 @@ jobs: cache-to: type=gha,mode=max # ══════════════════════════════════════════════════════════════════════════ - # Stage 4: Update preprod K8s manifest (ArgoCD GitOps, only on main) + # Stage 5: Update preprod K8s manifest (ArgoCD GitOps, only on main push) # ══════════════════════════════════════════════════════════════════════════ update-k8s-manifest: