Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,17 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# ADDED: Match base container version
# ADDED: Tag the image with the pinned Playwright version so it matches the
# monorepo's @playwright/test. Derived from the `install` line since the base
# image is now plain Node (no mcr.microsoft.com/playwright FROM to grep).
- name: Extract Playwright version
id: dockerfile
run: |
VERSION=$(grep -oP 'mcr\.microsoft\.com/playwright:v\K[0-9]+\.[0-9]+\.[0-9]+' Dockerfile)
VERSION=$(grep -oP '@playwright/test@\K[0-9]+\.[0-9]+\.[0-9]+' Dockerfile)
if [ -z "$VERSION" ]; then
echo "Could not extract Playwright version from Dockerfile" >&2
exit 1
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT

# This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about) to extract tags and labels that will be applied to the specified image. The `id` "meta" allows the output of this step to be referenced in a subsequent step. The `images` value provides the base name for the tags and labels.
Expand Down
39 changes: 31 additions & 8 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,14 +1,37 @@
# Keep the image up to date with https://playwright.dev/docs/docker#pull-the-image
# Once updated here, also use the correct tag in the monorepo's workflow
FROM mcr.microsoft.com/playwright:v1.57.0-noble
# PixieBrix container image for GitHub Actions E2E (webext-e2e + web-app-e2e).
#
# Slimmed to only the browsers our suites actually launch:
# - webext-e2e: the `chromium` and `msedge` channels
# - web-app-e2e: bundled `chromium`
# The `chrome` channel is disabled (pixiebrix-source#2797) and firefox/webkit are
# unused by both suites. We therefore build on a plain Node base and install just
# those browsers, instead of the batteries-included mcr.microsoft.com/playwright
# image, which bakes firefox + webkit into its base layers and roughly doubles the
# image pull time on CI (see pixiebrix-source#9209).
#
# Node is pinned to the monorepo's version (package.json engines / .nvmrc). Node's
# official images are Debian-based (there is no Ubuntu `-noble` variant); Playwright
# supports Debian 12 (bookworm).
FROM node:24.18.0-bookworm

# List all the browsers including those that are included by default
RUN npx @playwright/test@1.57.0 install --with-deps chrome chromium msedge msedge-beta
# Match the official Playwright image layout so Playwright resolves the browsers at
# runtime without re-downloading them. The monorepo workflow runs the container as
# `--user 1001`, so the installed browsers must be readable/executable by that uid.
ENV PLAYWRIGHT_BROWSERS_PATH=/ms-playwright

# Keep 3 commands in one RUN to save space in the image. rm -rf also cleans up the cache
# Re-set root around apt-get
USER root
# Keep the Playwright version in sync with the monorepo's @playwright/test pin.
# The release workflow derives the published image tag from this version string.
RUN npx --yes @playwright/test@1.57.0 install --with-deps chromium msedge msedge-beta && \
chmod -R a+rX /ms-playwright && \
rm -rf /var/lib/apt/lists/*
Comment on lines +24 to +26

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

npx --yes @playwright/test@1.57.0 downloads the package into npm's cache (/root/.npm) and npx's staging area before running the install sub-command. These artefacts are never cleaned up, so they remain in this layer permanently. Given the PR's goal is to shrink pull time, it's worth purging them in the same RUN:

Suggested change
RUN npx --yes @playwright/test@1.57.0 install --with-deps chromium msedge msedge-beta && \
chmod -R a+rX /ms-playwright && \
rm -rf /var/lib/apt/lists/*
RUN npx --yes @playwright/test@1.57.0 install --with-deps chromium msedge msedge-beta && \
chmod -R a+rX /ms-playwright && \
rm -rf /var/lib/apt/lists/* /root/.npm /tmp/*


# Extra native deps used elsewhere in CI (xmlsec, etc.).
RUN apt-get update && \
apt-get install -y libxmlsec1 libxmlsec1-dev libxml2 pkg-config lsb-release python3-pip && \
rm -rf /var/lib/apt/lists/*

# The monorepo runs this container as `--user 1001`; create that user (mirrors the
# official image's `pwuser`) so $HOME and npm caches resolve to a writable path.
RUN groupadd --gid 1001 pwuser && \
useradd --uid 1001 --gid 1001 --create-home --shell /bin/bash pwuser
USER 1001
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,21 @@ jobs:
options: --user 1001
```

## Browsers

The image installs only the browsers the monorepo's E2E suites launch: bundled
`chromium` plus the `msedge`/`msedge-beta` channels. Firefox and WebKit are
deliberately omitted (unused), and the `chrome` channel is disabled in the
monorepo (pixiebrix-source#2797). It is built on the official Node image rather
than `mcr.microsoft.com/playwright` to avoid pulling the firefox/webkit layers on
every CI job (see pixiebrix-source#9209).

## Updates

The browsers are automatically updated every 3 days. Playwright must be updated manually because the version must match:

1. This repo: Update the version anywhere it appears in the Dockerfile
- a new tag will be created, the old one will continue working but it won't receive browser updates
1. This repo: Update the `@playwright/test@<version>` pin in the Dockerfile
- the published image tag is derived from that version; a new tag will be created, and the old one keeps working but won't receive browser updates
3. Monorepo: Update the version both in package.json and in the workflow

## Documentation
Expand Down