Skip to content

Commit aebe2b9

Browse files
authored
Merge pull request #1910 from Hack23/copilot/analyze-github-workflows
ci: prebuilt browser images for Cypress/Playwright + harden ZAP workflow
2 parents 018db60 + be99b25 commit aebe2b9

5 files changed

Lines changed: 149 additions & 148 deletions

File tree

โ€Ž.github/workflows/release.ymlโ€Ž

Lines changed: 24 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,29 @@ jobs:
2222
prepare:
2323
name: Prepare Release
2424
runs-on: ubuntu-latest
25+
# Run inside Cypress's official browsers image so Chrome/Firefox/Edge/Xvfb and all
26+
# GTK/NSS/font system libs are preinstalled. Node is normalised to the version pinned
27+
# in .nvmrc by actions/setup-node below.
28+
container:
29+
# Use cypress/browsers:latest โ€” keeps Chrome/Firefox/Edge/Xvfb on a
30+
# rolling release. We don't pin to a specific patch tag because .nvmrc is
31+
# a Node major (26) and `actions/setup-node` would override the
32+
# container's Node anyway, which would defeat the purpose of digest
33+
# pinning the container's Node.
34+
image: cypress/browsers:latest
35+
# Run as root so the in-job apt-get (graphviz/ffmpeg/zip/git) and
36+
# actions/setup-node cache writes don't hit permission errors. The
37+
# cypress/browsers image's default USER is non-root.
38+
options: --user root
2539
# Only prepare job needs write permissions for commit and tagging
2640
permissions:
2741
contents: write # Required for git auto-commit
2842
outputs:
2943
version: ${{ steps.get-version.outputs.version }}
3044
is_prerelease: ${{ github.event.inputs.prerelease || 'false' }}
3145
steps:
32-
- name: Harden Runner
33-
uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
34-
with:
35-
egress-policy: audit
46+
# NOTE: step-security/harden-runner does not support container jobs and is
47+
# intentionally omitted from this job.
3648

3749
- name: Checkout repository
3850
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -50,54 +62,21 @@ jobs:
5062
echo "version=${VERSION}" >> $GITHUB_OUTPUT
5163
echo "Version: ${VERSION}"
5264
53-
- name: Cache APT packages
54-
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
55-
with:
56-
path: /var/cache/apt/archives
57-
key: v2-${{ runner.os }}-apt-chrome-${{ hashFiles('.github/workflows/release.yml') }}
58-
restore-keys: |
59-
v2-${{ runner.os }}-apt-chrome-
60-
6165
- name: Setup Three.js Test Environment
6266
env:
6367
CYPRESS_VIDEO: true
6468
# Suppress X11 keyboard configuration warnings
6569
XKB_DEFAULT_RULES: evdev
6670
XKB_DEFAULT_MODEL: pc105
6771
XKB_DEFAULT_LAYOUT: us
68-
timeout-minutes: 10
72+
timeout-minutes: 5
6973
run: |
70-
echo "๐Ÿ”ง Setting up Three.js test environment for release validation..."
71-
72-
# Install all dependencies
73-
sudo DEBIAN_FRONTEND=noninteractive apt-get update -qq
74-
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
75-
xvfb dbus-x11 graphviz \
76-
libgtk2.0-0 libgtk-3-0 libgbm-dev libgbm1 \
77-
ffmpeg libnotify-dev libnss3 libxss1 \
78-
libxtst6 xauth \
79-
fonts-noto fonts-noto-cjk fonts-noto-cjk-extra \
80-
ca-certificates fonts-liberation curl gnupg \
81-
libatk-bridge2.0-0 libatk1.0-0 \
82-
libcups2 libdbus-1-3 libdrm2 \
83-
libnspr4 libx11-xcb1 libxcomposite1 \
84-
libxdamage1 libxfixes3 libxrandr2 \
85-
libxrender1 libxshmfence1 xdg-utils libxkbcommon0 xkb-data
86-
87-
# Install Chrome using signed keyring (modern method, resilient)
88-
curl -fsSL --retry 3 --retry-delay 5 --connect-timeout 30 \
89-
https://dl.google.com/linux/linux_signing_key.pub \
90-
| sudo gpg --dearmor -o /usr/share/keyrings/google-chrome-keyring.gpg
91-
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/google-chrome-keyring.gpg] https://dl.google.com/linux/chrome/deb/ stable main" \
92-
| sudo tee /etc/apt/sources.list.d/google-chrome.list > /dev/null
93-
sudo DEBIAN_FRONTEND=noninteractive apt-get update -qq
94-
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends google-chrome-stable
95-
96-
# Setup D-Bus and Xvfb
97-
sudo mkdir -p /var/run/dbus
98-
sudo dbus-daemon --system --fork
99-
export DISPLAY=:99
100-
74+
echo "๐Ÿ”ง Verifying Three.js test environment for release validation..."
75+
# Chrome / Xvfb / GTK libs are baked into cypress/browsers image.
76+
# Only graphviz (for diagrams documentation), ffmpeg, and zip (for
77+
# release artifact packaging) are still required on top.
78+
apt-get update -qq
79+
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends graphviz ffmpeg zip git
10180
echo "โœ… Three.js environment ready"
10281
google-chrome --version
10382
@@ -148,7 +127,7 @@ jobs:
148127
TERM: dumb
149128
run: |
150129
echo "๐Ÿš€ Running Three.js E2E tests for release validation..."
151-
NODE_OPTIONS="--max-old-space-size=4096" xvfb-run --auto-servernum --server-args="-screen 0 1280x720x24 -ac +extension GLX +extension RANDR +render -nolisten tcp" npm run test:e2e || TEST_EXIT_CODE=$?
130+
NODE_OPTIONS="--max-old-space-size=4096" npm run test:e2e || TEST_EXIT_CODE=$?
152131
exit ${TEST_EXIT_CODE:-0}
153132
154133

