Skip to content

♻️ refactor(clean): compile the sanitizer's policy in C #2175

♻️ refactor(clean): compile the sanitizer's policy in C

♻️ refactor(clean): compile the sanitizer's policy in C #2175

Workflow file for this run

name: 🛠️ check
on:
workflow_dispatch:
push:
branches: ["main"]
tags-ignore: ["**"]
pull_request:
schedule:
- cron: "0 8 * * *"
concurrency:
group: check-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
test:
name: 🧪 ${{ matrix.py }} - ${{ matrix.label }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
# The C-coverage gate runs where gcov/llvm-cov exist; on Windows the same
# suite runs without it (MSVC has no gcov), gated natively in tox.toml.
os: ["ubuntu-24.04", "macos-15", "windows-2025"]
py: ["3.15", "3.14", "3.13", "3.12", "3.11", "3.10", "3.15t", "3.14t"]
include:
- {os: "ubuntu-24.04", label: Linux, cov: "gcov"}
- {os: "macos-15", label: macOS, cov: "xcrun llvm-cov gcov"}
- {os: "windows-2025", label: Windows, cov: ""}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- name: ⬇️ Install test data
run: git submodule update --init tests/html5lib-tests tests/conformance/unicodetools
- name: 🟢 Install Node
# zizmor: ignore[cache-poisoning] no cache: input is set, so setup-node writes no restorable cache
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: "22"
- name: 🔄 Install uv
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
with:
enable-cache: false
- name: ✅ Run ${{ matrix.py }}
run: uvx --with tox-uv tox run --skip-missing-interpreters false -e ${{ matrix.py }}
env:
UV_PYTHON_PREFERENCE: only-managed
COV_GCOV: ${{ matrix.cov }}
pypy:
# PyPy stands outside the test matrix because it runs no coverage gate: gcovr reaches cpyext only through lxml,
# which publishes no PyPy wheels, and a cpyext build has no gcov to feed it. Both gates run on the matrix above.
name: 🧪 ${{ matrix.py }} - Linux
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
py: ["pypy3.11", "pypy3.10"]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- name: ⬇️ Install test data
run: git submodule update --init tests/html5lib-tests tests/conformance/unicodetools
- name: 🟢 Install Node
# zizmor: ignore[cache-poisoning] no cache: input is set, so setup-node writes no restorable cache
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: "22"
- name: 🔄 Install uv
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
with:
enable-cache: false
- name: ✅ Run ${{ matrix.py }}
run: uvx --with tox-uv tox run --skip-missing-interpreters false -e ${{ matrix.py }}
env:
UV_PYTHON_PREFERENCE: only-managed
check:
name: 🔎 ${{ matrix.tox_env }}
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
tox_env: ["type", "docs", "pkg_meta"]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- name: 🔄 Install uv
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
with:
enable-cache: false
- name: ✅ Run ${{ matrix.tox_env }}
run: uvx --with tox-uv tox run -e ${{ matrix.tox_env }}
env:
UV_PYTHON_PREFERENCE: only-managed
conformance:
name: 🔬 conformance
runs-on: ubuntu-24.04
# The tests/conformance/ suites validate each feature against a competitor's or standards body's OWN test suite,
# vendored as pinned submodules under tests/conformance/<oracle> (libxml2, unicodetools, xml-conformance-suite,
# qt3tests, parse5, DOMPurify, ...) and/or a Node oracle in tools/bench/node (jsdom, DOMPurify, parse5). They must
# RUN with those oracles present: a suite whose submodule is absent errors instead of skipping, which is the whole
# point of this job. The normal matrix deselects tests/conformance (tox --ignore) so it never runs an oracle suite
# without the oracle. This is a pass/fail correctness gate, not a coverage gate -- the 100% line/branch gate stays
# on the matrix (env_run_base), deliberately not bolted on here.
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0 # meson project() derives the version from git history
submodules: recursive # every conformance oracle plus the html5lib-tests data; shallow submodules init here too
persist-credentials: false
- name: 🟢 Install Node
# zizmor: ignore[cache-poisoning] no cache: input is set, so setup-node writes no restorable cache
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: "22"
- name: 📦 Install the Node oracle deps (jsdom, DOMPurify, parse5)
run: npm ci
working-directory: tools/bench/node
- name: 🔄 Install uv
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
with:
enable-cache: false
- name: ✅ Run the conformance suites
run: uvx --with tox-uv tox run -e conformance
env:
UV_PYTHON_PREFERENCE: only-managed
warnings:
name: 🚨 -Werror (${{ matrix.label }})
runs-on: ${{ matrix.os }}
# compile the C extension with -Werror so any compiler warning fails the build. The
# warning set differs per compiler (gcc flags fall-through clang does not) and the SIMD
# helpers are #if-gated per architecture (SSE2 on x86, NEON on arm64), so the gate is a
# compiler x SIMD-path grid: gcc and clang each over x86 and arm64. MSVC is a separate
# job below because it is detected without CC. macOS gcc is omitted as redundant with
# Linux gcc arm64 — same compiler, same NEON path, and the OS does not change the warnings.
strategy:
fail-fast: false
matrix:
include:
- {os: "ubuntu-24.04", cc: "gcc", label: "gcc · Linux x64"}
- {os: "ubuntu-24.04", cc: "clang", label: "clang · Linux x64"}
- {os: "ubuntu-24.04-arm", cc: "gcc", label: "gcc · Linux arm64"}
- {os: "macos-15", cc: "clang", label: "clang · macOS arm64"}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0 # meson project() derives the version from git history
persist-credentials: false
- name: 🔄 Install uv
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
with:
enable-cache: false
- name: ✅ Build with -Werror
run: uvx --with tox-uv tox run -e warnings
env:
UV_PYTHON_PREFERENCE: only-managed
CC: ${{ matrix.cc }}
warnings-msvc:
name: 🚨 -Werror (${{ matrix.label }})
runs-on: ${{ matrix.os }}
# MSVC is detected by meson without a CC override and maps -Werror to /WX; split from the matrix
# above so an empty CC env never shadows the auto-detection. x64 builds the SSE2 branch; on
# windows-11-arm meson does not self-detect MSVC, so that cell installs an arm64 dev Python and
# activates the native arm64 toolchain with msvc-dev-cmd (its INCLUDE/LIB ride through tox via
# pass_env), giving MSVC coverage of the _M_ARM64 NEON branch too.
strategy:
fail-fast: false
matrix:
include:
- {os: "windows-2025", label: "MSVC · Windows x64", arm: false}
- {os: "windows-11-arm", label: "MSVC · Windows arm64", arm: true}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0 # meson project() derives the version from git history
persist-credentials: false
- name: 🐍 Install arm64 dev Python (carries the .lib meson needs)
if: matrix.arm
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.13"
architecture: arm64
- name: 🧰 Activate native arm64 MSVC (so meson picks cl over MinGW gcc)
if: matrix.arm
uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1
with:
arch: arm64
- name: 🔄 Install uv
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
with:
enable-cache: false
- name: ✅ Build with -Werror
run: uvx --with tox-uv tox run -e warnings
env:
UV_PYTHON_PREFERENCE: ${{ matrix.arm && 'only-system' || 'only-managed' }}
clang-tidy:
name: 🧹 clang-tidy (${{ matrix.arch }})
runs-on: ${{ matrix.os }}
# the clang-tidy pre-commit hook needs a local Meson build of the C extension, so it
# is skipped on pre-commit.ci; run it here where the toolchain and headers are available.
# both architectures run because the SIMD escape/scan helpers are #if-gated — x86 compiles
# the SSE2 variant, arm64 the NEON one — and clang-tidy only analyzes the branch it builds.
strategy:
fail-fast: false
matrix:
include:
- {os: "ubuntu-24.04", arch: "x64"}
- {os: "ubuntu-24.04-arm", arch: "arm64"}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0 # meson project() derives the version from git history
persist-credentials: false
- name: 🔄 Install uv
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
with:
enable-cache: false
- name: ✅ Run clang-tidy
run: uvx pre-commit run clang-tidy --all-files --show-diff-on-failure --color always
env:
UV_PYTHON_PREFERENCE: only-managed
tsan:
name: 🧵 ThreadSanitizer
runs-on: ubuntu-24.04
# prebuilt no-GIL CPython compiled with --with-thread-sanitizer; building one is slow and fiddly
container:
image: ghcr.io/nascheme/cpython-tsan:3.14t
options: --shm-size=2g # TSan shadow memory needs the headroom
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- name: 🔄 Install uv
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
with:
enable-cache: false
- name: ✅ Run tsan
run: uvx --with tox-uv tox run -e tsan
env:
UV_PYTHON_PREFERENCE: only-system # use the container's TSan interpreter, not a uv-managed one