@redpanda-data/docs-extensions-and-macros 5.11.1 → 5.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs-data/rpk-overrides.schema.json +744 -0
- package/extensions/set-available-attachment-versions.js +32 -10
- package/macros/DOCUMENTING_UNRELEASED_FEATURES.adoc +188 -0
- package/macros/PROPERTY_AND_ENTERPRISE_REFERENCES.adoc +23 -3
- package/macros/REFERENCE.adoc +98 -9
- package/macros/badge.js +33 -3
- package/macros/enterprise.js +232 -22
- package/macros/prop.js +687 -187
- package/package.json +5 -4
- package/tools/property-extractor/cloud_config.py +16 -3
- package/tools/property-extractor/generate-handlebars-docs.js +100 -0
- package/tools/property-extractor/helpers/anchorName.js +14 -1
- package/tools/property-extractor/helpers/canonicalizePropertyXrefs.js +54 -0
- package/tools/property-extractor/helpers/index.js +2 -0
- package/tools/property-extractor/helpers/normalizePropertyAnchors.js +86 -0
- package/tools/property-extractor/templates/topic-property-mappings.hbs +13 -4
- package/tools/property-extractor/templates/topic-property.hbs +11 -1
- package/tools/redpanda-connect/report-delta.js +49 -3
- package/tools/rpk-docs/extract-conditional-content.js +3 -1
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
const { raiseListenerLimit } = require('./util/raise-listener-limit')
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
// The same comparator the prop macro uses to pick a dataset. semver.coerce
|
|
6
|
+
// keeps 'rc10' as one alphanumeric identifier and string-compares it, so it
|
|
7
|
+
// ranked v26.3.1-rc2 above v26.3.1-rc10 while the macro ranked them correctly:
|
|
8
|
+
// build-time validation and the runtime tooltip fetch would then read different
|
|
9
|
+
// files. Sharing the comparator is the only way they cannot disagree.
|
|
10
|
+
const { compareTags } = require('../macros/prop')
|
|
6
11
|
|
|
7
12
|
/**
|
|
8
13
|
* Points UI templates at generated JSON attachments that actually exist.
|
|
@@ -19,7 +24,9 @@ const semver = require('semver')
|
|
|
19
24
|
* component version:
|
|
20
25
|
*
|
|
21
26
|
* - available-properties-tag: newest redpanda-properties-<tag>.json attachment
|
|
22
|
-
* in the reference module of
|
|
27
|
+
* in the reference module of a component version that publishes property
|
|
28
|
+
* data (the ROOT and streaming components, plus any component shipping such
|
|
29
|
+
* an attachment of its own)
|
|
23
30
|
* - available-connect-version: newest connect-<version>.json attachment in the
|
|
24
31
|
* components module of the connect component
|
|
25
32
|
* - page-disable-property-tooltips: 'true' on streaming versions that have no
|
|
@@ -29,6 +36,12 @@ const semver = require('semver')
|
|
|
29
36
|
* overwritten.
|
|
30
37
|
*/
|
|
31
38
|
|
|
39
|
+
// Components known to publish Redpanda property data. Any other component that
|
|
40
|
+
// ships a redpanda-properties-<tag>.json attachment is picked up too: the docs
|
|
41
|
+
// UI resolves the tooltip dataset against the page's own component when that
|
|
42
|
+
// component declares available-properties-tag, so a component publishing its
|
|
43
|
+
// own data must get the attribute or its tooltips fall back to streaming's and
|
|
44
|
+
// describe different properties from the ones its pages document.
|
|
32
45
|
const PROPERTIES_COMPONENTS = ['ROOT', 'streaming']
|
|
33
46
|
const CONNECT_COMPONENTS = ['connect', 'redpanda-connect']
|
|
34
47
|
|
|
@@ -41,13 +54,26 @@ module.exports.register = function () {
|
|
|
41
54
|
|
|
42
55
|
this.once('contentClassified', ({ contentCatalog }) => {
|
|
43
56
|
contentCatalog.getComponents().forEach((component) => {
|
|
44
|
-
const
|
|
57
|
+
const publishesProperties = (contentCatalog.findBy({ component: component.name, family: 'attachment' }) || [])
|
|
58
|
+
.some((file) => file.src.module === 'reference' && PROPERTIES_JSON_RX.test(file.src.relative.split('/').pop()))
|
|
59
|
+
const isProperties = PROPERTIES_COMPONENTS.includes(component.name) || publishesProperties
|
|
45
60
|
const isConnect = CONNECT_COMPONENTS.includes(component.name)
|
|
46
61
|
if (!isProperties && !isConnect) return
|
|
47
62
|
|
|
48
63
|
component.versions.forEach((compVer) => {
|
|
49
|
-
|
|
50
|
-
|
|
64
|
+
// Copy before writing. Antora hands every component version whose
|
|
65
|
+
// antora.yml declares no `asciidoc:` block THE SAME siteAsciiDocConfig
|
|
66
|
+
// object -- see the NOTE at content-classifier/lib/content-catalog.js
|
|
67
|
+
// ("if no AsciiDoc attributes are defined in the component descriptor,
|
|
68
|
+
// asciidoc is the siteAsciiDocConfig object"). Mutating it in place
|
|
69
|
+
// wrote these attributes into the shared site config, so a component
|
|
70
|
+
// publishing no property data still advertised a dataset, and because
|
|
71
|
+
// the write is guarded on the attribute being unset, the first version
|
|
72
|
+
// processed won and every later version silently kept that value --
|
|
73
|
+
// no log line, and the wrong tag. Cloning both levels makes the write
|
|
74
|
+
// per-version, which is what the attribute means.
|
|
75
|
+
const asciidoc = (compVer.asciidoc = { ...compVer.asciidoc })
|
|
76
|
+
const attributes = (asciidoc.attributes = { ...asciidoc.attributes })
|
|
51
77
|
const attachments = contentCatalog.findBy({
|
|
52
78
|
component: component.name,
|
|
53
79
|
version: compVer.version,
|
|
@@ -90,17 +116,13 @@ module.exports.register = function () {
|
|
|
90
116
|
|
|
91
117
|
function findNewestVersion (attachments, module, rx) {
|
|
92
118
|
let newestRaw = null
|
|
93
|
-
let newestSemver = null
|
|
94
119
|
attachments.forEach((attachment) => {
|
|
95
120
|
if (attachment.src.module !== module) return
|
|
96
121
|
const basename = attachment.src.relative.split('/').pop()
|
|
97
122
|
const match = basename.match(rx)
|
|
98
123
|
if (!match) return
|
|
99
124
|
const raw = match[1]
|
|
100
|
-
|
|
101
|
-
if (!parsed) return
|
|
102
|
-
if (!newestSemver || semver.gt(parsed, newestSemver)) {
|
|
103
|
-
newestSemver = parsed
|
|
125
|
+
if (!newestRaw || compareTags(raw, newestRaw) > 0) {
|
|
104
126
|
newestRaw = raw
|
|
105
127
|
}
|
|
106
128
|
})
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
= Documenting properties and enterprise features before they ship
|
|
2
|
+
:toc:
|
|
3
|
+
:toclevels: 3
|
|
4
|
+
|
|
5
|
+
How to reference a configuration property or an enterprise feature that is not in a released version of Redpanda yet, so that the build checks your work instead of you having to remember which release something landed in.
|
|
6
|
+
|
|
7
|
+
For how the macros work generally, see link:PROPERTY_AND_ENTERPRISE_REFERENCES.adoc[the explainer] and link:REFERENCE.adoc[the macros reference].
|
|
8
|
+
|
|
9
|
+
== The two situations
|
|
10
|
+
|
|
11
|
+
Redpanda cuts release candidates before every release, and the docs track them on a prerelease branch (`beta`) that publishes under `/beta/` on the site. Two different things can be true of a feature or property on that branch:
|
|
12
|
+
|
|
13
|
+
*Unreleased.* It exists only in a release candidate. Nobody outside can get it yet. You are writing the docs ahead of the release so they ship with it.
|
|
14
|
+
|
|
15
|
+
*Released beta.* It is publicly available, but as a beta: real users can turn it on, and it may still change.
|
|
16
|
+
|
|
17
|
+
The distinction matters because it decides where a mention is allowed. An unreleased thing referenced from released docs promises readers something they cannot have. A released beta is fine to mention anywhere, as long as readers can see it is a beta.
|
|
18
|
+
|
|
19
|
+
The macros enforce that distinction, so the rule you need to remember is short: *write the mention on the branch the feature is actually on, and let the build tell you if you got it wrong.*
|
|
20
|
+
|
|
21
|
+
== Properties in a release candidate
|
|
22
|
+
|
|
23
|
+
=== What has to exist first
|
|
24
|
+
|
|
25
|
+
A property mention is only as good as the property data behind it. Each release series publishes its own `redpanda-properties-v<major>.<minor>.<patch>.json` as a reference-module attachment, and a page validates against the file for *its own* series. A prerelease branch is no exception: it needs a file generated from the RC tag.
|
|
26
|
+
|
|
27
|
+
[,bash]
|
|
28
|
+
----
|
|
29
|
+
# On the beta branch, from the docs repo
|
|
30
|
+
npx doc-tools generate property-docs --tag v26.3.1-rc1
|
|
31
|
+
----
|
|
32
|
+
|
|
33
|
+
`--tag` accepts release-candidate tags. The generated file is `redpanda-properties-v26.3.1-rc1.json`, and because its series is `26.3` it is picked up by a component version at `version: 26.3`.
|
|
34
|
+
|
|
35
|
+
Regenerate it for each RC. Tags compare by release precedence, so `rc2` supersedes `rc1` and the GA `v26.3.1` supersedes both -- you can leave older RC files in place and the build will use the newest.
|
|
36
|
+
|
|
37
|
+
=== Writing the mention
|
|
38
|
+
|
|
39
|
+
Once that file is committed on the branch, nothing special is needed. Write the macro as you would anywhere:
|
|
40
|
+
|
|
41
|
+
[,asciidoc]
|
|
42
|
+
----
|
|
43
|
+
Set prop:my_new_property[] to enable the thing.
|
|
44
|
+
----
|
|
45
|
+
|
|
46
|
+
The build validates the name against the RC data. A typo gets a warning naming the file it checked. A property that only exists in the RC validates on the beta branch and, correctly, fails validation if someone copies the sentence to a released branch, because it is not in that release's data.
|
|
47
|
+
|
|
48
|
+
=== If you forget the property data
|
|
49
|
+
|
|
50
|
+
You get told, once per component version, with the command to run:
|
|
51
|
+
|
|
52
|
+
[literal]
|
|
53
|
+
----
|
|
54
|
+
prop macro: streaming@26.3 publishes no redpanda-properties-v26.3.*.json attachment
|
|
55
|
+
in its reference module (found for other series: v26.2.1). prop: targets on 26.3
|
|
56
|
+
pages are therefore not validated and their tooltips carry no data, rather than
|
|
57
|
+
being checked against another release's properties. Generate it with
|
|
58
|
+
'npx doc-tools generate property-docs --tag v26.3.<patch>' on that branch, or
|
|
59
|
+
leave prop: out of 26.3 content.
|
|
60
|
+
----
|
|
61
|
+
|
|
62
|
+
Mentions render as plain code with no tooltip until the file exists. That is deliberate: validating 26.3 content against 26.2 data would accept properties that release never had and flag removed ones as typos.
|
|
63
|
+
|
|
64
|
+
=== Cloud pages and release candidates
|
|
65
|
+
|
|
66
|
+
Cloud runs released Redpanda, so Cloud pages always validate against the newest *GA* property data and ignore release candidates entirely. You cannot document an RC-only property on a Cloud page, and you should not want to -- the property is not in Cloud until the release ships and Cloud picks it up.
|
|
67
|
+
|
|
68
|
+
A property is available to Cloud only when its `cloud_supported` field is `true`, which comes from the Cloud support data the extractor fetches. For a property new in an RC that flag is `false`, so a Cloud mention renders as plain code with a warning. When Cloud gains the property, regenerating the data flips the flag and the mention starts working with no docs change.
|
|
69
|
+
|
|
70
|
+
=== Single-sourced pages need a second look
|
|
71
|
+
|
|
72
|
+
A Cloud page that is a stub including a self-managed page inherits that page's `prop:` calls, and they are then checked against Cloud's surface. A self-managed-only property therefore renders as plain code on the Cloud rendering of shared prose, with a warning naming the Cloud page even though the mention lives in the included file.
|
|
73
|
+
|
|
74
|
+
That is the macro doing its job: the shared sentence is telling a Cloud reader to set something they cannot set. Fix the prose rather than the macro -- usually by moving the instruction inside an `ifndef::env-cloud[]` block.
|
|
75
|
+
|
|
76
|
+
== Enterprise features in a release candidate
|
|
77
|
+
|
|
78
|
+
Enterprise features are declared in the registry (`enterprise-features.yml` in the `shared` component), and the release status lives there rather than in each mention. That way one edit updates every reference and every generated licensing table.
|
|
79
|
+
|
|
80
|
+
=== Declaring the status
|
|
81
|
+
|
|
82
|
+
[,yaml]
|
|
83
|
+
----
|
|
84
|
+
# Only in a release candidate: not public yet.
|
|
85
|
+
- name: My Upcoming Feature
|
|
86
|
+
scope: redpanda
|
|
87
|
+
status: unreleased
|
|
88
|
+
description: What it does.
|
|
89
|
+
expiration: What happens when the licence expires.
|
|
90
|
+
|
|
91
|
+
# Publicly available as a beta.
|
|
92
|
+
- name: My Beta Feature
|
|
93
|
+
scope: redpanda
|
|
94
|
+
status: beta
|
|
95
|
+
description: What it does.
|
|
96
|
+
expiration: What happens when the licence expires.
|
|
97
|
+
----
|
|
98
|
+
|
|
99
|
+
`status` is one of:
|
|
100
|
+
|
|
101
|
+
[cols="1,3a"]
|
|
102
|
+
|===
|
|
103
|
+
| Value | Meaning
|
|
104
|
+
|
|
105
|
+
| `ga`
|
|
106
|
+
| Shipped. The default when `status` is absent, so existing entries need no change. Referenced anywhere, no badge.
|
|
107
|
+
|
|
108
|
+
| `beta`
|
|
109
|
+
| Publicly available as a beta. Referenced anywhere. Renders a `beta` badge in prose and in the licensing tables.
|
|
110
|
+
|
|
111
|
+
| `unreleased`
|
|
112
|
+
| In a release candidate only. Referenced *only* from prerelease docs. Renders an `unreleased` badge there, and is omitted from licensing tables on released docs.
|
|
113
|
+
|===
|
|
114
|
+
|
|
115
|
+
`beta: true` is the older spelling and still means `status: beta`. Prefer `status` in new entries: it can express "not public at all", which a boolean cannot.
|
|
116
|
+
|
|
117
|
+
Add `status-tooltip` to override the hover text on an `unreleased` badge, or `beta-tooltip` on a `beta` badge.
|
|
118
|
+
|
|
119
|
+
=== Writing the mention
|
|
120
|
+
|
|
121
|
+
Unchanged:
|
|
122
|
+
|
|
123
|
+
[,asciidoc]
|
|
124
|
+
----
|
|
125
|
+
enterprise:My Upcoming Feature[] requires a licence.
|
|
126
|
+
----
|
|
127
|
+
|
|
128
|
+
On the prerelease branch this renders with the `unreleased` badge. On released docs it renders as plain text with no enterprise styling, no tooltip, and no link, plus a warning:
|
|
129
|
+
|
|
130
|
+
[literal]
|
|
131
|
+
----
|
|
132
|
+
enterprise:My Upcoming Feature[] in modules/manage/pages/example.adoc:
|
|
133
|
+
'My Upcoming Feature' is marked status: unreleased in the enterprise features
|
|
134
|
+
registry, so it is only documented for an upcoming release. This page belongs to
|
|
135
|
+
a released version, so the mention renders as plain text with no enterprise
|
|
136
|
+
styling, tooltip, or link. Move the mention to the prerelease (beta) branch, or
|
|
137
|
+
change the status once the feature ships.
|
|
138
|
+
----
|
|
139
|
+
|
|
140
|
+
The `unreleased` badge cannot be suppressed with `enterprise-beta-badge=false`. "Not in a release yet" is information a reader needs, not decoration.
|
|
141
|
+
|
|
142
|
+
=== Licensing tables
|
|
143
|
+
|
|
144
|
+
`enterprise_features::<scope>[]` omits `unreleased` features on released docs, because the table states what a licence covers today and listing something unavailable makes it wrong. On prerelease docs the same table lists them with their badge.
|
|
145
|
+
|
|
146
|
+
== When the release ships
|
|
147
|
+
|
|
148
|
+
Two edits, in this order:
|
|
149
|
+
|
|
150
|
+
. *Properties.* Generate the GA property data on the branch that becomes the released version:
|
|
151
|
+
+
|
|
152
|
+
[,bash]
|
|
153
|
+
----
|
|
154
|
+
npx doc-tools generate property-docs --tag v26.3.1
|
|
155
|
+
----
|
|
156
|
+
+
|
|
157
|
+
The GA tag supersedes its release candidates automatically, so no mention changes. Cloud starts seeing the new properties when the Cloud support data marks them `cloud_supported`.
|
|
158
|
+
|
|
159
|
+
. *Enterprise features.* Change `status: unreleased` to `status: beta` (if it ships as a public beta) or remove the `status` field (if it ships generally). Every mention and every table updates from that one edit.
|
|
160
|
+
|
|
161
|
+
Nothing in prose needs touching for either.
|
|
162
|
+
|
|
163
|
+
== Checklist
|
|
164
|
+
|
|
165
|
+
Before opening a PR that documents something unreleased:
|
|
166
|
+
|
|
167
|
+
* [ ] The mention is on the prerelease branch, not on `main` or a released `v/*` branch.
|
|
168
|
+
* [ ] For a property: the RC property JSON is committed on that branch, generated from the RC tag.
|
|
169
|
+
* [ ] For an enterprise feature: the registry entry has `status: unreleased`, not `beta: true`, unless it is genuinely a public beta.
|
|
170
|
+
* [ ] The build log has no `prop macro:` or `enterprise:` warnings for your additions.
|
|
171
|
+
* [ ] No mention of an unreleased property or feature on a Cloud page.
|
|
172
|
+
|
|
173
|
+
== Seeing it work
|
|
174
|
+
|
|
175
|
+
The preview site in this repository has fixtures for every case above, including a prerelease component version and a Cloud component:
|
|
176
|
+
|
|
177
|
+
[,bash]
|
|
178
|
+
----
|
|
179
|
+
./scripts/macro-test.sh --serve
|
|
180
|
+
----
|
|
181
|
+
|
|
182
|
+
Open `/preview/macros-showcase/`, which shows each macro call, what it renders, and why. `/preview/release-status-test/` and `/macro-fixtures/26.3/` show the same unreleased feature gated on a released version and badged on a prerelease one.
|
|
183
|
+
|
|
184
|
+
== Why the build enforces this rather than trusting reviewers
|
|
185
|
+
|
|
186
|
+
Every one of these rules is checkable from data the build already has: which release series a page belongs to, whether its component version is a prerelease, which properties that release actually defines, and what the registry says about a feature's status. A reviewer would have to hold all of that in their head across hundreds of mentions and nine doc versions.
|
|
187
|
+
|
|
188
|
+
So the macros check it, and the failure mode is always the same: render the plain name and say why. That is deliberate. A wrong tooltip or a link to a page describing a feature nobody can get is worse than no tooltip at all, because the reader has no way to tell it is wrong.
|
|
@@ -23,13 +23,15 @@ prop:cloud_storage_enabled[]
|
|
|
23
23
|
|
|
24
24
|
That's it. Here's what happens for you:
|
|
25
25
|
|
|
26
|
-
*It's checked.* The name is looked up in the published property data -- the same JSON, generated from Redpanda's source code, that powers the reference pages and tooltips. A typo gets a build warning
|
|
26
|
+
*It's checked, against the right release.* The name is looked up in the published property data -- the same JSON, generated from Redpanda's source code, that powers the reference pages and tooltips. A typo gets a build warning naming the file, the release data it was checked against, and a "did you mean" suggestion. Nothing unverified ships. (A site can turn this up to a hard build failure with the `property-validate` attribute.)
|
|
27
|
+
|
|
28
|
+
Every release series has its own copy of that data, and the build picks the copy matching the page's own version: a 25.3 page is checked against 25.3 properties, never against the newest. Otherwise a property added in 26.2 would pass silently on a 25.3 page, and one removed since 25.3 would be flagged there as a typo. If a version branch has no property data of its own, the build says so and skips validation for that version rather than substituting a neighbouring release's -- and names the command that generates the missing file.
|
|
27
29
|
|
|
28
30
|
*It gets a tooltip.* The docs UI decorates only elements the macro marked. A plain backticked word never gets a tooltip anymore, so `admin` in a Helm example stays plain text unless a writer deliberately writes `prop:admin[]`.
|
|
29
31
|
|
|
30
32
|
*It can link itself.* Add `link=true` and the property links to its reference page. You don't say which page -- the build works that out by looking at which reference page actually documents that property (details below). If our property reference is ever reorganized into different pages, every link follows automatically.
|
|
31
33
|
|
|
32
|
-
*It adapts to Kubernetes pages.* Add `helm-path=auto` and, on pages rendered for Kubernetes, the property displays as the Helm values path readers actually type -- `config.cluster.log_segment_size`, `config.node.fips_mode`, or `storage.tiered.config.cloud_storage_enabled` for tiered storage settings. On Linux pages the same call shows the plain name. One sentence, correct for both audiences.
|
|
34
|
+
*It adapts to Kubernetes pages.* Add `helm-path=auto` and, on pages rendered for Kubernetes, the property displays as the Helm values path readers actually type -- `config.cluster.log_segment_size`, `config.node.fips_mode`, or `storage.tiered.config.cloud_storage_enabled` for tiered storage settings. On Linux pages the same call shows the plain name, as does a topic property anywhere: topic properties are set per topic rather than in `values.yaml`, so there is no path to show. One sentence, correct for both audiences.
|
|
33
35
|
|
|
34
36
|
*Once per paragraph is enough.* Mark the first mention of a property in a paragraph and leave later mentions as plain backticks -- a paragraph doesn't need three identical tooltips. The migration tool follows this rule, and the UI enforces it as a backstop: even if every mention is marked, only the first one per paragraph gets the tooltip.
|
|
35
37
|
|
|
@@ -37,10 +39,28 @@ That's it. Here's what happens for you:
|
|
|
37
39
|
|
|
38
40
|
Rather than hardcoding "cluster properties live on the cluster-properties page," the macro reads the actual docs during the build. Every documented property appears as a heading in the generated property files, and each reference page pulls in one or more of those files. The macro follows that chain -- which pages exist, what they include, which property headings end up where -- and builds a lookup table per doc set.
|
|
39
41
|
|
|
40
|
-
Because the lookup is done separately for each part of the site, a Cloud page links to Cloud's own property pages and a streaming page to streaming's
|
|
42
|
+
Because the lookup is done separately for each part of the site, a Cloud page links to Cloud's own property pages and a streaming page to streaming's, and a link is only ever emitted when a page in that same doc set actually documents the property. Nothing is linked across doc sets, and no page is guessed from a property's scope -- a link the build can't verify is a broken link.
|
|
43
|
+
|
|
44
|
+
Availability is a separate question from linking, and it comes from the data rather than from which pages happen to include what. Cloud is managed Redpanda, so it has no property release of its own: a Cloud page reads the newest *released* self-managed file, ignoring release candidates, because Cloud runs released Redpanda.
|
|
45
|
+
|
|
46
|
+
What that file can rule out is narrower than it looks. `cloud_supported` is derived from the Cloud control plane's install pack, and that source describes *cluster* configuration and nothing else. So the gate applies to cluster properties only: a cluster property the control plane forbids renders as plain code -- no link and no tooltip -- plus a build warning naming the property and the file, because a tooltip there would tell a Cloud reader they can change something they can't. For any other scope the file has no opinion, and a mention is allowed. Topic properties in particular are set per topic through the Kafka API, rpk, or Console -- a surface the control plane doesn't gate -- and Cloud publishes a topic properties reference of its own.
|
|
47
|
+
|
|
48
|
+
An absent `cloud_supported` therefore means "not asserted", not "unsupported". Only an explicit `false` on a cluster property blocks a mention. (Where the flag is written, it is self-consistent: no published property is editable or read-only in Cloud without also being supported.)
|
|
49
|
+
|
|
50
|
+
Doc sets with no property data -- Connect, the agentic data plane -- get nothing, and nothing is inferred for them. Their version numbers are their own product's, and say nothing about which Redpanda properties exist. Adding a third doc set is a deliberate change to the macro, not something it guesses.
|
|
51
|
+
|
|
52
|
+
An available property that no page *renders* is a different situation, and keeps its tooltip. Deprecated properties are the usual case: the reference pages filter them out, but the published data still describes them accurately, so a tooltip on the deprecated-properties page is exactly what a reader wants. There's no page to link, so `link=true` renders unlinked and warns; a tooltip-only mention is silent.
|
|
41
53
|
|
|
42
54
|
Think phone book, not memory: if a property moves, the next build's phone book is already right.
|
|
43
55
|
|
|
56
|
+
=== Features and properties that have not shipped yet
|
|
57
|
+
|
|
58
|
+
Redpanda cuts release candidates before every release, and the docs track them on a prerelease branch. Something in an RC is not the same as something in a public beta, and the difference decides where a mention is allowed: an unreleased thing referenced from released docs promises readers something they cannot have.
|
|
59
|
+
|
|
60
|
+
Both macros enforce that from data rather than from reviewer memory. A property validates against its own release series, so an RC-only property works on the beta branch and fails on a released one. An enterprise feature carries `status: unreleased` or `status: beta` in the registry, and an unreleased feature referenced from released docs renders as plain text with a warning, and is omitted from licensing tables there. Cloud always uses GA property data and ignores release candidates entirely, because Cloud runs released Redpanda.
|
|
61
|
+
|
|
62
|
+
The writer-facing procedure, including how to generate property data from an RC tag, is in link:DOCUMENTING_UNRELEASED_FEATURES.adoc[Documenting properties and enterprise features before they ship].
|
|
63
|
+
|
|
44
64
|
=== What happened to config_ref
|
|
45
65
|
|
|
46
66
|
The old `config_ref` macro did a smaller version of this job with three problems: you had to tell it which page to link to by hand, it never checked the property name, and on Kubernetes pages it prefixed *every* property with `storage.tiered.config.` -- which is only correct for tiered storage settings. The live docs really did render `storage.tiered.config.log_segment_size`, a path that mislabels where that setting belongs.
|
package/macros/REFERENCE.adoc
CHANGED
|
@@ -20,7 +20,7 @@ antora:
|
|
|
20
20
|
|
|
21
21
|
== config_ref
|
|
22
22
|
|
|
23
|
-
IMPORTANT: `config_ref` is deprecated. The
|
|
23
|
+
IMPORTANT: `config_ref` is deprecated. The `prop` macro supersedes all of its functionality: it validates names against the published property reference, discovers the target page dynamically instead of taking a manual path, powers hover tooltips, and its `helm-path=auto` attribute replaces `config_ref`'s Kubernetes prefixing with a per-property correct Helm values path (`config_ref` prefixed every property with `storage.tiered.config.`, mislabeling non-tiered properties). Migrate call sites with `doc-tools generate migrate-property-refs --config-refs`. The macro stays registered only because older versioned docs, which are frozen, still contain it; generated content emits `prop` (the extractor rewrites any `config_ref` it finds).
|
|
24
24
|
|
|
25
25
|
This inline macro is used to generate a reference to a configuration value in the Redpanda documentation. The macro's parameters allow for control over the generated reference's format and the type of output produced.
|
|
26
26
|
|
|
@@ -46,7 +46,7 @@ This is the path to the document where the configuration value is defined. This
|
|
|
46
46
|
|
|
47
47
|
IMPORTANT: The path must be the name of a document at the root of the `reference` module.
|
|
48
48
|
|
|
49
|
-
NOTE: The `config_ref` macro is environment-aware. It checks if the document it is being used in is part of a Kubernetes environment by checking if the `env-kubernetes` attribute is set in the document's attributes. Depending on this check, it either prepends `storage.
|
|
49
|
+
NOTE: The `config_ref` macro is environment-aware. It checks if the document it is being used in is part of a Kubernetes environment by checking if the `env-kubernetes` attribute is set in the document's attributes. Depending on this check, it either prepends `storage.tiered.config.` to the `configRef` or just uses the `configRef` as is.
|
|
50
50
|
|
|
51
51
|
For example:
|
|
52
52
|
|
|
@@ -113,6 +113,31 @@ Set to `false` to render the term without a link.
|
|
|
113
113
|
enterprise-beta-badge::
|
|
114
114
|
Set to `false` to suppress the beta badge in prose. Generated tables always show it. See <<beta-features>>.
|
|
115
115
|
|
|
116
|
+
[[release-status]]
|
|
117
|
+
=== Release status
|
|
118
|
+
|
|
119
|
+
A registry entry's `status` field declares where a feature may be referenced. It is the enterprise equivalent of `cloud_supported` for properties: one field in the data, checked at build time, rather than a rule reviewers have to remember.
|
|
120
|
+
|
|
121
|
+
[cols="1,3a"]
|
|
122
|
+
|===
|
|
123
|
+
| `status` | Behavior
|
|
124
|
+
|
|
125
|
+
| `ga` (default)
|
|
126
|
+
| Shipped. Referenced anywhere, no badge. Applies when `status` is absent, so existing entries need no change.
|
|
127
|
+
|
|
128
|
+
| `beta`
|
|
129
|
+
| Publicly available as a beta. Referenced anywhere, with a `beta` badge in prose and in the generated tables.
|
|
130
|
+
|
|
131
|
+
| `unreleased`
|
|
132
|
+
| In a release candidate only, not public. Referenced *only* from a prerelease component version. On a released page the mention renders as plain text with no enterprise styling, tooltip, or link, and the build reports it according to `enterprise-validate`. Omitted from `enterprise_features` tables on released pages; listed with its badge on prerelease pages.
|
|
133
|
+
|===
|
|
134
|
+
|
|
135
|
+
A prerelease page is one whose component version sets `prerelease` in `antora.yml`. A playbook can declare it directly with the `page-component-version-is-prerelease` document attribute.
|
|
136
|
+
|
|
137
|
+
`beta: true` predates this field and still means `status: beta`, so old entries keep working. Prefer `status` in new entries, because a boolean cannot express "not public at all". An unrecognized `status` value is reported rather than silently treated as shipped. Use `status-tooltip` to override the `unreleased` badge's hover text.
|
|
138
|
+
|
|
139
|
+
For the writer-facing procedure, see link:DOCUMENTING_UNRELEASED_FEATURES.adoc[Documenting properties and enterprise features before they ship].
|
|
140
|
+
|
|
116
141
|
[[beta-features]]
|
|
117
142
|
=== Beta features
|
|
118
143
|
|
|
@@ -159,7 +184,7 @@ asciidoc:
|
|
|
159
184
|
|
|
160
185
|
== enterprise_features
|
|
161
186
|
|
|
162
|
-
This block macro renders the licensing feature table for one scope from the enterprise features registry (see
|
|
187
|
+
This block macro renders the licensing feature table for one scope from the enterprise features registry (see the `enterprise` macro above). Because the table is generated, it can never drift from the registry.
|
|
163
188
|
|
|
164
189
|
=== Usage
|
|
165
190
|
|
|
@@ -180,13 +205,13 @@ Optional third-column heading override. The default is `Behavior Upon Expiration
|
|
|
180
205
|
|
|
181
206
|
=== Registration
|
|
182
207
|
|
|
183
|
-
Registered together with the `enterprise` inline macro
|
|
208
|
+
Registered together with the `enterprise` inline macro.
|
|
184
209
|
|
|
185
210
|
== prop
|
|
186
211
|
|
|
187
212
|
This inline macro references a Redpanda configuration property in prose. The property renders as a marked `<code>` element (`property-ref` class plus a `data-property-name` attribute) that the docs UI decorates with a hover-documentation tooltip. Marking is opt-in: only properties referenced through this macro get tooltips, so ambiguous words such as `admin` or `rack` in unrelated contexts (Helm values, feature settings) are never decorated by mistake.
|
|
188
213
|
|
|
189
|
-
The macro
|
|
214
|
+
The macro checks that a property is actually available to the audience reading the page, and links it only where a page documents it. It validates against the published property data: a `redpanda-properties-<tag>.json` attachment in the `reference` module, the same data the tooltips fetch at runtime. See <<prop-availability>> for which properties each doc set may reference and <<prop-version-selection>> for which file a given page uses. To migrate existing plain-backtick property mentions, use `doc-tools generate migrate-property-refs`.
|
|
190
215
|
|
|
191
216
|
=== Usage
|
|
192
217
|
|
|
@@ -194,20 +219,20 @@ The macro validates its target against the published property reference: the new
|
|
|
194
219
|
----
|
|
195
220
|
prop:cloud_storage_enabled[]
|
|
196
221
|
prop:iceberg_enabled[link=true]
|
|
197
|
-
prop:
|
|
222
|
+
prop:retention.ms[link=true,page=properties/topic-properties]
|
|
198
223
|
prop:write_caching_default[text=write caching]
|
|
199
224
|
----
|
|
200
225
|
|
|
201
226
|
The macro target is the property name. Named attributes:
|
|
202
227
|
|
|
203
228
|
link::
|
|
204
|
-
Set to `true` to also link the property to its reference page. The page is discovered dynamically: the macro indexes which reference-module page in the current component documents each property, by scanning property headings in the partials each page includes (respecting include tag filters such as `tags=redpanda-cloud`). Links are component-relative, so a Cloud page links to the Cloud component's own property pages, and they keep working if properties are split across different pages in the future.
|
|
229
|
+
Set to `true` to also link the property to its reference page. The page is discovered dynamically: the macro indexes which reference-module page in the current component documents each property, by scanning property headings in the partials each page includes (respecting include tag filters such as `tags=redpanda-cloud`). Links are component-relative, so a Cloud page links to the Cloud component's own property pages, and they keep working if properties are split across different pages in the future. See <<prop-availability>> for properties the current component does not document. This supersedes the `config_ref` macro's linking for most uses.
|
|
205
230
|
|
|
206
231
|
page::
|
|
207
232
|
Optional reference-page override (module-relative, without `.adoc`), for example `properties/object-storage-properties`. Overrides discovery entirely.
|
|
208
233
|
|
|
209
234
|
helm-path::
|
|
210
|
-
Set to `auto` to display the property as its Helm values path on pages rendered with the `env-kubernetes` attribute, so single-sourced content reads correctly for both Linux and Kubernetes audiences. The path is derived per property: `storage.tiered.config.<name>` for
|
|
235
|
+
Set to `auto` to display the property as its Helm values path on pages rendered with the `env-kubernetes` attribute, so single-sourced content reads correctly for both Linux and Kubernetes audiences. The path is derived per property: `storage.tiered.config.<name>` for properties whose name begins `cloud_storage_`, `config.node.<name>` for broker properties, and `config.cluster.<name>` for cluster properties. Topic properties render as the plain name, because they are set per topic through the Kafka API, rpk, or a Topic resource and have no `values.yaml` key at all. The plain name also renders on any page where `env-kubernetes` is unset or explicitly `false`. This supersedes the deprecated `config_ref` macro's prefixing.
|
|
211
236
|
|
|
212
237
|
text::
|
|
213
238
|
Optional display text override. Wins over the Helm path display.
|
|
@@ -215,11 +240,75 @@ Optional display text override. Wins over the Helm path display.
|
|
|
215
240
|
=== Configuration options
|
|
216
241
|
|
|
217
242
|
property-validate::
|
|
218
|
-
How to report a target that does not match any published property: `warn` (default) logs a build warning with the file path and close-match suggestions
|
|
243
|
+
How to report a target that does not match any published property: `warn` (default) logs a build warning with the file path, the dataset the page was checked against, and close-match suggestions; `error` fails the build; and `off` disables validation and silences the unknown-name, unavailable-property, unpublished-property and missing-data warnings. Diagnostics about the build itself are not silenced by `off`, because they report a broken input rather than a questionable mention: unusable property JSON, a property claimed by two declared sources, and an index built after conversion started. When no property JSON is available in the build, the macro renders without validation and logs one warning per component version.
|
|
244
|
+
|
|
245
|
+
[[prop-version-selection]]
|
|
246
|
+
=== Which property data a page validates against
|
|
247
|
+
|
|
248
|
+
Each published Redpanda release series ships its own `redpanda-properties-v<major>.<minor>.<patch>.json`, so a page must be checked against the data for *its own* series. A 25.3 page validated against 26.2 data would accept properties that release never had and flag removed ones as typos.
|
|
249
|
+
|
|
250
|
+
The macro therefore selects by series (`major.minor`) rather than by newest tag:
|
|
251
|
+
|
|
252
|
+
. For a component version with a numeric series (`streaming` at `25.3`), the newest patch whose tag matches that series -- preferring the copy attached to the page's own version, then the same series published anywhere in the component, since a series' JSON sometimes lives only on the main branch. Patch numbers compare numerically, so `v25.3.11` beats `v25.3.2`.
|
|
253
|
+
. For a Cloud component (`env-cloud`), the newest `streaming` dataset, then `ROOT`. Cloud is managed Redpanda and always tracks the current release, so its own version is never consulted.
|
|
254
|
+
|
|
255
|
+
Selecting by series rather than newest tag matters in practice: the docs repo's main branch carries the previous series' JSON alongside its own, and a prerelease tag could land there too. Newest-tag-wins would hand that file to pages of a different release. A component with no property data and no `env-cloud` attribute gets no dataset at all -- see <<prop-availability>>.
|
|
256
|
+
|
|
257
|
+
Tags compare by release precedence, so a GA release outranks its own release candidates and `rc2` outranks `rc1`. A cycle publishes `v26.3.1-rc1`, then `rc2`, then the GA `v26.3.1`, and a beta branch at `version: 26.3` lands on the newest of those deterministically rather than on whichever file the content catalog happened to yield first. Redpanda spells prereleases as one identifier (`-rc2`, not `-rc.2`), which the semver spec compares as a string, so the trailing digits are split out before comparing; otherwise `rc10` would sort below `rc2`.
|
|
258
|
+
|
|
259
|
+
Cloud takes the newest *GA* dataset and ignores prereleases entirely, because Cloud runs released Redpanda. An RC published on a beta branch outranks the current GA by version number, so without this every Cloud page would start validating against an unreleased property list. When a build contains only prerelease data, Cloud goes unvalidated and the warning says so specifically rather than reporting no data at all.
|
|
260
|
+
|
|
261
|
+
When a component publishes property data for other series but none for the page's own, the macro declines to validate rather than use a neighbouring release's data. It logs one warning per component version naming the missing file, the tags it did find, and the `doc-tools generate property-docs --tag` command that produces it. `prop:` targets on those pages render unvalidated and their tooltips carry no data, so either generate the series' JSON on that branch or leave `prop:` out of that version's content.
|
|
219
262
|
|
|
220
263
|
property-ref-role::
|
|
221
264
|
CSS class applied to the code element. The default is `property-ref`.
|
|
222
265
|
|
|
266
|
+
[[prop-availability]]
|
|
267
|
+
=== Which properties a doc set may reference
|
|
268
|
+
|
|
269
|
+
Property data exists for two doc sets.
|
|
270
|
+
|
|
271
|
+
*Self-managed (`streaming`)* publishes its own properties JSON per release, as a reference-module attachment. Every property in that release's file is available.
|
|
272
|
+
|
|
273
|
+
*Cloud* is managed Redpanda, so it has no property data of its own and always tracks the newest self-managed file. A Cloud component is recognized by its `env-cloud` attribute.
|
|
274
|
+
|
|
275
|
+
A *cluster* property is available to Cloud unless its `cloud_supported` field is explicitly `false`. That field is the union of the Cloud states -- no published property is `cloud_editable` or `cloud_readonly` without also being `cloud_supported` -- so it is the single gate for that scope.
|
|
276
|
+
|
|
277
|
+
*Topic and broker* properties are not gated by it. `cloud_supported` is derived from the Cloud control plane's install pack, whose two sections (`customer_managed_configs` and `readonly_cluster_config`) describe cluster configuration and contain nothing else: every entry resolves to a cluster property, and no topic property appears anywhere in the file. A `false` value on another scope therefore asserted something that source cannot know, while Cloud users set topic properties routinely through the Kafka API and Console and Cloud publishes a topic properties reference of its own. The property extractor no longer writes the field for other scopes, and the macro treats an absent value as "no opinion", so already-published datasets stay correct too.
|
|
278
|
+
|
|
279
|
+
Any other component (`connect`, the agentic data plane, a preview site) has no property data, and none is inferred for it. Those components carry their own product versions, which say nothing about which Redpanda properties exist, so a version number is never read as a Redpanda release. Supporting a further doc set is a deliberate addition to the macro.
|
|
280
|
+
|
|
281
|
+
When a property is not available to the page's audience -- a non-`cloud_supported` property on a Cloud page -- the macro renders it as plain `<code>`: no link, no `data-property-name` marker, and therefore no tooltip. A tooltip would imply the reader can set something they cannot. The build logs a warning naming the property, the file, and the dataset consulted. Fix `cloud_supported` in the property extractor if the data is wrong; otherwise reword the sentence and drop the macro.
|
|
282
|
+
|
|
283
|
+
When no dataset covers the component at all, the macro warns once per component version and renders every `prop:` target as plain code, rather than emitting tooltips it could not verify.
|
|
284
|
+
|
|
285
|
+
=== Linking
|
|
286
|
+
|
|
287
|
+
`link=true` links the property to its reference page, but only when a page *in the same component* documents it. Nothing is linked across components, and no target is guessed from the property's `config_scope`: a link the build cannot verify is a broken link. An available property that no page renders -- a deprecated property, or one held back by include tags -- keeps its tooltip and renders unlinked; `link=true` warns in that case. Use `page=` to set a target explicitly for one mention.
|
|
288
|
+
|
|
289
|
+
[[prop-property-source]]
|
|
290
|
+
==== Declaring which page is the reference
|
|
291
|
+
|
|
292
|
+
A reference page can declare the property collection it publishes:
|
|
293
|
+
|
|
294
|
+
[,asciidoc]
|
|
295
|
+
----
|
|
296
|
+
= Cluster Configuration Properties
|
|
297
|
+
:page-property-source: cluster-properties
|
|
298
|
+
----
|
|
299
|
+
|
|
300
|
+
Claims on a property are then ranked, highest first:
|
|
301
|
+
|
|
302
|
+
. A page that declares `page-property-source`.
|
|
303
|
+
. A property heading pulled in from a generated partial.
|
|
304
|
+
. A bare heading on a page that happens to match a property name.
|
|
305
|
+
|
|
306
|
+
The ranking exists because inference alone is ambiguous. Several real property names are ordinary words -- `admin`, `brokers`, `rack`, `retries`, `superusers` -- so any reference page titled or sectioned with one of those would otherwise claim the property from the page that documents it, and a page title generates no anchor, so both the link and the tooltip URL would point at nothing. Ranking also makes resolution independent of the order Antora aggregates content, which is stable for one checkout but carries no meaning.
|
|
307
|
+
|
|
308
|
+
Within a rank, the first page wins, ordered by path so the result is deterministic. When two *declared* pages claim the same property the build warns and names both: that is an authoring conflict rather than something to resolve quietly.
|
|
309
|
+
|
|
310
|
+
Declaring the attribute is optional. Existing pages keep working through inference, and the declaration is worth adding when a property could plausibly be claimed by more than one page in the component, or to state the intent explicitly rather than relying on the generated partials happening to win.
|
|
311
|
+
|
|
223
312
|
=== Registration
|
|
224
313
|
|
|
225
314
|
[,yaml]
|
package/macros/badge.js
CHANGED
|
@@ -15,22 +15,52 @@
|
|
|
15
15
|
* @param {string} [opts.tooltip] - Tooltip text, rendered as `data-tooltip`.
|
|
16
16
|
* @returns {string} Badge HTML.
|
|
17
17
|
*/
|
|
18
|
+
// Hover text for the labels this macro is asked for by name. The badge is
|
|
19
|
+
// styled with a help cursor, so a badge with nothing to say promises an
|
|
20
|
+
// explanation and then withholds it. Callers with something more specific pass
|
|
21
|
+
// their own tooltip, which wins.
|
|
22
|
+
const DEFAULT_TOOLTIPS = {
|
|
23
|
+
beta: 'This feature is in public beta. You can enable it, but it may change before it is generally available.',
|
|
24
|
+
unreleased: 'This feature is not in a released version of Redpanda yet. It is documented here for the upcoming release.',
|
|
25
|
+
};
|
|
26
|
+
|
|
18
27
|
function buildBadgeHtml ({ label, size, tooltip } = {}) {
|
|
19
28
|
const text = label || 'label';
|
|
20
|
-
const className = `badge--${text.toLowerCase().replace(/\s+/g, '-')}`;
|
|
21
29
|
const isLarge = size === 'large';
|
|
22
30
|
const sizeClass = isLarge ? 'badge--large' : '';
|
|
23
|
-
|
|
31
|
+
// Escape before interpolating: these values reach the macro from .adoc source
|
|
32
|
+
// and from registry fields, and an unescaped quote terminates the attribute
|
|
33
|
+
// early, turning the rest of the text into stray attributes (including event
|
|
34
|
+
// handlers). The label needs it as much as the tooltip -- it lands in the
|
|
35
|
+
// class attribute and in the text content, and escaping only the tooltip left
|
|
36
|
+
// `badge:x[label=x" onmouseover="...]` free to break out of the class.
|
|
37
|
+
const escapeAttr = (value) => String(value)
|
|
38
|
+
.replace(/&/g, '&')
|
|
39
|
+
.replace(/"/g, '"')
|
|
40
|
+
.replace(/</g, '<')
|
|
41
|
+
.replace(/>/g, '>');
|
|
42
|
+
const className = `badge--${escapeAttr(text.toLowerCase().replace(/\s+/g, '-'))}`;
|
|
43
|
+
// hasOwnProperty, not a bare index: `label=constructor` and `label=__proto__`
|
|
44
|
+
// are already lowercase, so a bare lookup shipped
|
|
45
|
+
// `function Object() { [native code] }` to readers as hover text. prop.js
|
|
46
|
+
// guards its property lookups the same way.
|
|
47
|
+
const labelKey = text.trim().toLowerCase();
|
|
48
|
+
const defaultTooltip = Object.prototype.hasOwnProperty.call(DEFAULT_TOOLTIPS, labelKey)
|
|
49
|
+
? DEFAULT_TOOLTIPS[labelKey]
|
|
50
|
+
: undefined;
|
|
51
|
+
const hoverText = tooltip || defaultTooltip;
|
|
52
|
+
const tooltipAttr = hoverText ? ` data-tooltip="${escapeAttr(hoverText)}"` : '';
|
|
24
53
|
|
|
25
54
|
// Add brackets if not large. The brackets matter beyond styling: they are
|
|
26
55
|
// real text content, so the label survives an HTML-to-Markdown conversion as
|
|
27
56
|
// "(beta)" rather than vanishing with the CSS class.
|
|
28
|
-
const renderedLabel = isLarge ? text : `(${text})`;
|
|
57
|
+
const renderedLabel = isLarge ? escapeAttr(text) : `(${escapeAttr(text)})`;
|
|
29
58
|
|
|
30
59
|
return `<span class="badge ${className} ${sizeClass}"${tooltipAttr}>${renderedLabel}</span>`;
|
|
31
60
|
}
|
|
32
61
|
|
|
33
62
|
module.exports.buildBadgeHtml = buildBadgeHtml;
|
|
63
|
+
module.exports.DEFAULT_TOOLTIPS = DEFAULT_TOOLTIPS;
|
|
34
64
|
|
|
35
65
|
module.exports.register = function (registry) {
|
|
36
66
|
registry.inlineMacro(function () {
|