-
Notifications
You must be signed in to change notification settings - Fork 8
120 lines (115 loc) · 6.24 KB
/
Copy pathchecks.yml
File metadata and controls
120 lines (115 loc) · 6.24 KB
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
name: Run Checks
on:
workflow_dispatch:
# `staging` is this repo's default branch and the one the deploy
# workflow publishes from, so that is what PRs target. Checking only
# PRs into `main` meant this never ran.
#
# Pushes are deliberately not listed: tbdocs-gh-pages.yml already
# builds and checks on every push to `staging` before it deploys, so a
# push trigger here would duplicate that work. This workflow's job is
# to catch the breakage BEFORE the merge.
pull_request:
branches: [ staging, main ]
# No `paths:` filter. It used to be `docs/**`, which skipped any PR that
# touched only builder/ or scripts/ -- exactly the code most able to break
# the build, the link checker, or asset vendoring. The whole run is a couple
# of minutes, so filtering buys little and silently drops real coverage.
# Check-only job: it never deploys, so it needs no Pages or OIDC rights.
permissions:
contents: read
# Must NOT share the deploy workflow's "pages" group -- that made PR checks
# queue against production deployments. Keyed per PR, and superseded runs are
# cancelled when new commits arrive.
concurrency:
group: checks-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
# Build job
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version: '22'
cache: 'npm'
cache-dependency-path: package-lock.json
- name: Install dependencies
run: npm ci
# check_a11y.mjs drives axe-core inside headless Chromium. The
# build itself needs no browser -- only this scan does.
# fonts-liberation is installed explicitly, not incidentally. axe's
# target-size rule measures rendered boxes, and an inline element's
# measured height is its font's content area -- so the 24px floor is
# cleared or missed depending on what system-ui resolves to. At the
# mobile h3 size: Segoe UI 19px, Verdana and Tahoma 17px, Arial 16px,
# Liberation Sans / DejaVu Sans / Roboto 15px. The site's padding is
# calibrated against the smallest of those, so the runner has to have
# it. ubuntu-latest migrates to Ubuntu 26 on 19 October 2026; pinning
# the image would also work and expires differently, while this
# addresses the actual variable.
- name: Install Liberation fonts
run: sudo apt-get install -y --no-install-recommends fonts-liberation
- name: Install Chromium
# Same incantation as tbdocs-gh-pages.yml's install step, which
# is the proven-working one in this repo: --install-deps apt-installs
# the shared libraries Chromium needs, which requires root.
run: sudo npx puppeteer browsers install chrome --install-deps
- name: Build and check links with tbdocs
# --no-fetch-assets: CI must never download a referenced image. An
# author who wrote the markdown but forgot to commit the file would
# otherwise get a green build while the published site went on
# hotlinking a third party. A missing asset is a hard failure here,
# naming the file to commit. ($CI already implies this; the flag
# states it.) See builder/vendor-assets.mjs.
#
# --check runs the link and site-integrity check over the HTML the
# build already holds in worker memory, instead of writing three
# trees out and reading ~270 MB of them back through
# scripts/check_links.mjs. Same findings -- that equivalence is
# gated by scripts/check_links_diff.mjs, run by hand when either
# front end changes. Do NOT also add a check_links.mjs pass
# over _site/: it would check the same bytes a second time.
#
# --check-audit-index adds the index audit on top: a diff of the
# tree index the build derives from its own records against what
# landed on disk. It is the one direction the findings comparison
# cannot see -- a spurious entry makes the oracle answer "exists"
# for a path that 404s in production, and on a clean site nothing
# links to a path that does not exist, so nothing else would
# notice. CI lost its previous coverage of this when the FsOracle
# pass was removed.
#
# It covers all three trees: _site/ (links, fragments, duplicate
# ids, well-formedness, remote <img src>, sitemap, search index,
# canonical URLs), _site-offline/ (the same minus sitemap and
# search, plus the forbidden-prefix rule that catches live-site
# links the offline rewrite missed), and _site-pdf/book.html
# (informational). A failing check never aborts the build -- a
# broken link still produces a site worth inspecting -- so the
# step fails on the exit code: 1 for link failures, 2 for
# integrity failures, 3 for both.
run: node builder/tbdocs.mjs --src docs --no-fetch-assets --check-audit-index
# The gates both workflows run, in one list: see
# .github/actions/run-gates/action.yml, which check_ci_workflows.mjs
# checks against test.bat and check.bat. Each gate is its own group in
# this step's log.
- name: Run the gates
uses: ./.github/actions/run-gates
# The action's first step compares the standalone link checker's two
# front ends over a hand-written tree. This one compares the script
# against the BUILD's own checker, over a three-page tree the build
# produces from test/fixtures/check-src. That is the pass the harness
# exists for and the one nothing exercised: `--b fused` skipped the
# synthetic `fixture` case every time, because the build cannot check a
# tree it did not write. A regression in builder/check.mjs that stopped
# REPORTING a category would have left every gate green.
#
# One extra three-page build, ~1 s. It is here and not in the deploy
# workflow because this is the PR gate: catching it before a merge is
# the point, and the deploy workflow has a site to ship.
- name: Verify the build's own link checker (check_links_diff.mjs)
run: node scripts/check_links_diff.mjs --case fixture-built --case fixture-built-offline --a script --b fused