Skip to content

feat(#288): post-deploy @smoke suite + fix(#348) the CSS-as-script bug it caught#349

Merged
TortoiseWolfe merged 2 commits into
mainfrom
feat/288-smoke-suite
Jul 24, 2026
Merged

feat(#288): post-deploy @smoke suite + fix(#348) the CSS-as-script bug it caught#349
TortoiseWolfe merged 2 commits into
mainfrom
feat/288-smoke-suite

Conversation

@TortoiseWolfe

@TortoiseWolfe TortoiseWolfe commented Jul 24, 2026

Copy link
Copy Markdown
Owner

What

#288, item 2 — the post-deploy production smoke suite: the missing verification that the deployed product works. #287 proved the whole suite can be green while prod is unusable. This runs against the live origin after each deploy (+ daily) and asserts the thing a customer touches — and on its very first run it caught a real production bug, which this PR also fixes.

Refs #288 (item 2). Closes #348.

It caught a real prod defect — and we fixed it (not muted it)

Run against live scripthammer.com, the "sign-in loads with zero console errors" check went red on a genuine defect: the exported HTML emits the same stylesheet twice — correctly as <link rel="stylesheet"> and wrongly as <script src="/_next/static/css/….css" async>. The browser fetches the CSS as a script → SyntaxError: Invalid or unexpected token, partially breaking the client on every page. The sloppy-mode check-chunks-parse.mjs gate never saw it (it only parses JS chunks), so it shipped green — the exact #287/#288 class.

This is a known Next.js 15 App-Router static-export bug. Fix (#348): scripts/strip-css-script-tags.mjs, wired into pnpm build after next build, strips the bogus <script src="*.css"> from every exported HTML file (the <link> stays, styling unaffected). Idempotent + logs the count, so a future Next upgrade that fixes it upstream shows 0 and the script can retire.

No test was skipped or allowlisted — the console-error check gates, and it passes because prod is actually fixed.

The smoke checks (all gating)

Check Method
Providers enabled GET /auth/v1/settingsexternal.{github,google,email}
OAuth client_id validity (#287 detector) GET /auth/v1/authorize?provider=… maxRedirects:0assertValidOAuthClientId(Location)
Sign-in zero console errors console/pageerror collector on /sign-incaught #348
Canonical origin BASE_URL serves 200 + github.io 301s → custom domain

Structure

Verified

  • Strip regex on the real prod HTML: removes the 1 bad <script src=css>, keeps all 3 <link>s.
  • Fresh build (out/) has 0 <script src="*.css"> after the strip; the strip logs the removed count.
  • Smoke against live prod: 4/4 gating checks green (the console check now passes once this deploys). type-check + lint clean.

Note for the owner

Canonical: public/CNAME=www but live traffic resolves to apex (github.io 301s → scripthammer.com, apex serves 200). Works, but the CNAME/config mismatch is worth a glance.

🤖 Generated with Claude Code

TurtleWolfe and others added 2 commits July 24, 2026 19:13
… defect → #348)

#288 item 2 — the missing post-deploy verification. Runs against the LIVE origin after each deploy (+ daily) and asserts the deployed product a customer touches works (the #287 gap: green tests, unusable prod).

- tests/e2e/smoke/production.smoke.spec.ts + playwright.smoke.config.ts + .github/workflows/smoke.yml: read-only checks against prod — providers enabled (/auth/v1/settings), OAuth authorize redirects carry real non-placeholder client_ids (#287 detector, read from the live /auth/v1/authorize Location — no flaky provider nav), canonical origin serves + github.io 301s to the custom domain. Triggered on workflow_run after 'Deploy to GitHub Pages' (success) + daily cron + dispatch + PRs touching the suite. No build/serve — hits prod directly.

- tests/e2e/utils/oauth-validity.ts: extracted assertValidOAuthClientId (was module-private in oauth-csrf.spec.ts) so the pre-merge E2E and the smoke share one source of truth for the #287 regexes.

The suite immediately DID ITS JOB: the 'sign-in zero console errors' check caught a REAL live defect — /sign-in throws a browser-only 'Invalid or unexpected token' parse error (#294 SWC-octal class; the sloppy-mode build gate misses it). Filed as #348 (p1); that one check is SKIPPED (not deleted/allowlisted) with a link — delete the skip line to re-gate once #348 is fixed. Verified locally: 4 passed / 1 skipped against live prod; type-check + lint clean.

Refs #288 (item 2).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… the smoke console check

The @smoke suite (previous commit) caught a real, SITE-WIDE prod defect on its first run: Next.js 15 App-Router static export emits the same stylesheet BOTH as <link rel=stylesheet> AND as <script src="....css">. The browser runs the CSS as JS → 'SyntaxError: Invalid or unexpected token', partially breaking the client on 108/110 pages. The sloppy-mode check-chunks-parse gate misses it (JS-only), so it shipped green — the exact #287/#288 class.

- scripts/strip-css-script-tags.mjs + package.json build: strip the bogus <script src="*.css"> from every exported HTML after 'next build' (the <link> stays). Verified: a fresh build removed 108 tags → 0 css-as-script in out/, stylesheets intact.

- tests/e2e/smoke/production.smoke.spec.ts: UN-SKIP the 'sign-in zero console errors' check — it gates for real now (no skip, no allowlist). Passes once this deploys (prod actually fixed).

- .github/workflows/smoke.yml: drop the pull_request trigger — a post-deploy monitor tests the DEPLOYED site, so it can't gate a PR whose fix isn't live yet; runs after Deploy + daily + dispatch.

Closes #348. Refs #288.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@TortoiseWolfe TortoiseWolfe changed the title feat(#288): post-deploy production @smoke suite (+ caught a real prod defect → #348) feat(#288): post-deploy @smoke suite + fix(#348) the CSS-as-script bug it caught Jul 24, 2026
@TortoiseWolfe
TortoiseWolfe merged commit 6e0f78f into main Jul 24, 2026
18 checks passed
@TortoiseWolfe
TortoiseWolfe deleted the feat/288-smoke-suite branch July 24, 2026 20:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

prod /sign-in throws 'Invalid or unexpected token' — browser-only JS parse error (client-partial-dead, #294 SWC-octal class)

2 participants