manifest/chrome.json now carries a fixed public key, so the extension id and the chrome.storage.local partition holding the wallet stay stable across checkout moves and re-clones instead of being derived from the absolute path. A release entrypoint produces a self-contained versioned artifact per browser, including the files that sit at dist/ root outside both browser directories. One version source of truth, enforced: the build fails naming the culprit when the two manifests and package.json disagree, and BUILD_COMMIT now marks a dirty tree as dirty. Firefox ships an unsigned XPI; the README states that release Firefox and ESR refuse it, that Developer Edition or Unbranded is required, and that Remove is irreversible except from the recovery phrase, which is asserted by test.
83 lines
3.5 KiB
Docker
83 lines
3.5 KiB
Docker
# Firefox end-to-end image: stock Firefox plus geckodriver on a node base,
|
|
# with this repo and a freshly built extension inside it, built by
|
|
# script/test-e2e-firefox. The harness itself has no dependencies, so
|
|
# nothing is installed for it.
|
|
#
|
|
# The build context is the repo root. The repo is baked in rather than
|
|
# bind-mounted because a bind mount does not resolve under Gitea Actions:
|
|
# the runner runs the job in a container against the HOST's docker socket,
|
|
# so the source side of a -v is resolved by the host daemon while the job's
|
|
# checkout lives on a docker volume that is not a host path -- the mount
|
|
# silently succeeds and /work is empty. Baking the build in is also the
|
|
# only way this suite can have both a built extension and the
|
|
# `--network none` it runs under, since a container with no network cannot
|
|
# install anything.
|
|
#
|
|
# All three external artifacts are pinned by digest, and are fetched in
|
|
# layers above the repo copy, so editing the harness or any source file
|
|
# re-runs only the two cheap layers at the bottom. The Firefox version in
|
|
# particular must not float: -remote-allow-system-access is mandatory on
|
|
# 153 and was not on 142, so the flag the harness passes is
|
|
# version-coupled.
|
|
|
|
# node:22-bookworm-slim, 2026-08-12
|
|
FROM node@sha256:d649c27dae7ba0137b3cef5dd75baa422c08dc3d9e3fc0c23dfb172dc3cc6436
|
|
|
|
ENV DEBIAN_FRONTEND=noninteractive
|
|
|
|
# Firefox's shared-library dependencies on a slim base, plus the two tools
|
|
# needed to fetch and unpack the pinned tarballs.
|
|
RUN apt-get update \
|
|
&& apt-get install -y --no-install-recommends \
|
|
ca-certificates \
|
|
curl \
|
|
libasound2 \
|
|
libdbus-glib-1-2 \
|
|
libgtk-3-0 \
|
|
libx11-xcb1 \
|
|
libxt6 \
|
|
libxtst6 \
|
|
xz-utils \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Firefox 153.0.3, linux-x86_64, en-US
|
|
ARG FIREFOX_URL=https://ftp.mozilla.org/pub/firefox/releases/153.0.3/linux-x86_64/en-US/firefox-153.0.3.tar.xz
|
|
ARG FIREFOX_SHA256=22b312280900bfb174b685ece32c7b3c6d72e7f8e53d6d30f21ac41a8dc500a2
|
|
RUN curl -fsSL -o /tmp/firefox.tar.xz "$FIREFOX_URL" \
|
|
&& echo "$FIREFOX_SHA256 /tmp/firefox.tar.xz" | sha256sum -c - \
|
|
&& tar -xJf /tmp/firefox.tar.xz -C /opt \
|
|
&& rm /tmp/firefox.tar.xz \
|
|
&& /opt/firefox/firefox --version
|
|
|
|
# geckodriver v0.36.0, linux64
|
|
ARG GECKODRIVER_URL=https://github.com/mozilla/geckodriver/releases/download/v0.36.0/geckodriver-v0.36.0-linux64.tar.gz
|
|
ARG GECKODRIVER_SHA256=0bde38707eb0a686a20c6bd50f4adcc7d60d4f73c60eb83ee9e0db8f65823e04
|
|
RUN curl -fsSL -o /tmp/geckodriver.tar.gz "$GECKODRIVER_URL" \
|
|
&& echo "$GECKODRIVER_SHA256 /tmp/geckodriver.tar.gz" | sha256sum -c - \
|
|
&& tar -xzf /tmp/geckodriver.tar.gz -C /usr/local/bin \
|
|
&& rm /tmp/geckodriver.tar.gz \
|
|
&& geckodriver --version
|
|
|
|
ENV FIREFOX_BIN=/opt/firefox/firefox
|
|
ENV GECKODRIVER=/usr/local/bin/geckodriver
|
|
|
|
WORKDIR /work
|
|
|
|
# Same layering as the root Dockerfile: script/bootstrap installs the
|
|
# prerequisites and the dependencies, and the manifests are copied first so
|
|
# that layer is cached until they change.
|
|
COPY script/ script/
|
|
COPY package.json yarn.lock ./
|
|
RUN script/bootstrap
|
|
|
|
COPY . .
|
|
|
|
# make package builds (and verifies) dist/ and then writes the release
|
|
# artifacts, so the image carries both: run.js installs the unpacked
|
|
# dist/firefox and reinstall.js installs the packaged .xpi, which is how the
|
|
# artifact that would actually be handed to someone gets exercised in a real
|
|
# Firefox rather than only being produced.
|
|
RUN make package
|
|
|
|
CMD ["node", "tests/e2e/firefox/run.js", "dist/firefox"]
|