Repository navigation
Catch-up CI: cache Playwright browsers (unblocks staging deploys) #33
Description
Parent issue: #23
Parent: search for issue titled “Epic Stack catch-up: tracking”.
Do this next after package 1/7 (#24) is merged to dev. It is not an Epic Stack port. It unblocks every later catch-up PR: merge-to-dev staging deploys needs the Playwright job, and that job has been hanging ~60 minutes on Install Playwright Browsers (then cancelled). Same hang on an origin/dev push, so it is not unique to the RR bump.
Read .cursor/skills/epic-stack-catch-up/SKILL.md before coding.
Goal
Make the Playwright job in .github/workflows/deploy.yml reliably get past browser install so lint / typecheck / vitest / Playwright can finish and dev can auto-deploy staging.
Do not skip Playwright. Do not drop e2e coverage on dependency PRs.
Why
Observed on 2026-08-19:
- PR Bump React Router to 7.18.2 for __manifest DoS CVEs #31 (package 1/7) first Playwright run did install browsers, then failed collection by parsing
sprite.svgas JS (fixed in that PR with a test-only stub — do not redo unless it regressed). - A later run of the same PR, and a push to
origin/dev, sat on📥 Install Playwright Browsers(npm run test:e2e:install→npx playwright install --with-deps chromium) until the 60-minute job timeout / cancel. Tests never started.
There is no cache of ~/.cache/ms-playwright. Epic Stack’s workflow is the same uncached install; this issue is our CI reliability, not a file copy from upstream.
Do this
Branch off current origin/dev. PR into dev.
- Cache Playwright browsers, keyed by runner OS +
@playwright/testversion (so package 6/7’s Playwright bump refills once, on purpose). - On cache hit, do not re-download browsers. Still install OS deps if needed (
npx playwright install-deps chromium) unless you verify theubuntu-22.04image already has them. - On cache miss, install Chromium (keep
--with-depsif required). Prefer failing the install step in ~10–15 minutes over eating the full 60-minute job timeout with a silent hang. - Keep
timeout-minutes: 60on the job (tests need it). Add a step-level timeout on install if Actions supports it for that step. - Do not change test files, app code, or
playwright.config.tsunless install/cache requires a one-line script tweak inpackage.json. - Do not skip the Playwright job, and do not make it
continue-on-error.
Suggested shape (adapt; do not paste blindly if Playwright’s current CI docs differ):
- name: 📥 Get Playwright version
id: playwright-version
run: echo "version=$(node -e "console.log(require('@playwright/test/package.json').version)")" >> "$GITHUB_OUTPUT"
- name: 🏦 Cache Playwright browsers
id: playwright-cache
uses: actions/cache@v4
with:
path: ~/.cache/ms-playwright
key: playwright-${{ runner.os }}-${{ steps.playwright-version.outputs.version }}
- name: 📥 Install Playwright Browsers
if: steps.playwright-cache.outputs.cache-hit != 'true'
timeout-minutes: 15
run: npm run test:e2e:install
- name: 📥 Install Playwright OS deps
if: steps.playwright-cache.outputs.cache-hit == 'true'
timeout-minutes: 10
run: npx playwright install-deps chromiumIf the first cache-miss install still hangs, say so in the PR with the log snippet (download vs apt --with-deps). Do not “fix” it by deleting Playwright from needs.
Files allowed
.github/workflows/deploy.ymlpackage.jsononly if you splittest:e2e:installinto install vs install-deps scriptsplaywright.config.tsonly if a documented Playwright CI requirement appears (prefer not)
Do not
- Do not bump
@playwright/test, Vite, Express, Sentry, Prisma, or React Router - Do not skip Playwright on PRs
- Do not start packages 2–7
- Do not use PR P/patn dev stack updater #21 as a base
- Do not edit dashboard, Fly, or app routes
Acceptance
- Playwright job gets past browser install in well under 60 minutes on a PR (cache miss once, cache hit on a follow-up push if needed)
- Lint, typecheck, vitest still run; Playwright still required for deploy
- Cache key includes
@playwright/testversion - PR targets
dev
Staging smoke (human, after merge to dev)
- Confirm the
devworkflow’s Playwright job completes (not cancelled on Install Browsers) - Staging deploy can proceed when the rest of CI is green
PR target: dev (never main). Implement only this issue.
Activity
goodeats commentedon Aug 25, 2026
Started. PR: #37 (into
dev).Implements the versioned
~/.cache/ms-playwrightcache, 15-minute install timeout on miss, andinstall-deps chromiumon hit.Extra (required): the #31 merge to
devfailed Playwright tests (not install) withTypeError: Unknown file extension ".svg". Addedtests/svg-esm-loader.mjsandNODE_OPTIONS=--importon the test step so collection can find tests. No package bumps, Playwright still required for deploy.goodeats commentedon Aug 25, 2026
Dropped the SVG stubs on PR #37 to match Epic Stack’s
playwright.config.ts(nobuild.external, no Babel/ESM loaders). The #24 stub was causing GHAUnknown file extension ".svg". Cache + 15-minute install timeout stay as specified.#37
goodeats commentedon Aug 25, 2026
Matching Epic Stack’s Playwright config on 1.51 failed CI:
SyntaxErrorparsingsprite.svgas JS (the original #24 error). Restored the Babel stub withoutbuild.external(that flag causedUnknown file extension ".svg"). Cache unchanged. Playwright bump stays in #29.Merge pull request #37 from goodeats/cursor/playwright-ci-cache-ba9d
goodeats commentedon Aug 25, 2026
PR #37 merged to
dev: #37Leave this issue open until staging smoke (homepage, login, notes, dashboard). The
devDeploy workflow is running now; if Playwright stays green, staging should deploy.When Playwright is bumped in #29 (1.51 → 1.58), delete the collection shims (
svg-import-stub.cjs,PW_TEST_SOURCE_TRANSFORM,NODE_OPTIONS=--no-experimental-strip-types).