fix(e2e): deploy packed apps before webServer, avoid fresh resolution (#435) - #443
fix(e2e): deploy packed apps before webServer, avoid fresh resolution (#435)#443omridevk wants to merge 1 commit into
Conversation
…resh resolution (#435) pnpm --filter <app> deploy --legacy discards the workspace lockfile and does a fully independent resolution of the whole 2700+ package workspace graph, previously run inside playwright's webServer.command alongside next dev, all under one 180s timeout. On CI the resolution phase alone (individual registry metadata requests, 10-30s each) could exhaust the budget before next dev (which boots in under a second) ever started. - deployPackedApp() (e2e/e2e-utils/src/deploy.ts) runs the legacy deploy with --prefer-offline, which skips the per-package staleness revalidation GET that was the actual bottleneck, while still falling back to a live fetch for anything not cached (unlike --offline, which hard-errors the moment a workspace-wide "latest" specifier floats to a version nothing has fetched yet - reproduced locally resolving @neodrag/solid via a newer @tanstack/react-devtools). CONCIV_DEPLOY_FRESH=1 opts back into a live resolve, mirroring #378's CONCIV_PACKED_FRESH=1. - Each app's test:e2e script now runs the deploy as a pretest step (`pnpm --filter @conciv/e2e-utils run deploy <app> <pnpmFilter> && playwright test`), before playwright's webServer phase even starts. webServer.command is now just `cd <deployDir> && next dev`, and e2eConfig() grew a webServerTimeout option so nextjs/nextjs-component can tighten their webServer budget to 60s without touching the other e2e apps' 180s default. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 36 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (10)
Comment |
Diagnosis
#435:
Error: Timed out waiting 180000ms from config.webServer.on the nextjs e2e shard(run 31548790369 attempt 7).
webServer.commandine2e/nextjs/playwright.config.tsande2e/nextjs-component/playwright.config.tsranpnpm --filter <app> deploy --legacy --prod=falsethen
next dev, both inside one 180s webServer budget.Reproduced locally:
pnpm --filter conciv-e2e-nextjs deploy --legacy --prod=false <dir>shows[WARN] Shared workspace lockfile detected but configuration forces legacy deploy implementation.then does a completely fresh dependency resolution —
Progress: resolved 229, reused 0, downloaded 0(exact match to the CI log quoted in the issue), climbing to
resolved 2705, reused 0beforenext devis even spawned. Individual registry metadata requests stall for seconds (
[WARN] Request took 10384ms: https://registry.npmjs.org/playwright-core,29962ms: .../drizzle-orm).next devitselfboots in well under a second once the deploy is done.
Fix
Stop the fresh resolve.
deploy.tsnow runs the legacy deploy with--prefer-offline(skipCONCIV_DEPLOY_FRESH=1to opt back into a live consumer-realism resolve, mirroring theCONCIV_PACKED_FRESH=1convention from fix(e2e): resolve packed installs from a committed lockfile #378's packed-lockfile fix).--prefer-offlineskips theper-package staleness-revalidation GET that
--offline/no-flag both pay for on every already-cachedpackage — that revalidation round trip is exactly what the CI log's
[WARN] Request took 10384ms: .../playwright-corelines are.--legacydeploy resolves against the whole workspace graph, not just the deployed package's owndeps (confirmed:
[WARN] Shared workspace lockfile detected but configuration forces legacy deploy implementation— pnpm sees the workspace lockfile and would normally reuse it, but--legacydeliberately discards that reuse and re-resolves from scratch instead, floating any
"latest"-pinnedspecifier anywhere in the 68-package workspace, e.g.
e2e/tanstack-start's@tanstack/react-router: latest, to whatever the registry says right now). That ruled out thestricter
--offline: it hard-errors (ERR_PNPM_NO_OFFLINE_META, reproduced locally resolving@neodrag/solid@3.0.0-next.11pulled in transitively via a newer@tanstack/react-devtools) themoment that live re-resolution lands on a version whose metadata was never fetched.
--prefer-offlinedegrades gracefully instead: reuse the cache when it has the answer, fetch live only when it
doesn't, never error.
Verified locally (same store, same lockfile, controlled A/B):
--offlinefailed outright withERR_PNPM_NO_OFFLINE_META;--prefer-offlinecompleted clean with zero[WARN] Request tookstalls in the log,
resolved 2705, reused 0, downloaded 3, exit 0. Modern (non-legacy) deploy wasalso tried and rejected: it requires
inject-workspace-packages=trueworkspace-wide(
ERR_PNPM_DEPLOY_NONINJECTED_WORKSPACE), a much larger blast-radius config change than this issuewarrants and out of scope per the dispatch's scope guard.
Decouple deploy from webServer's clock.
@conciv/e2e-utilsgets adeployPackedApphelper(
e2e/e2e-utils/src/deploy.ts) plus adeploy-cli.tsentry point, invoked from each app'stest:e2escript beforeplaywright teststarts:"test:e2e": "pnpm --filter @conciv/e2e-utils run deploy nextjs conciv-e2e-nextjs && playwright test".The deploy target is now a deterministic path (
deployDir(app)inconfig.ts, underos.tmpdir()/conciv-e2e-deploy/<app>) shared between the pretest deploy step andwebServer.command, which is now justcd "<dir>" && pnpm exec next dev --port <port>.e2eConfig()grew awebServerTimeoutoption (default unchanged, 180s) so the two apps that nolonger do any installing inside their webServer command can tighten it to 60s — comfortable
headroom over the observed ~1-10s next-dev + first-compile time — without touching every other
e2e app's webServer timeout. Applied identically to
both
nextjsandnextjs-component, the only two apps using this deploy pattern (surveyed everye2e/*/playwright.config.ts; no other app matches).Playwright always starts
webServerbefore runningglobalSetup(confirmed inplaywright/lib/runner/index.js:createGlobalSetupTasksruns plugin setup — which startswebServer — before the
globalSetupstask), soglobalSetupisn't usable for this; a pretestnpm-script step is.
Trade-off: local iterative
pnpm test:e2ereruns now always redeploy first (previously, withreuseExistingServer: trueoutside CI, an already-running dev server would skip the deploy stepinline in webServer.command). CI never reuses, so this doesn't affect the actual bug; noted here
for anyone iterating locally.
Gates
pnpm turbo run typecheck --filter=@conciv/e2e-utils --filter=conciv-e2e-nextjs --filter=conciv-e2e-nextjs-component— passpnpm turbo run test:e2e --filter=conciv-e2e-nextjs --concurrency=1— pass, 10/10 (6.5m)pnpm turbo run test:e2e --filter=conciv-e2e-nextjs-component --concurrency=1— pass, 1/1 (18.7s)pnpm lint— pass (pre-existing unrelated warnings only)pnpm format:check— pass on all touched files (one pre-existing unrelated failure indocs/assets/page-session-card-spike/fake-form.html, untouched by this diff)pnpm exec fallow audit --changed-since main --format json— pass, zero introduced findingsCloses #435
🤖 Generated with Claude Code