@redpanda-data/docs-extensions-and-macros 4.10.5 → 4.10.7
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
|
@@ -4,9 +4,7 @@ const { execSync, spawnSync } = require('child_process');
|
|
|
4
4
|
const os = require('os');
|
|
5
5
|
const { Command, Option } = require('commander');
|
|
6
6
|
const path = require('path');
|
|
7
|
-
const yaml = require('yaml');
|
|
8
7
|
const fs = require('fs');
|
|
9
|
-
const handlebars = require('handlebars');
|
|
10
8
|
const { determineDocsBranch } = require('../cli-utils/self-managed-docs-branch.js');
|
|
11
9
|
const fetchFromGithub = require('../tools/fetch-from-github.js');
|
|
12
10
|
const { urlToXref } = require('../cli-utils/convert-doc-links.js');
|
|
@@ -1031,12 +1029,12 @@ automation
|
|
|
1031
1029
|
});
|
|
1032
1030
|
|
|
1033
1031
|
automation
|
|
1034
|
-
|
|
1032
|
+
.command('property-docs')
|
|
1035
1033
|
.description(
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1034
|
+
'Generate JSON and consolidated AsciiDoc partials for Redpanda configuration properties. ' +
|
|
1035
|
+
'By default, only extracts properties to JSON. Use --generate-partials to create consolidated ' +
|
|
1036
|
+
'AsciiDoc partials (including deprecated properties).'
|
|
1037
|
+
)
|
|
1040
1038
|
.option('--tag <tag>', 'Git tag or branch to extract from', 'dev')
|
|
1041
1039
|
.option('--diff <oldTag>', 'Also diff autogenerated properties from <oldTag> to <tag>')
|
|
1042
1040
|
.option('--overrides <path>', 'Optional JSON file with property description overrides')
|
|
@@ -1049,14 +1047,12 @@ automation
|
|
|
1049
1047
|
.option('--template-deprecated-property <path>', 'Custom Handlebars template for individual deprecated property sections')
|
|
1050
1048
|
.option('--generate-partials', 'Generate consolidated property partials (cluster-properties.adoc, topic-properties.adoc, etc.) in the partials directory')
|
|
1051
1049
|
.option('--partials-dir <path>', 'Directory for property partials (relative to output-dir)', 'partials')
|
|
1052
|
-
|
|
1053
|
-
|
|
1050
|
+
.action((options) => {
|
|
1051
|
+
verifyPropertyDependencies();
|
|
1054
1052
|
|
|
1055
1053
|
// Validate cloud support dependencies if requested
|
|
1056
1054
|
if (options.cloudSupport) {
|
|
1057
1055
|
console.log('🔍 Validating cloud support dependencies...');
|
|
1058
|
-
|
|
1059
|
-
// Check for GITHUB_TOKEN, GH_TOKEN, or REDPANDA_GITHUB_TOKEN
|
|
1060
1056
|
const token = process.env.GITHUB_TOKEN || process.env.GH_TOKEN || process.env.REDPANDA_GITHUB_TOKEN;
|
|
1061
1057
|
if (!token) {
|
|
1062
1058
|
console.error('❌ Cloud support requires GITHUB_TOKEN, GH_TOKEN, or REDPANDA_GITHUB_TOKEN environment variable');
|
|
@@ -1068,7 +1064,6 @@ automation
|
|
|
1068
1064
|
console.error(' Or: export REDPANDA_GITHUB_TOKEN=your_token_here');
|
|
1069
1065
|
process.exit(1);
|
|
1070
1066
|
}
|
|
1071
|
-
|
|
1072
1067
|
console.log('📦 Cloud support enabled - Python dependencies will be validated during execution');
|
|
1073
1068
|
if (process.env.VIRTUAL_ENV) {
|
|
1074
1069
|
console.log(` Using virtual environment: ${process.env.VIRTUAL_ENV}`);
|
|
@@ -1077,87 +1072,88 @@ automation
|
|
|
1077
1072
|
console.log('✅ GitHub token validated');
|
|
1078
1073
|
}
|
|
1079
1074
|
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
// Pass all paths as environment variables for consistency
|
|
1091
|
-
const env = { ...process.env };
|
|
1092
|
-
|
|
1093
|
-
if (overrides) {
|
|
1094
|
-
env.OVERRIDES = path.resolve(overrides);
|
|
1095
|
-
}
|
|
1096
|
-
if (options.cloudSupport) {
|
|
1097
|
-
env.CLOUD_SUPPORT = '1';
|
|
1098
|
-
}
|
|
1099
|
-
if (templates.property) {
|
|
1100
|
-
env.TEMPLATE_PROPERTY = path.resolve(templates.property);
|
|
1101
|
-
}
|
|
1102
|
-
if (templates.topicProperty) {
|
|
1103
|
-
env.TEMPLATE_TOPIC_PROPERTY = path.resolve(templates.topicProperty);
|
|
1104
|
-
}
|
|
1105
|
-
if (templates.topicPropertyMappings) {
|
|
1106
|
-
env.TEMPLATE_TOPIC_PROPERTY_MAPPINGS = path.resolve(templates.topicPropertyMappings);
|
|
1107
|
-
}
|
|
1108
|
-
if (templates.deprecated) {
|
|
1109
|
-
env.TEMPLATE_DEPRECATED = path.resolve(templates.deprecated);
|
|
1110
|
-
}
|
|
1111
|
-
if (templates.deprecatedProperty) {
|
|
1112
|
-
env.TEMPLATE_DEPRECATED_PROPERTY = path.resolve(templates.deprecatedProperty);
|
|
1113
|
-
}
|
|
1114
|
-
|
|
1115
|
-
if (tempDir) {
|
|
1116
|
-
env.OUTPUT_JSON_DIR = path.resolve(tempDir, 'examples');
|
|
1117
|
-
env.OUTPUT_AUTOGENERATED_DIR = path.resolve(tempDir);
|
|
1118
|
-
} else {
|
|
1119
|
-
env.OUTPUT_JSON_DIR = path.resolve(outDir, 'examples');
|
|
1120
|
-
env.OUTPUT_AUTOGENERATED_DIR = path.resolve(outDir);
|
|
1121
|
-
}
|
|
1122
|
-
|
|
1123
|
-
// Partials generation options
|
|
1124
|
-
if (options.generatePartials) {
|
|
1125
|
-
env.GENERATE_PARTIALS = '1';
|
|
1126
|
-
env.OUTPUT_PARTIALS_DIR = path.resolve(outDir, options.partialsDir || 'partials');
|
|
1127
|
-
}
|
|
1128
|
-
|
|
1129
|
-
const r = spawnSync('make', args, { cwd, stdio: 'inherit', env });
|
|
1130
|
-
if (r.error) {
|
|
1131
|
-
console.error(`❌ ${r.error.message}`);
|
|
1132
|
-
process.exit(1);
|
|
1133
|
-
}
|
|
1134
|
-
if (r.status !== 0) process.exit(r.status);
|
|
1135
|
-
};
|
|
1136
|
-
|
|
1137
|
-
// Collect template options
|
|
1138
|
-
const templates = {
|
|
1139
|
-
property: options.templateProperty,
|
|
1140
|
-
topicProperty: options.templateTopicProperty,
|
|
1141
|
-
topicPropertyMappings: options.templateTopicPropertyMappings,
|
|
1142
|
-
deprecated: options.templateDeprecated,
|
|
1143
|
-
deprecatedProperty: options.templateDeprecatedProperty,
|
|
1144
|
-
};
|
|
1145
|
-
|
|
1075
|
+
const newTag = options.tag;
|
|
1076
|
+
let oldTag = options.diff;
|
|
1077
|
+
const overridesPath = options.overrides;
|
|
1078
|
+
const outputDir = options.outputDir;
|
|
1079
|
+
const cwd = path.resolve(__dirname, '../tools/property-extractor');
|
|
1080
|
+
|
|
1081
|
+
// If --diff is not provided, try to get the latest-redpanda-tag from Antora attributes
|
|
1082
|
+
if (!oldTag) {
|
|
1083
|
+
oldTag = getAntoraValue('asciidoc.attributes.latest-redpanda-tag');
|
|
1146
1084
|
if (oldTag) {
|
|
1147
|
-
|
|
1148
|
-
|
|
1085
|
+
console.log(`Using latest-redpanda-tag from Antora attributes for --diff: ${oldTag}`);
|
|
1086
|
+
} else {
|
|
1087
|
+
console.log('No --diff provided and no latest-redpanda-tag found in Antora attributes. Skipping diff.');
|
|
1149
1088
|
}
|
|
1089
|
+
}
|
|
1150
1090
|
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1091
|
+
const make = (tag, overrides, templates = {}, outDir = 'modules/reference/') => {
|
|
1092
|
+
console.log(`⏳ Building property docs for ${tag}…`);
|
|
1093
|
+
const args = ['build', `TAG=${tag}`];
|
|
1094
|
+
const env = { ...process.env };
|
|
1095
|
+
if (overrides) {
|
|
1096
|
+
env.OVERRIDES = path.resolve(overrides);
|
|
1097
|
+
}
|
|
1098
|
+
if (options.cloudSupport) {
|
|
1099
|
+
env.CLOUD_SUPPORT = '1';
|
|
1100
|
+
}
|
|
1101
|
+
if (templates.property) {
|
|
1102
|
+
env.TEMPLATE_PROPERTY = path.resolve(templates.property);
|
|
1103
|
+
}
|
|
1104
|
+
if (templates.topicProperty) {
|
|
1105
|
+
env.TEMPLATE_TOPIC_PROPERTY = path.resolve(templates.topicProperty);
|
|
1106
|
+
}
|
|
1107
|
+
if (templates.topicPropertyMappings) {
|
|
1108
|
+
env.TEMPLATE_TOPIC_PROPERTY_MAPPINGS = path.resolve(templates.topicPropertyMappings);
|
|
1109
|
+
}
|
|
1110
|
+
if (templates.deprecated) {
|
|
1111
|
+
env.TEMPLATE_DEPRECATED = path.resolve(templates.deprecated);
|
|
1112
|
+
}
|
|
1113
|
+
if (templates.deprecatedProperty) {
|
|
1114
|
+
env.TEMPLATE_DEPRECATED_PROPERTY = path.resolve(templates.deprecatedProperty);
|
|
1157
1115
|
}
|
|
1116
|
+
env.OUTPUT_JSON_DIR = path.resolve(outDir, 'examples');
|
|
1117
|
+
env.OUTPUT_AUTOGENERATED_DIR = path.resolve(outDir);
|
|
1118
|
+
if (options.generatePartials) {
|
|
1119
|
+
env.GENERATE_PARTIALS = '1';
|
|
1120
|
+
env.OUTPUT_PARTIALS_DIR = path.resolve(outDir, options.partialsDir || 'partials');
|
|
1121
|
+
}
|
|
1122
|
+
const r = spawnSync('make', args, { cwd, stdio: 'inherit', env });
|
|
1123
|
+
if (r.error) {
|
|
1124
|
+
console.error(`❌ ${r.error.message}`);
|
|
1125
|
+
process.exit(1);
|
|
1126
|
+
}
|
|
1127
|
+
if (r.status !== 0) process.exit(r.status);
|
|
1128
|
+
};
|
|
1129
|
+
|
|
1130
|
+
const templates = {
|
|
1131
|
+
property: options.templateProperty,
|
|
1132
|
+
topicProperty: options.templateTopicProperty,
|
|
1133
|
+
topicPropertyMappings: options.templateTopicPropertyMappings,
|
|
1134
|
+
deprecated: options.templateDeprecated,
|
|
1135
|
+
deprecatedProperty: options.templateDeprecatedProperty,
|
|
1136
|
+
};
|
|
1137
|
+
|
|
1138
|
+
const tagsAreSame = oldTag && newTag && oldTag === newTag;
|
|
1139
|
+
if (oldTag && !tagsAreSame) {
|
|
1140
|
+
make(oldTag, overridesPath, templates, outputDir);
|
|
1141
|
+
}
|
|
1142
|
+
make(newTag, overridesPath, templates, outputDir);
|
|
1143
|
+
if (oldTag && !tagsAreSame) {
|
|
1144
|
+
generatePropertyComparisonReport(oldTag, newTag, outputDir);
|
|
1145
|
+
} else if (tagsAreSame) {
|
|
1146
|
+
console.log('--diff and --tag are the same. Skipping diff and Antora config update.');
|
|
1147
|
+
}
|
|
1158
1148
|
|
|
1159
|
-
|
|
1160
|
-
|
|
1149
|
+
// If we used Antora's latest-redpanda-tag for diff, update it to the new tag
|
|
1150
|
+
if (!options.diff && !tagsAreSame) {
|
|
1151
|
+
setAntoraValue('asciidoc.attributes.latest-redpanda-tag', newTag);
|
|
1152
|
+
console.log(`✅ Updated Antora latest-redpanda-tag to: ${newTag}`);
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
process.exit(0);
|
|
1156
|
+
});
|
|
1161
1157
|
|
|
1162
1158
|
automation
|
|
1163
1159
|
.command('rpk-docs')
|
|
@@ -10,9 +10,17 @@ const yaml = require('js-yaml');
|
|
|
10
10
|
* @returns {Object|undefined} The parsed YAML as a JavaScript object, or undefined if not found or on error.
|
|
11
11
|
*/
|
|
12
12
|
function loadAntoraConfig() {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
// Support both antora.yml and antora.yaml
|
|
14
|
+
const cwd = process.cwd();
|
|
15
|
+
const ymlPath = path.join(cwd, 'antora.yml');
|
|
16
|
+
const yamlPath = path.join(cwd, 'antora.yaml');
|
|
17
|
+
let antoraPath;
|
|
18
|
+
if (fs.existsSync(ymlPath)) {
|
|
19
|
+
antoraPath = ymlPath;
|
|
20
|
+
} else if (fs.existsSync(yamlPath)) {
|
|
21
|
+
antoraPath = yamlPath;
|
|
22
|
+
} else {
|
|
23
|
+
// No antora.yml or antora.yaml in project root
|
|
16
24
|
return undefined;
|
|
17
25
|
}
|
|
18
26
|
|
|
@@ -20,12 +28,12 @@ function loadAntoraConfig() {
|
|
|
20
28
|
const fileContents = fs.readFileSync(antoraPath, 'utf8');
|
|
21
29
|
const config = yaml.load(fileContents);
|
|
22
30
|
if (typeof config !== 'object' || config === null) {
|
|
23
|
-
console.error(
|
|
31
|
+
console.error(`Warning: ${path.basename(antoraPath)} parsed to a non‐object value.`);
|
|
24
32
|
return undefined;
|
|
25
33
|
}
|
|
26
34
|
return config;
|
|
27
35
|
} catch (err) {
|
|
28
|
-
console.error(`Error reading/parsing
|
|
36
|
+
console.error(`Error reading/parsing ${path.basename(antoraPath)}: ${err.message}`);
|
|
29
37
|
return undefined;
|
|
30
38
|
}
|
|
31
39
|
}
|
|
@@ -74,9 +82,17 @@ function getAntoraValue(keyPath) {
|
|
|
74
82
|
* True if it succeeded, false otherwise.
|
|
75
83
|
*/
|
|
76
84
|
function setAntoraValue(keyPath, newValue) {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
85
|
+
// Support both antora.yml and antora.yaml
|
|
86
|
+
const cwd = process.cwd();
|
|
87
|
+
const ymlPath = path.join(cwd, 'antora.yml');
|
|
88
|
+
const yamlPath = path.join(cwd, 'antora.yaml');
|
|
89
|
+
let antoraPath;
|
|
90
|
+
if (fs.existsSync(ymlPath)) {
|
|
91
|
+
antoraPath = ymlPath;
|
|
92
|
+
} else if (fs.existsSync(yamlPath)) {
|
|
93
|
+
antoraPath = yamlPath;
|
|
94
|
+
} else {
|
|
95
|
+
console.error('Cannot update antora.yml or antora.yaml: file not found in project root.');
|
|
80
96
|
return false;
|
|
81
97
|
}
|
|
82
98
|
|
|
@@ -88,7 +104,7 @@ function setAntoraValue(keyPath, newValue) {
|
|
|
88
104
|
config = {};
|
|
89
105
|
}
|
|
90
106
|
} catch (err) {
|
|
91
|
-
console.error(`Error reading/parsing
|
|
107
|
+
console.error(`Error reading/parsing ${path.basename(antoraPath)}: ${err.message}`);
|
|
92
108
|
return false;
|
|
93
109
|
}
|
|
94
110
|
|
|
@@ -115,7 +131,37 @@ function setAntoraValue(keyPath, newValue) {
|
|
|
115
131
|
fs.writeFileSync(antoraPath, newYaml, 'utf8');
|
|
116
132
|
return true;
|
|
117
133
|
} catch (err) {
|
|
118
|
-
console.error(`Error writing
|
|
134
|
+
console.error(`Error writing ${path.basename(antoraPath)}: ${err.message}`);
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Look for antora.yml in the current working directory
|
|
141
|
+
* (the project's root), load it if present, and return
|
|
142
|
+
* its `prerelease` value (boolean). If missing or on error,
|
|
143
|
+
* returns false.
|
|
144
|
+
*/
|
|
145
|
+
function getPrereleaseFromAntora() {
|
|
146
|
+
// Support both antora.yml and antora.yaml
|
|
147
|
+
const cwd = process.cwd();
|
|
148
|
+
const ymlPath = path.join(cwd, 'antora.yml');
|
|
149
|
+
const yamlPath = path.join(cwd, 'antora.yaml');
|
|
150
|
+
let antoraPath;
|
|
151
|
+
if (fs.existsSync(ymlPath)) {
|
|
152
|
+
antoraPath = ymlPath;
|
|
153
|
+
} else if (fs.existsSync(yamlPath)) {
|
|
154
|
+
antoraPath = yamlPath;
|
|
155
|
+
} else {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
try {
|
|
160
|
+
const fileContents = fs.readFileSync(antoraPath, 'utf8');
|
|
161
|
+
const antoraConfig = yaml.load(fileContents);
|
|
162
|
+
return antoraConfig.prerelease === true;
|
|
163
|
+
} catch (error) {
|
|
164
|
+
console.error(`Error reading ${path.basename(antoraPath)}:`, error.message);
|
|
119
165
|
return false;
|
|
120
166
|
}
|
|
121
167
|
}
|
|
@@ -124,4 +170,5 @@ module.exports = {
|
|
|
124
170
|
loadAntoraConfig,
|
|
125
171
|
getAntoraValue,
|
|
126
172
|
setAntoraValue,
|
|
173
|
+
getPrereleaseFromAntora
|
|
127
174
|
};
|
package/package.json
CHANGED
package/tools/bundle-openapi.js
CHANGED
|
@@ -28,21 +28,15 @@ function normalizeTag(tag) {
|
|
|
28
28
|
throw new Error('Invalid version format: tag cannot be empty');
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
// Handle dev branch
|
|
32
|
-
if (tag === 'dev') {
|
|
33
|
-
return 'dev';
|
|
34
|
-
}
|
|
35
|
-
|
|
36
31
|
// Remove 'v' prefix if present
|
|
37
32
|
const normalized = tag.startsWith('v') ? tag.slice(1) : tag;
|
|
38
|
-
|
|
39
33
|
// Validate semantic version format
|
|
40
34
|
const semverPattern = /^\d+\.\d+\.\d+(-[\w\.-]+)?(\+[\w\.-]+)?$/;
|
|
41
|
-
if (
|
|
42
|
-
|
|
35
|
+
if (semverPattern.test(normalized)) {
|
|
36
|
+
return normalized;
|
|
43
37
|
}
|
|
44
|
-
|
|
45
|
-
return
|
|
38
|
+
// If not a valid semver, treat as branch name and return as-is
|
|
39
|
+
return tag;
|
|
46
40
|
}
|
|
47
41
|
|
|
48
42
|
/**
|
|
@@ -59,22 +53,20 @@ function getMajorMinor(version) {
|
|
|
59
53
|
throw new Error('Version must be a non-empty string');
|
|
60
54
|
}
|
|
61
55
|
|
|
62
|
-
if (
|
|
63
|
-
|
|
56
|
+
// Only process if valid semver, else return as-is (branch name)
|
|
57
|
+
const semverPattern = /^\d+\.\d+\.\d+(-[\w\.-]+)?(\+[\w\.-]+)?$/;
|
|
58
|
+
if (!semverPattern.test(version)) {
|
|
59
|
+
return version;
|
|
64
60
|
}
|
|
65
|
-
|
|
66
61
|
const parts = version.split('.');
|
|
67
62
|
if (parts.length < 2) {
|
|
68
63
|
throw new Error(`Invalid version format: ${version}. Expected X.Y.Z format`);
|
|
69
64
|
}
|
|
70
|
-
|
|
71
65
|
const major = parseInt(parts[0], 10);
|
|
72
66
|
const minor = parseInt(parts[1], 10);
|
|
73
|
-
|
|
74
67
|
if (isNaN(major) || isNaN(minor)) {
|
|
75
68
|
throw new Error(`Major and minor versions must be numbers: ${version}`);
|
|
76
69
|
}
|
|
77
|
-
|
|
78
70
|
return `${major}.${minor}`;
|
|
79
71
|
}
|
|
80
72
|
|
|
@@ -4,7 +4,7 @@ const yaml = require('js-yaml');
|
|
|
4
4
|
const fs = require('fs');
|
|
5
5
|
const path = require('path');
|
|
6
6
|
const GetLatestConsoleVersion = require('../extensions/version-fetcher/get-latest-console-version.js');
|
|
7
|
-
const { getPrereleaseFromAntora } = require('../cli-utils/
|
|
7
|
+
const { getPrereleaseFromAntora } = require('../cli-utils/antora-utils.js');
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Fetches and prints the latest Console version and Docker repo.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
const GetLatestRedpandaVersion = require('../extensions/version-fetcher/get-latest-redpanda-version.js');
|
|
4
|
-
const { getPrereleaseFromAntora } = require('../cli-utils/
|
|
4
|
+
const { getPrereleaseFromAntora } = require('../cli-utils/antora-utils.js');
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Fetches and prints the latest Redpanda version and Docker repository.
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const yaml = require('js-yaml');
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Look for antora.yml in the current working directory
|
|
7
|
-
* (the project's root), load it if present, and return
|
|
8
|
-
* its `prerelease` value (boolean). If missing or on error,
|
|
9
|
-
* returns false.
|
|
10
|
-
*/
|
|
11
|
-
function getPrereleaseFromAntora() {
|
|
12
|
-
const antoraPath = path.join(process.cwd(), 'antora.yml');
|
|
13
|
-
if (!fs.existsSync(antoraPath)) {
|
|
14
|
-
return false;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
try {
|
|
18
|
-
const fileContents = fs.readFileSync(antoraPath, 'utf8');
|
|
19
|
-
const antoraConfig = yaml.load(fileContents);
|
|
20
|
-
return antoraConfig.prerelease === true;
|
|
21
|
-
} catch (error) {
|
|
22
|
-
console.error('Error reading antora.yml:', error.message);
|
|
23
|
-
return false;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
module.exports = { getPrereleaseFromAntora };
|