Skip to content

Deprecate chromium installer, add arm64 Linux support for chrome-headless-shell#14334

Open
cderv wants to merge 12 commits intomainfrom
fix/chromium-deprecation-arm64
Open

Deprecate chromium installer, add arm64 Linux support for chrome-headless-shell#14334
cderv wants to merge 12 commits intomainfrom
fix/chromium-deprecation-arm64

Conversation

@cderv
Copy link
Copy Markdown
Collaborator

@cderv cderv commented Apr 7, 2026

quarto install chromium uses Puppeteer 9.0.2 (2021), which pins a Chromium revision far older than the CVE-2026-5281 fix. On arm64 Linux, quarto install chrome-headless-shell doesn't work because Google's Chrome for Testing (CfT) API has no arm64 builds — forcing arm64 users to fall back to the vulnerable legacy installer or install a system Chrome manually.

Deprecation

quarto install chromium and quarto update chromium now print a deprecation warning and transparently redirect to chrome-headless-shell. No new interactive prompts are added, so CI pipelines using quarto install chromium --no-prompt continue to work without changes. quarto uninstall chromium is unchanged, allowing users to clean up legacy installs.

On the update path, legacy chromium is uninstalled before the chrome-headless-shell install begins. installTool() calls Deno.exit() on completion, so cleanup after install is not possible — the uninstall happens upfront.

arm64 Linux via Playwright CDN

On arm64 Linux, chrome-headless-shell install now uses Microsoft's Playwright CDN as the download source (same approach as Remotion). Version metadata comes from Playwright's browsers.json, which tracks Chrome stable closely. The arm64 binary is named headless_shell in a chrome-linux/ directory layout, compared to CfT's chrome-headless-shell in chrome-headless-shell-{platform}/. chromeHeadlessShellBinaryName() abstracts this difference for all call sites.

detectChromePlatform() (renamed from detectCftPlatform) now includes linux-arm64 in the platform map rather than throwing. isPlaywrightCdnPlatform() routes to the Playwright code path based on the mapped platform value.

Binder

Generated post-build scripts now use quarto install chrome-headless-shell instead of quarto install chromium. The internal QuartoTool type keeps "chromium" as a generic "needs a headless browser" signal — only the generated shell command changed.

Test Plan

  • quarto install chromium --no-prompt shows deprecation warning, installs chrome-headless-shell
  • quarto uninstall chromium still works for legacy cleanup
  • Unit tests for Playwright CDN fetch, URL construction, arm64 directory layout
  • Unit tests for chrome-headless-shell install lifecycle

Closes #11877

cderv added 12 commits April 7, 2026 14:16
CfT API has no linux-arm64 builds. Add functions to fetch Playwright's
browsers.json and construct download URLs from their CDN, which hosts
arm64 chromium-headless-shell builds. Also update detectCftPlatform()
to return a valid PlatformInfo for arm64 instead of throwing.
- Route latestRelease() through Playwright CDN on arm64 Linux
- Use "headless_shell" binary name for Playwright CDN builds
- Check both binary names in chromeHeadlessShellExecutablePath() and isInstalled()
- Add Playwright CDN integration test (skipped on CI)
Print deprecation warning and transparently redirect to chrome-headless-shell.
No new prompts — CI/automation that uses 'quarto install chromium' continues
to work without changes. 'quarto update chromium' also uninstalls legacy
chromium if present before installing chrome-headless-shell.
Binder environments now install chrome-headless-shell instead of the
legacy chromium tool for mermaid/graphviz rendering support.
Updates bundled Chromium used in Playwright integration tests.
The file now handles both CfT API and Playwright CDN downloads.
detectCftPlatform → detectChromePlatform, findCftExecutable →
findChromeExecutable, downloadAndExtractCft → downloadAndExtractChrome,
CftPlatform → ChromePlatform. These functions now handle both CfT API
and Playwright CDN platforms. CfT-specific types (CftDownload,
CftStableRelease, fetchLatestCftRelease) keep their names since they
are genuinely CfT-only.

Also refactor detectChromePlatform() to include linux-arm64 in the
platform map instead of special-casing it, and restore proactive
legacy chromium uninstall on the update redirect path.
- isPlaywrightCdnPlatform: check platform === "linux-arm64" instead of
  re-checking raw os/arch values (single source of truth)
- detectChromePlatform error message: say "chrome-headless-shell" not
  "Chrome for Testing" since the function covers both CfT and Playwright
- Fix misleading comment in tools-console.ts deprecation redirect
Call detectChromePlatform() once and pass the result to both
isPlaywrightCdnPlatform() and the CfT platform destructure,
instead of computing it twice.
Single source of truth for the platform-dependent binary name
(chrome-headless-shell on CfT platforms, headless_shell on Playwright
arm64). Used by chromeHeadlessShellExecutablePath, isInstalled, and
preparePackage instead of duplicating the check or trying both names.
On unsupported platforms, detectChromePlatform() throws. The previous
code was tolerant because findChromeExecutable caught this internally
and fell back to a directory walk. Now that chromeHeadlessShellBinaryName
calls isPlaywrightCdnPlatform directly, catch the exception and default
to the CfT binary name to preserve non-throwing probe behavior.
External HTTP tests (CfT API and Playwright CDN) are skipped on CI to
avoid flaky failures from network issues. They run locally to catch
API contract changes. Removed misleading "arm64 only" from comment —
these tests validate platform-independent code.
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.

Chrome Headless improvements

1 participant