@redpanda-data/docs-extensions-and-macros 5.41.0 → 5.44.0
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/bin/doc-tools.js
CHANGED
|
@@ -1476,6 +1476,9 @@ automation
|
|
|
1476
1476
|
* parsing `-X list` text for rpk versions that predate it. Hidden -X options
|
|
1477
1477
|
* appear in neither source, so they are excluded automatically.
|
|
1478
1478
|
*
|
|
1479
|
+
* The table is sectioned by the API group rpk reports for each option, and is
|
|
1480
|
+
* a single flat table on rpk versions that report no groups.
|
|
1481
|
+
*
|
|
1479
1482
|
* The main rpk-docs pipeline also writes this partial from the tree it
|
|
1480
1483
|
* already holds; this standalone command is for targeted refreshes without
|
|
1481
1484
|
* a full generation run.
|
|
@@ -1492,7 +1495,7 @@ automation
|
|
|
1492
1495
|
*/
|
|
1493
1496
|
automation
|
|
1494
1497
|
.command('rpk-env-partial')
|
|
1495
|
-
.description('Generate the -X -> RPK_* env var mapping partial from rpk
|
|
1498
|
+
.description('Generate the -X -> RPK_* env var mapping partial from rpk itself.')
|
|
1496
1499
|
.option('-r, --ref <ref>', 'Git branch or tag to build rpk from (e.g., dev, v26.2.1). Clones from GitHub.')
|
|
1497
1500
|
.option('--from-source <path>', 'Path to local rpk source (src/go/rpk directory)')
|
|
1498
1501
|
.option('--rpk-bin <path>', 'Path to an existing rpk binary (skips clone and build)')
|
|
@@ -47,16 +47,16 @@ The build validates the name against the RC data. A typo gets a warning naming t
|
|
|
47
47
|
|
|
48
48
|
=== If you forget the property data
|
|
49
49
|
|
|
50
|
-
You get told, once per component version, with the command to run:
|
|
50
|
+
You get told, once per component version, with the command to run. Every excerpt below is what actually lands in the build log, through Antora's own logger rather than the macro printing its own text -- `HH:MM:SS.mmm` stands in for the real timestamp, which varies on every build:
|
|
51
51
|
|
|
52
52
|
[literal]
|
|
53
53
|
----
|
|
54
|
-
prop macro: streaming@26.3 publishes no
|
|
55
|
-
in its reference module (found for
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
'npx doc-tools generate property-docs
|
|
59
|
-
leave prop: out of 26.3 content.
|
|
54
|
+
[HH:MM:SS.mmm] WARN (prop-macro): prop macro: streaming@26.3 publishes no
|
|
55
|
+
redpanda-properties-v26.3.*.json attachment in its reference module (found for
|
|
56
|
+
other series: v26.2.1). prop: targets on 26.3 pages are therefore not validated
|
|
57
|
+
and their tooltips carry no data, rather than being checked against another
|
|
58
|
+
release's properties. Generate it with 'npx doc-tools generate property-docs
|
|
59
|
+
--tag v26.3.<patch>' on that branch, or leave prop: out of 26.3 content.
|
|
60
60
|
----
|
|
61
61
|
|
|
62
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.
|
|
@@ -116,6 +116,34 @@ Enterprise features are declared in the registry (`enterprise-features.yml` in t
|
|
|
116
116
|
|
|
117
117
|
Add `status-tooltip` to override the hover text on an `unreleased` badge, or `beta-tooltip` on a `beta` badge.
|
|
118
118
|
|
|
119
|
+
=== A shipped feature that only exists as of a version: `since`
|
|
120
|
+
|
|
121
|
+
`status` answers "is this public yet," which is a question about a *branch* (prerelease or not). A different question comes up once a feature has fully shipped: an ordinarily-GA feature -- no `status` key at all -- still has a *first* version, and older released versions predate it. Without a check, a feature that ships in 26.3 would render as fully available on a 24.1 page that predates it by two years, because `status` alone has nothing to say about that.
|
|
122
|
+
|
|
123
|
+
`since` closes that gap:
|
|
124
|
+
|
|
125
|
+
[,yaml]
|
|
126
|
+
----
|
|
127
|
+
- name: My Shipped Feature
|
|
128
|
+
scope: redpanda
|
|
129
|
+
since: '26.3'
|
|
130
|
+
description: What it does.
|
|
131
|
+
expiration: What happens when the licence expires.
|
|
132
|
+
----
|
|
133
|
+
|
|
134
|
+
The check is against the *page's own version*, not the newest release: a mention on a 26.3 (or later) page renders normally, with no badge, because as of that page's version the feature has shipped. The identical mention on a 26.2 page renders as plain text with no styling, tooltip, or link, and a warning -- the same failure mode as an unreleased feature, but for a version reason rather than a branch reason:
|
|
135
|
+
|
|
136
|
+
[literal]
|
|
137
|
+
----
|
|
138
|
+
[HH:MM:SS.mmm] WARN (enterprise-macro): enterprise:My Shipped Feature[] in
|
|
139
|
+
modules/manage/pages/example.adoc: 'My Shipped Feature' is marked since: 26.3 in
|
|
140
|
+
the enterprise features registry, but this page is version 26.2, which predates
|
|
141
|
+
it. Move the mention to a page whose version is at or after the since version, or
|
|
142
|
+
remove since if the feature covers this version too.
|
|
143
|
+
----
|
|
144
|
+
|
|
145
|
+
`since` and `status: unreleased` are independent and can combine: a feature still in an RC carries `status: unreleased` while it is not public at all, then drops that key once it ships and (optionally) gains `since` set to the version it shipped in, so older released versions stop claiming it. Most shipped features need neither key.
|
|
146
|
+
|
|
119
147
|
=== Writing the mention
|
|
120
148
|
|
|
121
149
|
Unchanged:
|
|
@@ -129,12 +157,12 @@ On the prerelease branch this renders with the `unreleased` badge. On released d
|
|
|
129
157
|
|
|
130
158
|
[literal]
|
|
131
159
|
----
|
|
132
|
-
enterprise:My Upcoming Feature[] in
|
|
133
|
-
'My Upcoming Feature' is marked status:
|
|
134
|
-
registry, so it is only documented for an
|
|
135
|
-
a released version, so the mention renders
|
|
136
|
-
styling, tooltip, or link. Move the mention to
|
|
137
|
-
change the status once the feature ships.
|
|
160
|
+
[HH:MM:SS.mmm] WARN (enterprise-macro): enterprise:My Upcoming Feature[] in
|
|
161
|
+
modules/manage/pages/example.adoc: 'My Upcoming Feature' is marked status:
|
|
162
|
+
unreleased in the enterprise features registry, so it is only documented for an
|
|
163
|
+
upcoming release. This page belongs to a released version, so the mention renders
|
|
164
|
+
as plain text with no enterprise styling, tooltip, or link. Move the mention to
|
|
165
|
+
the prerelease (beta) branch, or change the status once the feature ships.
|
|
138
166
|
----
|
|
139
167
|
|
|
140
168
|
The `unreleased` badge cannot be suppressed with `enterprise-beta-badge=false`. "Not in a release yet" is information a reader needs, not decoration.
|
|
@@ -167,19 +195,22 @@ Before opening a PR that documents something unreleased:
|
|
|
167
195
|
* [ ] The mention is on the prerelease branch, not on `main` or a released `v/*` branch.
|
|
168
196
|
* [ ] For a property: the RC property JSON is committed on that branch, generated from the RC tag.
|
|
169
197
|
* [ ] For an enterprise feature: the registry entry has `status: unreleased`, not `beta: true`, unless it is genuinely a public beta.
|
|
198
|
+
* [ ] For a shipped feature gated to a specific version: the registry entry has `since` set to the version it ships in, not left unset.
|
|
170
199
|
* [ ] The build log has no `prop macro:` or `enterprise:` warnings for your additions.
|
|
171
200
|
* [ ] No mention of an unreleased property or feature on a Cloud page.
|
|
172
201
|
|
|
173
202
|
== Seeing it work
|
|
174
203
|
|
|
175
|
-
The preview site in this repository has fixtures for every case above, including a prerelease component version and a Cloud component:
|
|
204
|
+
The preview site in this repository has fixtures for every case above, including a prerelease component version and a Cloud component. The fast, fully local way to build just those fixtures, with no GitHub token and no real docs/cloud-docs content:
|
|
176
205
|
|
|
177
206
|
[,bash]
|
|
178
207
|
----
|
|
179
|
-
./scripts/macro-
|
|
208
|
+
./scripts/macro-showcase.sh --serve
|
|
180
209
|
----
|
|
181
210
|
|
|
182
|
-
|
|
211
|
+
That builds `local-macro-showcase-playbook.yml` in seconds. Run `./scripts/macro-test.sh --serve` instead when you also want the fixtures proven against real production content (needs a token; pulls the full docs, cloud-docs, redpanda-labs, and rp-connect-docs repos).
|
|
212
|
+
|
|
213
|
+
Either way, open `/preview/macros-course/` first -- it's a hands-on course, not just a reference: it has you mark a property and register an enterprise feature, then edit the actual fixture data (a property JSON, the enterprise registry) yourself and rebuild to watch the macros react, including reproducing the `status: unreleased` gate on purpose. It links to `/preview/macros-showcase/`, which shows every other macro call, what it renders, and why, as pure reference. `/macro-fixtures/26.2/` and `/macro-fixtures/26.3/` are two versions of the SAME component -- one released, one prerelease (`prerelease: true` in its `antora.yml`) -- so flipping the version selector between them shows the same enterprise: mentions rendering differently with no edits: the unreleased feature badged on 26.3 and gated on 26.2, the since-gated feature (shipped `since: '26.3'`) gated on 26.2 and shipped plain on 26.3, and the beta feature badged on both. `/preview/release-status-test/` shows the unreleased/beta contrast again from a third, versionless component. `/macro-fixtures-cloud/` shows the Cloud availability rules.
|
|
183
214
|
|
|
184
215
|
== Why the build enforces this rather than trusting reviewers
|
|
185
216
|
|
package/macros/REFERENCE.adoc
CHANGED
|
@@ -68,7 +68,7 @@ asciidoc:
|
|
|
68
68
|
|
|
69
69
|
This inline macro marks a feature as an enterprise feature in prose. The feature name renders as a uniquely styled term with a tooltip explaining that the feature requires an Enterprise Edition license, and links to the feature's documentation or to the licensing page.
|
|
70
70
|
|
|
71
|
-
The macro validates its target against the enterprise features registry: `modules/ROOT/partials/enterprise-features.yml` in the `shared` component (the `shared/` folder of the docs repository). The registry is the canonical list of enterprise features and their approved external names. Targets are matched case-insensitively, including aliases, and the canonical name, feature page link, and tooltip come from the matching entry. A target that matches no entry is reported according to `enterprise-validate
|
|
71
|
+
The macro validates its target against the enterprise features registry: `modules/ROOT/partials/enterprise-features.yml` in the `shared` component (the `shared/` folder of the docs repository). The registry is the canonical list of enterprise features and their approved external names. Targets are matched case-insensitively, including aliases, and the canonical name, feature page link, and tooltip come from the matching entry. A target that matches no entry is reported according to `enterprise-validate` and renders as plain text -- no styling, tooltip, or link, since there is nothing verified to style it with. To mark a new feature as enterprise, add it to the registry first.
|
|
72
72
|
|
|
73
73
|
=== Usage
|
|
74
74
|
|
package/macros/enterprise.js
CHANGED
|
@@ -639,22 +639,27 @@ function enterpriseInlineMacro (config) {
|
|
|
639
639
|
let registry
|
|
640
640
|
if (config && config.contentCatalog) {
|
|
641
641
|
registry = loadRegistry(config)
|
|
642
|
-
if (!registry) warnNoRegistry(config
|
|
642
|
+
if (!registry) warnNoRegistry(config.contentCatalog)
|
|
643
|
+
}
|
|
644
|
+
if (!registry) {
|
|
645
|
+
// Nothing to validate against, so nothing should render as if it
|
|
646
|
+
// were. Mirrors prop:'s plain fallback for the same reason: a styled
|
|
647
|
+
// term this build cannot check is worse than an unstyled one.
|
|
648
|
+
return self.createInline(parent, 'quoted', attributes.text || target)
|
|
643
649
|
}
|
|
644
650
|
let feature = target
|
|
645
|
-
|
|
646
|
-
if (
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
}
|
|
651
|
+
const entry = registry.lookup.get(target.trim().toLowerCase())
|
|
652
|
+
if (entry) {
|
|
653
|
+
feature = entry.name
|
|
654
|
+
} else {
|
|
655
|
+
reportUnknownFeature({ feature: target, mode, registry, filePath })
|
|
656
|
+
// An unrecognized name has nothing behind it to style -- no xref, no
|
|
657
|
+
// tooltip, no licence terms to point at. Falling through to the same
|
|
658
|
+
// styled output a real feature gets, just with a generic fallback
|
|
659
|
+
// tooltip, let a typo pass for a real feature with nothing on the
|
|
660
|
+
// page to show a reader it was wrong. Mirrors prop:'s plain fallback
|
|
661
|
+
// for an unrecognized property name, for the same reason.
|
|
662
|
+
return self.createInline(parent, 'quoted', attributes.text || feature)
|
|
658
663
|
}
|
|
659
664
|
const status = entryStatus(entry, { mode, filePath, contentCatalog: config && config.contentCatalog })
|
|
660
665
|
if (status === STATUS_UNRELEASED && !isPrereleasePage(config, document)) {
|
package/package.json
CHANGED
|
@@ -3227,7 +3227,11 @@ function writeEnvVarsPartial (tree, partialsDir) {
|
|
|
3227
3227
|
return { written: false }
|
|
3228
3228
|
}
|
|
3229
3229
|
const { renderPartial, keyToEnvVar } = require('./generate-x-env-partial.js')
|
|
3230
|
-
const options = tree.x_options.map(o => ({
|
|
3230
|
+
const options = tree.x_options.map(o => ({
|
|
3231
|
+
name: o.name,
|
|
3232
|
+
env: o.env || keyToEnvVar(o.name),
|
|
3233
|
+
groupTitle: o.group_title || null
|
|
3234
|
+
}))
|
|
3231
3235
|
const output = path.join(partialsDir, 'rpk-env-vars.adoc')
|
|
3232
3236
|
fs.mkdirSync(path.dirname(output), { recursive: true })
|
|
3233
3237
|
fs.writeFileSync(output, renderPartial(options))
|
|
@@ -11,6 +11,12 @@
|
|
|
11
11
|
* descriptions.
|
|
12
12
|
* 2. `rpk -X list` text output, for rpk versions that predate x_options.
|
|
13
13
|
*
|
|
14
|
+
* Each x_option also carries the API it configures, as `group` (a stable
|
|
15
|
+
* slug) and `group_title` (the heading), added in
|
|
16
|
+
* redpanda-data/streaming-enterprise#311. When rpk supplies them the table is
|
|
17
|
+
* sectioned by API, so the grouping comes from rpk rather than being restated
|
|
18
|
+
* here; rpk versions without them get one flat table.
|
|
19
|
+
*
|
|
14
20
|
* The partial is included by both reference:rpk/rpk-x-options.adoc and
|
|
15
21
|
* reference:environment-variables.adoc in the docs repo. Hidden -X options
|
|
16
22
|
* (for example cloud_environment, whose values are deliberately
|
|
@@ -38,10 +44,12 @@ const GENERATED_BANNER = `// tag::generated[]
|
|
|
38
44
|
/**
|
|
39
45
|
* Extract -X options from `rpk --print-tree` JSON.
|
|
40
46
|
* @param {string} output - Raw stdout from `rpk --print-tree`
|
|
41
|
-
* @returns {Array<{name: string, env: string}>|null}
|
|
42
|
-
* order, or null when the tree has no x_options (rpk
|
|
43
|
-
* redpanda#31520). The env name comes from rpk itself when present
|
|
47
|
+
* @returns {Array<{name: string, env: string, group: ?string, groupTitle: ?string}>|null}
|
|
48
|
+
* options in display order, or null when the tree has no x_options (rpk
|
|
49
|
+
* predates redpanda#31520). The env name comes from rpk itself when present
|
|
44
50
|
* (the tree's env field is produced by the same derivation rpk reads).
|
|
51
|
+
* group and groupTitle are null on rpk versions that do not group the
|
|
52
|
+
* options.
|
|
45
53
|
*/
|
|
46
54
|
function xOptionsFromTree (output) {
|
|
47
55
|
let tree
|
|
@@ -51,7 +59,12 @@ function xOptionsFromTree (output) {
|
|
|
51
59
|
return null
|
|
52
60
|
}
|
|
53
61
|
if (!Array.isArray(tree.x_options) || tree.x_options.length === 0) return null
|
|
54
|
-
return tree.x_options.map(o => ({
|
|
62
|
+
return tree.x_options.map(o => ({
|
|
63
|
+
name: o.name,
|
|
64
|
+
env: o.env || keyToEnvVar(o.name),
|
|
65
|
+
group: o.group || null,
|
|
66
|
+
groupTitle: o.group_title || null
|
|
67
|
+
}))
|
|
55
68
|
}
|
|
56
69
|
|
|
57
70
|
/**
|
|
@@ -96,16 +109,53 @@ function keyToAnchor (key) {
|
|
|
96
109
|
return key.replace(/\./g, '-')
|
|
97
110
|
}
|
|
98
111
|
|
|
112
|
+
/**
|
|
113
|
+
* Group options by the API group rpk reports, in first-seen order.
|
|
114
|
+
*
|
|
115
|
+
* Returns null unless every option carries a group title, so a table is
|
|
116
|
+
* either fully sectioned or not sectioned at all: a half-sectioned table
|
|
117
|
+
* would read as though the options with no heading belonged to the section
|
|
118
|
+
* above them.
|
|
119
|
+
*
|
|
120
|
+
* Grouping by title rather than slicing on the boundaries means a group whose
|
|
121
|
+
* options are not contiguous still gets one heading instead of two.
|
|
122
|
+
* @param {Array<{name: string, env: string, groupTitle: ?string}>} options
|
|
123
|
+
* @returns {Array<{title: string, options: Array<Object>}>|null}
|
|
124
|
+
*/
|
|
125
|
+
function groupOptions (options) {
|
|
126
|
+
if (!options.every(o => o.groupTitle)) return null
|
|
127
|
+
const byTitle = new Map()
|
|
128
|
+
for (const option of options) {
|
|
129
|
+
const existing = byTitle.get(option.groupTitle)
|
|
130
|
+
if (existing) existing.push(option)
|
|
131
|
+
else byTitle.set(option.groupTitle, [option])
|
|
132
|
+
}
|
|
133
|
+
return [...byTitle].map(([title, opts]) => ({ title, options: opts }))
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Render one table row for an option.
|
|
138
|
+
* @param {{name: string, env: string}} option
|
|
139
|
+
* @returns {string}
|
|
140
|
+
*/
|
|
141
|
+
function renderRow ({ name, env }) {
|
|
142
|
+
return `|xref:reference:rpk/rpk-x-options.adoc#${keyToAnchor(name)}[${name}] |${env}`
|
|
143
|
+
}
|
|
144
|
+
|
|
99
145
|
/**
|
|
100
146
|
* Render the partial's AsciiDoc content.
|
|
101
|
-
*
|
|
147
|
+
*
|
|
148
|
+
* The table is sectioned by API group when rpk reports one for every option,
|
|
149
|
+
* and is a single flat table otherwise (rpk versions that predate the groups,
|
|
150
|
+
* and the -X list fallback, which has no group data to parse).
|
|
151
|
+
* @param {Array<{name: string, env: string, groupTitle: ?string}>} options - -X options
|
|
102
152
|
* @returns {string}
|
|
103
153
|
*/
|
|
104
154
|
function renderPartial (options) {
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
155
|
+
const groups = groupOptions(options)
|
|
156
|
+
const body = groups
|
|
157
|
+
? groups.map(g => `2+s|${g.title}\n${g.options.map(renderRow).join('\n')}`).join('\n\n')
|
|
158
|
+
: options.map(renderRow).join('\n')
|
|
109
159
|
return `${GENERATED_BANNER}
|
|
110
160
|
Every \`-X\` option has a corresponding \`RPK_*\` environment variable. Convert by prefixing with \`RPK_\` and replacing dots with underscores:
|
|
111
161
|
|
|
@@ -113,7 +163,7 @@ Every \`-X\` option has a corresponding \`RPK_*\` environment variable. Convert
|
|
|
113
163
|
|===
|
|
114
164
|
|\`-X\` Option |Environment Variable
|
|
115
165
|
|
|
116
|
-
${
|
|
166
|
+
${body}
|
|
117
167
|
|===
|
|
118
168
|
// end::generated[]
|
|
119
169
|
`
|
|
@@ -276,6 +326,7 @@ function handleXEnvPartialGeneration (options) {
|
|
|
276
326
|
|
|
277
327
|
module.exports = {
|
|
278
328
|
xOptionsFromTree,
|
|
329
|
+
groupOptions,
|
|
279
330
|
parseXList,
|
|
280
331
|
keyToEnvVar,
|
|
281
332
|
keyToAnchor,
|