โ€Ž.github/workflows/screenshot-analysis.ymlโ€Ž

Lines changed: 20 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,18 @@ jobs:
1515
name: Capture UI/UX Screenshots
1616
runs-on: ubuntu-latest
1717
timeout-minutes: 30
18+
# Run inside Microsoft's official Playwright image. Includes all browsers
19+
# (Chromium/Firefox/WebKit) plus every system dependency Playwright needs,
20+
# so we no longer need a custom apt-get block or `playwright install --with-deps`.
21+
# Tag pinned to v1.59.1-noble to match the `playwright` version in package.json
22+
# so the bundled browser binaries always match the npm client. Node is then
23+
# normalised to the version in .nvmrc by actions/setup-node below.
24+
container:
25+
image: mcr.microsoft.com/playwright:v1.59.1-noble
26+
# Run as root so actions/setup-node cache writes and the Playwright
27+
# browser cache write work without permission issues. The Playwright
28+
# noble image runs as the `pwuser` non-root user by default.
29+
options: --user root
1830
env:
1931
# Suppress X11 keyboard configuration warnings
2032
XKB_DEFAULT_RULES: evdev
@@ -28,60 +40,22 @@ jobs:
2840
node-version-file: '.nvmrc'
2941
cache: "npm"
3042

31-
- name: Cache APT packages
32-
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
33-
with:
34-
path: /var/cache/apt/archives
35-
key: v2-${{ runner.os }}-apt-playwright-${{ hashFiles('.github/workflows/screenshot-analysis.yml') }}
36-
restore-keys: |
37-
v2-${{ runner.os }}-apt-playwright-
38-
39-
- name: Setup Screenshot Environment
40-
timeout-minutes: 10
41-
run: |
42-
echo "๐Ÿ”ง Setting up screenshot capture environment..."
43-
44-
# Install dependencies for Playwright screenshot capture
45-
sudo DEBIAN_FRONTEND=noninteractive apt-get update -qq
46-
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
47-
xvfb dbus-x11 \
48-
libgtk2.0-0 libgtk-3-0 libgbm-dev libgbm1 \
49-
libnotify-dev libnss3 libxss1 \
50-
libxtst6 xauth \
51-
fonts-noto fonts-noto-cjk fonts-noto-cjk-extra \
52-
ca-certificates fonts-liberation \
53-
libatk-bridge2.0-0 libatk1.0-0 \
54-
libcups2 libdbus-1-3 libdrm2 \
55-
libnspr4 libx11-xcb1 libxcomposite1 \
56-
libxdamage1 libxfixes3 libxrandr2 \
57-
libxrender1 libxshmfence1 xdg-utils libxkbcommon0 xkb-data
58-
59-
# Setup D-Bus
60-
sudo mkdir -p /var/run/dbus
61-
sudo dbus-daemon --system --fork
62-
63-
echo "โœ… Screenshot environment ready"
64-
6543
- name: Install dependencies
6644
run: npm ci
6745

