1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
name: CI
on:
push:
branches:
pull_request:
jobs:
check:
# Pinned, not `ubuntu-latest`. The suite now launches a real browser, so the image is
# part of the contract: `ubuntu-latest` moved from 22.04 to 24.04 under existing
# workflows once already, and 26.04 is in public preview. A surprise image change would
# arrive as a browser failure in an unrelated PR.
runs-on: ubuntu-24.04
# A wedged browser used to be able to burn the full 6h default. The CDP call deadline
# makes that unlikely; this makes it impossible.
timeout-minutes: 30
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@1.95.0
- run: cargo check
- run: cargo clippy -- -D warnings
# The browser tests skip themselves when Chrome is missing, and a skip is a pass.
# Assert Chrome exists here so that a runner image that drops it fails the build
# instead of silently turning ~57 of 68 tests into no-ops.
- name: Require a real browser for the test run
run: |
if ! command -v google-chrome >/dev/null && ! command -v chromium >/dev/null; then
echo "::error::No Chrome on this runner. The browser tests would skip themselves and report green."
exit 1
fi
google-chrome --version || chromium --version
# Ubuntu 23.10+ blocks unprivileged user namespaces through AppArmor, which is
# what Chrome's sandbox uses. The google-chrome .deb ships a profile that grants
# it, so the system Chrome we launch is expected to work — this lifts the
# restriction anyway, because the alternative if it ever does bite is passing
# --no-sandbox, and weakening the sandbox for every user of the tool to keep CI
# green is the wrong trade. Failure to set it is not fatal.
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 || true
# Prove the browser actually launches before spending the suite on finding out.
google-chrome --headless=new --disable-gpu --dump-dom about:blank >/dev/null
# vendor/extract.js has its own jsdom suite (120+ tests) that nothing used to run —
# not cargo test, not CI. tests/js_suite_tests.rs runs it now, but only if jsdom is
# installed; without this step it would skip, and under CHROME_AGENT_REQUIRE_CHROME
# that skip is fatal. Installing it here is what makes the extraction engine gated.
# `npm ci`, with no `|| npm install` fallback: the fallback would regenerate the
# lockfile on the fly and let a drifted package.json pass green, which is the
# failure this whole pass keeps closing elsewhere. A lockfile that no longer
# satisfies package.json is a commit somebody forgot to make, not a hiccup.
- name: Install the extraction suite's dependencies
run: npm ci --prefix tests/js
- run: cargo test -- --test-threads=1
env:
# Turns every "SKIP: …" into a failure. See tests/common/mod.rs.
CHROME_AGENT_REQUIRE_CHROME: 1
# Linux release binaries are fully static musl builds (issue #3). That only works
# while the dependency graph stays pure Rust — a C-linking crate (TLS/crypto backend)
# would reintroduce a glibc dependency. Fail fast if one sneaks back in.
- name: Guard pure-Rust dependency graph
run: |
for c in ring openssl-sys aws-lc-sys; do
if cargo tree -i "$c" >/dev/null 2>&1; then
echo "::error::Crate '$c' pulls in C code and breaks fully-static musl Linux builds (issue #3). Use a pure-Rust alternative or disable the offending feature."
exit 1
fi
done
echo "Dependency graph is pure Rust — static musl Linux builds stay portable."