Skip to content

docs: generate the command reference from the cobra tree - #71

Merged
yutkin merged 6 commits into
mainfrom
docs/generated-command-reference
Nov 10, 2026
Merged

yutkin merged 6 commits into
mainfrom
docs/generated-command-reference

Conversation

@yutkin

@yutkin yutkin commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

How to review

Review the commits in order. Commits 1–5 change code, tests and CI (+998 −13). Commit 6 contains only generated docs (+3,426 −174).

  1. Read the release.yml diff. Check that the docs step runs before the commit and tag step.
  2. Read docgen.go together with docgen_test.go. The tests show the expected output.
  3. Read isolateEnv in cmd/gen-docs/main.go. It isolates the generator from the real config directory.
  4. Open docs/reference/vm.md. Compare it with verda vm --help from v1.10.0.
  5. Skip the other generated pages. The same code renders all pages.

Summary

docs/commands.md was hand-written and did not match the CLI. Nine top-level commands had no entry: container, doctor, mcp, object-storage, registry, skills, status, template and version. This PR generates the command reference from the cobra command tree, and regenerates it at each release, so the docs on GitHub match the released binary, not unreleased code on main.

release.yml (workflow_dispatch, vX.Y.Z)
  make changelog VERSION=vX.Y.Z
  make docs VERSION=vX.Y.Z        # new; fails before anything is tagged or pushed
    cmd/gen-docs                  # builds the root command with VERDA_* cleared
      docgen.Generate
        docs/commands.md          # index: same groups and order as verda --help
        docs/reference/<cmd>.md   # usage, aliases, flags, examples
                                  # every page: "> Verda CLI **vX.Y.Z** · [other versions](…/tags)" under the title
  git add CHANGELOG.md docs/commands.md; git add -A docs/reference
  commit "chore(release): update changelog and command docs for vX.Y.Z [skip ci]", tag, push
  goreleaser
 docs/
-├── commands.md              # hand-written
+├── commands.md              # generated index
+├── reference/               # generated, one page per top-level command
+└── guides/
+    ├── authentication.md    # hand-written: environment variables
+    └── scripting.md         # hand-written: --output, --wait, --agent
+.gitattributes               # marks the generated files as generated
+cmd/gen-docs/                # make docs VERSION=vX.Y.Z (required)
Before After
Source Text copied by hand from --help Use, Short, Long, Example and flags of each command
Coverage Nine top-level commands missing 90 index rows, 23 reference pages
Freshness Drifted silently Regenerated in the release commit; each tag's docs/ matches its code
Version Not stated Named under the title of every page
Contributor step Edit the Markdown by hand None: PRs leave the generated files alone

CommandGroups.Add also registers cobra groups and a declaration rank, so the index keeps the verda --help order. The verda --help output does not change. Hidden and deprecated commands are not in the docs.

The generator stays exercised between releases: TestRun (in make test, so in CI) builds the docs from the real command tree twice, each with a fresh temp home, and fails on generator errors (including ANSI escapes) or help text derived from the home directory.

