DOC-2220: comprehensive rpk documentation automation system#203
Conversation
✅ Deploy Preview for docs-extensions-and-macros ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughThis PR implements a comprehensive Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
✨ Finishing Touches🧪 Generate unit tests (beta)
|
There was a problem hiding this comment.
Actionable comments posted: 16
🧹 Nitpick comments (10)
__tests__/docs-data/overrides.json (1)
2-2: ⚡ Quick winUse the checked-in schema path for this fixture too.
Like the production override file, this should validate against the schema in the current branch, not whatever is on
mainat the time an editor opens it. A local$schemapath avoids that drift and removes the network dependency.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@__tests__/docs-data/overrides.json` at line 2, The fixture's "$schema" currently points to the remote main-branch URL; update the "$schema" value in __tests__/docs-data/overrides.json to the checked-in local schema path used by the production override file (replace the full GitHub raw URL with the repository-relative schema path used elsewhere) so the test fixture validates against the branch-local schema and removes the network dependency.docs-data/property-overrides.json (1)
2-2: ⚡ Quick winPrefer a repo-local
$schemareference here.Pointing at
mainmeans editor validation can drift from the schema in this branch until the PR merges, and it breaks offline validation. Matching the local-path pattern used bydocs-data/rpk-overrides.jsonkeeps the file tied to the checked-in schema.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs-data/property-overrides.json` at line 2, The $schema property currently points at the remote "main" URL; change it to the repo-local schema reference pattern used elsewhere (e.g., mirror the local-path style used in rpk-overrides) so editor/CI use the checked-in schema; update the "$schema" value in docs-data/property-overrides.json to reference the local property-overrides.schema.json file in the repo instead of the raw GitHub main URL.tools/rpk-docs/validate-overrides.js (2)
217-291: 💤 Low valueConsider adding a maximum depth limit for reference resolution.
The reference validation doesn't impose a maximum depth limit when traversing nested structures. While circular references are now prevented (after applying the cycle detection fix), deeply nested legitimate structures could still cause performance issues or very long validation times.
🛡️ Optional depth limit
- const checkObject = (obj, context = '') => { + const MAX_DEPTH = 100 + const checkObject = (obj, context = '', depth = 0) => { if (!obj || typeof obj !== 'object') return + if (depth > MAX_DEPTH) { + result.addWarning(`Maximum reference depth (${MAX_DEPTH}) exceeded`, context) + return + } // Detect cycles if (visited.has(obj)) return visited.add(obj) if (Array.isArray(obj)) { - obj.forEach((item, i) => checkObject(item, `${context}[${i}]`)) + obj.forEach((item, i) => checkObject(item, `${context}[${i}]`, depth + 1)) return } // ... rest of function with depth + 1 in recursive calls🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tools/rpk-docs/validate-overrides.js` around lines 217 - 291, The validateReferences function should enforce a maximum traversal depth to avoid pathological deep recursion: introduce a MAX_DEPTH constant and thread a depth counter through checkObject, checkRef and checkRefs (e.g., add a depth parameter defaulting to 0), increment it on each recursive descent, and if depth > MAX_DEPTH call result.addError(...) and stop traversing that branch; update checkObject to pass depth+1 into nested checkObject calls and checkRefs to pass depth into checkRef calls so deep or maliciously nested structures yield a clear error instead of unbounded work.
465-470: ⚡ Quick winImprove HTML entity detection regex to reduce false positives.
The pattern
&[a-z]+;will match regular text containing&followed by lowercase letters and a semicolon anywhere in the string (e.g., "Jane & John; the end" would trigger a false positive). Consider making the pattern more restrictive to match only known HTML entity names.♻️ Improved regex
// Check for HTML entities that should have been decoded - if (desc.match(/&`#x`[0-9a-fA-F]+;|&#\d+;|&[a-z]+;/)) { + if (desc.match(/&`#x`[0-9a-fA-F]+;|&#\d+;|&[a-zA-Z]{2,10};/)) { result.addWarning( `Description may contain unescaped HTML entities`, descContext ) }This version:
- Includes uppercase letters (e.g.,
≠)- Limits entity name length to 2-10 characters (most HTML entities fall in this range)
- Reduces false positives from
&in prose🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tools/rpk-docs/validate-overrides.js` around lines 465 - 470, The entity-detection regex used in the desc.match(...) check is too permissive; update the pattern in that match call (the branch that currently uses &[a-z]+;) to only detect named HTML entities by allowing both uppercase and lowercase letters and restricting the entity name length (e.g., 2–10 characters) while keeping the existing hex (&`#x`...) and decimal (&#...) branches; leave the call to result.addWarning(...) and descContext untouched.__tests__/docs-data/property-overrides.json (1)
2-2: ⚡ Quick winConsider using a relative file path instead of a GitHub raw URL for the test schema reference.
The
$schemafield points to the GitHub raw URL on themainbranch. For test files, consider using a relative file path (e.g.,"../../docs-data/schemas/property-overrides.schema.json") to ensure tests validate against the schema version in the current working tree rather than whatever is on GitHub main. This prevents test failures if the schema changes upstream before the code is merged.📋 Recommended change
- "$schema": "https://raw.githubusercontent.com/redpanda-data/docs-extensions-and-macros/main/docs-data/schemas/property-overrides.schema.json", + "$schema": "../../docs-data/schemas/property-overrides.schema.json",🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@__tests__/docs-data/property-overrides.json` at line 2, Update the "$schema" field in property-overrides.json to use a relative path instead of the GitHub raw URL: replace the current "https://raw.githubusercontent.com/..." value with a repository-relative path such as "../../docs-data/schemas/property-overrides.schema.json" so tests validate against the local schema in the working tree.__tests__/tools/rpk-docs/validate-overrides.test.js (1)
466-489: ⚡ Quick winStrengthen the integration assertion.
This test exercises the full
validateOverridespipeline but only asserts thatwarnings/errorsare defined, which holds for virtually anyValidationResult. A composition regression (e.g., a sub-validator dropped from the aggregate) would not be caught. Consider asserting the expected outcome for this valid override (result.valid === true) and that no errors are reported.♻️ Suggested assertion
const result = validateOverrides(overrides) - // Should pass schema validation if schema file exists - // and pass all other validations - expect(result.warnings).toBeDefined() - expect(result.errors).toBeDefined() + expect(result.errors).toBeDefined() + expect(result.warnings).toBeDefined() + expect(result.valid).toBe(true) + expect(result.errors).toHaveLength(0)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@__tests__/tools/rpk-docs/validate-overrides.test.js` around lines 466 - 489, The test currently only asserts that result.warnings and result.errors are defined, which is too weak; update the assertions in the 'should run all validations' test to assert the expected successful outcome from validateOverrides: check that result.valid === true and that no errors are reported (e.g. expect(result.errors).toHaveLength(0) or expect(result.errors).toEqual([])); you can still assert warnings exist if desired, but ensure the primary assertions reference validateOverrides and result.valid to catch regressions in the validation pipeline.tools/rpk-docs/rpk-docs-handler.js (2)
214-253: 💤 Low valueRemove unnecessary async keyword.
Line 214 declares
downloadRpkBinaryas async, but the function only uses synchronous operations (spawnSync,fs.mkdtempSync,fs.chmodSync). The async keyword is misleading and unnecessary.♻️ Proposed fix
-async function downloadRpkBinary(version, platform = null, arch = null) { +function downloadRpkBinary(version, platform = null, arch = null) { platform = platform || (os.platform() === 'darwin' ? 'darwin' : 'linux')🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tools/rpk-docs/rpk-docs-handler.js` around lines 214 - 253, The function declaration for downloadRpkBinary should drop the unnecessary async keyword because it only performs synchronous operations (fs.mkdtempSync, spawnSync, fs.chmodSync) and does not use await; update the declaration to a plain function (remove "async" from the downloadRpkBinary definition) and ensure callers still treat its return as a direct string path (no awaited promise).
483-493: 💤 Low valueConsider pinning golang image version for reproducibility.
Line 487 uses
golang:1which will pull the latest Go 1.x version. This can lead to non-reproducible builds if Go releases a new minor version that changes build behavior or introduces bugs. For production automation, consider pinning to a specific version likegolang:1.23or using the same Go version that Redpanda's CI uses.💡 Optional: Pin to specific Go version
// Use golang image to build and run rpk from source inside Linux // Mount the source directory as read-only - // Use golang:1 (latest 1.x) to get a recent stable Go version + // Use golang:1.23 for reproducible builds const result = spawnSync('docker', [ 'run', '--rm', '-v', `${absoluteSourcePath}:/rpk-source:ro`, '-w', '/rpk-source', - 'golang:1', + 'golang:1.23', 'go', 'run', 'cmd/rpk/main.go', '--print-tree' ], {🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tools/rpk-docs/rpk-docs-handler.js` around lines 483 - 493, The Docker image used in the spawnSync call (the array passed to spawnSync that currently contains 'golang:1') is unpinned and should be fixed to a specific Go version for reproducible builds; update the image string (used in the same spawnSync invocation that assigns to result) to a concrete tag such as 'golang:1.23' or read the tag from a configurable env var (e.g., DOCKER_GO_VERSION) so the command arguments become deterministic and configurable..github/workflows/update-rpk-docs.yml (1)
50-50: ⚖️ Poor tradeoffConsider pinning actions to commit hashes.
Lines 50, 55, 129, 134, and 207 use mutable tag references (
@v4,@v6) for GitHub Actions. While tag pinning is common practice, pinning to specific commit hashes provides stronger security guarantees against tag manipulation. This is a defense-in-depth measure.For this internal automation workflow with trusted standard actions, the current tag-based approach is acceptable. If moving to hash pinning, use Dependabot or Renovate to keep hashes updated automatically.
Also applies to: 55-55, 129-129, 134-134, 207-207
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/update-rpk-docs.yml at line 50, The workflow uses mutable action tags (e.g., actions/checkout@v4 and other actions referenced with `@v6`) which can be replaced with explicit commit SHAs to improve security; update each action usage (actions/checkout@v4, actions/setup-node@v6, and the other `@v4/`@v6 occurrences) to the corresponding full commit SHA for that action release, and if you want automatic updates configure Dependabot/Renovate to refresh those SHAs so the workflow stays current while remaining pinned.tools/rpk-docs/report-delta.js (1)
37-40: ⚡ Quick winHandle potential undefined flag names.
If a flag object lacks a
nameproperty, Line 39 will create a Map entry with keyundefined, which could cause multiple flags to overwrite each other if multiple flags are unnamed. While this is likely a data quality issue upstream, defensive handling would prevent silent data loss in diff results.♻️ Optional: Filter out invalid flags
function getFlagsMap(command) { const flags = command.flags || [] - return new Map(flags.map(f => [f.name, f])) + return new Map(flags.filter(f => f.name).map(f => [f.name, f])) }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tools/rpk-docs/report-delta.js` around lines 37 - 40, The getFlagsMap function can insert undefined keys when a flag lacks a name; update getFlagsMap to defensively skip or filter out flags without a truthy string name (e.g., check f && typeof f.name === 'string' && f.name.length) before mapping, and optionally log or collect/report invalid flag entries so unnamed flags don't overwrite each other in the returned Map; reference the getFlagsMap function and the flags/f.name check when implementing the fix.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/update-rpk-docs.yml:
- Around line 49-52: For the check-version job, update the Checkout step that
uses actions/checkout@v4 to explicitly set persist-credentials: false under its
with block (so the step keeps fetch-depth: 0 and adds persist-credentials:
false) to avoid exposing Git credentials; locate the Checkout step in the
check-version job and add the persist-credentials key with value false to the
existing with mapping.
- Around line 33-36: The workflow currently sets broad permissions at the
workflow level; change this to minimal workflow-level permissions and move the
needed scopes into the specific jobs: set the top-level permissions to the least
privilege (e.g., no write scopes), update the check-version job to use
permissions: contents: read, and add permissions: contents: write and
pull-requests: write to the generate-docs job; refer to the job names
generate-docs and check-version when updating the YAML so only generate-docs
gets write access.
- Around line 63-94: The script directly interpolates workflow inputs into shell
variables (TARGET_VERSION from inputs.version and any use of inputs.diff_from)
without validation; add strict validation/sanitization before using them: when
setting TARGET_VERSION (and any variable derived from inputs.diff_from) validate
with a semver regex (e.g., only digits and dots, optionally prefixed by "v") and
reject/exit (or normalize) on mismatch, strip any leading/trailing whitespace,
and remove/deny shell metacharacters (``;|&$<>``, backticks, newlines) so only
safe characters remain before writing to GITHUB_OUTPUT or using in commands;
update the logic around TARGET_VERSION assignment (and the place that reads
diff_from) to perform these checks and fail fast with a clear error when
validation fails.
In `@CLI_REFERENCE.adoc`:
- Line 667: Replace the incorrect expansion "Redpanda Keeper" for the term "rpk"
in the CLI introduction sentence and update it to "Redpanda CLI" (or leave as
"rpk") so the intro reads something like "rpk (Redpanda CLI)" or just "rpk";
ensure the single-line description that currently expands rpk to "Redpanda
Keeper" is changed wherever present in the CLI_REFERENCE.adoc intro paragraph
referencing rpk.
In `@docs-data/rpk-overrides.json`:
- Around line 149-196: The entries for "rpk cluster storage" and its subcommands
("rpk cluster storage mount", "rpk cluster storage unmount", "rpk cluster
storage cancel-mount", "rpk cluster storage list-mountable", "rpk cluster
storage list-mount", "rpk cluster storage status-mount") only add a cloud note
but still render in self-hosted docs; mark each of these command definitions as
cloud-only by adding cloudOnly: true (or the repo's equivalent exclusion flag)
to each of those objects instead of relying solely on cloudContent.after_header
so they are excluded from self-hosted documentation.
In `@docs-data/rpk-overrides.schema.json`:
- Around line 159-188: The nested override objects (e.g., the "includes" object
and the referenced "$defs/includeList") currently allow arbitrary keys so typos
pass validation; update the schema by adding "additionalProperties": false to
the "includes" object (alongside its "properties") and also add
"additionalProperties": false to the "$defs/includeList" definition (and any
other override object definitions referenced in the sections noted) so only the
listed keys like "after_header", "after_description", "after_usage",
"after_aliases", "after_flags", "after_examples", "before_see_also", and "end"
are permitted and typos will fail validation.
In `@tools/rpk-docs/file-preservations.js`:
- Around line 168-178: groupByLocation is missing a 'before-see-also' bucket and
the location normalization only replaces the first underscore so
'before_see_also' becomes 'before-see_alwo' (treated as unknown); update
groupByLocation to include a 'before-see-also' key and change the
location.replace('_','-') call to replace all underscores (use replaceAll or
replace(/_/g,'-')) so 'before_see_also' correctly maps to 'before-see-also';
apply the same fixes to the duplicate logic around lines 334-359 (the other
grouping/block-preservation function) to ensure consistent handling.
- Around line 52-67: The code initializes currentSection to 'after-header' which
causes preserved blocks after the rendered description to be categorized
incorrectly; change the initialization and/or header checks so the default
section before any "==" section is 'after-description' (or add an explicit check
for a '== Description' header) and update the section-transition logic that uses
currentSection (e.g., the variable currentSection and the header-detection block
that checks line.startsWith('== '), as well as the related logic in the
subsequent block around lines 69-107) so blocks between the description and the
first section are extracted as 'after-description' instead of 'after-header'.
- Around line 295-301: The current same-location check (using
sameLocationOverride from overridePreservations against filePres.type and
filePres.location) discards preserved includes even when the override targets a
different include path; change the logic so a same-location override only
suppresses a preserved include if it either targets the same include path
(compare sameLocationOverride.includePath === filePres.includePath) or is an
explicit conditional override (check for a condition flag like
sameLocationOverride.condition or similar); otherwise keep the preserved
include. Ensure you update the condition around sameLocationOverride to use
these checks and leave deduplication by includePath intact.
In `@tools/rpk-docs/generate-rpk-docs.js`:
- Around line 151-195: The $refs handling in resolveReferences currently gives
referenced objects precedence over local fields (merged starts from rest and
deepMerge(merged, resolved)), which inverts the desired override behavior used
by $ref; update the loop in resolveReferences so that for each ref you merge
with referenced data first and then local/previous merged data so local fields
win (e.g., use deepMerge(resolved, merged) or otherwise ensure merging order
yields { ...resolved, ...merged }), keeping the same visited/newVisited logic
and reusing the variables merged, rest, and resolved.
- Around line 935-965: Filter out excluded child commands before mapping to
subcommands: replace (command.commands || []).map(...) with (command.commands ||
[]).filter(child => { /* use the same exclusion predicate used earlier at lines
~903-907 */ }).map(...). Ensure the filter uses the identical exclusion
logic/identifier (e.g., the same excludedSet or predicate that checks the full
child path like `${commandPath} ${child.name}`) so that subcommands, xrefPath
generation and shortDesc (ensurePeriod, capToTwoSentences, formatDescription)
only run for children that will actually be generated.
In `@tools/rpk-docs/report-delta.js`:
- Around line 14-30: The flattenToMap function builds currentPath using
node.name but doesn't guard against missing or non-string names; add a defensive
check in flattenToMap to normalize node.name (e.g., treat undefined/null as
empty string or use a placeholder like '<unnamed>') before composing
currentPath, and ensure result.set uses that normalized value; update any logic
that relies on node.name in flattenToMap to handle the normalizedName so
malformed nodes don't produce "undefined" segments in paths.
- Around line 48-68: The JSON.stringify-based comparison in compareFlags
incorrectly reports changes for equivalent objects with different key orders;
replace that check with a proper deep equality check (e.g., use lodash.isEqual
or Node's util.isDeepStrictEqual) to compare oldFlag.default and
newFlag.default, ensuring you import the chosen helper and handle null/undefined
consistently; update the conditional in compareFlags to use that deep-equal
function and keep the rest of the changes logic identical.
- Around line 224-233: The code handling diff.details.newCommands should
defensively normalize cmd.description before slicing and checking length: ensure
cmd.description is coerced to a safe string (e.g., const desc = cmd.description
|| ''), derive shortDesc from desc.split('\n')[0] (or use a fallback ''), and
use desc.length (or shortDesc.length when appropriate) consistently when
deciding whether to append '...'; update the block that sets shortDesc and the
subsequent length check to use these safe variables (references:
diff.details.newCommands, cmd.description, shortDesc).
In `@tools/rpk-docs/validate-overrides.js`:
- Around line 217-291: validateReferences can infinite-recurse on cyclic
override objects; add cycle detection by introducing a visited WeakSet (e.g.,
const visited = new WeakSet()) and use it inside checkObject to skip
already-seen objects: at the start of checkObject return if visited.has(obj),
otherwise visited.add(obj) before recursing into its properties (you may remove
after recursion or rely on WeakSet semantics). Update checkObject (and any
recursive array handling) so it checks visited for objects/arrays to prevent
stack overflow; keep function names validateReferences and checkObject unchanged
so callers remain the same.
- Around line 238-247: The JSON Pointer resolution in the refPath loop doesn't
unescape RFC 6901 sequences, so properties with '~' or '/' fail to resolve;
update the resolution to run RFC6901 unescaping on each path token (for each
part from ref.replace(/^#\//,'').split('/')) by replacing '~1' with '/' then
'~0' with '~' before using it to index into resolved (the variables to change
are refPath generation and the loop that assigns to resolved using
part/ref/resolved/overrides).
---
Nitpick comments:
In `@__tests__/docs-data/overrides.json`:
- Line 2: The fixture's "$schema" currently points to the remote main-branch
URL; update the "$schema" value in __tests__/docs-data/overrides.json to the
checked-in local schema path used by the production override file (replace the
full GitHub raw URL with the repository-relative schema path used elsewhere) so
the test fixture validates against the branch-local schema and removes the
network dependency.
In `@__tests__/docs-data/property-overrides.json`:
- Line 2: Update the "$schema" field in property-overrides.json to use a
relative path instead of the GitHub raw URL: replace the current
"https://raw.githubusercontent.com/..." value with a repository-relative path
such as "../../docs-data/schemas/property-overrides.schema.json" so tests
validate against the local schema in the working tree.
In `@__tests__/tools/rpk-docs/validate-overrides.test.js`:
- Around line 466-489: The test currently only asserts that result.warnings and
result.errors are defined, which is too weak; update the assertions in the
'should run all validations' test to assert the expected successful outcome from
validateOverrides: check that result.valid === true and that no errors are
reported (e.g. expect(result.errors).toHaveLength(0) or
expect(result.errors).toEqual([])); you can still assert warnings exist if
desired, but ensure the primary assertions reference validateOverrides and
result.valid to catch regressions in the validation pipeline.
In @.github/workflows/update-rpk-docs.yml:
- Line 50: The workflow uses mutable action tags (e.g., actions/checkout@v4 and
other actions referenced with `@v6`) which can be replaced with explicit commit
SHAs to improve security; update each action usage (actions/checkout@v4,
actions/setup-node@v6, and the other `@v4/`@v6 occurrences) to the corresponding
full commit SHA for that action release, and if you want automatic updates
configure Dependabot/Renovate to refresh those SHAs so the workflow stays
current while remaining pinned.
In `@docs-data/property-overrides.json`:
- Line 2: The $schema property currently points at the remote "main" URL; change
it to the repo-local schema reference pattern used elsewhere (e.g., mirror the
local-path style used in rpk-overrides) so editor/CI use the checked-in schema;
update the "$schema" value in docs-data/property-overrides.json to reference the
local property-overrides.schema.json file in the repo instead of the raw GitHub
main URL.
In `@tools/rpk-docs/report-delta.js`:
- Around line 37-40: The getFlagsMap function can insert undefined keys when a
flag lacks a name; update getFlagsMap to defensively skip or filter out flags
without a truthy string name (e.g., check f && typeof f.name === 'string' &&
f.name.length) before mapping, and optionally log or collect/report invalid flag
entries so unnamed flags don't overwrite each other in the returned Map;
reference the getFlagsMap function and the flags/f.name check when implementing
the fix.
In `@tools/rpk-docs/rpk-docs-handler.js`:
- Around line 214-253: The function declaration for downloadRpkBinary should
drop the unnecessary async keyword because it only performs synchronous
operations (fs.mkdtempSync, spawnSync, fs.chmodSync) and does not use await;
update the declaration to a plain function (remove "async" from the
downloadRpkBinary definition) and ensure callers still treat its return as a
direct string path (no awaited promise).
- Around line 483-493: The Docker image used in the spawnSync call (the array
passed to spawnSync that currently contains 'golang:1') is unpinned and should
be fixed to a specific Go version for reproducible builds; update the image
string (used in the same spawnSync invocation that assigns to result) to a
concrete tag such as 'golang:1.23' or read the tag from a configurable env var
(e.g., DOCKER_GO_VERSION) so the command arguments become deterministic and
configurable.
In `@tools/rpk-docs/validate-overrides.js`:
- Around line 217-291: The validateReferences function should enforce a maximum
traversal depth to avoid pathological deep recursion: introduce a MAX_DEPTH
constant and thread a depth counter through checkObject, checkRef and checkRefs
(e.g., add a depth parameter defaulting to 0), increment it on each recursive
descent, and if depth > MAX_DEPTH call result.addError(...) and stop traversing
that branch; update checkObject to pass depth+1 into nested checkObject calls
and checkRefs to pass depth into checkRef calls so deep or maliciously nested
structures yield a clear error instead of unbounded work.
- Around line 465-470: The entity-detection regex used in the desc.match(...)
check is too permissive; update the pattern in that match call (the branch that
currently uses &[a-z]+;) to only detect named HTML entities by allowing both
uppercase and lowercase letters and restricting the entity name length (e.g.,
2–10 characters) while keeping the existing hex (&`#x`...) and decimal (&#...)
branches; leave the call to result.addWarning(...) and descContext untouched.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 3b6373b3-9dec-438a-bfaf-259697cbe9a2
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (25)
.github/workflows/update-rpk-docs.ymlCLAUDE.mdCLI_REFERENCE.adoc__tests__/docs-data/overrides.json__tests__/docs-data/property-overrides.json__tests__/tools/rpk-docs/file-preservations.test.js__tests__/tools/rpk-docs/generate-rpk-docs.test.js__tests__/tools/rpk-docs/helpers.test.js__tests__/tools/rpk-docs/report-delta.test.js__tests__/tools/rpk-docs/validate-overrides.test.jsbin/doc-tools-mcp.jsbin/doc-tools.jsbin/mcp-tools/rpk-docs.jsdocs-data/property-overrides.jsondocs-data/rpk-overrides.jsondocs-data/rpk-overrides.schema.jsonpackage.jsontools/rpk-docs/WRITER_GUIDE.adoctools/rpk-docs/file-preservations.jstools/rpk-docs/generate-rpk-docs.jstools/rpk-docs/helpers/index.jstools/rpk-docs/report-delta.jstools/rpk-docs/rpk-docs-handler.jstools/rpk-docs/templates/command.hbstools/rpk-docs/validate-overrides.js
Core documentation generation system that creates AsciiDoc pages from rpk --print-tree JSON output. Includes: - Command tree traversal and AsciiDoc generation - Handlebars templates for consistent page structure - Text transformations for style guide compliance - Flag and example extraction from source - Deprecation scanning utilities - Output validation No Docker required - fetches and builds rpk from source.
Flexible JSON-based system allowing writers to customize auto-generated rpk documentation without modifying source code: - Description overrides and appends - Flag description improvements with version tracking - Structured examples with output blocks - Custom sections, admonitions, and includes - excludeExamples for filtering source examples - Section replacement and exclusion - Platform restrictions and deprecation support - Reusable definitions via $ref - JSON Schema for editor validation and autocomplete
- Add generate rpk-docs command to doc-tools CLI - Add MCP tool for AI-assisted documentation generation - Support --tag, --branch, --diff, --fetch-binary flags - Add --draft-missing for new command scaffolding - Track latest-rpk-version separate from redpanda-tag
215+ tests covering: - Text transformations and formatting - Override merging and validation - Example filtering with excludeExamples - Section replacement and content positioning - File preservation during regeneration - Delta reporting for version diffs - Table conversion utilities - MCP integration contracts
- RPK_OVERRIDES_GUIDE.adoc: comprehensive guide for all override features - CLI_REFERENCE.adoc: updated with rpk-docs command documentation - CLAUDE.md: updated repository overview - GitHub workflow for automated rpk docs updates
- Remove inline properties/connect version detection from version-fetcher (moved to separate extension in PR #200) - Add $schema reference to property-overrides.json - Remove obsolete test file
2ede47f to
c6d4d02
Compare
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 4
♻️ Duplicate comments (1)
tools/rpk-docs/report-delta.js (1)
46-67:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winValidate
node.nameexists before using it in path construction.Line 54 uses
node.nameto constructcurrentPathafter checking thatnodeis a valid object (lines 49-52), but doesn't verify that thenameproperty exists. If a valid object node lacks anameproperty,currentPathwill include"undefined"segments (e.g.,"rpk undefined"), corrupting the path map and producing incorrect diff results.🛡️ Proposed fix to validate name property
function flattenToMap(node, parentPath = '') { const result = new Map() // Defensive check for missing or invalid node if (!node || typeof node !== 'object') { return result } + + // Ensure node has a name property + if (!node.name) { + return result + } const currentPath = parentPath ? `${parentPath} ${node.name}` : node.name result.set(currentPath, node)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tools/rpk-docs/report-delta.js` around lines 46 - 67, The function flattenToMap currently uses node.name when building currentPath without verifying it exists; update flattenToMap to validate that node.name is a non-empty string before using it (check node.name !== undefined && typeof node.name === 'string' && node.name.trim() !== ''), and handle missing names by either skipping setting a path for that node or using a safe fallback (e.g., inherit parentPath or a placeholder) so that currentPath and the result Map are never polluted with "undefined"; apply this validation where currentPath is computed and ensure recursive calls to flattenToMap pass a valid parentPath when child nodes lack name.
🧹 Nitpick comments (3)
docs-data/RPK_OVERRIDES_GUIDE.adoc (2)
21-36: ⚡ Quick winClarify that JSON comments are illustrative only.
The JSON code block includes
//comment syntax (lines 25, 28), which is not valid in standard JSON. While this is common in documentation to show structure, users who copy-paste this template will encounter syntax errors. Consider adding a note that comments are for illustration purposes only and must be removed, or use a different syntax like"_comment": "..."for valid JSON.📝 Suggested clarification
Add a note before the code block:
== Basic Structure +NOTE: The examples below use `//` comments for clarity. These are not valid JSON and must be removed from actual override files. + [source,json]Or use valid JSON comment alternatives in the examples:
{ "definitions": { - // Reusable content blocks + "_comment": "Reusable content blocks" }, "textTransformations": { - // Global text transformations + "_comment": "Global text transformations" },🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs-data/RPK_OVERRIDES_GUIDE.adoc` around lines 21 - 36, The JSON example in the docs contains JavaScript-style comments (e.g., lines inside the JSON for "definitions", "textTransformations", and "commands" / "rpk <command> <subcommand>") which are invalid JSON and will break if copied; update the docs by either (a) adding a one-line clarifying note immediately before the code block that these // comments are illustrative only and must be removed before use, or (b) replace the comment lines inside the example with valid JSON-safe placeholders (e.g., "_comment": "...") so the example is valid JSON while keeping the structure for "definitions", "textTransformations", and "commands". Ensure the chosen approach is applied to the JSON block shown in the file.
425-444: ⚡ Quick winConsider enhancing the validation section with expected output examples.
The validation section explains what is validated but doesn't show what successful validation looks like or how to interpret validation errors. Adding a brief example of validation output (both success and error cases) would help users understand if their overrides are correct.
📝 Suggested enhancement
Add after line 435:
# Check for validation errors in the output ---- +The generator reports validation results: + +[source,bash] +---- +✓ Schema validation passed +✓ All command paths exist +✓ All content positions are valid +✓ All $ref references resolved +---- + +Validation errors are reported with specific details: + +[source,bash] +---- +✗ Schema validation failed: + - commands["rpk invalid"]: Command not found in tree + - commands["rpk topic create"].content[0]: Invalid position "after_invalid" +---- +🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs-data/RPK_OVERRIDES_GUIDE.adoc` around lines 425 - 444, Add concrete example output for the Validation section under the "== Validation" header (after the existing npx doc-tools generate rpk-docs command) showing a successful run and a representative failure: include one brief success log snippet (e.g., "Validation completed: no errors found" with exit code 0) and one error example demonstrating a common validation failure (e.g., JSON/schema/$ref error with an error message and suggested next steps), and annotate each snippet with one-line guidance on how to interpret the output and where to look (logs, file paths) when errors occur so users can tell at a glance whether overrides passed validation.__tests__/tools/rpk-docs/rpk-docs-handler.test.js (1)
24-30: ⚡ Quick winUse
fs.rmSyncwithrecursive: truefor more robust cleanup.The current cleanup uses
fs.rmdirSync(tempDir)which requires the directory to be empty and will fail if tests create additional files. Consider usingfs.rmSync(tempDir, { recursive: true, force: true })like inoverride-features.test.jsfor more robust cleanup.♻️ Proposed fix for more robust cleanup
afterEach(() => { - // Clean up temp files - if (fs.existsSync(overridesPath)) { - fs.unlinkSync(overridesPath) - } - fs.rmdirSync(tempDir) + fs.rmSync(tempDir, { recursive: true, force: true }) })🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@__tests__/tools/rpk-docs/rpk-docs-handler.test.js` around lines 24 - 30, The afterEach cleanup currently calls fs.rmdirSync(tempDir) which fails if tempDir contains files; update the afterEach block (where overridesPath and tempDir are referenced) to use fs.rmSync(tempDir, { recursive: true, force: true }) and also replace any individual fs.unlinkSync(overridesPath) with a tolerant removal (either keep the overridesPath unlink but wrap with exists check as present, or rely on rmSync to remove the whole tempDir); ensure the call order still cleans overridesPath if needed and that errors are not thrown when files are present.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs-data/RPK_OVERRIDES_GUIDE.adoc`:
- Around line 513-517: The link "link:../tools/rpk-docs/README.adoc[rpk-docs
tool documentation]" in the Related Resources section is pointing to a
non-existent target; locate that exact link string in RPK_OVERRIDES_GUIDE.adoc
and update its target to the correct existing README/source file for the
rpk-docs tool (replace ../tools/rpk-docs/README.adoc with the actual relative
path and filename that exists in the repo so the link resolves during the docs
build).
In `@docs-data/rpk-overrides.schema.json`:
- Around line 226-229: There are two duplicate definitions of the property
"pageAliases" in the JSON schema; remove the earlier/first "pageAliases" entry
and keep the later, more detailed "pageAliases" definition so the schema has a
single unique key and the intended description is preserved; ensure no other
duplicate keys remain in the schema.
In `@tools/rpk-docs/extract-conditional-content.js`:
- Around line 21-24: The git command invocations that build shell strings using
execSync with the user-controlled docsDir and relPath (see modifiedFilesOutput
and the later execSync call around lines 50-53) are vulnerable to command
injection; replace both execSync usages with child_process.spawnSync, passing
git and its arguments as an array (e.g.,
['git','diff','--name-only','modules/reference/pages/rpk/']) and using the cwd
option set to docsDir (or passing relPath as a separate argument where needed)
so no user input is interpolated into a shell string; additionally
validate/sanitize docsDir and relPath (ensure they’re expected relative paths)
and avoid shell:true so the inputs cannot inject commands.
In `@tools/rpk-docs/report-delta.js`:
- Around line 194-211: The loop currently only records default changes from
compareFlags into changedDefaults, so extend the diff handling to also record
type, description, and required changes: when compareFlags(oldFlag, newFlag)
returns changes.type, changes.description, or changes.required, push
corresponding objects (include commandPath: path, flagName, and old/new values)
into new arrays (e.g., changedTypes, changedDescriptions, changedRequired) or a
unified changedFlags array; update any downstream consumers to use these new
arrays. Locate and modify the loop that iterates newFlagsMap and the
compareFlags function usage to add these pushes for changes.type,
changes.description, and changes.required (in addition to the existing
changes.default handling).
---
Duplicate comments:
In `@tools/rpk-docs/report-delta.js`:
- Around line 46-67: The function flattenToMap currently uses node.name when
building currentPath without verifying it exists; update flattenToMap to
validate that node.name is a non-empty string before using it (check node.name
!== undefined && typeof node.name === 'string' && node.name.trim() !== ''), and
handle missing names by either skipping setting a path for that node or using a
safe fallback (e.g., inherit parentPath or a placeholder) so that currentPath
and the result Map are never polluted with "undefined"; apply this validation
where currentPath is computed and ensure recursive calls to flattenToMap pass a
valid parentPath when child nodes lack name.
---
Nitpick comments:
In `@__tests__/tools/rpk-docs/rpk-docs-handler.test.js`:
- Around line 24-30: The afterEach cleanup currently calls fs.rmdirSync(tempDir)
which fails if tempDir contains files; update the afterEach block (where
overridesPath and tempDir are referenced) to use fs.rmSync(tempDir, { recursive:
true, force: true }) and also replace any individual
fs.unlinkSync(overridesPath) with a tolerant removal (either keep the
overridesPath unlink but wrap with exists check as present, or rely on rmSync to
remove the whole tempDir); ensure the call order still cleans overridesPath if
needed and that errors are not thrown when files are present.
In `@docs-data/RPK_OVERRIDES_GUIDE.adoc`:
- Around line 21-36: The JSON example in the docs contains JavaScript-style
comments (e.g., lines inside the JSON for "definitions", "textTransformations",
and "commands" / "rpk <command> <subcommand>") which are invalid JSON and will
break if copied; update the docs by either (a) adding a one-line clarifying note
immediately before the code block that these // comments are illustrative only
and must be removed before use, or (b) replace the comment lines inside the
example with valid JSON-safe placeholders (e.g., "_comment": "...") so the
example is valid JSON while keeping the structure for "definitions",
"textTransformations", and "commands". Ensure the chosen approach is applied to
the JSON block shown in the file.
- Around line 425-444: Add concrete example output for the Validation section
under the "== Validation" header (after the existing npx doc-tools generate
rpk-docs command) showing a successful run and a representative failure: include
one brief success log snippet (e.g., "Validation completed: no errors found"
with exit code 0) and one error example demonstrating a common validation
failure (e.g., JSON/schema/$ref error with an error message and suggested next
steps), and annotate each snippet with one-line guidance on how to interpret the
output and where to look (logs, file paths) when errors occur so users can tell
at a glance whether overrides passed validation.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 8ccaf4c6-aaae-4689-ab1d-b37ba959b84c
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (38)
.github/workflows/update-rpk-docs.yml.gitignoreCLAUDE.mdCLI_REFERENCE.adoc__tests__/docs-data/overrides.json__tests__/docs-data/property-overrides.json__tests__/mcp/cli-contract.test.js__tests__/mcp/doc-tools-mcp.test.js__tests__/mcp/integration.test.js__tests__/tools/rpk-docs/generate-rpk-docs.test.js__tests__/tools/rpk-docs/helpers.test.js__tests__/tools/rpk-docs/override-features.test.js__tests__/tools/rpk-docs/report-delta.test.js__tests__/tools/rpk-docs/rpk-docs-handler.test.js__tests__/tools/rpk-docs/table-conversion.test.js__tests__/tools/rpk-docs/text-transformations.test.js__tests__/tools/rpk-docs/validate-overrides.test.jsbin/doc-tools-mcp.jsbin/doc-tools.jsbin/mcp-tools/rpk-docs.jsdocs-data/RPK_OVERRIDES_GUIDE.adocdocs-data/property-overrides.jsondocs-data/rpk-overrides.jsondocs-data/rpk-overrides.schema.jsonpackage.jsontools/rpk-docs/DEPRECATION-SCANNING.mdtools/rpk-docs/extract-conditional-content.jstools/rpk-docs/extract-overrides.jstools/rpk-docs/generate-rpk-docs.jstools/rpk-docs/helpers/index.jstools/rpk-docs/report-delta.jstools/rpk-docs/rpk-docs-handler.jstools/rpk-docs/scan-deprecated-commands.jstools/rpk-docs/templates/command.hbstools/rpk-docs/templates/content-item.hbstools/rpk-docs/templates/subsection.hbstools/rpk-docs/validate-output.jstools/rpk-docs/validate-overrides.js
✅ Files skipped from review due to trivial changes (8)
- tools/rpk-docs/templates/subsection.hbs
- CLAUDE.md
- .gitignore
- tests/docs-data/property-overrides.json
- tools/rpk-docs/DEPRECATION-SCANNING.md
- tests/docs-data/overrides.json
- CLI_REFERENCE.adoc
- docs-data/property-overrides.json
🚧 Files skipped from review as they are similar to previous changes (5)
- bin/doc-tools-mcp.js
- tests/tools/rpk-docs/report-delta.test.js
- tests/tools/rpk-docs/validate-overrides.test.js
- tests/tools/rpk-docs/helpers.test.js
- tools/rpk-docs/validate-overrides.js
- Fix broken link in RPK_OVERRIDES_GUIDE.adoc (README.adoc → CLI_REFERENCE.adoc) - Remove duplicate pageAliases property in schema (keep detailed version) - Use fs.rmSync with recursive in test cleanup (prevents failures with files) - Add node.name validation in flattenToMap (prevents undefined paths)
Add the infrastructure for automated rpk CLI documentation generation. Does not include generated pages - those will be created by running the workflow after merge. ## New files - `.github/workflows/update-rpk-docs.yml` - GitHub Action for automated updates - `docs-data/rpk-overrides.json` - Writer override configuration - `docs-data/rpk-overrides.schema.json` - JSON Schema for validation - `docs-data/RPK_OVERRIDES_GUIDE.adoc` - Writer guide for customization - `docs-data/README.adoc` - Directory reference ## Workflow features - Manual trigger via workflow_dispatch - Cross-repo trigger via repository_dispatch - Automatic PR creation with diff summary - Support for version tags and dev branch ## Excluded commands - `rpk ai *` - 41 commands marked "coming soon" - `rpk oxla` - Marked "coming soon" Related: redpanda-data/docs-extensions-and-macros#203
Replace execSync with spawnSync using argument arrays and cwd option to prevent potential command injection via docsDir or relPath inputs. Also add validation that docsDir exists and is a directory.
- Remove non-existent --fetch-binary flag - Use --ref instead of --tag for version specification - Clarify that tool builds from source with Go Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add the infrastructure for automated rpk CLI documentation generation. Does not include generated pages - those will be created by running the workflow after merge. ## New files - `.github/workflows/update-rpk-docs.yml` - GitHub Action for automated updates - `docs-data/rpk-overrides.json` - Writer override configuration - `docs-data/rpk-overrides.schema.json` - JSON Schema for validation - `docs-data/RPK_OVERRIDES_GUIDE.adoc` - Writer guide for customization - `docs-data/README.adoc` - Directory reference ## Workflow features - Manual trigger via workflow_dispatch - Cross-repo trigger via repository_dispatch - Automatic PR creation with diff summary - Support for version tags and dev branch ## Excluded commands - `rpk ai *` - 41 commands marked "coming soon" - `rpk oxla` - Marked "coming soon" Related: redpanda-data/docs-extensions-and-macros#203
Rely solely on dynamic detection methods: - Source scanning for //go:build linux tags - Tree comparison when Docker available (Linux vs Darwin builds) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Explain that Docker is only needed on macOS for dynamic Linux-only command detection, and that Linux/CI environments don't need Docker. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add exampleItem definition and reference it in contentItemExamples and subsection - Allow subsections to have both content AND items (not just one or the other) - Add descriptionScope property to commandOverride for platform-specific descriptions Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add try-catch around Docker builds to fall back to native Go when Docker fails - Document Go version requirements in CLI_REFERENCE.adoc with check command - Explain Docker's optional role (macOS only, for Linux-only detection) - Note that validation warnings for Linux-only commands are expected on macOS Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add early Go version check against go.mod requirements before building - Handle arbitrary output directories that don't match docs repo structure - Create sibling partials directory when output path is non-standard Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove redundant "NOTE:" prefix from content in type: "note" items (template already adds the prefix) - Add safety net text transformations for duplicate admonitions - Add comprehensive review report for rpk-docs automation Fixes: - rpk security acl create: "NOTE: NOTE:" → "NOTE:" - rpk cluster self-test start: "NOTE: NOTE:" → "NOTE:" Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add the infrastructure for automated rpk CLI documentation generation. Does not include generated pages - those will be created by running the workflow after merge. - `.github/workflows/update-rpk-docs.yml` - GitHub Action for automated updates - `docs-data/rpk-overrides.json` - Writer override configuration - `docs-data/rpk-overrides.schema.json` - JSON Schema for validation - `docs-data/RPK_OVERRIDES_GUIDE.adoc` - Writer guide for customization - `docs-data/README.adoc` - Directory reference - Manual trigger via workflow_dispatch - Cross-repo trigger via repository_dispatch - Automatic PR creation with diff summary - Support for version tags and dev branch - `rpk ai *` - 41 commands marked "coming soon" - `rpk oxla` - Marked "coming soon" Related: redpanda-data/docs-extensions-and-macros#203
rpk-docs Automation Review ReportBranch: Executive SummaryThe rpk-docs automation is production-ready with excellent code quality, comprehensive testing, and a well-designed override schema. All 261 unit tests pass, all CLI paths work correctly, and the generated output meets doc team standards. ✅ Verdict: APPROVED
Test ResultsUnit TestsAll 8 test files pass with 261 total tests:
CLI Integration Tests
Override Schema AssessmentThe 740-line JSON Schema is excellent for writer usability:
Issues Found and FixedDuring review, I found and fixed duplicate admonition prefixes in 2 override entries:
Root Cause: Override content included "NOTE:" prefix, but template already adds it for Also added safety net text transformations to catch any future occurrences. Fixes committed to:
Generated Output Quality
Recommendations for Future
✅ Approved for merge - No outstanding issues. Full review report available at: |
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add generateWhatsNewSection() to create AsciiDoc content for what's-new file - Add updateWhatsNewFile() helper to insert rpk CLI section - Update CLI to accept --update-whats-new <path> option - Generates sections for new commands, new flags, and changed defaults - Auto-inserts before "New configuration properties" or similar sections Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
kbatuigas
left a comment
There was a problem hiding this comment.
Approving, but may want to double check:
The generated CLI reference still describes rpk as “Redpanda Keeper” in CLI_REFERENCE.adoc:671. That text is coming from the command description in doc-tools.js:1029, so the fix should be made there and then CLI_REFERENCE.adoc regenerated.
Optional cleanup: several headings in RPK_OVERRIDES_GUIDE.adoc:11 are still title case rather than sentence case, and the generated Examples sections still include a generic filler sentence in command.hbs:373 and content-item.hbs:26. I’d treat those as nits rather than blockers.
Make path optional with default value of modules/get-started/pages/release-notes/redpanda.adoc Users can still override with custom path if needed. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add the infrastructure for automated rpk CLI documentation generation. Does not include generated pages - those will be created by running the workflow after merge. ## New files - `.github/workflows/update-rpk-docs.yml` - GitHub Action for automated updates - `docs-data/rpk-overrides.json` - Writer override configuration - `docs-data/rpk-overrides.schema.json` - JSON Schema for validation - `docs-data/RPK_OVERRIDES_GUIDE.adoc` - Writer guide for customization - `docs-data/README.adoc` - Directory reference ## Workflow features - Manual trigger via workflow_dispatch - Cross-repo trigger via repository_dispatch - Automatic PR creation with diff summary - Support for version tags and dev branch ## Excluded commands - `rpk ai *` - 41 commands marked "coming soon" - `rpk oxla` - Marked "coming soon" Related: redpanda-data/docs-extensions-and-macros#203
Add the infrastructure for automated rpk CLI documentation generation. Does not include generated pages - those will be created by running the workflow after merge. - `.github/workflows/update-rpk-docs.yml` - GitHub Action for automated updates - `docs-data/rpk-overrides.json` - Writer override configuration - `docs-data/rpk-overrides.schema.json` - JSON Schema for validation - `docs-data/RPK_OVERRIDES_GUIDE.adoc` - Writer guide for customization - `docs-data/README.adoc` - Directory reference - Manual trigger via workflow_dispatch - Cross-repo trigger via repository_dispatch - Automatic PR creation with diff summary - Support for version tags and dev branch - `rpk ai *` - 41 commands marked "coming soon" - `rpk oxla` - Marked "coming soon" Related: redpanda-data/docs-extensions-and-macros#203
Summary
A complete documentation automation system for
rpkCLI commands. Generates AsciiDoc reference pages fromrpk --print-treeJSON output while allowing writers to customize, enhance, and fix auto-generated content through a flexible overrides system.This tool eliminates manual maintenance of 200+ rpk command pages while giving writers full control over editorial enhancements.
Key capabilities
Automatic documentation generation
rpk --print-treeJSON output for complete command metadataLinux-only command detection
The tool automatically detects commands that only work on Linux:
//go:build linuxbuild tagsCommands detected as Linux-only get
page-platforms: linuxin their page attributes.Writer override system
The
rpk-overrides.jsonfile provides comprehensive customization without modifying source code:Description overrides
descriptionScope(cloud vs self-hosted)Flag overrides
Structured examples
descriptionandcodekeys for consistent formattingoutputandoutputLanguagefieldsexcludeExamplesregex patternsCustom sections
Additional customizations
seeAlsolinksText transformations
Global transformations ensure consistent formatting:
Content positioning
Place content at precise locations:
after_header- After page title (ideal for warnings)after_description- After intro paragraphafter_usage- After Usage sectionafter_aliases- After Aliases section (ideal for examples)after_flags- After Flags sectionafter_modifiers- After format modifier sectionsafter_examples- After Examples sectionbefore_see_also- Before See Also sectionend- At end of pageRequirements
Testing locally
Option 1: npm link (recommended)
Option 2: Run directly
# From docs-extensions-and-macros directory node bin/doc-tools.js generate rpk-docs --ref dev --output-dir ../docs/modules/reference/pages/rpkCLI options
--ref <version>dev,v26.2.0)--from-source <path>--from-json <path>--diff <version>--output-dir <path>--overrides <path>--draft-missingFiles changed
tools/rpk-docs/- Main generator codedocs-data/rpk-overrides.json- Writer overrides filedocs-data/rpk-overrides.schema.json- JSON schema for validationdocs-data/RPK_OVERRIDES_GUIDE.adoc- Writer documentationbin/doc-tools.js- CLI integrationmcp/- MCP server integrationRelated