From 0fc8148c47179d7042fedffe6ab104a921205219 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 2 Mar 2026 09:41:10 +0000 Subject: [PATCH 1/2] Initial plan From ea0f7fb54fd081d2e2a8e0b97a2a82accfe1bc52 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 2 Mar 2026 09:45:59 +0000 Subject: [PATCH 2/2] ci: optimize pipeline for fail-fast feedback loop - Move mypy to Stage 1 (runs in parallel with lint & html-lint, no needs) - Decouple dependency-scan from test-quick; tests now start as soon as static analysis passes (needs: [lint, html-lint, mypy]) - dependency-scan runs as a parallel background track and still gates build/deploy to prevent shipping with known CVEs - Integration tests remain sequentially after quick tests pass (Stage 4) - Build & deploy remain gated on ALL stages including dependency-scan (Stage 5) - Reorder job definitions to match logical stage flow for readability - Update section comments to reflect the new 5-stage architecture Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com> --- .github/workflows/ci.yml | 62 +++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 27 deletions(-) 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: