Run it in CI¶
Run the check on every merge request, with no path filter. On the phpboyscout
toolchain that is the docs-verify component:
include:
- component: gitlab.com/phpboyscout/cicd/docs-verify@v0.57.1
inputs:
image: golang:1.27
command: "go test ./... -run TestDocumentedCommandsExist"
image and command are both required, because only your project knows what
the check needs on PATH. The component deliberately has no change-detection
input, for the reason below. Pin whichever release is current; v0.57.1 is the
one this example was checked against.
The check is an ordinary Go test, so it runs wherever your Go tests run. That is also the trap.
The trap: your Go tests do not run on a docs-only change¶
Most pipelines gate the Go suite on change detection, since there is no value in running tests for a typo. That is correct, and it means a documentation check living in the Go suite is skipped by exactly the merge requests that change documentation.
Here is what actually ran on one merge request that fixed three broken documentation pages:
security sbom, lockfile-lint, audit-signatures, retire, npm-audit,
semgrep, analyze, osv-scanner, gitleaks, trivy, govulncheck
pages zensical-build
No Go test job. The guard would have sat in the suite looking green while never running.
Make it run on both kinds of change¶
A documentation claim breaks in two directions, and each defeats a different gate:
| How it breaks | Source-gated job | Docs-gated job |
|---|---|---|
| A docs change describes something that does not exist | never runs | catches it |
| A code change invalidates a page nobody touched | catches it | never runs |
So gating on either path alone misses half of it. Run the check unconditionally
on every merge request. The
docs-verify component does exactly
that. Elsewhere, the equivalent is a job with no changes:/path filter at all.
Fail loudly when the check cannot run¶
New returns an error for a tree with no name or no subcommands, and Walk
returns ErrNoFiles when no file matched its patterns. Do not treat these as
"nothing to check". A guard that has lost its input has verified nothing, and
must not report success. The example test uses t.Fatal for exactly this.
The invocation count in the report serves the same purpose: files scanned with zero invocations resolved usually means the tool name is wrong, not that the documentation is clean.