From 8df3faf9794521d8e652eb63db2a7e6be8dddf16 Mon Sep 17 00:00:00 2001 From: Niek Otten Date: Thu, 10 Sep 2026 11:02:52 +0200 Subject: [PATCH] test(docs): fail when a page under docs/ is missing from the nav (refs #169) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only the pages listed in mkdocs.yml's nav are published, and mkdocs' own `omitted_files: warn` keeps the build green while dropping the rest — so nothing ever said that the site had quietly stopped at ADR-0010 and runbooks/ci.md. Runs in `make lint` (python3 only, no new tooling), so it gates every PR through the existing job. Red: 31 pages are missing — ADR-0011 through ADR-0034, six of the seven runbooks, and synthetic-data.md. --- Makefile | 3 +++ infra/check-docs-nav.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100755 infra/check-docs-nav.py diff --git a/Makefile b/Makefile index 56141f6..83cd9d9 100644 --- a/Makefile +++ b/Makefile @@ -64,6 +64,9 @@ frontend: ## lint: verify formatting (no changes) lint: dotnet format $(SLN) --verify-no-changes + # Only pages in mkdocs.yml's nav are published, and mkdocs keeps a build green + # when one is missing — so the nav is checked here rather than not at all. + python3 infra/check-docs-nav.py ## build: release build build: diff --git a/infra/check-docs-nav.py b/infra/check-docs-nav.py new file mode 100755 index 0000000..ef51803 --- /dev/null +++ b/infra/check-docs-nav.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 +"""Fail when a page under docs/ is missing from mkdocs.yml's nav. + +docs/ is the source of truth (CLAUDE.md §12), but only the pages listed in the nav +are published — and mkdocs' own `omitted_files: warn` keeps a build green while +silently dropping them, which is how every ADR after 0010 and every runbook but +ci.md fell off the site. + +ponytail: a substring test, not a YAML parse — a page's path either appears in +mkdocs.yml or it doesn't, and that needs no dependency. +""" + +import sys +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +nav = (ROOT / "mkdocs.yml").read_text() + +missing = sorted( + str(page.relative_to(ROOT / "docs")) + for page in (ROOT / "docs").rglob("*.md") + if str(page.relative_to(ROOT / "docs")) not in nav +) + +if missing: + print(f"{len(missing)} page(s) under docs/ are not in mkdocs.yml's nav:") + print("\n".join(f" {m}" for m in missing)) + sys.exit(1) + +print("docs nav complete: every page under docs/ is published")