Doc CI¶
The portal's static checks (markdown lint, link check, terminology scan, TBD scan) don't live in docs/ — they live in tools/docs/ at the repo root, alongside the GitHub Actions pipeline at .github/workflows/docs-ci.yml. This README is the doc-side forward-pointer.
Convention: tooling sits next to other repo tooling under
tools/, not insidedocs/. This page exists so the reader who clicks a[Doc CI]link from inside the portal lands somewhere — not so docs duplicates the script docs.
What runs and when¶
CI workflow: .github/workflows/docs-ci.yml. Triggers on push to main and on every pull_request that touches docs/**, tools/docs/**, or the workflow itself. Four jobs run in parallel; a fifth summary job aggregates the artifacts into the GitHub step summary.
| Job | Tool | Blocking? | Catches |
|---|---|---|---|
mdlint |
tools/docs/mdlint.sh (markdownlint-cli2 + Python fallback) |
yes | Heading hierarchy, single H1, ATX style, fenced-block spacing |
link-check |
tools/docs/check-links.sh |
yes | Broken relative paths; URL HEADs (skipped in CI by default) |
terminology |
tools/docs/check-terminology.sh |
warn-only | Canonical spellings from ../STYLE.md §6 (OTel, BullMQ, p95, …) |
tbd-scan |
tools/docs/find-tbd.sh |
XXX-only | {{TBD}} (info), TBD/TODO/FIXME (warn), XXX (error) |
Each tool — when it fails, what to do¶
The full per-tool reference is in tools/docs/README.md. Short version:
mdlint.sh— read the rule code (e.g.MD025= single H1) and fix the heading. To genuinely need an exception, wrap the offending lines in a<!-- markdownlint-disable MDxxx -->/<!-- markdownlint-enable MDxxx -->pair with a justifying comment.check-links.sh— the file moved, was never written, or you spelled the path wrong. Search the portal — most often the doc you meant to link is one directory over.check-terminology.sh(warn-only today) — replace the variant with the canonical spelling. Quoting an upstream proper noun? Wrap in inline backticks; the scrubber skips fenced/inline code automatically.find-tbd.sh—XXXalways fails the build. Convert to{{TBD: …}}if the work is deferred; the portal uses one marker on purpose so the count is meaningful.
Per-line escapes for false positives:
| Annotation | Effect |
|---|---|
<!-- skip-link-check --> |
check-links.sh ignores links on this line |
<!-- skip-terminology --> |
check-terminology.sh ignores this line |
<!-- skip-tbd --> |
find-tbd.sh ignores this line |
<!-- markdownlint-disable MDxxx --> … <!-- markdownlint-enable MDxxx --> |
markdownlint-cli2 block escape |
Local pre-commit hook¶
Three lines in .git/hooks/pre-commit:
Make it executable:
run-all.sh is the same combined runner the CI summary job uses; passing locally is a strong predictor of passing in CI. Network HEADs are slow — EBIT_DOCS_NET_LINKS=0 ./tools/docs/run-all.sh docs/ matches CI exactly.
Adding a new check¶
- Drop a script under
tools/docs/<check-name>.sh. Mirror the conventions in the existing scripts: takes$1as the docs dir (defaultdocs), exits non-zero on failure, prints one finding per line inpath:line: messageformat. - Add a job to
.github/workflows/docs-ci.ymlfollowing the existing four-job shape (actions/checkout→ run script → upload artifact). For warn-only checks, setcontinue-on-error: true. - Add a row to the table in
tools/docs/README.md§"What each check does" plus the "When a check fails" section. - If the check enforces a STYLE.md rule, add (or update) the canonical row in
../STYLE.md§6. - If the check needs a per-line escape, add
<!-- skip-<name> -->handling and document it under §"Skip annotations" intools/docs/README.md.
Pre-flight before running¶
The 4 jobs assume:
python3is on$PATH(stdlib only; nopip install).markdownlint-cli2is available (CI installsmarkdownlint-cli2@0.13.0vianpm); locally,mdlint.shfalls back to a Python checker if it's missing.- The repo is checked out at the path shape the workflow expects —
docs/lives at the repo root. Thetools/docs/README.md§"Integration target" section discusses the standalone-repo vs in-product-repo home choice.
Cross-references¶
tools/docs/README.md— full per-script reference and dependency matrix.github/workflows/docs-ci.yml— the GitHub Actions workflow../STYLE.md§6 — canonical terminology thatcheck-terminology.shenforces../STYLE.md§7 —{{TBD}}marker convention thatfind-tbd.shenforces../README.md— portal entrypoint that links here../audits/PORTAL-AUDIT.md— manual audit procedure that complements (and will eventually be replaced by) this CI