Skip to content
Handbook navigation

Testing docs in CI

Automated checks for style, links and code samples so docs stay correct.

1 min read

Documentation rots when nobody notices it breaking. Automated checks make breakage visible at the moment it's cheapest to fix.

The four checks#

CheckToolCatches
StyleValePassive voice, banned words, inconsistent terms
StructuremarkdownlintSkipped headings, missing alt text, bad fences
LinkslycheeBroken internal and external links
SamplesCustom runnerCode that no longer works

A minimal workflow#

.github/workflows/docs.yml
name: docs
on: [pull_request]

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: errata-ai/vale-action@reviewdog
        with:
          files: docs
      - run: npx markdownlint-cli2 "docs/**/*.md"
      - uses: lycheeverse/lychee-action@v2
        with:
          args: --offline docs

Test the code samples#

Extract fenced blocks from the Markdown and run them against a sandbox. A snippet that returns an error fails the build with the file and line number.

scripts/test-snippets.ts
import { readFileSync } from "node:fs";
import { globSync } from "node:fs";

for (const file of globSync("docs/**/*.md")) {
  const source = readFileSync(file, "utf8");
  for (const match of source.matchAll(/```(?:js|ts)[^\n]*\n([\s\S]*?)```/g)) {
    await runInSandbox(match[1], file);
  }
}

Start small#

Turn on link checking first. It has the best signal-to-noise ratio. Add Vale with a short rule set next, and only promote a rule from warning to error once the backlog is clean.