Skip to content

ci: regenerate a single rpk plugin's docs when the plugin releases - #1834

Merged
JakeSCahill merged 6 commits into
mainfrom
rpk-plugin-docs-automation
Jul 31, 2026
Merged

ci: regenerate a single rpk plugin's docs when the plugin releases#1834
JakeSCahill merged 6 commits into
mainfrom
rpk-plugin-docs-automation

Conversation

@JakeSCahill

@JakeSCahill JakeSCahill commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

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 a repository_dispatch with {plugin, version}, and this workflow refreshes only that plugin's subtree in the committed rpk snapshot (doc-tools --plugin mode, docs-extensions-and-macros#225) and opens a PR against main.

Routing: main only

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 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 beta to the branch matrix. Without it, beta never receives doc-tools version bumps — the RC-triggered update-rpk-docs runs check out beta and npm ci from 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 the rpk cluster health Prometheus-metrics note exists only in beta's page, not in rpk-overrides.json — needs restoring separately.

Merge order

  1. docs-extensions-and-macros#225 (publishes doc-tools 5.3.0; Add connector sizing #221 recommended alongside).
  2. This PR, then let the auto dependency-bump PRs land on main and beta.
  3. Sender PRs (independent): ci: dispatch rpk connect plugin docs regeneration on releases connect#4636, redpanda-operator#1703, redpanda-check#10, redpanda-data/cloudv2#28552 (rpk ai).

#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)

PR Role Depends on
redpanda-data/docs-extensions-and-macros#225 Generator: --plugin mode, change detection, deprecations, What's-new merge, flag extraction, stub reconciler (publishes doc-tools 5.3.0)
#1834 Receiver workflow for plugin-release dispatches #225
#1844 Release workflow: auto What's-new diff base + pre-GA plugin pins #225
#1849 Removes two stale rpk ai partials merge before #1852/adp-docs#165 activate
#1852 Sender: docs main → adp-docs stub sync dispatch #225, adp-docs#165
redpanda-data/adp-docs#165 Receiver: reconciles rpk ai stubs and nav #225, docs#1852
Senders (merged/open) redpanda-data/connect#4636, redpanda-operator#1703 (merged), redpanda-check#10, cloudv2#28552 docs#1834

Merge order: #225 → dependency bumps on docs main and beta → #1834 + #1844 (+ #1849) → #1852 + adp-docs#165 → remaining senders. Jira: DOC-2355, DOC-1090.

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.
@JakeSCahill
JakeSCahill requested a review from a team as a code owner July 28, 2026 11:15
@netlify

netlify Bot commented Jul 28, 2026

Copy link
Copy Markdown

Deploy Preview for redpanda-docs-preview ready!

Name Link
🔨 Latest commit 3388213
🔍 Latest deploy log https://app.netlify.com/projects/redpanda-docs-preview/deploys/6a6c5a8beebf690008518e2d
😎 Deploy Preview https://deploy-preview-1834--redpanda-docs-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d27acff8-a0dd-4d67-b3bd-8be574eb410b

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a GitHub Actions workflow for regenerating documentation for one rpk plugin from the newest eligible snapshot on main and beta. It supports manual and repository-dispatch triggers, validates plugin and version inputs, generates documentation, detects changes, and opens labeled pull requests. The existing extension update matrix also gains beta as a target branch.

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
Loading

Suggested reviewers: kbatuigas

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is substantive, but it omits the required template sections like Resolves, Review deadline, Page previews, and Checks. Add the template sections: Description with Jira link, Review deadline, Page previews, and the Checks checklist, even if some are left unchecked.
✅ Passed checks (4 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the main change: adding automated docs regeneration for a single rpk plugin on release.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch rpk-plugin-docs-automation

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 9645029 and 3766325.

📒 Files selected for processing (2)
  • .github/workflows/update-extensions.yml
  • .github/workflows/update-rpk-plugin-docs.yml

Comment on lines +89 to +94
# 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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ 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.

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 micheleRP left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
@micheleRP

Copy link
Copy Markdown
Contributor

One change requested and one coordination question. The guard work is solid.

I exercised the resolve-parameters guards as extracted shell rather than through act, so no token was in scope. All behaved correctly: banana rejected as unknown, rpai rejected with the manifest-slug message, v4.102.0 normalized to 4.102.0, empty version accepted as latest, and both a newline-bearing version (the GITHUB_OUTPUT override case your comment calls out) and ; rm -rf / rejected by the version regex. Passing the payload through env: rather than interpolating into run: is the right pattern, and the ~-normalized sort -V appears correctly in both the snapshot selection and the backport guard.

Requested: PRs created with GITHUB_TOKEN skip the repo's own checks

On the last automated rpk PR, #1845, the Netlify preview ran and passed, but setup and run-tests never ran at all. Every human PR in the repo shows both. That is the documented secrets.GITHUB_TOKEN behavior: it does not trigger Actions workflows. So the PRs that change around 350 files are the only ones in the repo with no Actions validation, which is backwards for generated content.

#1852 already uses the pattern that fixes this, an actions bot token from AWS Secrets Manager. Using the same token here, and in the adp-docs sync workflow, would restore run-tests on generated PRs.

Coordination: the manual follow-up step overlaps the automated sync

The Flag adp-docs follow-up for rpk ai structural changes step labels the PR and comments that it needs a follow-up: add or delete the matching stub pages and nav entries in redpanda-data/adp-docs. Once #1852 and redpanda-data/adp-docs#165 are in, that reconciliation happens automatically and the instruction is misleading. Either reword it to point at the automated sync PR, or drop the step when those land.

…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.
@JakeSCahill

Copy link
Copy Markdown
Contributor Author

Both addressed in 33882138:

  • Bot-token PR creation: the workflow now assumes the org role, fetches sdlc/prod/github/actions_bot_token, and creates the PR with it, so generated PRs trigger setup/run-tests like human PRs. Good catch on docs: update rpk CLI documentation (v26.2.1) #1845 — that gap would have shipped ~350-file PRs with zero Actions validation indefinitely.
  • Follow-up overlap: the rpk-ai structural-change comment now points at the automated adp-docs sync ("review and merge that follow-on PR") instead of instructing manual stub/nav edits. Kept the label and comment as the human-attention signal; the reconciliation itself is ci: notify adp-docs when rpk ai partials change on main #1852 + adp-docs#165's job.
  • Also added timeout-minutes while in there.

@micheleRP micheleRP left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@JakeSCahill
JakeSCahill merged commit c891460 into main Jul 31, 2026
8 checks passed
@JakeSCahill
JakeSCahill deleted the rpk-plugin-docs-automation branch July 31, 2026 15:23
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