Skip to content

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

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

Deprecate chromium installer, add arm64 Linux support for chrome-headless-shell#14334
cderv wants to merge 28 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.

Chromium is marked as "Chromium (deprecated)" in the tool registry. Help text examples for chromium have been removed from install/update/uninstall commands. The tool will be removed entirely from the registry in v1.11.

When chrome-headless-shell is installed (via any path — direct install, redirect, or binder scripts), the afterInstall hook automatically detects and removes any legacy chromium installation from quartoDataDir("chromium"). This ensures users don't accumulate orphaned files.

quarto check install shows a warning in the tools table when legacy chromium is detected, directing users to install chrome-headless-shell.

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.

Refactoring

Path and version utility functions (chromeHeadlessShellInstallDir, chromeHeadlessShellExecutablePath, readInstalledVersion, etc.) were extracted from chrome-headless-shell.ts into chrome-headless-shell-paths.ts to break a circular dependency: chrome-headless-shellchromiumpuppeteerchrome-headless-shell. The original module re-exports everything for backward compatibility.

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.

CI

New test-install.yml workflow:

  • test-install job: verifies chrome-headless-shell install on arm64 Linux and macOS
  • test-chromium-deprecation job: verifies the redirect behavior, deprecation warnings, and clean quarto check output across all platforms (Ubuntu, arm64, macOS, Windows)

Runs on push to src/tools/**, on PRs, and weekly to detect upstream CDN/API breakage.

Test Plan

  • quarto install chromium --no-prompt shows deprecation warning, installs chrome-headless-shell
  • quarto update tool chromium --no-prompt shows deprecation warning, redirects
  • quarto check install shows "Chrome Headless Shell" after redirect, no "outdated" warning
  • 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 (16 tests passing)
  • CI workflow passes on all platforms

Closes #11877
Fixes #9710

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.
@cderv
Copy link
Copy Markdown
Collaborator Author

cderv commented Apr 8, 2026

As this is driven by security measure - I decide to work on a backport version for 1.9 that brings this too.

@cderv
Copy link
Copy Markdown
Collaborator Author

cderv commented Apr 8, 2026

I am missing quarto check update and a few user workflow

@cderv cderv marked this pull request as draft April 8, 2026 13:08
…ency

Move path/version utility functions from chrome-headless-shell.ts into
chrome-headless-shell-paths.ts so puppeteer.ts can import them without
creating a cycle (chrome-headless-shell → chromium → puppeteer →
chrome-headless-shell). The original module re-exports everything for
backward compatibility.
cderv added a commit that referenced this pull request Apr 8, 2026
* Add CI workflow for tool install on arm64 Linux and macOS

Integration test for quarto install tinytex and chrome-headless-shell on
platforms not covered by smoke tests (arm64 Linux, macOS). Path-filtered
to src/tools/** with weekly schedule for upstream breakage detection.

Also add test-install.yml to paths-ignore in test-smokes-parallel.yml
and test-ff-matrix.yml so changes to the new workflow don't trigger
unrelated test suites.

* Skip chrome-headless-shell install on arm64 until #14334 lands
cderv added a commit that referenced this pull request Apr 8, 2026
* Add CI workflow for tool install on arm64 Linux and macOS

Integration test for quarto install tinytex and chrome-headless-shell on
platforms not covered by smoke tests (arm64 Linux, macOS). Path-filtered
to src/tools/** with weekly schedule for upstream breakage detection.

Also add test-install.yml to paths-ignore in test-smokes-parallel.yml
and test-ff-matrix.yml so changes to the new workflow don't trigger
unrelated test suites.

* Skip chrome-headless-shell install on arm64 until #14334 lands
Port test-install.yml from v1.9 backport, adapted for v1.10 redirect
behavior. Tests chrome-headless-shell install on arm64 Linux and macOS,
and verifies the chromium deprecation redirect across all platforms.

Also adds tools-table warning in quarto check install when legacy
Chromium (deprecated) is detected.
cderv and others added 8 commits April 8, 2026 17:23
Port improvements from v1.9 backport PR:
- Use exit code instead of grep for install success detection
- Use grep -Fq with specific strings for deprecation checks
- Fix unit tests to use chromeHeadlessShellBinaryName() for arm64
  Playwright CDN binary layout compatibility
- Add tools-table warning in quarto check for Chromium (deprecated)
The tools-table warning already tells users to install chrome-headless-shell
when legacy chromium is detected. No need for a second NOTE in the Chrome
Headless section.
Tests now import path utilities directly from chrome-headless-shell-paths.ts.
No other consumer needs the re-export.
@cderv cderv marked this pull request as ready for review April 8, 2026 16:30
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 Wrong chromium installed on linux arm64

1 participant