68-
- name: Cache Playwright browsers
69-
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
70-
with:
71-
path: ~/.cache/ms-playwright
72-
key: v2-playwright-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
73-
restore-keys: |
74-
v2-playwright-${{ runner.os }}-
75-
76-
- name: Install Playwright
77-
timeout-minutes: 20
78-
run: npx playwright install chromium --with-deps
79-
46+
# The mcr.microsoft.com/playwright:v1.59.1-noble image already ships the
47+
# browser binaries for Playwright 1.59.1 under /ms-playwright. Because the
48+
# image is pinned to the same Playwright version as the `playwright` npm
49+
# dep in package.json, we deliberately skip both `playwright install` and
50+
# the Playwright browser cache here โ€” they would just re-download what
51+
# the image already provides and add network flake.
8052
- name: Build application
8153
run: npm run build
8254

8355
- name: Start Xvfb
8456
run: |
57+
# The playwright:noble image ships xvfb. Start it so any screenshot
58+
# script that relies on $DISPLAY (e.g. headed Chromium) has a server.
8559
Xvfb :99 -ac -screen 0 1280x1024x24 +extension GLX +extension RANDR +render -nolisten tcp > /dev/null 2>&1 &
8660
echo "DISPLAY=:99" >> $GITHUB_ENV
8761
sleep 2 # Give Xvfb time to start

โ€Ž.github/workflows/test-and-report.ymlโ€Ž

Lines changed: 31 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,23 @@ jobs:
113113
e2e-tests:
114114
needs: [prepare, build-validation]
115115
runs-on: ubuntu-latest
116+
# Use Cypress's official browsers image: ships Node + Chrome + Firefox + Edge + Xvfb
117+
# + all GTK/NSS/font system libs preinstalled, removing the need for a custom
118+
# apt-get + Google Chrome bootstrap step. Node is then normalised to the version
119+
# in .nvmrc via actions/setup-node below.
120+
container:
121+
# Use cypress/browsers:latest โ€” this keeps Chrome/Firefox/Edge/Xvfb on a
122+
# rolling release, and `actions/setup-node` below normalises Node to the
123+
# major pinned in .nvmrc (currently 26). We deliberately accept the
124+
# rolling browser version over digest-pinning because .nvmrc is a Node
125+
# major (26), not a patch, so attempting to also pin the container's Node
126+
# patch would just be silently overridden by setup-node and create a
127+
# misleading impression of full reproducibility.
128+
image: cypress/browsers:latest
129+
# Run as root so actions/setup-node cache writes and Cypress binary cache
130+
# writes work without permission issues. The cypress/browsers image's
131+
# default USER is non-root.
132+
options: --user root
116133
# Needs write permissions to upload artifacts
117134
permissions:
118135
contents: write # Required to check out code
@@ -126,60 +143,22 @@ jobs:
126143
XKB_DEFAULT_MODEL: pc105
127144
XKB_DEFAULT_LAYOUT: us
128145
steps:
129-
- name: Harden the runner (Audit all outbound calls)
130-
uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
131-
with:
132-
egress-policy: audit
146+
# NOTE: step-security/harden-runner does not support container jobs, so it
147+
# is intentionally omitted here. Egress hardening for E2E browser traffic
148+
# would block legitimate test traffic anyway.
133149

134150
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
135151
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
136152
with:
137153
node-version-file: '.nvmrc'
138154
cache: "npm"
139155

