From 1a5d0b48c1809dbf9b4ea7da4dddcef966433bab Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 10 Aug 2026 12:54:48 +0000 Subject: [PATCH 1/3] Run all four checks on every PR so they can be required MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Required status checks and path filters do not mix: a required check whose workflow is filtered out never reports, and GitHub blocks the PR at "Expected — waiting for status" forever. With Frontend, Backend, Contract and Docker required on main, that would have stalled every backend-only sync PR (no frontend/** changes) and every docs-only PR. Dropping the filters costs about a minute per job and makes the gates real: nothing merges, automatically or otherwise, until the full suite passes. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_011texLkDBELWbXsBf6San3M --- .github/workflows/backend.yml | 2 -- .github/workflows/contract.yml | 2 -- .github/workflows/docker.yml | 14 -------------- .github/workflows/frontend.yml | 2 -- 4 files changed, 20 deletions(-) diff --git a/.github/workflows/backend.yml b/.github/workflows/backend.yml index f2e0e48..3383ccc 100644 --- a/.github/workflows/backend.yml +++ b/.github/workflows/backend.yml @@ -5,9 +5,7 @@ name: Backend on: push: branches: [main] - paths: ["backend/**", ".github/workflows/backend.yml"] pull_request: - paths: ["backend/**", ".github/workflows/backend.yml"] jobs: backend: diff --git a/.github/workflows/contract.yml b/.github/workflows/contract.yml index 0aa067a..7e578c3 100644 --- a/.github/workflows/contract.yml +++ b/.github/workflows/contract.yml @@ -7,9 +7,7 @@ name: Contract on: push: branches: [main] - paths: ["frontend/**", "backend/**", ".github/workflows/contract.yml"] pull_request: - paths: ["frontend/**", "backend/**", ".github/workflows/contract.yml"] jobs: contract: diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index d71cea0..f3a9aca 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -8,21 +8,7 @@ name: Docker on: push: branches: [main] - paths: - [ - "frontend/**", - "backend/**", - "compose.yaml", - ".github/workflows/docker.yml", - ] pull_request: - paths: - [ - "frontend/**", - "backend/**", - "compose.yaml", - ".github/workflows/docker.yml", - ] jobs: docker: diff --git a/.github/workflows/frontend.yml b/.github/workflows/frontend.yml index 1f05f0f..6372d53 100644 --- a/.github/workflows/frontend.yml +++ b/.github/workflows/frontend.yml @@ -3,9 +3,7 @@ name: Frontend on: push: branches: [main] - paths: ["frontend/**", ".github/workflows/frontend.yml"] pull_request: - paths: ["frontend/**", ".github/workflows/frontend.yml"] jobs: frontend: From 41815d8af67fc4d4d25b3783fe35dfbf4f143036 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 10 Aug 2026 13:07:48 +0000 Subject: [PATCH 2/3] Narrow the Docker check to the wiring, not the contract The two jobs asserted the same three endpoints, once against uvicorn and once through nginx. Docker now makes a single request: reaching /health under /api proves the image runs and the proxy strips the prefix, which is all this job is for. The endpoints themselves stay the Contract workflow's job, where they are asserted once. Verified against the real compose stack: frontend served, /api/health returns ok through nginx. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_011texLkDBELWbXsBf6San3M --- .github/workflows/docker.yml | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index f3a9aca..bae5ca5 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -1,8 +1,8 @@ -# Builds both container images and runs the composed stack, checking the same -# contract as contract.yml but through nginx — catches images that build but -# cannot start (missing runtime deps, broken CMD, bad base tags) and proxy -# misconfiguration. Complements the docker.yml that python-copier-template -# renders into standalone backend repos. +# Builds both container images and runs the composed stack: catches images that +# build but cannot start (missing runtime deps, broken CMD, bad base tags), a +# broken nginx config, and compose wiring. The API contract itself is checked by +# contract.yml. Complements the docker.yml that python-copier-template renders +# into standalone backend repos. name: Docker on: @@ -25,18 +25,14 @@ jobs: - name: "Frontend served" run: curl -sf http://localhost:8080/ | grep -q "React Template" - - name: "Contract via nginx: GET /api/ returns version info" + # One request is enough to prove the wiring: reaching /health under /api + # means the image runs and nginx strips the prefix. The endpoints + # themselves are the Contract workflow's job. + - name: "Backend reachable through the /api proxy" run: | - body=$(curl -sf http://localhost:8080/api/) + body=$(curl -sf http://localhost:8080/api/health) echo "$body" - echo "$body" | jq -e 'to_entries[0].value | test("version")' - - - name: "Contract via nginx: POST /api/predict echoes the input" - run: | - body=$(curl -sf -X POST http://localhost:8080/api/predict \ - -H "Content-Type: application/json" -d '{"input": 5}') - echo "$body" - echo "$body" | jq -e '.output == 5' + echo "$body" | jq -e '.status == "ok"' - name: Container logs if: always() From 9a7b9d36764e443a80bc00d29035cf2394bcc067 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 10 Aug 2026 13:29:23 +0000 Subject: [PATCH 3/3] Let Dependabot open PRs for the backend's Python dependencies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The dependency graph already scans backend/uv.lock (the "Graph Update: uv in /backend" runs), but PRs need an explicit ecosystem entry, and the backend package sits in a subdirectory so it needs its own. Routine bumps here are largely redundant — a template sync regenerates uv.lock by re-resolving to the newest allowed versions — but they are harmless, and the same entry is what surfaces vulnerable transitive dependencies as PRs between syncs. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_011texLkDBELWbXsBf6San3M --- .github/dependabot.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index e4cdb97..a74969e 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -10,5 +10,10 @@ updates: schedule: interval: weekly - # Backend Python dependencies are updated via the python-copier-template - # sync (uv.lock is regenerated on each render), so uv is not listed here. + # The backend package lives in a subdirectory, so it needs its own entry + # (`uv.lock` there is already picked up by the dependency graph, but an entry + # is what turns alerts into pull requests). + - package-ecosystem: uv + directory: /backend + schedule: + interval: weekly