Skip to content

feat(crd-docs): mark beta CRDs with (beta) heading suffix and badge - #1833

Merged
JakeSCahill merged 3 commits into
betafrom
feat/crd-beta-marking
Jul 28, 2026
Merged

feat(crd-docs): mark beta CRDs with (beta) heading suffix and badge#1833
JakeSCahill merged 3 commits into
betafrom
feat/crd-beta-marking

Conversation

@JakeSCahill

@JakeSCahill JakeSCahill commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

The gap

The auto-generated modules/reference/pages/k-crd.adoc carries no beta indicators for beta CRDs. The Pipeline CRD is a beta feature in operator 26.2 (per the 26.2 release notes, which mark only Redpanda Connect pipelines and Gateway API Console support as beta), but its sections render unmarked in the otherwise-GA reference page. StretchCluster and ShadowLink are GA in 26.2. The NodePool CRD (beta since 26.1) is not part of this reference page, and its own page already carries :page-beta: true.

The convention

Per the team convention for beta features inside an otherwise-GA page:

  • A plain (beta) suffix on the section heading (no macros in headings, which leak markup into the TOC and anchors).
  • A badge::[label=beta] badge at the start of the section body.
  • :page-beta: is not used because the page as a whole is GA.

Design choice: template-level marking, driven by one editable pattern

The marking is implemented in the docs-side crd-ref-docs template (.github/crd-config/templates/asciidoctor/operator/type.tpl), keyed on a single commented pattern at the top of the template:

{{- $betaTypePattern := "^(Pipeline|NamedValueSource$)" -}}

Why the template rather than a post-processing step or a betaKinds entry in .github/crd-config/config.yaml:

  • Every regen path flows through these templates. The generate-crd.yml workflow, the doc-tools generate crd-spec command (its default --templates-dir is this directory), and manual crd-ref-docs runs all consume .github/crd-config/templates/asciidoctor/operator. A post-processing step would have to be wired into each of those paths separately and would silently drop off any path that forgets it. The config paths do NOT converge the same way: the workflow and doc-tools both pull the crd-ref-docs config from the operator repo, so .github/crd-config/config.yaml here is not consumed by any regen path today, and a betaKinds list there would be dead config.
  • crd-ref-docs cannot pass custom config values into templates, so the list lives as a clearly commented one-line pattern in the template itself. Writers edit that one line when a feature graduates to GA or a new beta CRD ships. crd-ref-docs v0.1.0 (the version pinned in the workflow) ships Sprig, so regexMatch is available (verified by running the real binary).
  • No operator repo changes (no godoc edits, no operator-side markers).

The pattern uses a prefix rather than exact kind names because a beta CRD brings a family of generated type sections that are all beta: Pipeline* (6 sections: Pipeline, PipelineBudget, PipelinePhase, PipelineSpec, PipelineStatus, PipelineUserRef) plus NamedValueSource (exact match, a Pipeline-only supporting type that does not share the prefix; the shared ValueSource type predates Pipeline and stays GA). Verified against the full 221-section output that no GA type matches the pattern.

This PR also registers @redpanda-data/docs-extensions-and-macros/macros/badge in local-antora-playbook.yml so local previews render the badge. The production docs-site playbooks already register it.

Anchor stability

The templates emit an explicit [id="..."] anchor line above every heading, so the heading text does not participate in ID generation:

[id="{anchor_prefix}-github-com-redpanda-data-redpanda-operator-operator-api-redpanda-v1alpha2-pipeline"]
== Pipeline (beta)

badge::[label=beta]

Proof from a real render (not just the source): generated the page before and after the change, converted both with Asciidoctor (with the real badge macro from docs-extensions-and-macros registered), and diffed the 221 <h2 id="..."> values. Byte-identical. Heading text differs only by the (beta) suffix on the beta sections (7 with the final Pipeline-only pattern). Existing xrefs such as xref:reference:k-crd.adoc#k8s-api-github-com-redpanda-data-redpanda-operator-operator-api-redpanda-v1alpha2-pipeline keep resolving unchanged.

Validation