Evidence

  • Every generated page starts like this (docs/reference/vm.md):

    # verda vm
    
    > Verda CLI **v1.10.0** · [other versions](https://github.com/verda-cloud/verda-cli/tags)
  • make docs without VERSION → VERSION is required. Usage: make docs VERSION=v1.0.0. A malformed version (latest, 1.2.3) fails and writes nothing.

  • The committed docs are generated from the v1.10.0 sources with this generator (the generator files copied onto git archive v1.10.0), so they describe the binary users have installed. Help-text changes on main since v1.10.0, such as the auth precedence text, appear at the next release.

  • TestRun, TestRun_RejectsBadVersion, TestGenerate_EveryPageNamesVersion and TestGenerate_RejectsBadVersion pass.

  • verda --help on this branch and on main gives the same bytes.

  • make build, make test, make lint and make fix.check pass.

  • The release workflow change cannot run outside a real release. Reviewed by hand: the docs step runs before the commit/tag step, and the rulesets on main have no path rules, so the release commit can carry docs/ as it already carries CHANGELOG.md.

Merge Danger

Door: two-way

A revert removes the generator and the release step and puts back the hand-written file.

Blast Radius: release

The release job gains one step before tagging. If make docs fails, the release stops before anything is committed, tagged or pushed. Between releases the docs lag main on purpose: they describe the latest release, which their version line names.

🤖 Generated with Claude Code

@yutkin
yutkin marked this pull request as draft November 5, 2026 14:40
@yutkin
yutkin force-pushed the docs/generated-command-reference branch 3 times, most recently from 20076a2 to b0dacc9 Compare November 9, 2026 14:19
yutkin and others added 6 commits November 10, 2026 10:52
docs/commands.md was hand-written and had drifted from the CLI: container,
registry, object-storage, template, mcp, skills, status, doctor, version,
the vm shortcuts and volume delete were missing. Instead of copying more
text from --help and the per-command READMEs, render it from the command
definitions themselves.

- cmd/gen-docs + internal/verda-cli/docgen write docs/commands.md (index
  grouped as in verda --help, with beta tags) and docs/reference/<cmd>.md
  (usage, aliases, flags, examples). Hidden and deprecated commands are
  skipped; output is deterministic (no dates, VERDA_* env stripped).
- CommandGroups.Add also registers native cobra groups and a declaration
  rank, so the index keeps the group order, titles and command order of
  verda --help (cobra sorts Commands() in place). verda --help output is
  unchanged.
- make docs regenerates; make docs.check fails when stale. A new Docs
  workflow (no paths-ignore) and the pre-commit hook run the check.
- .gitattributes marks the generated files linguist-generated.
- The env-var table moves to docs/guides/authentication.md and the
  scripting sections to docs/guides/scripting.md. The credential order
  stays only in verda auth --help, which docs/reference/auth.md renders.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- gen-docs builds the command tree under a throwaway HOME and VERDA_HOME
  that is removed after the run, instead of a fixed /home/user path.
- docgen filters inherited flags by identity, so a group flag that
  shadows a global flag of the same name is listed, not dropped.
- cmdutil.TagSuffix builds the " (beta)" suffix for both the root help
  and the generated docs.
- The pre-commit hook runs make docs.check once, before the Go checks.
- docgen uses one textLang constant for text fences.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The docs on main described unreleased commands and flags, because every PR
had to regenerate them. The release job now runs `make docs VERSION=vX.Y.Z`
before it commits the changelog and tags, so each tag carries docs that
match its code. docs/commands.md names the release it matches.

- release.yml: generate docs, commit them with the changelog (`git add -A`
  on docs/reference drops pages of removed commands)
- gen-docs: -version flag (vX.Y.Z), stamped into the index intro
- drop the docs.yml workflow, `make docs.check` and the pre-commit docs gate
- TestRun builds the docs from the real command tree in `make test`, twice,
  so a generator failure or environment-derived help text shows up in CI
- contributor docs: generated files stay out of PRs; `make docs` is a preview

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Committed command docs come only from the release job, which always has
a version, so the version is now required: gen-docs rejects a missing or
malformed -version and `make docs` requires VERSION, like `make changelog`.
Every page carries the version under its title, since readers often land
on a reference page directly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- auth guide: the published auth page is the v1.10.0 text, which lists a
  shorter order without config.yaml; say so instead of claiming the guide
  and the page match
- scripting guide: point "reference page" at the index that links them
- gen-docs: drop the -out flag; only `docs` was ever passed
- tests: reuse IndexFile/ReferenceDir, let generate() take a root, merge
  the two determinism tests, drop an ANSI check Generate already does

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Output of `make docs VERSION=v1.10.0` with this branch's generator run on
the v1.10.0 sources (generator files copied onto `git archive v1.10.0`).
The pages describe the installed v1.10.0, not main. Help-text changes made
on main since v1.10.0 appear at the next release. No hand edits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@yutkin
yutkin force-pushed the docs/generated-command-reference branch from c6ff905 to 1648d4d Compare November 10, 2026 08:53
@yutkin
yutkin marked this pull request as ready for review November 10, 2026 08:54
@yutkin
yutkin merged commit 66960cf into main Nov 10, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants