From 7288e0a4778419d62e4ec5772ba6c40650fc0a65 Mon Sep 17 00:00:00 2001 From: Mao Nakamoto <41178744+maonakamoto@users.noreply.github.com> Date: Tue, 4 Aug 2026 16:11:07 +0200 Subject: [PATCH] =?UTF-8?q?fix(ci):=20put=20the=20build=20back=20in=20veri?= =?UTF-8?q?fy=20=E2=80=94=20lint=20and=20typecheck=20cannot=20see=20a=20br?= =?UTF-8?q?oken=20build?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit verify was lint + typecheck only. The cost of that gap is on record: contentlayer 0.3.1 reaches into a React internal React 19 removed, so /blog/[slug] threw "d.getOwner is not a function" during prerender. Both gated signals stayed green and production served a stale build while every CI run reported success (#202). verify is now lint + typecheck + build, with `typecheck` promoted to its own named script so the chain reads as three steps instead of an inline `cd`. The prisma-engine problem that justified deferring the build no longer reproduces: `prisma generate` succeeds on 6.19.3. Co-Authored-By: Claude Opus 5 --- .claude/CLAUDE.md | 18 +++++++++++++----- .github/workflows/ci.yml | 21 ++++++++++++--------- package.json | 3 ++- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index ed0178fb..5de41670 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -61,15 +61,23 @@ npm run dev:backend # Docker npm run docker:dev -# Verify a change before declaring it done (mirrors CI: frontend lint + typecheck) +# Verify a change before declaring it done (mirrors CI: lint + typecheck + build) npm run verify ``` **Before declaring any change done, run `npm run verify`.** It runs the same -hermetic gates as CI (`.github/workflows/ci.yml`: frontend lint + typecheck), so -green locally means green on `main`. Build and the full-stack Playwright e2e are -not yet gated in CI (build hits a prisma-engine issue; e2e needs both servers + -a DB) — run those manually until wired. +hermetic gates as CI (`.github/workflows/ci.yml`: frontend lint + typecheck + +build), so green locally means green on `main`. + +The build is in the gate deliberately. It used to be deferred, and that gap has +a receipt: contentlayer 0.3.1 reaches into a React internal that React 19 +removed, so `/blog/[slug]` threw `d.getOwner is not a function` during prerender +and production sat on a stale build for weeks. Lint and typecheck were green the +whole time — only a build could have caught it. + +Note: the build needs Node 18 (`.nvmrc`); contentlayer crashes on exit under +Node 20+. The full-stack Playwright e2e is still not gated — it needs both +servers plus a seeded DB, so run it manually until that is wired. --- diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 68cc5ed6..a0a86084 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,15 +41,18 @@ jobs: run: npm ci --legacy-peer-deps # SSOT: one definition of "verified" lives in the ROOT package.json - # `verify` (frontend lint + typecheck), run identically here and locally. - # Runs from repo root — the script cds into frontend itself. + # `verify` (lint + typecheck + build), run identically here and locally. + # Runs from repo root — the scripts cd into frontend themselves. + # + # Build is IN the gate as of 2026-08-04. It was deferred on a prisma-engine + # issue, and the cost of that gap was exact: contentlayer 0.3.1 reaches into + # a React internal that React 19 removed, so `/blog/[slug]` threw + # "d.getOwner is not a function" during prerender. lint and typecheck were + # both green — only a build could have caught it. The breakage sat on main + # while every CI run reported success. - name: Verify run: npm run verify - # Build is DEFERRED, not skipped silently. `prisma generate` currently - # fails in CI on a missing engine (query_engine_bg.postgresql.wasm) — a - # repo tooling issue to fix separately, not a gate-worthy signal. The - # full-stack Playwright e2e is also deferred (needs both servers + a DB). - # This floor gates the frontend signals that never ran before: - # lint + typecheck. Add build + e2e once the prisma engine is resolved - # (revampit e2e-local pattern in dotfiles/templates/ci/README.md). + # The full-stack Playwright e2e is still DEFERRED, not skipped silently: + # it needs both servers plus a seeded DB (lift revampit's e2e-local pattern + # from dotfiles/templates/ci/README.md once that is wired). diff --git a/package.json b/package.json index 9dbddee4..ef757119 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,8 @@ "test:debug": "npx playwright test --debug", "test:headed": "npx playwright test --headed", "test:report": "npx playwright show-report", - "verify": "npm run lint && cd frontend && npx tsc --noEmit" + "typecheck": "cd frontend && npx tsc --noEmit", + "verify": "npm run lint && npm run typecheck && npm run build" }, "keywords": [ "data-capture",