From a4bef69c00c66d1450373cb720c8851bd2b25715 Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Tue, 3 Nov 2026 11:41:31 -0800 Subject: [PATCH 1/6] devops: pin the Node.js version of the driver in scripts/NODE_VERSION download_driver.sh used to pick the latest Node.js LTS at download time, so the same commit could assemble drivers with different Node.js binaries. Pin the version in scripts/NODE_VERSION; roll_driver.sh moves it to the latest LTS, the policy the upstream driver build script had. --- .claude/skills/playwright-roll/SKILL.md | 2 +- .github/workflows/test_docker.yml | 1 + AGENTS.md | 2 +- CONTRIBUTING.md | 2 +- scripts/NODE_VERSION | 1 + scripts/download_driver.sh | 19 ++++++------------- scripts/roll_driver.sh | 17 +++++++++++++++-- 7 files changed, 26 insertions(+), 18 deletions(-) create mode 100644 scripts/NODE_VERSION diff --git a/.claude/skills/playwright-roll/SKILL.md b/.claude/skills/playwright-roll/SKILL.md index 1efb5db90..a65cfe436 100644 --- a/.claude/skills/playwright-roll/SKILL.md +++ b/.claude/skills/playwright-roll/SKILL.md @@ -138,7 +138,7 @@ Common patterns: ## Rebuilding the driver-bundle after a roll -`./scripts/roll_driver.sh` does the whole roll pipeline end-to-end: bumps `DRIVER_VERSION`, downloads new driver files into `driver-bundle/src/main/resources/driver//`, regenerates `api.json` and the Java interfaces, and updates the README. When all of that succeeds, the next `mvn` invocation that touches `driver-bundle` will pick up the new files and you don't need to think about it. +`./scripts/roll_driver.sh` does the whole roll pipeline end-to-end: bumps `DRIVER_VERSION`, pins `NODE_VERSION` to the latest Node.js LTS (the policy of the other Playwright language ports), downloads new driver files into `driver-bundle/src/main/resources/driver//`, regenerates `api.json` and the Java interfaces, and updates the README. When all of that succeeds, the next `mvn` invocation that touches `driver-bundle` will pick up the new files and you don't need to think about it. But if any step in the pipeline fails (the very common case is the API generator throwing on a new type — see *Fixing generator and compilation errors*), the run aborts before `driver-bundle/target/classes/` has been refreshed. From that point on, until you manually rebuild `driver-bundle`, the test JVM will load the **old** driver from the cached `target/classes`/installed jar even though the source resources have already been swapped to the new version. diff --git a/.github/workflows/test_docker.yml b/.github/workflows/test_docker.yml index 36b07f466..cd8f86606 100644 --- a/.github/workflows/test_docker.yml +++ b/.github/workflows/test_docker.yml @@ -12,6 +12,7 @@ on: - .github/workflows/test_docker.yml - '**/Dockerfile*' - scripts/DRIVER_VERSION + - scripts/NODE_VERSION - '**/pom.xml' branches: - main diff --git a/AGENTS.md b/AGENTS.md index 1bc292f95..1740e3b2e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -7,7 +7,7 @@ Project checkouts (including the upstream `playwright` repo) live in the parent ## Build and test ```bash -scripts/download_driver.sh # the driver, once per DRIVER_VERSION +scripts/download_driver.sh # the driver, once per DRIVER_VERSION and NODE_VERSION mvn -B install -D skipTests --no-transfer-progress # build and install every module mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="install --with-deps" -f playwright/pom.xml --no-transfer-progress BROWSER=chromium mvn test -f playwright/pom.xml -D test=TestPageScreenshot --no-transfer-progress diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 30eb6d9b4..ff5a50e5a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -41,7 +41,7 @@ cd playwright-java scripts/download_driver.sh ``` -Each driver is assembled from the [`playwright-core`](https://www.npmjs.com/package/playwright-core) npm package (version pinned in [scripts/DRIVER_VERSION](scripts/DRIVER_VERSION)) and the matching Node.js binary from https://nodejs.org, the same way the upstream Playwright build does it. +Each driver is assembled from the [`playwright-core`](https://www.npmjs.com/package/playwright-core) npm package (version pinned in [scripts/DRIVER_VERSION](scripts/DRIVER_VERSION)) and the Node.js binary from https://nodejs.org (version pinned in [scripts/NODE_VERSION](scripts/NODE_VERSION)), the same way the upstream Playwright build does it. ### Building and running the tests with Maven diff --git a/scripts/NODE_VERSION b/scripts/NODE_VERSION new file mode 100644 index 000000000..1dda03ddb --- /dev/null +++ b/scripts/NODE_VERSION @@ -0,0 +1 @@ +26.13.0 diff --git a/scripts/download_driver.sh b/scripts/download_driver.sh index 5e36f91e3..29a8ee756 100755 --- a/scripts/download_driver.sh +++ b/scripts/download_driver.sh @@ -10,10 +10,10 @@ if [[ ($1 == '-h') || ($1 == '--help') ]]; then echo "" echo "This script downloads and assembles the Playwright driver for all platforms." echo "The platform-independent 'playwright-core' npm package is assembled once into the driver" - echo "module ('driver/src/main/resources/driver/package'), and the matching Node.js binary from" - echo "https://nodejs.org for each platform goes into the driver-bundle module" - echo "('driver-bundle/src/main/resources/driver/'), the same way the upstream" - echo "Playwright build does it." + echo "module ('driver/src/main/resources/driver/package'), and the Node.js binary of the version" + echo "pinned in scripts/NODE_VERSION from https://nodejs.org for each platform goes into the" + echo "driver-bundle module ('driver-bundle/src/main/resources/driver/'), the same way" + echo "the upstream Playwright build does it." echo "" echo "Usage: scripts/download_driver.sh [option]" echo "" @@ -46,15 +46,8 @@ npm_at_root() { (cd "$ROOT" && npm "$@") } -# The Node.js version used to be pinned in the upstream driver build script. The script was -# removed in microsoft/playwright#41518, so we follow the same policy it had: the latest -# Node.js LTS (see upstream utils/build/update-playwright-node.mjs). -NODE_VERSION=$(curl -fsSL "https://nodejs.org/dist/index.json" \ - | node -e "let s='';process.stdin.on('data',d=>s+=d).on('end',()=>console.log(JSON.parse(s).find(r=>r.lts).version.slice(1)))") -if [[ -z "$NODE_VERSION" ]]; then - echo "Failed to determine the latest Node.js LTS version" - exit 1 -fi +# roll_driver.sh moves the pin to the latest Node.js LTS. +NODE_VERSION=$(head -1 ./NODE_VERSION) echo "Driver version: $DRIVER_VERSION" echo "Node.js version: $NODE_VERSION" diff --git a/scripts/roll_driver.sh b/scripts/roll_driver.sh index f8535e57f..dd4d0a54a 100755 --- a/scripts/roll_driver.sh +++ b/scripts/roll_driver.sh @@ -24,10 +24,23 @@ fi CURRENT_VERSION=$(head -1 ./DRIVER_VERSION) echo "Rolling driver from $CURRENT_VERSION to $NEW_VERSION" -if [[ "$CURRENT_VERSION" == "$NEW_VERSION" ]]; then - echo "Current version is up to date. Skipping driver download."; +# The Node.js version used to be pinned in the upstream driver build script. The script was +# removed in microsoft/playwright#41518, so we follow the same policy it had: the latest +# Node.js LTS (see upstream utils/build/update-playwright-node.mjs). +CURRENT_NODE_VERSION=$(head -1 ./NODE_VERSION) +NEW_NODE_VERSION=$(curl -fsSL "https://nodejs.org/dist/index.json" \ + | node -e "let s='';process.stdin.on('data',d=>s+=d).on('end',()=>console.log(JSON.parse(s).find(r=>r.lts).version.slice(1)))") +if [[ -z "$NEW_NODE_VERSION" ]]; then + echo "Failed to determine the latest Node.js LTS version" + exit 1 +fi +echo "Rolling Node.js from $CURRENT_NODE_VERSION to $NEW_NODE_VERSION" + +if [[ "$CURRENT_VERSION" == "$NEW_VERSION" && "$CURRENT_NODE_VERSION" == "$NEW_NODE_VERSION" ]]; then + echo "Current versions are up to date. Skipping driver download."; else echo $NEW_VERSION > ./DRIVER_VERSION + echo $NEW_NODE_VERSION > ./NODE_VERSION ./download_driver.sh fi; From 46b18e75ab4688c40abfda7e85753fb53b599861 Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Tue, 3 Nov 2026 12:27:43 -0800 Subject: [PATCH 2/6] devops: pin only the Node.js major version, like the upstream Docker images scripts/NODE_VERSION holds the major version (26) and download_driver.sh downloads its latest release. roll_driver.sh moves the pin to the major version of the latest Node.js LTS (see upstream utils/build/update-playwright-node.mjs). --- .claude/skills/playwright-roll/SKILL.md | 2 +- CONTRIBUTING.md | 2 +- scripts/NODE_VERSION | 2 +- scripts/download_driver.sh | 20 ++++++++++++++------ scripts/roll_driver.sh | 7 +++---- 5 files changed, 20 insertions(+), 13 deletions(-) diff --git a/.claude/skills/playwright-roll/SKILL.md b/.claude/skills/playwright-roll/SKILL.md index a65cfe436..3caf4b81b 100644 --- a/.claude/skills/playwright-roll/SKILL.md +++ b/.claude/skills/playwright-roll/SKILL.md @@ -138,7 +138,7 @@ Common patterns: ## Rebuilding the driver-bundle after a roll -`./scripts/roll_driver.sh` does the whole roll pipeline end-to-end: bumps `DRIVER_VERSION`, pins `NODE_VERSION` to the latest Node.js LTS (the policy of the other Playwright language ports), downloads new driver files into `driver-bundle/src/main/resources/driver//`, regenerates `api.json` and the Java interfaces, and updates the README. When all of that succeeds, the next `mvn` invocation that touches `driver-bundle` will pick up the new files and you don't need to think about it. +`./scripts/roll_driver.sh` does the whole roll pipeline end-to-end: bumps `DRIVER_VERSION`, moves `NODE_VERSION` to the major version of the latest Node.js LTS (the policy of the upstream Docker images), downloads new driver files into `driver-bundle/src/main/resources/driver//`, regenerates `api.json` and the Java interfaces, and updates the README. When all of that succeeds, the next `mvn` invocation that touches `driver-bundle` will pick up the new files and you don't need to think about it. But if any step in the pipeline fails (the very common case is the API generator throwing on a new type — see *Fixing generator and compilation errors*), the run aborts before `driver-bundle/target/classes/` has been refreshed. From that point on, until you manually rebuild `driver-bundle`, the test JVM will load the **old** driver from the cached `target/classes`/installed jar even though the source resources have already been swapped to the new version. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ff5a50e5a..a1c38e94c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -41,7 +41,7 @@ cd playwright-java scripts/download_driver.sh ``` -Each driver is assembled from the [`playwright-core`](https://www.npmjs.com/package/playwright-core) npm package (version pinned in [scripts/DRIVER_VERSION](scripts/DRIVER_VERSION)) and the Node.js binary from https://nodejs.org (version pinned in [scripts/NODE_VERSION](scripts/NODE_VERSION)), the same way the upstream Playwright build does it. +Each driver is assembled from the [`playwright-core`](https://www.npmjs.com/package/playwright-core) npm package (version pinned in [scripts/DRIVER_VERSION](scripts/DRIVER_VERSION)) and the latest Node.js binary of the major version pinned in [scripts/NODE_VERSION](scripts/NODE_VERSION) from https://nodejs.org, the same way the upstream Playwright build does it. ### Building and running the tests with Maven diff --git a/scripts/NODE_VERSION b/scripts/NODE_VERSION index 1dda03ddb..6f4247a62 100644 --- a/scripts/NODE_VERSION +++ b/scripts/NODE_VERSION @@ -1 +1 @@ -26.13.0 +26 diff --git a/scripts/download_driver.sh b/scripts/download_driver.sh index 29a8ee756..64778c463 100755 --- a/scripts/download_driver.sh +++ b/scripts/download_driver.sh @@ -10,10 +10,10 @@ if [[ ($1 == '-h') || ($1 == '--help') ]]; then echo "" echo "This script downloads and assembles the Playwright driver for all platforms." echo "The platform-independent 'playwright-core' npm package is assembled once into the driver" - echo "module ('driver/src/main/resources/driver/package'), and the Node.js binary of the version" - echo "pinned in scripts/NODE_VERSION from https://nodejs.org for each platform goes into the" - echo "driver-bundle module ('driver-bundle/src/main/resources/driver/'), the same way" - echo "the upstream Playwright build does it." + echo "module ('driver/src/main/resources/driver/package'), and the Node.js binary of the latest" + echo "release of the major version pinned in scripts/NODE_VERSION from https://nodejs.org for each" + echo "platform goes into the driver-bundle module ('driver-bundle/src/main/resources/driver/')," + echo "the same way the upstream Playwright build does it." echo "" echo "Usage: scripts/download_driver.sh [option]" echo "" @@ -46,8 +46,16 @@ npm_at_root() { (cd "$ROOT" && npm "$@") } -# roll_driver.sh moves the pin to the latest Node.js LTS. -NODE_VERSION=$(head -1 ./NODE_VERSION) +# scripts/NODE_VERSION pins the Node.js major version, like the upstream Docker images do; +# roll_driver.sh moves it to the major version of the latest Node.js LTS. Use the latest +# release of that major version. +NODE_MAJOR_VERSION=$(head -1 ./NODE_VERSION) +NODE_VERSION=$(curl -fsSL "https://nodejs.org/dist/index.json" \ + | node -e "let s='';process.stdin.on('data',d=>s+=d).on('end',()=>console.log((JSON.parse(s).find(r=>r.version.startsWith('v$NODE_MAJOR_VERSION.'))||{version:'v'}).version.slice(1)))") +if [[ -z "$NODE_VERSION" ]]; then + echo "Failed to determine the latest Node.js $NODE_MAJOR_VERSION.x version" + exit 1 +fi echo "Driver version: $DRIVER_VERSION" echo "Node.js version: $NODE_VERSION" diff --git a/scripts/roll_driver.sh b/scripts/roll_driver.sh index dd4d0a54a..8fe8c7e42 100755 --- a/scripts/roll_driver.sh +++ b/scripts/roll_driver.sh @@ -24,12 +24,11 @@ fi CURRENT_VERSION=$(head -1 ./DRIVER_VERSION) echo "Rolling driver from $CURRENT_VERSION to $NEW_VERSION" -# The Node.js version used to be pinned in the upstream driver build script. The script was -# removed in microsoft/playwright#41518, so we follow the same policy it had: the latest -# Node.js LTS (see upstream utils/build/update-playwright-node.mjs). +# Pin the major version of the latest Node.js LTS, the policy of the upstream Docker images +# (see upstream utils/build/update-playwright-node.mjs). CURRENT_NODE_VERSION=$(head -1 ./NODE_VERSION) NEW_NODE_VERSION=$(curl -fsSL "https://nodejs.org/dist/index.json" \ - | node -e "let s='';process.stdin.on('data',d=>s+=d).on('end',()=>console.log(JSON.parse(s).find(r=>r.lts).version.slice(1)))") + | node -e "let s='';process.stdin.on('data',d=>s+=d).on('end',()=>console.log(JSON.parse(s).find(r=>r.lts).version.slice(1).split('.')[0]))") if [[ -z "$NEW_NODE_VERSION" ]]; then echo "Failed to determine the latest Node.js LTS version" exit 1 From d2be55179a07dd5dcc4a984593d5bea1932d17e6 Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Tue, 3 Nov 2026 12:33:43 -0800 Subject: [PATCH 3/6] devops: bump the Node.js major version manually, like upstream roll_driver.sh no longer moves NODE_VERSION. It always runs download_driver.sh, which downloads the latest release of the pinned major version, even when the driver version is unchanged. --- .claude/skills/playwright-roll/SKILL.md | 2 +- scripts/download_driver.sh | 5 ++--- scripts/roll_driver.sh | 22 ++++------------------ 3 files changed, 7 insertions(+), 22 deletions(-) diff --git a/.claude/skills/playwright-roll/SKILL.md b/.claude/skills/playwright-roll/SKILL.md index 3caf4b81b..1efb5db90 100644 --- a/.claude/skills/playwright-roll/SKILL.md +++ b/.claude/skills/playwright-roll/SKILL.md @@ -138,7 +138,7 @@ Common patterns: ## Rebuilding the driver-bundle after a roll -`./scripts/roll_driver.sh` does the whole roll pipeline end-to-end: bumps `DRIVER_VERSION`, moves `NODE_VERSION` to the major version of the latest Node.js LTS (the policy of the upstream Docker images), downloads new driver files into `driver-bundle/src/main/resources/driver//`, regenerates `api.json` and the Java interfaces, and updates the README. When all of that succeeds, the next `mvn` invocation that touches `driver-bundle` will pick up the new files and you don't need to think about it. +`./scripts/roll_driver.sh` does the whole roll pipeline end-to-end: bumps `DRIVER_VERSION`, downloads new driver files into `driver-bundle/src/main/resources/driver//`, regenerates `api.json` and the Java interfaces, and updates the README. When all of that succeeds, the next `mvn` invocation that touches `driver-bundle` will pick up the new files and you don't need to think about it. But if any step in the pipeline fails (the very common case is the API generator throwing on a new type — see *Fixing generator and compilation errors*), the run aborts before `driver-bundle/target/classes/` has been refreshed. From that point on, until you manually rebuild `driver-bundle`, the test JVM will load the **old** driver from the cached `target/classes`/installed jar even though the source resources have already been swapped to the new version. diff --git a/scripts/download_driver.sh b/scripts/download_driver.sh index 64778c463..399b68288 100755 --- a/scripts/download_driver.sh +++ b/scripts/download_driver.sh @@ -46,9 +46,8 @@ npm_at_root() { (cd "$ROOT" && npm "$@") } -# scripts/NODE_VERSION pins the Node.js major version, like the upstream Docker images do; -# roll_driver.sh moves it to the major version of the latest Node.js LTS. Use the latest -# release of that major version. +# scripts/NODE_VERSION pins the Node.js major version and is bumped manually, like +# ARG NODE_VERSION in the upstream Docker images. Use the latest release of that major version. NODE_MAJOR_VERSION=$(head -1 ./NODE_VERSION) NODE_VERSION=$(curl -fsSL "https://nodejs.org/dist/index.json" \ | node -e "let s='';process.stdin.on('data',d=>s+=d).on('end',()=>console.log((JSON.parse(s).find(r=>r.version.startsWith('v$NODE_MAJOR_VERSION.'))||{version:'v'}).version.slice(1)))") diff --git a/scripts/roll_driver.sh b/scripts/roll_driver.sh index 8fe8c7e42..4b45e85a2 100755 --- a/scripts/roll_driver.sh +++ b/scripts/roll_driver.sh @@ -24,24 +24,10 @@ fi CURRENT_VERSION=$(head -1 ./DRIVER_VERSION) echo "Rolling driver from $CURRENT_VERSION to $NEW_VERSION" -# Pin the major version of the latest Node.js LTS, the policy of the upstream Docker images -# (see upstream utils/build/update-playwright-node.mjs). -CURRENT_NODE_VERSION=$(head -1 ./NODE_VERSION) -NEW_NODE_VERSION=$(curl -fsSL "https://nodejs.org/dist/index.json" \ - | node -e "let s='';process.stdin.on('data',d=>s+=d).on('end',()=>console.log(JSON.parse(s).find(r=>r.lts).version.slice(1).split('.')[0]))") -if [[ -z "$NEW_NODE_VERSION" ]]; then - echo "Failed to determine the latest Node.js LTS version" - exit 1 -fi -echo "Rolling Node.js from $CURRENT_NODE_VERSION to $NEW_NODE_VERSION" - -if [[ "$CURRENT_VERSION" == "$NEW_VERSION" && "$CURRENT_NODE_VERSION" == "$NEW_NODE_VERSION" ]]; then - echo "Current versions are up to date. Skipping driver download."; -else - echo $NEW_VERSION > ./DRIVER_VERSION - echo $NEW_NODE_VERSION > ./NODE_VERSION - ./download_driver.sh -fi; +echo $NEW_VERSION > ./DRIVER_VERSION +# Download even when the driver version is unchanged: the driver bundles the latest release +# of the Node.js major version pinned in NODE_VERSION. +./download_driver.sh ./generate_api.sh ./update_readme.sh From f131160b3f1f2cd03cf9eeff89b9c30ebce7f8db Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Tue, 3 Nov 2026 12:39:28 -0800 Subject: [PATCH 4/6] devops: resolve the Node.js release from the per-major SHASUMS256.txt Fetch https://nodejs.org/dist/latest-v.x/SHASUMS256.txt through the download() helper instead of parsing the whole release index with node, so the lookup gets the same retries and wget fallback as the archives. Shorten the help text and keep AGENTS.md unchanged. --- AGENTS.md | 2 +- scripts/download_driver.sh | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 1740e3b2e..1bc292f95 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -7,7 +7,7 @@ Project checkouts (including the upstream `playwright` repo) live in the parent ## Build and test ```bash -scripts/download_driver.sh # the driver, once per DRIVER_VERSION and NODE_VERSION +scripts/download_driver.sh # the driver, once per DRIVER_VERSION mvn -B install -D skipTests --no-transfer-progress # build and install every module mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="install --with-deps" -f playwright/pom.xml --no-transfer-progress BROWSER=chromium mvn test -f playwright/pom.xml -D test=TestPageScreenshot --no-transfer-progress diff --git a/scripts/download_driver.sh b/scripts/download_driver.sh index 399b68288..d352adc06 100755 --- a/scripts/download_driver.sh +++ b/scripts/download_driver.sh @@ -10,10 +10,10 @@ if [[ ($1 == '-h') || ($1 == '--help') ]]; then echo "" echo "This script downloads and assembles the Playwright driver for all platforms." echo "The platform-independent 'playwright-core' npm package is assembled once into the driver" - echo "module ('driver/src/main/resources/driver/package'), and the Node.js binary of the latest" - echo "release of the major version pinned in scripts/NODE_VERSION from https://nodejs.org for each" - echo "platform goes into the driver-bundle module ('driver-bundle/src/main/resources/driver/')," - echo "the same way the upstream Playwright build does it." + echo "module ('driver/src/main/resources/driver/package'), and the Node.js binary from" + echo "https://nodejs.org (major version pinned in scripts/NODE_VERSION) for each platform goes" + echo "into the driver-bundle module ('driver-bundle/src/main/resources/driver/'), the" + echo "same way the upstream Playwright build does it." echo "" echo "Usage: scripts/download_driver.sh [option]" echo "" @@ -46,11 +46,14 @@ npm_at_root() { (cd "$ROOT" && npm "$@") } -# scripts/NODE_VERSION pins the Node.js major version and is bumped manually, like -# ARG NODE_VERSION in the upstream Docker images. Use the latest release of that major version. +TMP_DIR="$(mktemp -d)" +trap 'rm -rf "$TMP_DIR"' EXIT + +# scripts/NODE_VERSION pins the Node.js major version, like ARG NODE_VERSION in the upstream +# Docker images. Use the latest release of that major version. NODE_MAJOR_VERSION=$(head -1 ./NODE_VERSION) -NODE_VERSION=$(curl -fsSL "https://nodejs.org/dist/index.json" \ - | node -e "let s='';process.stdin.on('data',d=>s+=d).on('end',()=>console.log((JSON.parse(s).find(r=>r.version.startsWith('v$NODE_MAJOR_VERSION.'))||{version:'v'}).version.slice(1)))") +download "https://nodejs.org/dist/latest-v$NODE_MAJOR_VERSION.x/SHASUMS256.txt" "$TMP_DIR/SHASUMS256.txt" +NODE_VERSION=$(grep -om1 "node-v$NODE_MAJOR_VERSION\.[0-9.]*[0-9]" "$TMP_DIR/SHASUMS256.txt" | cut -c7-) if [[ -z "$NODE_VERSION" ]]; then echo "Failed to determine the latest Node.js $NODE_MAJOR_VERSION.x version" exit 1 @@ -64,9 +67,6 @@ echo "Node.js version: $NODE_VERSION" CORE_DEST="$ROOT/driver/src/main/resources/driver" NODE_DEST="$ROOT/driver-bundle/src/main/resources/driver" -TMP_DIR="$(mktemp -d)" -trap 'rm -rf "$TMP_DIR"' EXIT - # 1. playwright-core package -> driver module (once, shared by every platform). echo "Assembling playwright-core package to $CORE_DEST/package" rm -rf "$CORE_DEST/package" From 0dd0e7a0487787aa8d2d296fba1f5453ee242e10 Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Tue, 3 Nov 2026 13:23:50 -0800 Subject: [PATCH 5/6] devops: spell out how the Node.js release is read from SHASUMS256.txt --- scripts/download_driver.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/scripts/download_driver.sh b/scripts/download_driver.sh index d352adc06..24a53de7f 100755 --- a/scripts/download_driver.sh +++ b/scripts/download_driver.sh @@ -52,8 +52,11 @@ trap 'rm -rf "$TMP_DIR"' EXIT # scripts/NODE_VERSION pins the Node.js major version, like ARG NODE_VERSION in the upstream # Docker images. Use the latest release of that major version. NODE_MAJOR_VERSION=$(head -1 ./NODE_VERSION) -download "https://nodejs.org/dist/latest-v$NODE_MAJOR_VERSION.x/SHASUMS256.txt" "$TMP_DIR/SHASUMS256.txt" -NODE_VERSION=$(grep -om1 "node-v$NODE_MAJOR_VERSION\.[0-9.]*[0-9]" "$TMP_DIR/SHASUMS256.txt" | cut -c7-) +# The checksum list of the latest release names every file after the release, e.g. +# d38bd5e5... node-v26.13.0-darwin-arm64.tar.gz +SHASUMS="$TMP_DIR/SHASUMS256.txt" +download "https://nodejs.org/dist/latest-v$NODE_MAJOR_VERSION.x/SHASUMS256.txt" "$SHASUMS" +NODE_VERSION=$(sed -nE 's/.*node-v([0-9]+\.[0-9]+\.[0-9]+)-.*/\1/p' "$SHASUMS" | head -1) if [[ -z "$NODE_VERSION" ]]; then echo "Failed to determine the latest Node.js $NODE_MAJOR_VERSION.x version" exit 1 From d0f2c6af409a00e5aa5baac7250a74b780c7fbd2 Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Tue, 3 Nov 2026 13:25:31 -0800 Subject: [PATCH 6/6] fix(docker): install libatomic1, which the Node.js 26 binary of the driver links against --- utils/docker/Dockerfile.jammy | 2 ++ utils/docker/Dockerfile.noble | 2 ++ utils/docker/Dockerfile.resolute | 2 ++ 3 files changed, 6 insertions(+) diff --git a/utils/docker/Dockerfile.jammy b/utils/docker/Dockerfile.jammy index 4440772ea..316a95d4f 100644 --- a/utils/docker/Dockerfile.jammy +++ b/utils/docker/Dockerfile.jammy @@ -19,6 +19,8 @@ RUN find /etc/apt -type f \( -name '*.list' -o -name '*.sources' \) \ wget \ # Install utilities required for downloading driver unzip \ + # The Node.js binary of the driver links against libatomic (since Node.js 25) + libatomic1 \ # For the MSEdge install script gpg && \ rm -rf /var/lib/apt/lists/* && \ diff --git a/utils/docker/Dockerfile.noble b/utils/docker/Dockerfile.noble index 52779ce15..5ccd4d7bf 100644 --- a/utils/docker/Dockerfile.noble +++ b/utils/docker/Dockerfile.noble @@ -19,6 +19,8 @@ RUN find /etc/apt -type f \( -name '*.list' -o -name '*.sources' \) \ wget \ # Install utilities required for downloading driver unzip \ + # The Node.js binary of the driver links against libatomic (since Node.js 25) + libatomic1 \ # For the MSEdge install script gpg && \ rm -rf /var/lib/apt/lists/* && \ diff --git a/utils/docker/Dockerfile.resolute b/utils/docker/Dockerfile.resolute index 905962beb..7dabf1f96 100644 --- a/utils/docker/Dockerfile.resolute +++ b/utils/docker/Dockerfile.resolute @@ -21,6 +21,8 @@ RUN find /etc/apt -type f \( -name '*.list' -o -name '*.sources' \) \ wget \ # Install utilities required for downloading driver unzip \ + # The Node.js binary of the driver links against libatomic (since Node.js 25) + libatomic1 \ # For the MSEdge install script gpg && \ rm -rf /var/lib/apt/lists/* && \