140-
- name: Cache APT packages
141-
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
142-
with:
143-
path: /var/cache/apt/archives
144-
key: v2-${{ runner.os }}-apt-chrome-${{ hashFiles('.github/workflows/test-and-report.yml') }}
145-
restore-keys: |
146-
v2-${{ runner.os }}-apt-chrome-
147-
148-
- name: Setup Three.js Test Environment
149-
timeout-minutes: 10
156+
- name: Print browser versions
150157
run: |
151-
echo "๐Ÿ”ง Setting up Three.js test environment with optimized Chrome flags..."
152-
153-
# Install all required dependencies for E2E testing
154-
sudo DEBIAN_FRONTEND=noninteractive apt-get update -qq
155-
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
156-
xvfb dbus-x11 graphviz \
157-
libgtk2.0-0 libgtk-3-0 libgbm-dev libgbm1 \
158-
libnotify-dev libnss3 libxss1 \
159-
libxtst6 xauth \
160-
fonts-noto fonts-noto-cjk fonts-noto-cjk-extra \
161-
ca-certificates fonts-liberation curl gnupg \
162-
libatk-bridge2.0-0 libatk1.0-0 \
163-
libcups2 libdbus-1-3 libdrm2 \
164-
libnspr4 libx11-xcb1 libxcomposite1 \
165-
libxdamage1 libxfixes3 libxrandr2 \
166-
libxrender1 libxshmfence1 xdg-utils libxkbcommon0 xkb-data
167-
168-
# Install Chrome for Three.js WebGL support using signed keyring (modern method)
169-
curl -fsSL --retry 3 --retry-delay 5 --connect-timeout 30 \
170-
https://dl.google.com/linux/linux_signing_key.pub \
171-
| sudo gpg --dearmor -o /usr/share/keyrings/google-chrome-keyring.gpg
172-
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/google-chrome-keyring.gpg] https://dl.google.com/linux/chrome/deb/ stable main" \
173-
| sudo tee /etc/apt/sources.list.d/google-chrome.list > /dev/null
174-
sudo DEBIAN_FRONTEND=noninteractive apt-get update -qq
175-
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends google-chrome-stable
176-
177-
# Setup D-Bus
178-
sudo mkdir -p /var/run/dbus
179-
sudo dbus-daemon --system --fork
180-
181-
echo "โœ… Three.js test environment ready"
182-
google-chrome --version
158+
echo "Node: $(node --version)"
159+
google-chrome --version || true
160+
# cypress/browsers ships Xvfb (used by Cypress's bundled @cypress/xvfb).
161+
command -v Xvfb >/dev/null 2>&1 && echo "Xvfb available" || echo "Xvfb missing"
183162
184163
- name: Cache Cypress binary
185164
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
@@ -200,13 +179,16 @@ jobs:
200179
echo "๐Ÿš€ Starting Three.js E2E test execution at $(date +%T)"
201180
echo "๐Ÿ“Š Configuration:"
202181
echo " - Chrome: $(google-chrome --version)"
203-
echo " - Node memory: 4GB heap"
182+
echo " - Node: $(node --version) (memory: 4GB heap)"
204183
echo " - Display: $DISPLAY"
205184
echo " - Target: 10-12 minute execution"
206185
echo ""
207186
START_TIME=$(date +%s) || START_TIME=0
208-
# Run tests - xvfb-run handles display setup
209-
NODE_OPTIONS="--max-old-space-size=4096" xvfb-run --auto-servernum --server-args="-screen 0 1280x720x24 -ac +extension GLX +extension RANDR +render -nolisten tcp" npm run test:e2e || TEST_EXIT_CODE=$?
187+
# cypress/browsers image ships Xvfb but NOT xauth, so the xvfb-run
188+
# wrapper fails with "xauth command not found". Cypress's bundled
189+
# @cypress/xvfb spawns Xvfb directly (no xauth needed) when DISPLAY
190+
# is unset, so we just call npm run test:e2e and let Cypress manage it.
191+
NODE_OPTIONS="--max-old-space-size=4096" npm run test:e2e || TEST_EXIT_CODE=$?
210192
END_TIME=$(date +%s) || END_TIME=$START_TIME
211193
if [ "$START_TIME" -ne 0 ]; then
212194
DURATION=$((END_TIME - START_TIME))

0 commit comments

Comments
ย (0)