Skip to content

Commit 6f84bb5

Browse files
authored
Deprecate chromium installer, add arm64 Linux support for chrome-headless-shell (#14334)
Deprecate `quarto install chromium` in favor of `chrome-headless-shell`. The chromium command now prints a deprecation warning and transparently redirects to chrome-headless-shell, preserving `--no-prompt` for CI pipelines. The `afterInstall` hook automatically removes any legacy chromium installation when chrome-headless-shell is installed. Add arm64 Linux support for `quarto install chrome-headless-shell` using Microsoft's Playwright CDN as the download source, since Chrome for Testing has no arm64 Linux builds. The arm64 binary name difference (`headless_shell` vs `chrome-headless-shell`) is abstracted by a platform-aware helper. - Chromium marked "(deprecated)" in tool registry, removed from help text examples; full removal planned for v1.11 - `quarto check install` warns when legacy chromium is detected - Binder post-build scripts use chrome-headless-shell instead of chromium - Path/version utilities extracted to chrome-headless-shell-paths.ts to break a circular dependency - New `test-install.yml` CI workflow for arm64 install and chromium deprecation across all platforms Closes #11877 Fixes #9710
1 parent 4b3bf72 commit 6f84bb5

File tree

17 files changed

+505
-128
lines changed

17 files changed

+505
-128
lines changed

.github/workflows/test-install.yml

Lines changed: 100 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,109 @@ jobs:
4343
quarto install tinytex
4444
4545
- name: Install Chrome Headless Shell
46-
# arm64 Linux support requires #14334. Remove this condition once merged.
47-
if: runner.arch != 'ARM64'
4846
run: |
4947
quarto install chrome-headless-shell --no-prompt
5048
5149
- name: Verify tools with quarto check
5250
run: |
5351
quarto check install
52+
53+
test-chromium-deprecation:
54+
name: Chromium deprecation redirect (${{ matrix.os }})
55+
strategy:
56+
fail-fast: false
57+
matrix:
58+
os: [ubuntu-latest, ubuntu-24.04-arm, macos-latest, windows-latest]
59+
runs-on: ${{ matrix.os }}
60+
steps:
61+
- name: Checkout Repo
62+
uses: actions/checkout@v6
63+
64+
- uses: ./.github/workflows/actions/quarto-dev
65+
66+
- name: Make quarto available in bash (Windows)
67+
if: runner.os == 'Windows'
68+
shell: bash
69+
run: |
70+
quarto_cmd=$(command -v quarto.cmd)
71+
dir=$(dirname "$quarto_cmd")
72+
printf '#!/bin/bash\nexec "%s" "$@"\n' "$quarto_cmd" > "$dir/quarto"
73+
chmod +x "$dir/quarto"
74+
75+
- name: Install chromium (should redirect to chrome-headless-shell)
76+
id: install-chromium
77+
shell: bash
78+
run: |
79+
set +e
80+
output=$(quarto install chromium --no-prompt 2>&1)
81+
exit_code=$?
82+
set -e
83+
echo "$output"
84+
if echo "$output" | grep -Fq "is deprecated"; then
85+
echo "deprecation-warning=true" >> "$GITHUB_OUTPUT"
86+
fi
87+
if [ "$exit_code" -eq 0 ]; then
88+
echo "install-successful=true" >> "$GITHUB_OUTPUT"
89+
fi
90+
91+
- name: Assert deprecation warning was shown
92+
shell: bash
93+
run: |
94+
if [ "${{ steps.install-chromium.outputs.deprecation-warning }}" != "true" ]; then
95+
echo "::error::Deprecation warning missing from 'quarto install chromium' output"
96+
exit 1
97+
fi
98+
echo "Install deprecation warning found"
99+
100+
- name: Assert installation succeeded (via redirect)
101+
shell: bash
102+
run: |
103+
if [ "${{ steps.install-chromium.outputs.install-successful }}" != "true" ]; then
104+
echo "::error::Installation did not succeed — redirect to chrome-headless-shell may have failed"
105+
exit 1
106+
fi
107+
echo "Installation succeeded via redirect"
108+
109+
- name: Verify quarto check shows Chrome Headless Shell
110+
shell: bash
111+
run: |
112+
output=$(quarto check install 2>&1)
113+
echo "$output"
114+
if ! echo "$output" | grep -Fq "Chrome Headless Shell"; then
115+
echo "::error::Chrome Headless Shell not detected by quarto check after redirect install"
116+
exit 1
117+
fi
118+
if echo "$output" | grep -Fq 'chrome-headless-shell" to replace'; then
119+
echo "::error::Legacy Chromium still installed — afterInstall should have removed it"
120+
exit 1
121+
fi
122+
123+
- name: Update chromium (should redirect) and capture result
124+
id: update-chromium
125+
shell: bash
126+
run: |
127+
set +e
128+
output=$(quarto update tool chromium --no-prompt 2>&1)
129+
exit_code=$?
130+
set -e
131+
echo "$output"
132+
if echo "$output" | grep -Fq "is deprecated"; then
133+
echo "deprecation-warning=true" >> "$GITHUB_OUTPUT"
134+
fi
135+
if [ "$exit_code" -eq 0 ]; then
136+
echo "update-successful=true" >> "$GITHUB_OUTPUT"
137+
fi
138+
139+
- name: Assert update deprecation warning was shown and succeeded
140+
shell: bash
141+
run: |
142+
if [ "${{ steps.update-chromium.outputs.deprecation-warning }}" != "true" ]; then
143+
echo "::error::Deprecation warning missing from 'quarto update tool chromium' output"
144+
exit 1
145+
fi
146+
echo "Update deprecation warning found"
147+
if [ "${{ steps.update-chromium.outputs.update-successful }}" != "true" ]; then
148+
echo "::error::Update command failed — redirect to chrome-headless-shell may have failed"
149+
exit 1
150+
fi
151+
echo "Update succeeded via redirect"

news/changelog-1.10.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,15 @@ All changes included in 1.10:
1919

2020
- ([#14281](https://github.com/quarto-dev/quarto-cli/issues/14281)): Avoid creating a duplicate `.quarto_ipynb` file on preview startup for single-file Jupyter documents.
2121

22+
### `install`
23+
24+
- ([#11877](https://github.com/quarto-dev/quarto-cli/issues/11877), [#9710](https://github.com/quarto-dev/quarto-cli/issues/9710)): Add arm64 Linux support for `quarto install chrome-headless-shell` using Playwright CDN as download source, since Chrome for Testing has no arm64 Linux builds.
25+
- ([#11877](https://github.com/quarto-dev/quarto-cli/issues/11877)): Deprecate `quarto install chromium` — the command now transparently redirects to `chrome-headless-shell`. Installing `chrome-headless-shell` automatically removes any legacy Chromium installation. Use `chrome-headless-shell` instead, which always installs the latest stable Chrome (the legacy `chromium` installer pins an outdated Puppeteer revision that cannot receive security updates).
26+
27+
### `check`
28+
29+
- ([#11877](https://github.com/quarto-dev/quarto-cli/issues/11877)): `quarto check install` now shows a deprecation warning when legacy Chromium (installed via `quarto install chromium`) is detected, directing users to install `chrome-headless-shell` as a replacement.
30+
2231
### `quarto create`
2332

2433
- ([#14250](https://github.com/quarto-dev/quarto-cli/issues/14250)): Fix `quarto create` producing read-only files when Quarto is installed via system packages (e.g., `.deb`). Files copied from installed resources now have user-write permission ensured.

src/command/check/check.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,11 @@ async function checkInstall(conf: CheckConfiguration) {
364364
toolsJson[tool.name] = {
365365
version,
366366
};
367+
if (tool.name === "Chromium (deprecated)") {
368+
toolsOutput.push(
369+
`${kIndent} (Run "quarto install chrome-headless-shell" to replace)`,
370+
);
371+
}
367372
}
368373
for (const tool of tools.notInstalled) {
369374
toolsOutput.push(`${kIndent}${tool.name}: (not installed)`);

src/command/install/cmd.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,6 @@ export const installCommand = new Command()
4646
"Install Chrome Headless Shell",
4747
"quarto install chrome-headless-shell",
4848
)
49-
.example(
50-
"Install Chromium (legacy)",
51-
"quarto install chromium",
52-
)
5349
.example(
5450
"Choose tool to install",
5551
"quarto install",

src/command/uninstall/cmd.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,6 @@ export const uninstallCommand = new Command()
3737
"Uninstall Chrome Headless Shell",
3838
"quarto uninstall chrome-headless-shell",
3939
)
40-
.example(
41-
"Uninstall Chromium (legacy)",
42-
"quarto uninstall chromium",
43-
)
4440
.action(
4541
async (
4642
options: { prompt?: boolean; updatePath?: boolean },

src/command/update/cmd.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,6 @@ export const updateCommand = new Command()
5151
"Update Chrome Headless Shell",
5252
"quarto update tool chrome-headless-shell",
5353
)
54-
.example(
55-
"Update Chromium (legacy)",
56-
"quarto update tool chromium",
57-
)
5854
.example(
5955
"Choose tool to update",
6056
"quarto update tool",

src/command/use/commands/binder/binder.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -223,12 +223,14 @@ const createPostBuild = (
223223
postBuildScript.push(msg("Installed TinyTex"));
224224
}
225225

226-
// Maybe install Chromium
226+
// Maybe install Chrome Headless Shell for mermaid/graphviz rendering.
227+
// Note: quartoConfig.chromium comes from QuartoTool type which uses "chromium"
228+
// as a generic signal meaning "needs a headless browser", not the install command.
227229
if (quartoConfig.chromium) {
228-
postBuildScript.push(msg("Installing Chromium"));
229-
postBuildScript.push("# install chromium");
230-
postBuildScript.push("quarto install chromium --no-prompt");
231-
postBuildScript.push(msg("Installed Chromium"));
230+
postBuildScript.push(msg("Installing Chrome Headless Shell"));
231+
postBuildScript.push("# install chrome-headless-shell");
232+
postBuildScript.push("quarto install chrome-headless-shell --no-prompt");
233+
postBuildScript.push(msg("Installed Chrome Headless Shell"));
232234
}
233235

234236
if (vscodeConfig.version) {

src/core/puppeteer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
chromeHeadlessShellExecutablePath,
1717
chromeHeadlessShellInstallDir,
1818
readInstalledVersion,
19-
} from "../tools/impl/chrome-headless-shell.ts";
19+
} from "../tools/impl/chrome-headless-shell-paths.ts";
2020

2121
// deno-lint-ignore no-explicit-any
2222
// let puppeteerImport: any = undefined;

0 commit comments

Comments
 (0)