ci: regenerate a single rpk plugin's docs when the plugin releases - #1834
Conversation
rpk plugins (connect, ai, k8s, check) release on their own cadence, independent of Redpanda releases, so their docs went stale between rpk regenerations. Add a workflow that receives an update-rpk-plugin-docs dispatch from a plugin's release workflow and refreshes only that plugin's subtree via doc-tools' new --plugin mode, opening a PR against each branch whose newest rpk snapshot contains the plugin's command (connect/ai target main and beta, k8s/check target beta until 26.2 GA). Also add beta to the update-extensions matrix so the beta branch receives doc-tools version bumps. Without it, beta's lockfile stays pinned to whatever the last manual sync carried and new generator features never reach beta runs.
✅ Deploy Preview for redpanda-docs-preview 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 Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughAdds a GitHub Actions workflow for regenerating documentation for one Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant Trigger as Dispatch trigger
participant Workflow as GitHub Actions workflow
participant Snapshot as rpk snapshot
participant DocTools as doc-tools
participant PullRequest as Pull request
Trigger->>Workflow: Submit plugin and optional version
Workflow->>Snapshot: Check newest eligible snapshot
Snapshot-->>Workflow: Confirm plugin command
Workflow->>DocTools: Generate rpk plugin documentation
DocTools-->>Workflow: Write documentation changes
Workflow->>PullRequest: Create labeled pull request
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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-plugin-docs.yml:
- Around line 89-94: Validate VERSION in the workflow step before the echo
commands that write GITHUB_OUTPUT: reject any CR/LF characters and require
either an empty value or the expected release-version format after the existing
leading-v normalization. Exit with an error for invalid payloads, then emit
plugin and version outputs only after 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 Plus
Run ID: f1d36a0e-114c-4a38-a3f3-4faab3ddc78b
📒 Files selected for processing (2)
.github/workflows/update-extensions.yml.github/workflows/update-rpk-plugin-docs.yml
| # Normalize the version: strip a leading v (senders pass tag-derived | ||
| # values). An empty version means install latest. | ||
| VERSION="${VERSION#v}" | ||
|
|
||
| echo "plugin=$PLUGIN" >> $GITHUB_OUTPUT | ||
| echo "version=$VERSION" >> $GITHUB_OUTPUT |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Reject multiline and invalid version payloads before writing outputs.
Line 94 writes the dispatch-controlled version directly to $GITHUB_OUTPUT. A newline can append plugin=... and override the whitelisted plugin output, so downstream generation and PR creation can receive an unvalidated plugin. Reject CR/LF and validate the expected release-version format before emitting outputs.
Proposed fix
VERSION="${VERSION#v}"
+ if [[ "$VERSION" == *$'\n'* || "$VERSION" == *$'\r'* ]] ||
+ { [ -n "$VERSION" ] && ! "$VERSION" =~ ^[0-9]+(\.[0-9]+){2}([+-][0-9A-Za-z.-]+)?$ ]]; }; then
+ echo "::error::Invalid plugin version '$VERSION'"
+ exit 1
+ fi
echo "plugin=$PLUGIN" >> $GITHUB_OUTPUT🤖 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-plugin-docs.yml around lines 89 - 94, Validate
VERSION in the workflow step before the echo commands that write GITHUB_OUTPUT:
reject any CR/LF characters and require either an empty value or the expected
release-version format after the existing leading-v normalization. Exit with an
error for invalid payloads, then emit plugin and version outputs only after
validation.
11b3ac8 to
bdabd9f
Compare
bdabd9f to
3766325
Compare
Plugin versions are independent of Redpanda's major.minor docs versioning, so plugin doc changes always land on main. beta receives them through the regular main->beta syncs and RC-triggered full regenerations, and pre-merge testing showed direct beta generation is hazardous whenever beta's pages are ahead of its committed snapshot. Plugins missing from main's rpk line (k8s, check until 26.2 GA) skip green.
…leases A backport release (for example connect v4.95.1 after 4.102.0 is documented) would pin-install the older version and rewrite the docs to match it. Skip green when the dispatched version is older than the version recorded in the snapshot's plugin_versions; equal versions still run as idempotent refreshes and unrecorded plugins bootstrap normally. Also pass --update-whats-new so plugin releases append their changes to the What's new page in version-labeled blocks (doc-tools >= 5.3.0 merges blocks into the existing Redpanda CLI section).
micheleRP
left a comment
There was a problem hiding this comment.
Reviewed alongside docs-extensions-and-macros#225 and #1844; tested the generator side locally end-to-end. The receiver design is right (main-only routing, version-less PR branches, per-plugin concurrency, the rpai slug guard), and all four senders match the contract. One critical fix needed, one behavior change to request for ai, and a few smaller items:
1. (Critical) sort -V picks the rc snapshot over the GA snapshot. The eligibility step resolves the newest snapshot with ls docs-data/rpk-v*.json | sort -V | tail -1, but GNU sort ranks rpk-v26.2.1-rc2.json after rpk-v26.2.1.json (verified on ubuntu:24.04), and nothing deletes superseded rc snapshots. Today main has 26.1.12 + 26.2.1-rc2; the moment the GA regen commits rpk-v26.2.1.json, every plugin refresh here will pass --from-json the rc2 snapshot and re-render the full tree from it — reverting GA page content to rc2 state (the same failure class the beta leg of your e2e test demonstrated). Verified fix: normalize the prerelease suffix before sorting, e.g. sed 's/-rc/~rc/' | sort -V | sed 's/~rc/-rc/' (~ sorts lowest in GNU version sort) — or delete superseded -rcN snapshots when the GA snapshot lands. Same bug in #1844's diff-base resolution (CodeRabbit caught it there; this workflow has the identical pattern).
2. (Critical) The backport guard is inverted for prerelease→GA. sort -V also ranks 26.3.1 before 26.3.1-beta.1 (verified GNU + BSD). Concrete scenario: RC regens pin k8s=26.3.1-beta.1 (what #1844 enables), beta merges to main with that recorded in plugin_versions, then the operator GA release dispatches k8s 26.3.1 — the guard calls GA "older than the documented version" and skips it as a backport. Same tilde normalization on both sides of the comparison fixes it.
3. Skip --update-whats-new for plugin == ai. rpk ai's docs home is adp-docs (redpanda-data/adp-docs#161, now merged: this repo generates the rpk-ai partials, adp-docs publishes them via single-source stubs — the rpk cloud/cloud-docs pattern). The ADP release notes are already generated from cloudv2's adp/RELEASE_NOTES.md per release and cover rpk ai CLI changes with curated entries, so an === ai plugin <version> block in the Self-Managed What's-new would (a) promote a non-Self-Managed surface and (b) accumulate fast at ai's release cadence (several/week, one permanent block per version). The ai dispatch itself should absolutely stay — it keeps the shared partials fresh. Suggest a per-plugin opt-in map for the What's-new step (connect/k8s/check keep it).
4. Notify adp-docs when an ai refresh adds or removes commands. With #161's static stubs, a refresh that ADDS an ai command creates a partial with no adp-docs stub/nav entry (command invisible on the ADP site), and one that REMOVES a command deletes the partial and leaves a stub with an unresolved include (broken ADP page). The run already computes exactly this (newCommands/removedCommands in the plugin diff). Ask: when plugin == ai and the diff has structural changes, raise a signal — open an issue in adp-docs, or add a distinctive label + reviewer on the docs PR — so the stub/nav follow-up isn't discovered via a broken ADP page. Longer term an adp-docs stub/nav regenerator off the same dispatch would close the loop.
5. First automated PR won't be surgical. The 5.3.0 command.hbs :description: change touches every rpk page on first regeneration (~370 files in my local runs against clean main). If a plugin release fires before the GA regen lands that churn, the first plugin PR here carries it and the auto-description's "All other pages … should show no changes" will be wrong. Consider a one-time re-render right after the dependency bump, or a note in the PR body template.
6. (From CodeRabbit — worth taking) Validate the dispatched version string before writing it to $GITHUB_OUTPUT (newline injection can override the whitelisted plugin output; it also flows into the CLI and PR title). Low real-world risk since dispatch requires write access, but cheap hardening that also catches malformed sender payloads. Note its proposed patch has a shell syntax error (! "$VERSION" =~ outside [[ ]]) — adapt rather than paste.
From review: - Tilde-normalize prerelease suffixes before sort -V in the newest- snapshot resolution (plain sort ranks v26.2.1-rc2 after v26.2.1, so a lingering rc snapshot would win over GA) and in the backport guard (26.3.1 ranked below 26.3.1-beta.1, so a GA release after a pinned beta looked like a backport and was skipped). - Skip --update-whats-new for rpk ai: its docs home is adp-docs and the ADP release notes already cover its CLI changes per release. The dispatch still refreshes the shared partials. - Flag adp-docs follow-ups: when an ai refresh adds or removes commands, label the PR rpk-ai-structural-change and comment with the stub/nav follow-up needed (adp-docs uses static single-source stubs). - Validate the dispatched version string before writing it to outputs. - Note one-time template churn in the PR body template.
|
One change requested and one coordination question. The guard work is solid. I exercised the resolve-parameters guards as extracted shell rather than through Requested: PRs created with
|
…ow-ups at the automated sync PRs created with secrets.GITHUB_TOKEN do not trigger the repo's own Actions workflows, so the automated rpk PRs — the largest in the repo — were the only ones with no run-tests validation (observed on #1845: Netlify ran, setup and run-tests never did). Fetch the actions bot token and create PRs with it, matching the senders' pattern. Also reword the rpk-ai structural-change comment to point at the automated adp-docs stub sync instead of instructing a manual stub/nav edit (misleading once #1852 and adp-docs#165 land), and add a job timeout.
|
Both addressed in
|
micheleRP
left a comment
There was a problem hiding this comment.
Re-tested after your updates. Both items are addressed. Approving.
The generated PR now uses the actions bot token, so these PRs will pick up setup and run-tests like any human PR, which was the gap I raised. And the adp-docs follow-up comment now describes the automatic sync and tells the reviewer to merge the follow-on PR, rather than asking them to hand-edit stubs, which is what would have been wrong once #1852 and redpanda-data/adp-docs#165 land.
I re-ran the resolve-parameters guards as extracted shell, no token in scope: banana and rpai still blocked with their specific errors, v-prefix stripped, empty version accepted as latest, and both a newline-bearing version and shell metacharacters rejected. CI green.
Tiny nit, ignore if you like: the rpk-ai-structural-change label description still reads "adp-docs stubs and nav need a follow-up", which is the pre-automation framing. The comment body is the part people read, and that is now correct.
Summary
rpk plugins (connect, ai, k8s, check) release independently of Redpanda: connect ~weekly, rpk ai several times a week (cloudv2
adp/v*tags), rpk k8s per operator release, rpk check occasionally. Their docs currently refresh only when a Redpanda release triggers full rpk regeneration.This adds
update-rpk-plugin-docs.yml: each plugin's release workflow sends arepository_dispatchwith{plugin, version}, and this workflow refreshes only that plugin's subtree in the committed rpk snapshot (doc-tools--pluginmode, docs-extensions-and-macros#225) and opens a PR againstmain.Routing: main only
Plugin versions are independent of Redpanda's major.minor docs versioning, so plugin doc changes always land on
main.betareceives them through the regular main→beta syncs and the RC-triggered full regenerations. A plugin whose command is missing from main's newest rpk snapshot (k8s and check, until 26.2 GA rolls into main) skips green with a notice instead of failing.New commands found during a refresh are stamped with the plugin's own version in
rpk-overrides.json, so pages render "This command was introduced in<plugin>version X."PR branches are version-less (
rpk-plugin-docs/<plugin>-main) so rapid successive releases update the same open PR instead of stacking, and a per-plugin concurrency group serializes runs.update-extensions.yml
Adds
betato the branch matrix. Without it, beta never receives doc-tools version bumps — the RC-triggeredupdate-rpk-docsruns check out beta andnpm cifrom beta's lockfile, so beta must track doc-tools releases too.End-to-end test (already run)
Exercised in CI from this branch (temporary push trigger + doc-tools installed from the feature branch, both since removed): run 30354665055, plugin=connect, version=4.102.0. The main leg produced #1836 — exactly the expected surgical diff (snapshot
plugin_versions+ one nav line). A beta leg also ran in that test and confirmed why beta is excluded here: while beta's pages are ahead of its committed snapshot (until #1831 lands the rc2 snapshot), any direct regeneration on beta deletes 26.2 content. The test also surfaced that therpk cluster healthPrometheus-metrics note exists only in beta's page, not inrpk-overrides.json— needs restoring separately.Merge order
#1831 no longer blocks this PR (beta is out of the direct-generation path), but merging it remains important for beta's own consistency.
Related PRs (rpk docs automation train)
--pluginmode, change detection, deprecations, What's-new merge, flag extraction, stub reconciler (publishes doc-tools 5.3.0)Merge order: #225 → dependency bumps on docs main and beta → #1834 + #1844 (+ #1849) → #1852 + adp-docs#165 → remaining senders. Jira: DOC-2355, DOC-1090.