Merge pull request #124 from berkeleydb/docs/phase4-final #5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Documentation validation. | |
| # | |
| # Builds the modernized docs (docs-src/build.py: Markdown -> HTML + man + PDF) | |
| # and runs the validators that lock in the reverse-DocBook migration's | |
| # guarantees. Modeled on ci.yml/fuzz.yml conventions: hard gates block PRs, | |
| # advisory tiers are continue-on-error, and heavy work (PDF/TeX-free but slow, | |
| # external link check) is scheduled-only or best-effort so per-PR jobs stay | |
| # fast. | |
| # | |
| # Tooling comes from the flake dev shell (nix develop) so CI matches local | |
| # exactly -- pandoc, weasyprint, poppler-utils, mandoc, codespell, lychee and | |
| # write-good are all pinned there. | |
| # | |
| # HARD gates (fail the PR): build (HTML+man), no-loss, completeness, spelling, | |
| # internal link-check, man-lint. | |
| # ADVISORY (continue-on-error): prose (write-good), external link-check. | |
| # BEST-EFFORT (scheduled / continue-on-error): PDF build + validation (slow). | |
| name: Docs | |
| on: | |
| push: | |
| branches: [master] | |
| pull_request: | |
| paths: | |
| - 'docs-src/**' | |
| - '.github/workflows/docs.yml' | |
| - 'flake.nix' | |
| - 'dist/RELEASE' | |
| workflow_dispatch: | |
| schedule: | |
| # Weekly (Mon 05:23 UTC): the full run including the slow PDF build and the | |
| # external link check, which are best-effort/skipped on per-PR runs. | |
| - cron: '23 5 * * 1' | |
| concurrency: | |
| group: docs-${{ github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| jobs: | |
| # ---------------------------------------------------------------------------- | |
| # Build HTML + man (fast, always) and run the hard gates that depend on the | |
| # generated output. PDF is built here only on schedule/dispatch (see the | |
| # `pdf` job) so a PR isn't gated on the ~4-minute weasyprint pass. | |
| # ---------------------------------------------------------------------------- | |
| build: | |
| name: build + gates (html, man, no-loss, completeness, spelling, links, man-lint) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Nix (flakes enabled) | |
| uses: cachix/install-nix-action@v27 | |
| with: | |
| extra_nix_config: | | |
| experimental-features = nix-command flakes | |
| # 1. BUILD (hard): HTML + man with 0 errors. --no-pdf keeps the PR fast; | |
| # the PDF path is exercised by the `pdf` job (scheduled/best-effort). | |
| - name: Build HTML + man | |
| run: nix develop --command bash -c 'cd docs-src && python3 build.py --no-pdf' | |
| # build.py self-check guards the md->man reshape, PDF book discovery, and | |
| # the .md->.html link rewrite (unit-level, no external tools). | |
| - name: build.py self-check | |
| run: nix develop --command bash -c 'cd docs-src && python3 build.py --selfcheck' | |
| # 2. NO-LOSS GATE (hard): every migrated tree still retains its source | |
| # content (word-multiset retention + no code/section drop). Locks the | |
| # "nothing lost" guarantee against future edits. | |
| - name: No-loss gate (all trees) | |
| run: nix develop --command bash -c 'python3 docs-src/_migrate/verify_all.py' | |
| # 3. COMPLETENESS GATE (hard): every public db.h function is documented | |
| # (28/28), and every uncovered method is on the frozen allowlist -- a | |
| # NEW undocumented API fails. | |
| - name: Completeness gate (API coverage) | |
| run: nix develop --command bash -c 'python3 docs-src/_migrate/man_coverage.py --ci' | |
| # 4. SPELLING (hard on NEW typos): codespell, baselined against the legacy | |
| # typo backlog so only newly-introduced typos fail. | |
| - name: Spelling gate (codespell, baselined) | |
| run: nix develop --command bash -c 'python3 docs-src/_migrate/spellcheck.py' | |
| # 6. INTERNAL LINK CHECK (hard): every link into migrated content must | |
| # resolve. Deferred-tree + un-migrated-asset links are excluded (see | |
| # docs-src/_migrate/lychee.toml). External links are the advisory job. | |
| - name: Internal link check (lychee, offline) | |
| run: | | |
| nix develop --command bash -c \ | |
| 'shopt -s globstar; lychee --offline --config docs-src/_migrate/lychee.toml --no-progress "docs-build/html/**/*.html"' | |
| # 7. MAN-LINT (hard): 0 ERRORS from mandoc across every generated .3 | |
| # (STYLE/WARNING are fine). | |
| - name: Man-lint (mandoc -Tlint, 0 ERRORS) | |
| run: | | |
| nix develop --command bash -c ' | |
| e=0 | |
| for f in docs-build/man/man3/*.3; do | |
| if mandoc -Tlint "$f" 2>&1 | grep -q "ERROR"; then | |
| echo "ERRORS in $f:"; mandoc -Tlint "$f" 2>&1 | grep "ERROR" | head -3 | |
| e=$((e+1)) | |
| fi | |
| done | |
| echo "man pages with ERRORs: $e" | |
| test "$e" -eq 0' | |
| # ---------------------------------------------------------------------------- | |
| # 5. PROSE (advisory): write-good passive-voice / wordiness counts. This is | |
| # decades-old technical prose -- surface the numbers, never gate. | |
| # ---------------------------------------------------------------------------- | |
| prose: | |
| name: prose advisory (write-good) | |
| runs-on: ubuntu-latest | |
| continue-on-error: true | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Nix (flakes enabled) | |
| uses: cachix/install-nix-action@v27 | |
| with: | |
| extra_nix_config: | | |
| experimental-features = nix-command flakes | |
| - name: write-good suggestion counts (per tree) | |
| run: | | |
| nix develop --command bash -c ' | |
| shopt -s globstar | |
| total=0 | |
| for d in docs-src/api/* docs-src/guides/*; do | |
| [ -d "$d" ] || continue | |
| n=$(write-good "$d"/**/*.md 2>/dev/null | grep -c "on line" || true) | |
| printf "%-40s %5s suggestions\n" "$d" "$n" | |
| total=$((total+n)) | |
| done | |
| echo "::notice title=Prose (write-good)::$total advisory suggestion(s) across docs-src"' | |
| # ---------------------------------------------------------------------------- | |
| # PDF (best-effort / scheduled): weasyprint renders one PDF per book (~4 min | |
| # over all 13). Not a per-PR gate -- runs on schedule/dispatch, or on a PR | |
| # that touches build.py's PDF path. continue-on-error so a rendering hiccup | |
| # informs without blocking. | |
| # ---------------------------------------------------------------------------- | |
| pdf: | |
| name: pdf build + validate (best-effort) | |
| runs-on: ubuntu-latest | |
| continue-on-error: true | |
| if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.event_name == 'push' | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Nix (flakes enabled) | |
| uses: cachix/install-nix-action@v27 | |
| with: | |
| extra_nix_config: | | |
| experimental-features = nix-command flakes | |
| - name: Build all outputs (incl. PDF) | |
| run: nix develop --command bash -c 'cd docs-src && timeout 900 python3 build.py' | |
| - name: Validate PDFs (non-empty, page count, title-page version) | |
| run: nix develop --command bash -c 'python3 docs-src/_migrate/validate_pdf.py' | |
| - name: Upload PDFs | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: docs-pdf | |
| path: docs-build/pdf/*.pdf | |
| if-no-files-found: ignore | |
| # ---------------------------------------------------------------------------- | |
| # External link check (advisory / scheduled): lychee WITH network, so it | |
| # depends on the reachability of third-party sites. Never gates; scheduled | |
| # and dispatch only so PRs don't wait on the network. | |
| # ---------------------------------------------------------------------------- | |
| external-links: | |
| name: external link check (advisory) | |
| runs-on: ubuntu-latest | |
| continue-on-error: true | |
| if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Nix (flakes enabled) | |
| uses: cachix/install-nix-action@v27 | |
| with: | |
| extra_nix_config: | | |
| experimental-features = nix-command flakes | |
| - name: Build HTML | |
| run: nix develop --command bash -c 'cd docs-src && python3 build.py --no-pdf' | |
| - name: Check external links (network, advisory) | |
| run: | | |
| nix develop --command bash -c ' | |
| shopt -s globstar | |
| lychee --no-progress --scheme http --scheme https \ | |
| --exclude "localhost" --max-concurrency 8 \ | |
| "docs-build/html/**/*.html" || true' |