CI Validation
Run cmdocs check locally and in CI so broken docs never reach main.
CI Validation
cmdocs check is a fast, deterministic lint that catches the mistakes most likely to break your docs site. Run it locally before committing, wire it into a pre-commit hook, and run it in CI on every pull request — broken docs should never survive the path to main.
What it checks
| Check | Example failure |
|---|---|
| docs.json schema | name is required, Expected hex color (#RRGGBB), unknown field |
| Duplicate tab paths | Two tabs both resolve to the same URL segment — hard error |
| Duplicate page files | The same MDX file listed under two groups |
| Navigation → MDX | Missing MDX: guides/setup.mdx (referenced in "Documentation" > "Guides") |
| MDX frontmatter | Missing frontmatter "title" in: quickstart.mdx |
| Assets | Missing logo: public/logo/dark.svg |
| Internal links | Broken link in index.mdx:42: "/documentation/missing-page" |
Exit code 0 means you're clean. Exit code 1 prints every failure with a file and line number.
The three places to run it
- Locally while authoring — fastest feedback loop.
- Pre-commit hook — prevents broken commits from ever reaching the remote.
- CI on pull requests — blocks merges even if someone skipped the pre-commit hook.
Run it locally
npx @cmdoss/cmdocs checkPoint at a specific source directory if your docs aren't at the repo root:
npx @cmdoss/cmdocs check --source ./docsSample output
All checks pass:
ℹ Checking docs.json...
✓ Loaded "My Documentation"
ℹ Checking navigation references...
ℹ Checking MDX frontmatter...
ℹ Checking assets...
ℹ Checking internal links...
✓ All checks passedBroken link caught:
ℹ Checking internal links...
✖ Broken link in guides/writing-content.mdx:42: "/documentation/missing-page"
✖ 1 error foundPre-commit hook
Block bad commits before they happen. Pick whichever style fits your project.
Zero dependencies — just a shell script. Create .git/hooks/pre-commit:
#!/usr/bin/env bash
npx @cmdoss/cmdocs checkMake it executable:
chmod +x .git/hooks/pre-commit.git/hooks/ isn't tracked by git. For hooks that travel with the repo, use a folder like .githooks/ and point git at it:
git config core.hooksPath .githooksIf your project already uses Husky, add cmdocs check to the pre-commit hook:
npx husky init
echo 'npx @cmdoss/cmdocs check' >> .husky/pre-commitCommit .husky/pre-commit — every contributor who runs npm install gets the hook automatically.
For large repos where you only want to validate when docs-related files changed, combine with lint-staged:
{
"lint-staged": {
"**/*.{mdx,json}": "npx @cmdoss/cmdocs check"
}
}Then in .husky/pre-commit:
npx lint-stagedcmdocs check typically runs in well under a second. Keep it in pre-commit — it's faster than running a type-checker and catches a different class of errors.
Pre-push hook (alternative)
Some teams prefer to validate only at push time, not on every commit. Create .git/hooks/pre-push (or .githooks/pre-push):
#!/usr/bin/env bash
npx @cmdoss/cmdocs checkPre-commit gives faster feedback; pre-push is lighter-weight when authors make many small commits.
CI on pull requests
GitHub Actions
name: Docs
on:
pull_request:
paths:
- "**/*.mdx"
- "docs.json"
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npx @cmdoss/cmdocs checkFor a monorepo with docs under apps/docs/:
- run: npx @cmdoss/cmdocs check --source apps/docsGitLab CI
docs-check:
image: node:20
script:
- npx @cmdoss/cmdocs check
rules:
- changes:
- "**/*.mdx"
- "docs.json"Other CI providers
The pattern is identical on any CI platform: install Node 20, run npx @cmdoss/cmdocs check, let the exit code gate the merge.
What happens if I skip it?
The cmdocs dashboard's build worker runs the same validation before building — if your docs.json is broken or pages are missing, the dashboard build fails and the deployment never goes live. CI just catches this earlier, before it consumes dashboard build minutes and before a broken commit sits on main.
Troubleshooting
What's next
How is this guide?