@redpanda-data/docs-extensions-and-macros 5.57.0 → 5.58.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 +67 -0
- package/extension-utils/property-values.js +255 -0
- package/macros/PROPERTY_AND_ENTERPRISE_REFERENCES.adoc +25 -1
- package/macros/README.adoc +3 -1
- package/macros/REFERENCE.adoc +158 -1
- package/macros/USER_GUIDE.adoc +28 -0
- package/macros/prop.js +135 -0
- package/package.json +1 -1
- package/tools/lint-strings/surfaces/connect.js +18 -1
- package/tools/migrate-property-refs.js +15 -12
- package/tools/migrate-property-values.js +1255 -0
- package/tools/property-extractor/README.adoc +4 -2
- package/tools/redpanda-connect/AUTOMATION.md +4 -2
- package/tools/redpanda-connect/multi-version-summary.js +2 -1
- package/tools/redpanda-connect/pr-summary-formatter.js +49 -8
- package/tools/redpanda-connect/report-delta.js +14 -5
- package/tools/redpanda-connect/rpcn-connector-docs-handler.js +17 -8
|
@@ -1223,7 +1223,7 @@ npm test -- --coverage
|
|
|
1223
1223
|
==== The live overrides corpus
|
|
1224
1224
|
|
|
1225
1225
|
`__tests__/tools/property-extractor/property-corpus-rendering.test.js` runs the real
|
|
1226
|
-
overrides file, not a fixture, because a fixture passes while the live
|
|
1226
|
+
overrides file, not a fixture, because a fixture passes while the live overrides corpus
|
|
1227
1227
|
breaks. Two files feed it, both mirrors of the `docs` repo:
|
|
1228
1228
|
|
|
1229
1229
|
`__tests__/docs-data/property-overrides.json`:: A byte copy of `docs-data/property-overrides.json`.
|
|
@@ -1245,7 +1245,9 @@ test, so it sat three months and 114 entries behind. That test now has its own
|
|
|
1245
1245
|
`property-overrides-admin-fixture.json`; put new fixture data there or in the test
|
|
1246
1246
|
itself, never in the mirror.
|
|
1247
1247
|
|
|
1248
|
-
|
|
1248
|
+
Every Monday, `.github/workflows/property-corpus-drift.yml` compares both files against `docs` main. When they have drifted, it runs the recipe below and opens or updates one pull request from `bot/refresh-property-corpus`. If that PR's tests fail, the refresh has exposed a real bug: push the fix to the same branch, and while the PR is open the job stops updating the branch once its latest commit isn't the bot's.
|
|
1249
|
+
|
|
1250
|
+
To refresh by hand, for example between weekly runs, run the same recipe from a `docs` checkout:
|
|
1249
1251
|
|
|
1250
1252
|
[,bash]
|
|
1251
1253
|
----
|
|
@@ -169,7 +169,8 @@ For each version pair `(oldVersion → newVersion)`:
|
|
|
169
169
|
"removedFields": 2, // Breaking changes!
|
|
170
170
|
"deprecatedComponents": 0,
|
|
171
171
|
"deprecatedFields": 1,
|
|
172
|
-
"changedDefaults": 0
|
|
172
|
+
"changedDefaults": 0, // A default changed or was removed (breaking)
|
|
173
|
+
"documentedDefaults": 0 // A field with no default now states one (informational)
|
|
173
174
|
},
|
|
174
175
|
"details": {
|
|
175
176
|
"newComponents": [
|
|
@@ -385,7 +386,8 @@ Changes between two consecutive versions:
|
|
|
385
386
|
"newFields": [...],
|
|
386
387
|
"removedFields": [...],
|
|
387
388
|
"deprecatedFields": [...],
|
|
388
|
-
"changedDefaults": [...]
|
|
389
|
+
"changedDefaults": [...],
|
|
390
|
+
"documentedDefaults": [...]
|
|
389
391
|
},
|
|
390
392
|
"binaryAnalysis": {
|
|
391
393
|
"versions": {
|
|
@@ -63,7 +63,8 @@ function createMasterDiff(intermediateResults, finalDiffPath, outputPath) {
|
|
|
63
63
|
removedFields: releases.reduce((sum, r) => sum + (r.summary.removedFields || 0), 0),
|
|
64
64
|
deprecatedComponents: releases.reduce((sum, r) => sum + (r.summary.deprecatedComponents || 0), 0),
|
|
65
65
|
deprecatedFields: releases.reduce((sum, r) => sum + (r.summary.deprecatedFields || 0), 0),
|
|
66
|
-
changedDefaults: releases.reduce((sum, r) => sum + (r.summary.changedDefaults || 0), 0)
|
|
66
|
+
changedDefaults: releases.reduce((sum, r) => sum + (r.summary.changedDefaults || 0), 0),
|
|
67
|
+
documentedDefaults: releases.reduce((sum, r) => sum + (r.summary.documentedDefaults || 0), 0)
|
|
67
68
|
};
|
|
68
69
|
|
|
69
70
|
const masterDiff = {
|
|
@@ -3,6 +3,16 @@
|
|
|
3
3
|
* Outputs a console-parseable format for GitHub Actions
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Format a field default for the Markdown PR summary. A field with no default
|
|
8
|
+
* is `undefined`; a declared null default (Default(nil)) is a value.
|
|
9
|
+
* @param {*} value - The default, or undefined when the field has none
|
|
10
|
+
* @returns {string} Inline code, or `_no default_`
|
|
11
|
+
*/
|
|
12
|
+
function formatDefault(value) {
|
|
13
|
+
return value === undefined ? '_no default_' : `\`${JSON.stringify(value)}\``;
|
|
14
|
+
}
|
|
15
|
+
|
|
6
16
|
/**
|
|
7
17
|
* Render Bloblang changes section for PR summary
|
|
8
18
|
* @param {object} data - Bloblang change data
|
|
@@ -238,6 +248,9 @@ function generateMultiVersionPRSummary(masterDiff, binaryAnalysis = null, drafte
|
|
|
238
248
|
if (total.changedDefaults > 0) {
|
|
239
249
|
lines.push(`- **${total.changedDefaults}** changed default values`);
|
|
240
250
|
}
|
|
251
|
+
if (total.documentedDefaults > 0) {
|
|
252
|
+
lines.push(`- **${total.documentedDefaults}** newly stated default values`);
|
|
253
|
+
}
|
|
241
254
|
if (total.newBloblangMethods > 0) {
|
|
242
255
|
lines.push(`- **${total.newBloblangMethods}** new Bloblang methods`);
|
|
243
256
|
}
|
|
@@ -375,12 +388,25 @@ function generateMultiVersionPRSummary(masterDiff, binaryAnalysis = null, drafte
|
|
|
375
388
|
lines.push('| Component | Field | Old Default | New Default |');
|
|
376
389
|
lines.push('|-----------|-------|-------------|-------------|');
|
|
377
390
|
changedDefaults.forEach(change => {
|
|
378
|
-
const oldVal =
|
|
379
|
-
const newVal =
|
|
391
|
+
const oldVal = formatDefault(change.oldDefault);
|
|
392
|
+
const newVal = formatDefault(change.newDefault);
|
|
380
393
|
lines.push(`| \`${change.component}\` | \`${change.field}\` | ${oldVal} | ${newVal} |`);
|
|
381
394
|
});
|
|
382
395
|
lines.push('');
|
|
383
396
|
}
|
|
397
|
+
|
|
398
|
+
// Fields that gained a stated default
|
|
399
|
+
const documentedDefaults = details.documentedDefaults || [];
|
|
400
|
+
if (documentedDefaults.length > 0) {
|
|
401
|
+
lines.push(`**Newly Stated Defaults (${documentedDefaults.length}):**`);
|
|
402
|
+
lines.push('');
|
|
403
|
+
lines.push("_These fields now state a default. They usually behaved this way already, so they are not listed as changes in What's new. Check that none of them changed behavior._");
|
|
404
|
+
lines.push('');
|
|
405
|
+
documentedDefaults.forEach(change => {
|
|
406
|
+
lines.push(`- \`${change.component}.${change.field}\`: ${formatDefault(change.newDefault)}`);
|
|
407
|
+
});
|
|
408
|
+
lines.push('');
|
|
409
|
+
}
|
|
384
410
|
}
|
|
385
411
|
|
|
386
412
|
// Writer action items (aggregate)
|
|
@@ -558,9 +584,9 @@ function generateMultiVersionPRSummary(masterDiff, binaryAnalysis = null, drafte
|
|
|
558
584
|
lines.push('**Review Changed Defaults for Breaking Changes:**');
|
|
559
585
|
lines.push('');
|
|
560
586
|
allChangedDefaults.forEach(change => {
|
|
561
|
-
const oldVal =
|
|
562
|
-
const newVal =
|
|
563
|
-
lines.push(`- [ ] \`${change.component}.${change.field}\`:
|
|
587
|
+
const oldVal = formatDefault(change.oldDefault);
|
|
588
|
+
const newVal = formatDefault(change.newDefault);
|
|
589
|
+
lines.push(`- [ ] \`${change.component}.${change.field}\`: ${oldVal} → ${newVal} — changed in **${change.version}**`);
|
|
564
590
|
});
|
|
565
591
|
lines.push('');
|
|
566
592
|
}
|
|
@@ -717,6 +743,10 @@ function generatePRSummary(diffData, binaryAnalysis = null, draftedConnectors =
|
|
|
717
743
|
lines.push(`- **${stats.changedDefaults}** default value change${stats.changedDefaults !== 1 ? 's' : ''}`);
|
|
718
744
|
}
|
|
719
745
|
|
|
746
|
+
if (stats.documentedDefaults > 0) {
|
|
747
|
+
lines.push(`- **${stats.documentedDefaults}** newly stated default value${stats.documentedDefaults !== 1 ? 's' : ''} (no behavior change expected)`);
|
|
748
|
+
}
|
|
749
|
+
|
|
720
750
|
lines.push('');
|
|
721
751
|
|
|
722
752
|
// Writer Reminder for Commercial Names
|
|
@@ -1233,14 +1263,25 @@ function generatePRSummary(diffData, binaryAnalysis = null, draftedConnectors =
|
|
|
1233
1263
|
const [type, name] = component.split(':');
|
|
1234
1264
|
lines.push(`**${type}/${name}:**`);
|
|
1235
1265
|
changes.forEach(c => {
|
|
1236
|
-
|
|
1237
|
-
const newStr = JSON.stringify(c.newDefault);
|
|
1238
|
-
lines.push(`- \`${c.field}\`: ${oldStr} → ${newStr}`);
|
|
1266
|
+
lines.push(`- \`${c.field}\`: ${formatDefault(c.oldDefault)} → ${formatDefault(c.newDefault)}`);
|
|
1239
1267
|
});
|
|
1240
1268
|
lines.push('');
|
|
1241
1269
|
});
|
|
1242
1270
|
}
|
|
1243
1271
|
|
|
1272
|
+
// Newly stated defaults
|
|
1273
|
+
const documentedDefaults = diffData.details.documentedDefaults || [];
|
|
1274
|
+
if (documentedDefaults.length > 0) {
|
|
1275
|
+
lines.push('#### Newly Stated Defaults');
|
|
1276
|
+
lines.push('');
|
|
1277
|
+
lines.push("_These fields now state a default. They usually behaved this way already, so they are not listed as changes in What's new. Check that none of them changed behavior._");
|
|
1278
|
+
lines.push('');
|
|
1279
|
+
documentedDefaults.forEach(c => {
|
|
1280
|
+
lines.push(`- \`${c.component}.${c.field}\`: ${formatDefault(c.newDefault)}`);
|
|
1281
|
+
});
|
|
1282
|
+
lines.push('');
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1244
1285
|
// New Bloblang Methods
|
|
1245
1286
|
if (stats.newBloblangMethods > 0 && diffData.details.newBloblangMethods) {
|
|
1246
1287
|
lines.push('#### New Bloblang Methods');
|
|
@@ -175,6 +175,10 @@ function generateConnectorDiffJson(oldIndex, newIndex, opts = {}) {
|
|
|
175
175
|
const deprecatedFields = [];
|
|
176
176
|
// Changed default values
|
|
177
177
|
const changedDefaults = [];
|
|
178
|
+
// Fields that had no default and now state one. The field behaved the same
|
|
179
|
+
// way before, the spec just didn't say so, so these are not default changes
|
|
180
|
+
// and stay out of What's new and the breaking-change warning.
|
|
181
|
+
const documentedDefaults = [];
|
|
178
182
|
|
|
179
183
|
Object.keys(newMap).forEach(cKey => {
|
|
180
184
|
if (!(cKey in oldMap)) return;
|
|
@@ -209,14 +213,16 @@ function generateConnectorDiffJson(oldIndex, newIndex, opts = {}) {
|
|
|
209
213
|
const newDefaultStr = JSON.stringify(newDefault);
|
|
210
214
|
|
|
211
215
|
if (oldDefaultStr !== newDefaultStr) {
|
|
212
|
-
|
|
216
|
+
const entry = {
|
|
213
217
|
component: cKey,
|
|
214
218
|
field: fName,
|
|
215
219
|
oldDefault: oldDefault,
|
|
216
220
|
newDefault: newDefault,
|
|
217
221
|
description: newFieldObj && newFieldObj.description,
|
|
218
222
|
shortDescription: newFieldObj && newFieldObj.short_description
|
|
219
|
-
}
|
|
223
|
+
};
|
|
224
|
+
if (oldDefault === undefined) documentedDefaults.push(entry);
|
|
225
|
+
else changedDefaults.push(entry);
|
|
220
226
|
}
|
|
221
227
|
}
|
|
222
228
|
});
|
|
@@ -280,6 +286,7 @@ function generateConnectorDiffJson(oldIndex, newIndex, opts = {}) {
|
|
|
280
286
|
deprecatedComponents: deprecatedComponents.length,
|
|
281
287
|
deprecatedFields: deprecatedFields.length,
|
|
282
288
|
changedDefaults: changedDefaults.length,
|
|
289
|
+
documentedDefaults: documentedDefaults.length,
|
|
283
290
|
platformTransitions: platformTransitions.length,
|
|
284
291
|
newBloblangMethods: newBloblangMethods.length,
|
|
285
292
|
removedBloblangMethods: removedBloblangMethods.length,
|
|
@@ -296,6 +303,7 @@ function generateConnectorDiffJson(oldIndex, newIndex, opts = {}) {
|
|
|
296
303
|
deprecatedComponents,
|
|
297
304
|
deprecatedFields,
|
|
298
305
|
changedDefaults,
|
|
306
|
+
documentedDefaults,
|
|
299
307
|
platformTransitions,
|
|
300
308
|
newBloblangMethods,
|
|
301
309
|
removedBloblangMethods,
|
|
@@ -646,7 +654,8 @@ function printDeltaReport(oldIndex, newIndex, opts = {}) {
|
|
|
646
654
|
const oldDefaultStr = JSON.stringify(oldDefault);
|
|
647
655
|
const newDefaultStr = JSON.stringify(newDefault);
|
|
648
656
|
|
|
649
|
-
|
|
657
|
+
// A field that had no default and now states one is not a change.
|
|
658
|
+
if (oldDefaultStr !== newDefaultStr && oldDefault !== undefined) {
|
|
650
659
|
changedDefaultsList.push({
|
|
651
660
|
component: cKey,
|
|
652
661
|
field: fName,
|
|
@@ -719,8 +728,8 @@ function printDeltaReport(oldIndex, newIndex, opts = {}) {
|
|
|
719
728
|
console.log('➤ Changed default values:');
|
|
720
729
|
changedDefaultsList.forEach(entry => {
|
|
721
730
|
const { component, field, oldDefault, newDefault } = entry;
|
|
722
|
-
const oldStr = JSON.stringify(oldDefault);
|
|
723
|
-
const newStr = JSON.stringify(newDefault);
|
|
731
|
+
const oldStr = oldDefault === undefined ? 'no default' : JSON.stringify(oldDefault);
|
|
732
|
+
const newStr = newDefault === undefined ? 'no default' : JSON.stringify(newDefault);
|
|
724
733
|
console.log(` • ${component} → ${field}`);
|
|
725
734
|
console.log(` Old: ${oldStr}`);
|
|
726
735
|
console.log(` New: ${newStr}`);
|
|
@@ -657,7 +657,8 @@ function buildChangedDefaultsTable (changedDefaults, capFn) {
|
|
|
657
657
|
const byFieldAndDefaults = {}
|
|
658
658
|
for (const change of changedDefaults) {
|
|
659
659
|
const [type, compName] = change.component.split(':')
|
|
660
|
-
|
|
660
|
+
// JSON keeps null apart from "null" and one object default apart from another.
|
|
661
|
+
const compositeKey = JSON.stringify([change.field, change.oldDefault, change.newDefault])
|
|
661
662
|
if (!byFieldAndDefaults[compositeKey]) {
|
|
662
663
|
byFieldAndDefaults[compositeKey] = {
|
|
663
664
|
field: change.field,
|
|
@@ -675,23 +676,31 @@ function buildChangedDefaultsTable (changedDefaults, capFn) {
|
|
|
675
676
|
section += '|Field |Old default |New default |Description |Affected components\n\n'
|
|
676
677
|
|
|
677
678
|
for (const [, info] of Object.entries(byFieldAndDefaults)) {
|
|
678
|
-
// Values render as literal inline code, so interpolations like
|
|
679
|
-
// ${!uuid_v4()} and characters like * or _ show as typed.
|
|
680
679
|
// Values render as literal inline code through pass:c, which, unlike
|
|
681
680
|
// `+...+`, also keeps values with ++ or with spaces at either end. Strings
|
|
682
681
|
// that are empty, start or end with whitespace, or contain a newline show
|
|
683
682
|
// as JSON, so " " and "\n" read as the values they are.
|
|
684
|
-
const formatDefault = (val) => {
|
|
685
|
-
|
|
683
|
+
const formatDefault = (val, asJson = false) => {
|
|
684
|
+
// 'none' would read as a value, and is one for some fields (compression).
|
|
685
|
+
if (val === undefined) return '_no default_'
|
|
686
686
|
let text
|
|
687
|
-
if (
|
|
687
|
+
if (asJson) text = JSON.stringify(val)
|
|
688
|
+
// A null default is declared (Default(nil)), so it renders as a value.
|
|
689
|
+
else if (val === null) text = 'null'
|
|
690
|
+
else if (typeof val === 'string') text = (val === '' || /^\s|\s$|\n/.test(val)) ? JSON.stringify(val) : val
|
|
688
691
|
else if (typeof val === 'number' || typeof val === 'boolean') text = String(val)
|
|
689
692
|
else text = JSON.stringify(val)
|
|
690
693
|
return `\`pass:c[${text.replace(/\]/g, '\\]').replace(/\|/g, '\\|')}]\``
|
|
691
694
|
}
|
|
692
695
|
|
|
693
|
-
|
|
694
|
-
|
|
696
|
+
let oldVal = formatDefault(info.oldDefault)
|
|
697
|
+
let newVal = formatDefault(info.newDefault)
|
|
698
|
+
// A type change such as "5" to 5 or "null" to null would read as no
|
|
699
|
+
// change, so show both sides as JSON.
|
|
700
|
+
if (oldVal === newVal) {
|
|
701
|
+
oldVal = formatDefault(info.oldDefault, true)
|
|
702
|
+
newVal = formatDefault(info.newDefault, true)
|
|
703
|
+
}
|
|
695
704
|
// A | in the description would end the cell and shift the row.
|
|
696
705
|
const desc = info.description ? capFn(info.description).replace(/\|/g, '\\|') : '// TODO: Add description'
|
|
697
706
|
|