From fd5fb61f8fb3e83dc59d616e7f8ab089652816e1 Mon Sep 17 00:00:00 2001 From: AndresL230 <190146319+AndresL230@users.noreply.github.com> Date: Sun, 23 Aug 2026 02:31:59 -0400 Subject: [PATCH] ci: give the integration lane the function-mode env it demands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The lane has been red on every push to main since #574, which added tests/integration/test_quiz_subcutaneous_db.py. Its autouse fixture raises unless SAPLING_MODEL_MODE=function and SAPLING_FUNCTION_HANDLERS are set — deliberately, since a skip would let the gate report green having run nothing — but nothing that runs the lane sets them. 57 passed, 14 errored. Set the pair on the test step, mirroring e2e.yml, and fix the same gap in the documented invocation in docs/local-supabase.md. Also add a pull_request trigger. This lane ran only on push to main, so #574 could not have failed pre-merge no matter who reviewed it; the one gate built to catch route/schema drift was structurally blind to a PR introducing it. Co-Authored-By: Claude --- .github/workflows/integration.yml | 22 ++++++++++++++++++++++ docs/local-supabase.md | 9 ++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index cd6dff73..3220a434 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -1,7 +1,14 @@ name: integration (local supabase) +# `pull_request` is deliberate and deliberately unfiltered. Until #574 this lane +# ran only after a merge, so the one gate built to catch route/schema drift was +# structurally incapable of failing a PR: #574 added a test file demanding env +# this workflow did not set, merged green, and left main red for three pushes. +# A paths filter would buy back ~5 minutes on frontend-only PRs at the cost of a +# narrower version of the same blind spot, so the whole lane runs on every PR. on: workflow_dispatch: + pull_request: push: branches: [main] @@ -33,5 +40,20 @@ jobs: SUPABASE_DB_URL=postgresql://postgres:postgres@127.0.0.1:54322/postgres python -m db.migrate cp .env.local.example .env python -m db.seed_local_rich + # Function mode is a requirement of the lane, not a preference: the quiz + # subcutaneous tests (#545) drive `generate`/`answer`/`submit` through real + # HTTP, so without the seam they would call live Gemini. Their autouse + # fixture raises rather than skips when it is unset — a skip would report + # green having run nothing — which is what turned this step red. Set here + # rather than in the fixture so every test in the lane sees one mode, and + # mirroring e2e.yml, the other runner of these handlers. + # + # Safe to apply lane-wide: no other integration test constructs an agent, + # so nothing here can trip UnregisteredHandlerError. `.env.local.example` + # (copied to .env above) defines neither variable, so the integration + # conftest's load_dotenv(override=True) cannot clobber them. - name: Run integration tests + env: + SAPLING_MODEL_MODE: function + SAPLING_FUNCTION_HANDLERS: agents.function_handlers_e2e run: RUN_INTEGRATION=1 python -m pytest -m integration -q diff --git a/docs/local-supabase.md b/docs/local-supabase.md index 63fa0af5..b25ee4c7 100644 --- a/docs/local-supabase.md +++ b/docs/local-supabase.md @@ -178,12 +178,19 @@ The script refuses to run against a non-local `SUPABASE_URL`. With the local stack up and `backend/.env` active, from `backend/`: - RUN_INTEGRATION=1 python -m pytest -m integration -q + SAPLING_MODEL_MODE=function SAPLING_FUNCTION_HANDLERS=agents.function_handlers_e2e \ + RUN_INTEGRATION=1 python -m pytest -m integration -q These bypass the hermetic mocks and hit the real local Supabase (real Postgres, encryption round-trips, migrated schema). Skipped by default. The suite seeds the rich dataset (idempotent) on first run and never resets your DB. +The function-mode variables are not optional. The quiz subcutaneous tests (#545) +drive the write paths through real HTTP, so without the seam they would call live +Gemini; their fixture raises rather than skips when it is unset, so the bare +`RUN_INTEGRATION=1 …` invocation errors out. `.github/workflows/integration.yml` +sets the same pair. + ## Test-profile production build (`build:test` / `start:test`, #380) `npm run dev` is fine for hand-testing, but browser E2E (Playwright) should run