Skip to content

feat: assemble driver from npm + nodejs.org instead of deprecated CDN#615

Merged
mxschmitt merged 2 commits into
mainfrom
feat/assemble-driver-from-npm-and-nodejs
Jun 26, 2026
Merged

feat: assemble driver from npm + nodejs.org instead of deprecated CDN#615
mxschmitt merged 2 commits into
mainfrom
feat/assemble-driver-from-npm-and-nodejs

Conversation

@mxschmitt

Copy link
Copy Markdown
Owner

Summary

The Playwright /builds/driver CDN is being deprecated (#593): Microsoft will stop uploading new driver versions "very soon" and intends to delete existing ones later. playwright-go currently downloads a prebuilt, fixed-layout zip from exactly that CDN at install time, so this would break new releases and eventually all installs.

This PR stops depending on that CDN. Instead, Install() / DownloadDriver() assemble the driver from two durable upstream sources — the same move the official playwright-dotnet (#3322), playwright-python (#3092), and playwright-java (#1936) ports made in June 2026:

  • the platform-independent playwright-core package from the npm registry (registry.npmjs.org/playwright-core/-/playwright-core-<ver>.tgz), extracted into <DriverDirectory>/package/ — this contains cli.js; and
  • the matching per-platform Node.js binary from nodejs.org/dist, placed at <DriverDirectory>/node[.exe].

The resulting on-disk layout is identical to before, so Run(), Command(), patchDriverBundle(), and the driver-up-to-date check are unchanged. playwright-core ships pre-bundled with zero runtime dependencies, so a plain tarball extract is sufficient — no npm install step is needed.

Why these issues are related

All four issues are facets of one root cause: the driver was obtained as a single welded-together CDN zip with a rigid assumed layout. This PR decouples the two halves (platform-independent JS vs. platform-specific Node.js), which addresses them together:

New / changed configuration

Env var Purpose Default
PLAYWRIGHT_NODEJS_PATH (existing) Use a preinstalled Node.js; skips the Node.js download. Required on platforms without a prebuilt binary (e.g. 32-bit ARM).
PLAYWRIGHT_GO_NPM_REGISTRY (new) npm registry mirror for playwright-core. https://registry.npmjs.org
NODE_MIRROR (new) Node.js distribution mirror (nvm/n convention). https://nodejs.org/dist

Removed: PLAYWRIGHT_DOWNLOAD_HOST (was specific to the CDN zip path that no longer exists).

Notes on the bundled Node.js version

Pinned to Node.js 24.18.0 (nodeVersion const), matching what upstream Playwright bundles. Note that Node.js 24 dropped the linux-armv7l build, so 32-bit ARM (Raspberry Pi, #584) is handled via the PLAYWRIGHT_NODEJS_PATH escape hatch rather than a zero-config download. (Pinning a Node.js 22 LTS release would restore a prebuilt armv7l binary if a zero-config arm/v7 experience is preferred — noted inline.)

Hardening

Archive extraction is guarded against path traversal (tar/zip slip) via safeJoin, since the registry/mirror hosts are user-configurable and therefore not fully trusted. Download retries no longer hammer non-transient 4xx responses.

Testing

  • go build, go vet, gofmt clean.
  • Unit tests pass with -race, including the updated TestNpmRegistryEnv and new TestNodePlatformSuffix.
  • Verified end-to-end on darwin/arm64: assembled the driver from live npm + nodejs.org and confirmed node package/cli.js --version reports the expected version.

Refs #593, #584, #575, #496

The Playwright /builds/driver CDN is being deprecated (#593): new driver
versions will stop being uploaded and existing ones will be deleted. Rather
than downloading a prebuilt, fixed-layout zip from that CDN, assemble the
driver from two durable upstream sources, mirroring what the official
playwright-dotnet/python/java ports now do:

  - the platform-independent playwright-core package from the npm registry,
    extracted into <DriverDirectory>/package (contains cli.js); and
  - the matching per-platform Node.js binary from nodejs.org.

The on-disk layout is unchanged, so Run()/Command()/patchDriverBundle() and
the driver-up-to-date check keep working as before.

New environment variables:
  - PLAYWRIGHT_GO_NPM_REGISTRY: npm registry mirror (default registry.npmjs.org)
  - NODE_MIRROR: Node.js distribution mirror (default nodejs.org/dist)
  - PLAYWRIGHT_NODEJS_PATH (existing): when set, skip the Node.js download and
    use a preinstalled Node.js.

Also fixes the silent platform fallthrough behind #584: previously linux/arm
(and other unsupported GOARCH) mapped to the x64 build and failed at runtime
with a cryptic 'exec format error'. nodePlatformSuffix() now returns a clear,
actionable error pointing at PLAYWRIGHT_NODEJS_PATH for platforms without a
prebuilt Node.js binary (e.g. 32-bit ARM).

Extraction is hardened against path traversal (tar/zip slip) since the
registry/mirror hosts are configurable.

Refs #593, #584
@mxschmitt
mxschmitt requested a review from canstand June 26, 2026 02:15
@mxschmitt
mxschmitt merged commit 843d745 into main Jun 26, 2026
23 checks passed
@mxschmitt
mxschmitt deleted the feat/assemble-driver-from-npm-and-nodejs branch June 26, 2026 16:21
kdacosta0 added a commit to securesign/sigstore-e2e that referenced this pull request Jul 8, 2026
The Playwright /builds/driver CDN (azureedge) has been shut down by
Microsoft. Driver archives for macOS and Windows were deleted, causing
404 errors during `playwright install`.

v0.6100.0 assembles the driver from npm + nodejs.org instead of the
deprecated CDN (mxschmitt/playwright-go#615).

The module path also moved from playwright-community to mxschmitt.

Refs: SECURESIGN-4984

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
santiagovittor added a commit to santiagovittor/scrapemate that referenced this pull request Jul 13, 2026
playwright-community/playwright-go's driver download CDN
(playwright.azureedge.net and its mirrors) has been returning 404 for
every version, since the upstream ecosystem deprecated that CDN in
favor of assembling the driver from the npm registry and nodejs.org
(mxschmitt/playwright-go#615, merged 2026-06-26, after the repo was
renamed from playwright-community to mxschmitt). mxschmitt/playwright-go
v0.6100.0+ carries that fix; earlier versions, including v0.6000.0, are
still CDN-dependent.

Swaps the import in the four files that use playwright-go directly
(adapters/fetchers/jshttp/jshttp.go, page_slot_pool.go, session_slot.go,
adapters/browsers/playwright/page.go) and bumps go.mod/go.sum. No API
changes were needed, the two packages are compatible at the symbols
this module uses. Also updates the two README install commands that
reference the old import path.

Verified: go build, go vet, go mod verify, gofmt, golangci-lint, and
the full test suite all pass. Beyond that, built
gosom/google-maps-scraper against this branch via a local go.mod
replace and ran a real scrape job through it end to end, the driver
installed cleanly via mxschmitt's npm+nodejs.org path and the job
completed with real results (16 places found for a "coffee shop" query
near Buenos Aires, job status ok).

Related: gosom/google-maps-scraper#302
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant