docs-verify¶
Runs a project's own documentation check on every merge request, so a documented claim cannot go stale unnoticed.
include:
- component: gitlab.com/phpboyscout/cicd/[email protected]
inputs:
image: registry.gitlab.com/phpboyscout/images/dev-tools:v0.3.4
command: "go run ./cmd/mytool docs verify"
What problem this solves¶
Every other quality component is change-detected against code paths. That is correct — there is no point running Go tests on a docs-only merge request — but it leaves documentation with no gate at all.
go-test and go-lint both default to:
["**/*.go", "**/go.mod", "**/go.sum", ".golangci.*",
".gitlab-ci.yml", "CHANGELOG.md", "**/CHANGELOG.md"]
Neither covers a docs tree. On the krites merge request that fixed three stale
pages, the jobs that ran were the security set and zensical-build — no
go-test, no golangci-lint. A check sitting in the Go suite would have looked
green while never running.
Why there is no changes input¶
Gating this on documentation paths is the obvious design, and it is wrong — it would have missed the failure this exists for.
krites documented a command form that had errored since the command gained subcommands a fortnight earlier. The docs did not change and go stale; the code changed and left the docs behind.
| the merge request that… | touches | a docs-path filter would |
|---|---|---|
| broke the docs | code only | skip the check — the failure ships |
| fixed the docs | docs only | run it, after the fact |
A docs-path filter runs the check exactly when the documentation is already correct, and skips the merge requests that break it. It inverts the value.
So this component is always-on, like svelte-security, and offers no
changes input. Not offering one is deliberate: an input exists to be set, and
the plausible-looking value is the one that reintroduces the hole. The self-test
asserts the input's absence structurally, so adding it fails the pipeline rather
than being noticed a fortnight later.
Jobs¶
| Job | When |
|---|---|
docs-verify |
Every merge request (override with if). Rename with job_name. |
Inputs¶
| Input | Type | Default | Description |
|---|---|---|---|
image |
string | (required) | Image the check runs in. No default — the check invokes your tool, so only you know what must be on PATH. |
command |
string | (required) | The verification, e.g. go run ./cmd/mytool docs verify. No default: the check is project-specific by nature, and a default would be a guess at somebody else's documentation. |
stage |
string | test |
Stage to assign the job to. Declare it in your stages:. |
job_name |
string | docs-verify |
Rename the job. Use it to include the component more than once — one instance per documented surface — without a name collision. |
extra_before_script |
string | "" |
Shell run before the check: fetch a schema, generate a manpage, install the tool under test. |
allow_failure |
string | "false" |
Whether findings fail the pipeline. See below. |
if |
string | '$CI_PIPELINE_SOURCE == "merge_request_event"' |
Gating expression. There is deliberately no changes filter. |
The component owns the shape, not the check¶
The check needs your command tree, config schema or flag set, so it cannot live
here. The component supplies the always-runs guarantee, the job shape, the image
and the stage; you supply what "verified" means — the same split as
svelte-lint taking svelte_check_args rather than owning the linter's
opinion.
Your tool's output reaches the log verbatim — no wrapping, capture or reformatting. A docs checker's value is in which claim is wrong and where, and summarising that to pass/fail throws away the part you need.
Adopting against an existing docs tree¶
allow_failure defaults to false, because a gate that cannot fail is a report
— see spec 0060
for what a component that silently does nothing costs.
If you are adopting the check against documentation with a known backlog, set
allow_failure: "true" so the gate can land before the backlog is cleared and
the findings stay visible meanwhile — then flip it back.