Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
5af71f3
Add support for overrides and proper defaults
JakeSCahill Sep 4, 2025
4abacc2
Add support for providing examples in overrides
JakeSCahill Sep 4, 2025
2b937b2
Add support for overriding version
JakeSCahill Sep 4, 2025
d5beb57
Add support for templates
JakeSCahill Sep 5, 2025
55f4bc7
Apply suggestions
JakeSCahill Sep 6, 2025
6a83c7b
Update directories for output files
JakeSCahill Sep 7, 2025
61b7d89
Do not add name field
JakeSCahill Sep 8, 2025
7ce5cba
Fix test
JakeSCahill Sep 8, 2025
96b32be
Save only final properties to examples dir
JakeSCahill Sep 8, 2025
aa75591
Remove duplicates
JakeSCahill Sep 8, 2025
988d647
Bump version
JakeSCahill Sep 8, 2025
bf3f2b7
Improve error reporting
JakeSCahill Sep 8, 2025
98dd16b
Increase timeout
JakeSCahill Sep 8, 2025
95bcbce
Mock data for faster testing
JakeSCahill Sep 8, 2025
d447e48
Simplify
JakeSCahill Sep 8, 2025
1808fd1
Apply suggestions
JakeSCahill Sep 8, 2025
268a8ff
Allow for null defaults
JakeSCahill Sep 8, 2025
0ac1d62
Fix dirs
JakeSCahill Sep 8, 2025
649698b
Apply suggestions
JakeSCahill Sep 9, 2025
a291a59
Update tools/property-extractor/generate-handlebars-docs.js
JakeSCahill Sep 9, 2025
47bc9c7
Update deprecated
JakeSCahill Sep 9, 2025
e89296f
Fix doc
JakeSCahill Sep 12, 2025
1fbbff7
Merge branch 'end-to-end-config-property-automation' of https://githu…
JakeSCahill Sep 12, 2025
f08e9ba
Merge branch 'main' of https://github.com/redpanda-data/docs-extensio…
JakeSCahill Sep 12, 2025
7f834e7
Integrate topic property automation
JakeSCahill Sep 12, 2025
63d0d99
Bump version
JakeSCahill Sep 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/node_modules/*
/wip/*
/docs/*
.vscode
Expand All @@ -10,4 +9,5 @@ gen/
tree-sitter/
test/
modules/
cloud-controlplane/
cloud-controlplane/
node_modules
15 changes: 15 additions & 0 deletions __tests__/docs-data/examples/admin-example.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.Example Configuration for Admin API
This example shows how to configure the admin API endpoint with custom addressing.

[,yaml]
----
redpanda:
admin:
- address: "0.0.0.0"
port: 9644
- address: "127.0.0.1"
port: 9645
----

You can specify multiple admin endpoints to provide redundancy and load balancing.
The admin API is used for cluster management operations.
53 changes: 53 additions & 0 deletions __tests__/docs-data/property-overrides.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"properties": {
"admin": {
"description": "Network addresses for Admin API servers with version info.",
"version": "v23.1.0",
"example_file": "examples/admin-example.adoc"
},
"admin_api_tls": {
"description": "TLS configuration for the Admin API endpoints.",
"version": "v23.2.0",
"example_yaml": {
"title": "Example TLS Configuration",
"description": "This example shows how to configure TLS for the Admin API with client authentication.",
"config": {
"redpanda": {
"admin_api_tls": [
{
"name": "internal-admin",
"enabled": true,
"cert_file": "/etc/redpanda/certs/admin.crt",
"key_file": "/etc/redpanda/certs/admin.key",
"truststore_file": "/etc/redpanda/certs/ca.crt",
"require_client_auth": true
}
]
}
}
}
},
"abort_index_segment_size": {
"description": "Segment size for transaction abort index. Controls how large each abort index segment can grow.",
"example": [
".Example: Setting abort index segment size",
"[,yaml]",
"----",
"redpanda:",
" abort_index_segment_size: 134217728 # 128MB",
"----",
"",
"This setting controls the maximum size of abort index segments.",
"Smaller segments may improve memory usage but increase overhead."
]
},
"append_chunk_size": {
"description": "Size of data chunks for append operations.",
"version": "v24.1.0",
"example": "67108864"
},
"cloud_storage_access_key": {
"description": "Access key for cloud storage authentication. Used to authenticate with S3-compatible object storage services."
}
}
}
63 changes: 63 additions & 0 deletions __tests__/tools/property-docs-overrides.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Integration test for property-docs description override functionality using Jest
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const os = require('os');

const repoRoot = path.resolve(__dirname, '..', '..');
const docTools = path.join(repoRoot, 'bin', 'doc-tools.js');
const overridesFile = path.join(repoRoot, '__tests__', 'docs-data', 'property-overrides.json');

describe('property-docs description override', () => {
let tempOutdir;

beforeAll(() => {
tempOutdir = fs.mkdtempSync(path.join(os.tmpdir(), 'property-docs-test-'));
});

afterAll(() => {
fs.rmSync(tempOutdir, { recursive: true, force: true });
});

it('applies the override description for admin property', () => {
const command = `node "${docTools}" generate property-docs --tag v25.2.3 --overrides "${overridesFile}" --output-dir "${tempOutdir}"`;

try {
execSync(command, {
cwd: repoRoot,
stdio: 'pipe', // Capture output instead of inheriting
timeout: 120000 // 2 minute timeout for slower CI environments
});
} catch (error) {
const cleanError = new Error(`Command failed: ${error.message}`);
cleanError.code = error.code;
cleanError.signal = error.signal;

if (error.stdout) {
cleanError.stdout = error.stdout.toString();
}
if (error.stderr) {
cleanError.stderr = error.stderr.toString();
}

throw cleanError;
}

// Check that the generated file exists
const outFile = path.join(tempOutdir, 'pages', 'broker-properties.adoc');
expect(fs.existsSync(outFile)).toBe(true);
// Read the generated content
const content = fs.readFileSync(outFile, 'utf8');
// Load the overrides and check that they were applied
const overrides = JSON.parse(fs.readFileSync(overridesFile, 'utf8'));
const adminOverride = overrides.properties.admin;
expect(adminOverride).toBeTruthy();
expect(adminOverride.description).toBeTruthy();
// Verify the override description appears in the generated docs
expect(content).toContain(adminOverride.description);
// Verify the version override is applied
if (adminOverride.version) {
expect(content).toContain(`*Introduced in ${adminOverride.version}*`);
}
}, 150000);
});
67 changes: 61 additions & 6 deletions bin/doc-tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ function requireCmd(cmd, help, versionFlag = '--version') {
* @param {number} [minMinor=10] - Minimum required minor version of Python.
*/
function requirePython(minMajor = 3, minMinor = 10) {
const candidates = ['python3', 'python'];
const candidates = ['python3', 'python', 'python3.12', 'python3.11', 'python3.10'];
for (const p of candidates) {
try {
const out = execSync(`${p} --version`, { encoding: 'utf8' }).trim();
Expand Down Expand Up @@ -234,12 +234,16 @@ For more details, visit: https://github.com/norwoodj/helm-docs
/**
* Ensures all dependencies required for generating property documentation are installed.
*
* Checks for the presence of `make`, Python 3.10 or newer, C++ compiler, and C++ standard library headers.
* Checks for the presence of `make`, Python 3.10 or newer, Node.js, C++ compiler, and C++ standard library headers.
* Exits the process with an error message if any dependency is missing.
*/
function verifyPropertyDependencies() {
requireCmd('make', 'Your OS package manager');
requirePython();

// Check for Node.js (required for Handlebars templates)
requireCmd('node', 'https://nodejs.org/en/download/ or use your package manager (e.g., brew install node)');
requireCmd('npm', 'Usually installed with Node.js');

// Check for C++ compiler
let cppCompiler = null;
Expand Down Expand Up @@ -747,28 +751,79 @@ automation
.description('Generate JSON and AsciiDoc documentation for Redpanda configuration properties')
.option('--tag <tag>', 'Git tag or branch to extract from', 'dev')
.option('--diff <oldTag>', 'Also diff autogenerated properties from <oldTag> → <tag>')
.option('--overrides <path>', 'Optional JSON file with property description overrides')
.option('--output-dir <dir>', 'Where to write all generated AsciiDoc files', 'modules/reference/pages')
.option('--template-property-page <path>', 'Custom Handlebars template for property page layout')
.option('--template-property <path>', 'Custom Handlebars template for individual property sections')
.option('--template-deprecated <path>', 'Custom Handlebars template for deprecated properties page')
.option('--template-deprecated-property <path>', 'Custom Handlebars template for individual deprecated property sections')
.action((options) => {
verifyPropertyDependencies();

const newTag = options.tag;
const oldTag = options.diff;
const overridesPath = options.overrides;
const outputDir = options.outputDir;
const cwd = path.resolve(__dirname, '../tools/property-extractor');
const make = (tag) => {

const make = (tag, overrides, templates = {}, outputDir = 'modules/reference/pages') => {
console.log(`⏳ Building property docs for ${tag}…`);
const r = spawnSync('make', ['build', `TAG=${tag}`], { cwd, stdio: 'inherit' });
const args = ['build', `TAG=${tag}`];

// Pass all paths as environment variables for consistency
const env = { ...process.env };
if (overrides) {
env.OVERRIDES = path.resolve(overrides);
}
if (templates.propertyPage) {
env.TEMPLATE_PROPERTY_PAGE = path.resolve(templates.propertyPage);
}
if (templates.property) {
env.TEMPLATE_PROPERTY = path.resolve(templates.property);
}
if (templates.deprecated) {
env.TEMPLATE_DEPRECATED = path.resolve(templates.deprecated);
}
if (templates.deprecatedProperty) {
env.TEMPLATE_DEPRECATED_PROPERTY = path.resolve(templates.deprecatedProperty);
}

// Set output directories - everything goes into autogenerated for consistency with diff function
env.OUTPUT_ASCIIDOC_DIR = path.resolve('autogenerated', tag, 'properties', 'pages');
env.OUTPUT_JSON_DIR = path.resolve('autogenerated', tag, 'properties', 'examples');
env.OUTPUT_AUTOGENERATED_DIR = path.resolve('autogenerated', tag, 'properties');

// Also set the final output directory for copying AsciiDoc files
env.FINAL_OUTPUT_DIR = path.resolve(outputDir);

// Set the final JSON output directory to be the examples subdirectory inside outputDir
env.FINAL_JSON_OUTPUT_DIR = path.resolve(outputDir, 'examples');

// Everything else (errors, all-properties.txt) goes to /autogenerated
env.FINAL_AUTOGENERATED_DIR = path.resolve('autogenerated');

const r = spawnSync('make', args, { cwd, stdio: 'inherit', env });
if (r.error) {
console.error(`❌ ${r.error.message}`);
process.exit(1);
}
if (r.status !== 0) process.exit(r.status);
};

// Collect template options
const templates = {
propertyPage: options.templatePropertyPage,
property: options.templateProperty,
deprecated: options.templateDeprecated,
deprecatedProperty: options.templateDeprecatedProperty
};

if (oldTag) {
const oldDir = path.join('autogenerated', oldTag, 'properties');
if (!fs.existsSync(oldDir)) make(oldTag);
if (!fs.existsSync(oldDir)) make(oldTag, overridesPath, templates, outputDir);
}

make(newTag);
make(newTag, overridesPath, templates, outputDir);

if (oldTag) {
diffDirs('properties', oldTag, newTag);
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@redpanda-data/docs-extensions-and-macros",
"version": "4.7.4",
"version": "4.8.0",
"description": "Antora extensions and macros developed for Redpanda documentation.",
"keywords": [
"antora",
Expand Down
Loading
Loading