chore(ci): Use Playwright Docker images instead of install-playwright action#20270
Draft
chore(ci): Use Playwright Docker images instead of install-playwright action#20270
Conversation
Contributor
Semver Impact of This PR🟢 Patch (bug fixes) 📋 Changelog PreviewThis is how your changes will appear in the changelog. New Features ✨Cloudflare
Core
Deps
Other
Bug Fixes 🐛Deno
Other
Internal Changes 🔧Ci
Deps
Deps Dev
Other
🤖 This preview updates automatically when you update the PR. |
Contributor
size-limit report 📦
|
f051caa to
7696d34
Compare
… action Replace the custom `install-playwright` composite action with official Playwright Docker images for browser integration tests, and inline `npx playwright install` for other jobs. **Browser integration tests** (playwright + loader): - Use `mcr.microsoft.com/playwright:v1.56.1-noble` container image - Browsers are pre-installed, no download or caching needed **Remix, E2E, canary, flaky-test-detector**: - Replace composite action with `npx playwright install --with-deps chromium` - These jobs have complex setups (Node version matrix, pnpm, Verdaccio) where a container adds unnecessary complexity This also removes the `actions/cache@v4` usage from the composite action, eliminating another source of Node.js 20 deprecation warnings. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Build a custom Docker image extending the official Playwright image with yarn pre-installed, push it to GHCR, and use it across all CI jobs that need Playwright browsers. - Add `.github/docker/playwright.Dockerfile` with yarn@1.22.22 - Add build workflow that pushes to GHCR on Dockerfile or Playwright version changes - All Playwright jobs (browser tests, loader tests, Remix, E2E, canary, flaky-test-detector) now use the GHCR container image - No more `npx playwright install` or browser caching logic anywhere When bumping @playwright/test, also update the PLAYWRIGHT_IMAGE env var in build.yml, canary.yml, and flaky-test-detector.yml. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Trigger the build workflow on PRs that change the Dockerfile, Playwright version, or any e2e test application package.json - Add a version consistency check that verifies all packages and e2e test applications use the same @playwright/test version as the canonical source (dev-packages/browser-integration-tests) - On PRs, the image is built (to verify the Dockerfile) but not pushed - On push to develop and workflow_dispatch, the image is built and pushed Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…tandalone workflow Replace the standalone build-playwright-docker-image workflow with a composite action that runs as a prerequisite job in each workflow: - Verifies all @playwright/test versions are consistent across the repo - Checks if the GHCR image already exists (noop if so) - Builds and pushes only when the image is missing Each workflow (build, canary, flaky-test-detector) now has a small `job_playwright_image` prerequisite job that runs the composite action and outputs the image reference for downstream container jobs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove the default value for PLAYWRIGHT_VERSION ARG so the build fails if the arg isn't passed. The ensure-playwright-image action reads the version from browser-integration-tests/package.json and passes it as a build arg — that is the single source of truth. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Simplify the checkout steps — full checkout is fine here and avoids potential issues with missing files. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@playwright/test is in `dependencies` (not `devDependencies`) in browser-integration-tests/package.json. Check both fields so the version is found regardless of which section it's declared in. Also cleaned up the version consistency check to use a shared function and log the canonical version for easier debugging. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Firefox fails with "Sandbox: CanCreateUserNamespace() clone() failure: EPERM" when running in a Docker container on GitHub Actions because user namespaces are restricted. Adding --ipc=host allows the browser sandbox to work correctly for all browsers (chromium, firefox, webkit). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The image tag was only based on the Playwright version, so changes to the Dockerfile (e.g. adding yarn, system deps) didn't trigger a rebuild. Tag is now `v<playwright-version>-<8-char-dockerfile-hash>`, e.g. `v1.56.0-a1b2c3d4`. Any change to the Dockerfile produces a new tag, which misses the GHCR cache and triggers a fresh build. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
GitHub Actions runs containers as root but sets HOME=/github/home (owned by pwuser). Firefox refuses to launch as root in another user's home directory. Setting HOME=/root fixes this. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The -e flag in container options gets overridden by GitHub Actions. Use container.env which is the proper way to set environment variables inside job containers and takes precedence over the Actions default. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
actions/cache computes an internal version hash from the cache paths and runner environment. When a cache is saved on the host runner but restored inside a Docker container, the paths resolve differently (e.g. ~ expands to /home/runner vs /root), causing a version mismatch and cache miss. Adding `enableCrossOsArchive: true` to all cache save/restore steps makes the version hash environment-independent, allowing caches to be shared between host runners and container jobs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use ubuntu:24.04 as the base image instead of the official Playwright Docker image to avoid missing system packages and config differences. Install Node/Yarn via Volta to match the repo's version management. Since the container now uses the same OS as GHA runners, remove the enableCrossOsArchive workaround from all cache steps. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extend ghcr.io/actions/actions-runner:2.333.1 instead of plain ubuntu. Remove Volta — actions/setup-node in workflow steps handles Node/Yarn. Update HOME env to /home/runner to match the runner user in the image. Remove enableCrossOsArchive since the container OS matches the host. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ions Read node and yarn versions from the root package.json volta config and pass them as build args to the Dockerfile. This ensures the Docker image always has Node and Yarn installed at the same versions the repo pins. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Required by actions/cache for compression. The actions-runner base image does not include it. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
actions/cache needs this flag when caches are saved on the host but restored inside Docker containers, even when both run the same OS. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
GHA overrides HOME=/github/home inside containers, so browsers installed under /home/runner/.cache weren't found at runtime. Fix by: - Setting PLAYWRIGHT_BROWSERS_PATH=/opt/pw-browsers (fixed, HOME-independent) - Using system-wide git config for safe.directory (works with any HOME) - Removing HOME env overrides from all workflow container configs Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
E2E tests need Docker-in-Docker (Verdaccio registry). The actions-runner base image runs as non-root 'runner' user which cannot access the Docker socket mounted from the host. Run as root to fix permissions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Both host (ubuntu-24.04) and container (actions-runner, also Ubuntu 24.04) are the same OS, so enableCrossOsArchive is not needed. Removing it fixes cache misses caused by version hash differences between caches saved without the flag and restores attempted with it. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add v2 prefix to dependency cache key to bust stale caches that were saved without enableCrossOsArchive. Re-add the flag to all cache steps so new caches are saved in cross-OS format from the start. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
sudo resets environment variables by default, so the ENV set in the Dockerfile wasn't visible to the npx playwright install command. Explicitly pass the variable so browsers are installed to /opt/pw-browsers. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Firefox refuses to run as root when HOME points to a directory owned by a different user. GHA sets HOME=/github/home (owned by runner) but we run as --user root. Setting HOME=/root fixes the ownership mismatch. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
github.workspace resolves to different absolute paths on the host (/home/runner/work/...) vs inside a container (/__w/...), causing cache version hash mismatches. Use relative paths instead, which actions/cache resolves from the working directory. Bust cache key to v3 since the path format changed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
GHA hard-codes HOME=/github/home when creating the container, which overrides our container.env setting. Using -e HOME=/root in the container options flag takes precedence over GHA's injected value. Firefox requires HOME to be owned by the current user (root). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When running inside a GHA container, paths resolve to /__w/... which only exists inside the container. Docker-in-Docker volume mounts need host paths (/home/runner/work/...). Convert paths in registrySetup.ts. Also move HOME=/root to docker -e flag since GHA overrides container env settings with its own HOME=/github/home. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
runner.temp resolves to the host path (/home/runner/work/_temp) but inside a container the equivalent path is /__w/_temp. The copy step writes to the host path which doesn't exist inside the container. Use a workspace-relative path (dev-packages/tmp-test-application) instead, which is inside the mounted workspace volume and accessible from both host and container. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
GHA strips -e flags from container options, so HOME can't be overridden that way. Instead, add a 'Fix HOME for root user' step that writes HOME=/root to GITHUB_ENV at the start of every container job. Firefox requires HOME to be owned by the current user (root), and GHA sets HOME=/github/home (owned by runner). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Only the browser Playwright tests job runs Firefox (via matrix project). All other container jobs (loader tests, Remix, E2E, canary, flaky detector) only run chromium and don't need the HOME override. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
E2E tests use Docker-in-Docker (Verdaccio registry) which doesn't work inside a GHA container due to network isolation. On develop these jobs run directly on the host. Only browser Playwright, loader, and Remix tests need the Playwright container image. Revert registrySetup.ts path conversion and temp directory changes for E2E jobs since they now run on the host again. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Dockerfile.publish-packages container only provided a pinned Node.js version for running `npm publish` of pre-built tarballs. The host already has the correct Node.js version via Volta, so the Docker build+run overhead is unnecessary. Run the publish script directly on the host instead. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extract the tarball publishing logic into an importable function in lib/publishPackages.ts and call it directly from registrySetup instead of spawning a subprocess. Remove the old publish-packages.ts script. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
PR #20329 removed Docker-based package publishing, so E2E jobs can now run in the Playwright container without Docker-in-Docker issues. Re-add the container block to E2E jobs and use workspace-relative temp paths (runner.temp doesn't work inside containers). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…right-docker-images
29281a3 to
213b16a
Compare
Docker containers don't have IPv6 enabled on the loopback interface by default. Node.js fetch resolves localhost to ::1 (IPv6) first, which fails when IPv6 is disabled. This breaks E2E tests that do server-side self-referencing fetch (e.g., Astro SSR fetching its own API endpoints). Enable IPv6 via --sysctl net.ipv6.conf.all.disable_ipv6=0 on all container jobs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
install-playwrightcomposite action@playwright/testversion consistency across the entire repoArchitecture
Each workflow has a lightweight
job_playwright_imageprerequisite job that:@playwright/testversions match across packages and e2e test appsghcr.io/getsentry/sentry-javascript/playwright:v<version>already existsDownstream jobs reference the image via
needs.job_playwright_image.outputs.image.Jobs updated
install-playwrightcomposite actioninstall-playwrightcomposite actioninstall-playwrightcomposite actioninstall-playwrightcomposite actioninstall-playwrightcomposite actioninstall-playwrightcomposite actioninstall-playwrightcomposite actionBenefits
actions/cache@v4usage from the deleted composite action (Node.js 20 deprecation warning)@playwright/testversions fail CI with clear error annotationspackage.jsonautomaticallydocker manifest inspect)Maintenance
When bumping
@playwright/test, the ensure-playwright-image action automatically detects the new version and builds a new image on the first CI run. No manual workflow file updates needed.Test plan
job_playwright_imageis a noop when the image already exists🤖 Generated with Claude Code