Ran the real generation locally with crd-ref-docs v0.1.0 (same version and flags as generate-crd.yml), against two operator sources, using the same GA ignore config as the #1817/#1830 regens:

  • operator/v26.2.1-beta.3 tag (204 sections, StretchCluster + ShadowLink, no Pipeline because that tag predates the Pipeline CRD merge)
  • operator main (221 sections, includes Pipeline, same source Regenerate CRD reference with the Pipeline CRD #1830 regenerated from)

Old templates vs new templates, on the operator-main output:

Check Result
[id=...] anchor lines in the .adoc byte-identical (diff clean)
<h2 id> values in rendered HTML byte-identical, all 221
Sections gaining (beta) heading suffix 7, all matching ^(Pipeline|NamedValueSource$)
badge::[label=beta] lines added 7, one per beta section, all converting to <span class="badge badge--beta"> in the render
Beta-family sections missed 0
GA sections changed 0 (every diff hunk is a beta heading suffix, a badge line, or surrounding blank line)

Example rendered output for the Pipeline section:

<h2 id="k8s-api-github-com-redpanda-data-redpanda-operator-operator-api-redpanda-v1alpha2-pipeline">Pipeline (beta)</h2>
...
<p><span class="badge badge--beta ">(beta)</span></p>
<p>Pipeline defines a Redpanda Connect pipeline managed by the operator.</p>

What this PR does not do

k-crd.adoc itself is not regenerated here. #1830 (open, also based on beta) already regenerates it from operator main to add the Pipeline CRD. Regenerating in this PR too would duplicate and conflict with that work. After this merges, rerunning the #1830 regen with these templates (a single crd-ref-docs command) picks up the beta markers, and every future regen keeps them.

History note: an earlier revision of this PR also marked Stretch* and Shadow* types. That was wrong. Stretch Clusters and ShadowLink are GA in 26.2, and the pattern was corrected to Pipeline-only in commit 51a025f. The anchor-stability proof is pattern-independent (anchors come from explicit [id=...] lines, not heading text).

🤖 Generated with Claude Code

The generated CRD reference (k-crd.adoc) carried no beta indicators for
beta CRDs. Pipeline, StretchCluster, and ShadowLink are beta features in
operator 26.2 but rendered unmarked in the otherwise-GA reference page.

Add a beta-type pattern to the crd-ref-docs type template. Types whose
names match the pattern get a plain (beta) suffix on the section heading
and a badge::[label=beta] line at the start of the section body. The
explicit [id=...] anchor above each heading is untouched, so all
existing xrefs and inbound links keep resolving to the same anchors.

The pattern lives in one commented line at the top of type.tpl. Writers
edit that line when a feature graduates to GA or a new beta CRD ships.
Because every regeneration path (the generate-crd.yml workflow, the
doc-tools generate crd-spec command, and manual crd-ref-docs runs)
consumes these templates, the marking survives any regen without
touching the operator repo.

Also register the badge macro in the local Antora playbook so local
previews render the badge the same way the production site does.
@JakeSCahill
JakeSCahill requested a review from a team as a code owner July 28, 2026 09:51
@netlify

netlify Bot commented Jul 28, 2026

Copy link
Copy Markdown

Deploy Preview for redpanda-docs-preview ready!

Name Link
🔨 Latest commit 51a025f
🔍 Latest deploy log https://app.netlify.com/projects/redpanda-docs-preview/deploys/6a68b0927cde340008c87ad2
😎 Deploy Preview https://deploy-preview-1833--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

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

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: 9930a279-29c6-4350-b5b8-4d44c9b0224e

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
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/crd-beta-marking

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.

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

PR Review (docs-team-standards final pass)

Files reviewed: 2 (the crd-ref-docs type.tpl template + local playbook badge-macro registration)
Overall assessment: Excellent, unusually well-verified tooling PR — the design rationale, anchor-stability proof, and pattern validation are in the body and check out independently. One small pattern gap, and one delivery-coordination item that matters because GA is today.

Critical issues

None in the change itself. One delivery-coordination item: this PR marks nothing by itself — the badges appear only on the next regen, and the regen in flight (#1830) was generated before this template change, so its output is unmarked. Sequence needed: merge this + #1830, then rerun the CRD regen (generate-crd.yml) so the marked output reaches beta before promotion. Worth stating the plan in the PR body so it doesn't fall between the two PRs.

Suggestion

  1. NamedValueSource escapes the pattern. It's a Pipeline-family, beta-only type (introduced with the Pipeline CRD in #1830, referenced by PipelineSpec.valueSources, with its own generated section) — but it starts with "N", so it renders unmarked while its six sibling sections get badges. Extend the pattern (for example ^(Pipeline|Stretch|Shadow|NamedValueSource$)) or document the exclusion in the template comment. (ValueSource is correctly unmatched — it pre-dates Pipeline on beta as a shared type.)

Verified (independently, not just from the body)

  • Badge macro is registered in the production docs-site playbook — the local-playbook addition achieves preview/production parity.
  • Pattern behavior spot-checked: matches Pipeline/PipelineSpec/StretchListeners/ShadowTopicState, correctly skips shared ValueSource — consistent with the body's 221-section no-false-positive claim.
  • The anchor-stability argument is structurally sound (explicit [id="..."] lines mean heading text can't affect IDs), and the byte-identical diff proof is the right evidence.

What works well

  • Template-level design is the correct call, and the body's why-not-config/post-processing explanation (config paths don't converge; crd-ref-docs can't pass custom values to templates) is the kind of decision record that saves the next maintainer an afternoon.
  • Prefix-matching with documented counts (6/17/21) instead of exact kind names shows the failure mode was thought through.
  • Validation against the real pinned binary and two real operator sources — this is what "verified" should mean.

Minor: no DOC ticket linked; a DOC-2275/DOC-2198 reference in the body would help traceability.

🤖 Generated with Claude Code

NamedValueSource is a Pipeline-family, beta-only supporting type but
does not share the Pipeline prefix, so it rendered unmarked while its
six sibling sections got badges. Match it exactly; the shared
ValueSource type predates Pipeline and stays GA/unmarked. Beta section
count goes from 44 to 45.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Feediver1

Copy link
Copy Markdown
Contributor

Applied the review's suggestion in 161836c3: the pattern is now ^(Pipeline|Stretch|Shadow|NamedValueSource$) — exact-matching the Pipeline-only supporting type while the shared ValueSource (which predates Pipeline) stays GA/unmarked, with the rationale added to the template comment. Beta section count: 44 → 45. Regex behavior verified against the sibling and negative cases (NamedValueSourceFoo, ValueSource, GA kinds all correctly unmatched).

Reminder on the delivery sequencing from the review: after this and #1830 both merge, rerun generate-crd.yml so the marked output actually lands on beta before promotion.

🤖 Generated with Claude Code

@JakeSCahill
JakeSCahill merged commit f1bb55a into beta Jul 28, 2026
8 checks passed
@JakeSCahill
JakeSCahill deleted the feat/crd-beta-marking branch July 28, 2026 13:45
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