@redpanda-data/docs-extensions-and-macros 5.13.3 → 5.13.4
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.
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Shared `major.minor` derivation.
|
|
5
|
+
*
|
|
6
|
+
* Two variants exist because the callers have genuinely different contracts, and
|
|
7
|
+
* they live side by side here so a third copy never gets written:
|
|
8
|
+
*
|
|
9
|
+
* - `getMajorMinor` is strict. It is used by the OpenAPI bundler, where a bad
|
|
10
|
+
* version is a build error and a Git branch name (for example, `dev`) must
|
|
11
|
+
* pass through untouched.
|
|
12
|
+
* - `toShortVersion` is lenient. It is used by the Antora version fetcher, where
|
|
13
|
+
* a non-semver release channel (for example, `nightly`) must simply not
|
|
14
|
+
* produce a `-version-short` attribute rather than throw or leak the raw
|
|
15
|
+
* value into the docs.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
// A complete semantic version, optionally with prerelease and build metadata.
|
|
19
|
+
const SEMVER_PATTERN = /^\d+\.\d+\.\d+(-[\w.-]+)?(\+[\w.-]+)?$/;
|
|
20
|
+
|
|
21
|
+
// A leading `<major>.<minor>` pair that is followed by a separator or the end of
|
|
22
|
+
// the string. This also accepts two-part versions such as `26.2`, which Antora
|
|
23
|
+
// components use, and which `SEMVER_PATTERN` rejects.
|
|
24
|
+
const MAJOR_MINOR_PATTERN = /^(\d+)\.(\d+)(?:[.+-]|$)/;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Return the major.minor portion of a semantic version string.
|
|
28
|
+
*
|
|
29
|
+
* Accepts a semantic version like `25.1.1` and yields `25.1`. A value that is
|
|
30
|
+
* not a semantic version (for example, the branch name `dev`) is returned
|
|
31
|
+
* unchanged.
|
|
32
|
+
* @param {string} version - Semantic version (for example, `'25.1.1'`) or a branch name.
|
|
33
|
+
* @returns {string} The `major.minor` string (for example, `'25.1'`) or the input unchanged.
|
|
34
|
+
* @throws {Error} If `version` is not a non-empty string, lacks major/minor parts, or if major/minor are not numeric.
|
|
35
|
+
*/
|
|
36
|
+
function getMajorMinor(version) {
|
|
37
|
+
if (!version || typeof version !== 'string') {
|
|
38
|
+
throw new Error('Version must be a non-empty string');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Only process if valid semver, else return as-is (branch name)
|
|
42
|
+
if (!SEMVER_PATTERN.test(version)) {
|
|
43
|
+
return version;
|
|
44
|
+
}
|
|
45
|
+
const parts = version.split('.');
|
|
46
|
+
if (parts.length < 2) {
|
|
47
|
+
throw new Error(`Invalid version format: ${version}. Expected X.Y.Z format`);
|
|
48
|
+
}
|
|
49
|
+
const major = parseInt(parts[0], 10);
|
|
50
|
+
const minor = parseInt(parts[1], 10);
|
|
51
|
+
if (isNaN(major) || isNaN(minor)) {
|
|
52
|
+
throw new Error(`Major and minor versions must be numbers: ${version}`);
|
|
53
|
+
}
|
|
54
|
+
return `${major}.${minor}`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Return the major.minor portion of a version, or `null` when there is none.
|
|
59
|
+
*
|
|
60
|
+
* Unlike `getMajorMinor`, this never throws and never returns a value that is
|
|
61
|
+
* not a `major.minor` pair, so a caller can treat `null` as "no short version
|
|
62
|
+
* exists for this release channel". Leading zeros are normalized, so `26.02.1`
|
|
63
|
+
* yields `26.2`. The `v` prefix is not accepted: sanitize it first.
|
|
64
|
+
* @param {string} version - Version without a `v` prefix (for example, `'26.2.1'`).
|
|
65
|
+
* @returns {string|null} The `major.minor` string, or `null` for anything else.
|
|
66
|
+
*/
|
|
67
|
+
function toShortVersion(version) {
|
|
68
|
+
if (!version || typeof version !== 'string') return null;
|
|
69
|
+
const match = MAJOR_MINOR_PATTERN.exec(version);
|
|
70
|
+
return match ? `${Number(match[1])}.${Number(match[2])}` : null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
module.exports = { getMajorMinor, toShortVersion };
|
|
@@ -428,19 +428,53 @@ antora:
|
|
|
428
428
|
|
|
429
429
|
This extension fetches the latest release versions from GitHub.
|
|
430
430
|
|
|
431
|
+
=== Attributes
|
|
432
|
+
|
|
431
433
|
The following attributes are available to all versions of all Antora components:
|
|
432
434
|
|
|
433
|
-
`latest-console-version
|
|
434
|
-
`latest-connect-version
|
|
435
|
-
`redpanda-beta-version
|
|
436
|
-
`redpanda-beta-commit
|
|
435
|
+
`latest-console-version`:: The latest release version of Redpanda Console.
|
|
436
|
+
`latest-connect-version`:: The latest release version of Redpanda Connect.
|
|
437
|
+
`redpanda-beta-version`:: The latest RC version of Redpanda.
|
|
438
|
+
`redpanda-beta-commit`:: The commit hash for the latest RC version of Redpanda.
|
|
439
|
+
`console-beta-version`:: The latest beta version of Redpanda Console.
|
|
440
|
+
`operator-beta-version`:: The latest beta version of the Redpanda Operator.
|
|
441
|
+
`helm-beta-version`:: The latest beta version of the Redpanda Helm chart.
|
|
442
|
+
`latest-operator-version`:: The latest release version of the Redpanda Operator. This value keeps its `v` prefix (for example, `v25.1.3`) because pages pass it straight to `helm --version`.
|
|
443
|
+
`latest-redpanda-helm-chart-version`:: The latest release version of the Redpanda Helm chart.
|
|
444
|
+
|
|
445
|
+
The following attributes are available to the latest version of each Antora component:
|
|
446
|
+
|
|
447
|
+
`full-version`:: The latest release version of Redpanda. Only ever moves forwards: if the component's `antora.yml` already pins a higher version, that pin wins.
|
|
448
|
+
`latest-redpanda-version`:: The latest release version of Redpanda.
|
|
449
|
+
`latest-release-commit`:: The commit hash for the latest release version of Redpanda.
|
|
450
|
+
|
|
451
|
+
==== Tag and short-version siblings
|
|
452
|
+
|
|
453
|
+
Most `<base>-version` attributes in the previous lists also get two siblings.
|
|
454
|
+
`full-version` is the exception and gets neither, because it is set directly
|
|
455
|
+
rather than through the shared helper, and it is the one attribute that only
|
|
456
|
+
ever moves forwards.
|
|
457
|
+
|
|
458
|
+
`<base>-tag`:: The version exactly as the release publishes it, including any `v` prefix (for example, `latest-redpanda-tag` is `v26.2.1`). Use this for container image tags and Git references. There is no tag attribute for `latest-operator-version` or `latest-redpanda-helm-chart-version`, which are already raw values.
|
|
459
|
+
`<base>-version-short`:: Only the `major.minor` part (for example, `latest-redpanda-version-short` is `26.2` when `latest-redpanda-version` is `26.2.1`). Use this where a page needs the release line rather than an exact patch, such as a download directory or an install pack name.
|
|
437
460
|
|
|
438
|
-
|
|
461
|
+
A short attribute is only set when a `major.minor` pair can be derived. Release channels that are not versions, such as `nightly` or `latest`, get a `-version` and a `-tag` but no `-version-short`, so a page never renders a fabricated release line.
|
|
462
|
+
|
|
463
|
+
==== Seed a fallback in antora.yml
|
|
464
|
+
|
|
465
|
+
Every attribute here depends on a successful GitHub lookup at build time. If a lookup fails, for example because of a rate limit or a missing token, the attribute is never set and any page that references it renders the attribute name in braces.
|
|
466
|
+
|
|
467
|
+
To keep a page buildable, seed a soft default in the consuming component's `antora.yml`. The trailing `@` makes it a fallback that the extension overwrites when the fetch succeeds:
|
|
468
|
+
|
|
469
|
+
[,yaml]
|
|
470
|
+
----
|
|
471
|
+
asciidoc:
|
|
472
|
+
attributes:
|
|
473
|
+
latest-redpanda-version: 26.2.1@
|
|
474
|
+
latest-redpanda-version-short: 26.2@
|
|
475
|
+
----
|
|
439
476
|
|
|
440
|
-
`full-version
|
|
441
|
-
`latest-release-commit`: The commit hash for the latest release version of Redpanda.
|
|
442
|
-
`latest-operator-version`: The latest release version of the Redpanda Operator.
|
|
443
|
-
`latest-redpanda-helm-chart-version`: The latest release version of the Redpanda Helm chart.
|
|
477
|
+
CAUTION: Do not seed `full-version` with a value higher than the current release. `full-version` is the one attribute the extension refuses to move backwards, so a pin that is ahead of the current release stays ahead.
|
|
444
478
|
|
|
445
479
|
=== Environment variables
|
|
446
480
|
|
|
@@ -36,20 +36,45 @@ module.exports = async (github, owner, repo, logger = null) => {
|
|
|
36
36
|
release => release.tag_name.includes('-rc') && !release.draft
|
|
37
37
|
);
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
39
|
+
// A release can exist before its tag is pushed, which is routine for draft
|
|
40
|
+
// RCs, and GitHub answers the ref lookup with a 404. Losing the commit hash
|
|
41
|
+
// must not cost us the version: an uncaught 404 here aborts the whole
|
|
42
|
+
// lookup and every latest-redpanda-* attribute goes unset for the build.
|
|
43
|
+
const resolveCommitHash = async (release) => {
|
|
44
|
+
if (!release) return null;
|
|
45
|
+
try {
|
|
46
|
+
// Retry the ref lookup on its own. A rate limit or a 5xx is transient
|
|
47
|
+
// and deserves the attempts; swallowing it immediately turned one
|
|
48
|
+
// blip into a permanently unset commit attribute. Retrying HERE
|
|
49
|
+
// rather than letting the error escape is what keeps a exhausted
|
|
50
|
+
// retry from also costing us the version, which is strictly worse
|
|
51
|
+
// than losing the commit hash.
|
|
52
|
+
const commitData = await retryWithBackoff(
|
|
53
|
+
() => github.rest.git.getRef({ owner, repo, ref: `tags/${release.tag_name}` }),
|
|
54
|
+
{ shouldRetry: isRetryableGitHubError, operationName: `getRef ${release.tag_name}` },
|
|
55
|
+
logger
|
|
56
|
+
);
|
|
57
|
+
return commitData.data.object.sha.substring(0, 7);
|
|
58
|
+
} catch (error) {
|
|
59
|
+
const message = `Could not resolve the commit for ${release.tag_name}, so its commit attribute is unset: ${error.status || ''} ${error.message || error}`;
|
|
60
|
+
if (logger) {
|
|
61
|
+
logger.warn(message);
|
|
62
|
+
} else {
|
|
63
|
+
console.warn(message);
|
|
64
|
+
}
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const latestRedpandaReleaseCommitHash = await resolveCommitHash(latestRedpandaRelease);
|
|
48
70
|
|
|
49
|
-
//
|
|
50
|
-
//
|
|
51
|
-
//
|
|
52
|
-
//
|
|
71
|
+
// The RC's tag is resolved separately, not through resolveCommitHash:
|
|
72
|
+
// a missing tag must exclude the RC entirely (it's an unpublished
|
|
73
|
+
// draft slipping through by version alone, the bug this guards
|
|
74
|
+
// against), not just null out its commit hash while still reporting
|
|
75
|
+
// the draft's version as latest. Only a missing tag (404) is
|
|
76
|
+
// tolerated; any other error still propagates so retryWithBackoff can
|
|
77
|
+
// retry it.
|
|
53
78
|
let latestRcReleaseCommitHash = null;
|
|
54
79
|
let resolvedRcRelease = latestRcRelease;
|
|
55
80
|
if (latestRcRelease) {
|
|
@@ -59,7 +84,7 @@ module.exports = async (github, owner, repo, logger = null) => {
|
|
|
59
84
|
repo,
|
|
60
85
|
ref: `tags/${latestRcRelease.tag_name}`
|
|
61
86
|
});
|
|
62
|
-
latestRcReleaseCommitHash = rcCommitData.data.object.sha;
|
|
87
|
+
latestRcReleaseCommitHash = rcCommitData.data.object.sha.substring(0, 7);
|
|
63
88
|
} catch (error) {
|
|
64
89
|
if (error.status !== 404) throw error;
|
|
65
90
|
const message = `No git tag for RC release ${latestRcRelease.tag_name}; ignoring it.`;
|
|
@@ -75,11 +100,11 @@ module.exports = async (github, owner, repo, logger = null) => {
|
|
|
75
100
|
return {
|
|
76
101
|
latestRedpandaRelease: latestRedpandaRelease ? {
|
|
77
102
|
version: latestRedpandaRelease.tag_name,
|
|
78
|
-
commitHash: latestRedpandaReleaseCommitHash
|
|
103
|
+
commitHash: latestRedpandaReleaseCommitHash
|
|
79
104
|
} : null,
|
|
80
105
|
latestRcRelease: resolvedRcRelease ? {
|
|
81
106
|
version: resolvedRcRelease.tag_name,
|
|
82
|
-
commitHash: latestRcReleaseCommitHash
|
|
107
|
+
commitHash: latestRcReleaseCommitHash
|
|
83
108
|
} : null
|
|
84
109
|
};
|
|
85
110
|
},
|
|
@@ -5,13 +5,14 @@ const { raiseListenerLimit } = require('../util/raise-listener-limit')
|
|
|
5
5
|
module.exports.register = function ({ config }) {
|
|
6
6
|
raiseListenerLimit(this)
|
|
7
7
|
const GetLatestRedpandaVersion = require('./get-latest-redpanda-version');
|
|
8
|
-
const GetLatestConsoleVersion = require('./get-latest-console-version');
|
|
9
8
|
const GetLatestDockerTag = require('./fetch-latest-docker-tag');
|
|
10
9
|
const GetLatestHelmChartVersionFromOperator = require('./get-latest-redpanda-helm-version-from-operator');
|
|
11
10
|
const GetLatestConnectVersion = require('./get-latest-connect');
|
|
12
11
|
const logger = this.getLogger('set-latest-version-extension');
|
|
13
12
|
|
|
14
13
|
const { getGitHubToken } = require('../../cli-utils/github-token');
|
|
14
|
+
// Shared with tools/bundle-openapi.js so there is one major.minor derivation.
|
|
15
|
+
const { toShortVersion } = require('../../cli-utils/version');
|
|
15
16
|
const token = getGitHubToken();
|
|
16
17
|
|
|
17
18
|
if (!token) {
|
|
@@ -92,7 +93,10 @@ module.exports.register = function ({ config }) {
|
|
|
92
93
|
asciidoc.attributes['page-component-version-is-prerelease'] = 'true';
|
|
93
94
|
}
|
|
94
95
|
|
|
95
|
-
// Set operator and helm chart attributes via helper function
|
|
96
|
+
// Set operator and helm chart attributes via helper function. These keep
|
|
97
|
+
// their raw fetched form, including the "v" prefix on
|
|
98
|
+
// latest-operator-version, because docs pages pass that value straight
|
|
99
|
+
// to `helm --version`. Only the short sibling is derived.
|
|
96
100
|
updateAttributes(asciidoc, [
|
|
97
101
|
{ condition: latestVersions.operator, key: 'latest-operator-version', value: latestVersions.operator?.latestStableRelease },
|
|
98
102
|
{ condition: latestVersions.helmChart, key: 'latest-redpanda-helm-chart-version', value: latestVersions.helmChart?.latestStableRelease }
|
|
@@ -111,7 +115,9 @@ module.exports.register = function ({ config }) {
|
|
|
111
115
|
// Special handling for Redpanda RC versions if in beta
|
|
112
116
|
if (latestVersions.redpanda?.latestRcRelease?.version) {
|
|
113
117
|
setVersionAndTagAttributes(asciidoc, 'redpanda-beta', latestVersions.redpanda.latestRcRelease.version, name, version);
|
|
114
|
-
|
|
118
|
+
if (latestVersions.redpanda.latestRcRelease.commitHash) {
|
|
119
|
+
asciidoc.attributes['redpanda-beta-commit'] = latestVersions.redpanda.latestRcRelease.commitHash;
|
|
120
|
+
}
|
|
115
121
|
}
|
|
116
122
|
if (latestVersions.console?.latestBetaRelease) {
|
|
117
123
|
setVersionAndTagAttributes(asciidoc, 'console-beta', latestVersions.console.latestBetaRelease, name, version);
|
|
@@ -126,36 +132,66 @@ module.exports.register = function ({ config }) {
|
|
|
126
132
|
|
|
127
133
|
if (!component.latest.asciidoc) component.latest.asciidoc = { attributes: {} };
|
|
128
134
|
|
|
129
|
-
// For Redpanda GA
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
135
|
+
// For the Redpanda GA release, always publish latest-redpanda-version,
|
|
136
|
+
// latest-redpanda-tag, latest-redpanda-version-short and
|
|
137
|
+
// latest-release-commit. They describe the newest release, so they must
|
|
138
|
+
// not depend on how the component pins full-version: consuming repos seed
|
|
139
|
+
// full-version at the current GA (both docs and cloud-docs sit at 26.2.1
|
|
140
|
+
// today), which made the whole block unreachable and left those
|
|
141
|
+
// attributes unset until Redpanda shipped something strictly newer.
|
|
142
|
+
const gaRelease = latestVersions.redpanda?.latestRedpandaRelease;
|
|
143
|
+
if (semver.valid(gaRelease?.version)) {
|
|
144
|
+
setVersionAndTagAttributes(component.latest.asciidoc, 'latest-redpanda', gaRelease.version, component.latest.name, component.latest.version);
|
|
145
|
+
// An unresolvable tag leaves the commit hash null. Leave any antora.yml
|
|
146
|
+
// fallback in place rather than overwriting it with nothing.
|
|
147
|
+
if (gaRelease.commitHash) {
|
|
148
|
+
component.latest.asciidoc.attributes['latest-release-commit'] = gaRelease.commitHash;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Required for backwards compatibility. Some docs still use full-version,
|
|
152
|
+
// and treat it as a floor, so only ever move it forwards. An unparseable
|
|
153
|
+
// pin counts as no pin, otherwise semver.gt throws and aborts the run.
|
|
154
|
+
const pinnedVersion = component.latest.asciidoc.attributes['full-version'];
|
|
155
|
+
if (!semver.valid(pinnedVersion) || semver.gt(gaRelease.version, pinnedVersion)) {
|
|
156
|
+
component.latest.asciidoc.attributes['full-version'] = sanitizeVersion(gaRelease.version);
|
|
137
157
|
}
|
|
138
158
|
}
|
|
139
159
|
});
|
|
140
160
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
161
|
+
// Report what resolved and what did not. A failed lookup resolves to a null
|
|
162
|
+
// release rather than rejecting, so dereferencing it here used to throw and
|
|
163
|
+
// replace the real cause with a bare TypeError from the logger.
|
|
164
|
+
const summary = [
|
|
165
|
+
['Redpanda', latestVersions.redpanda?.latestRedpandaRelease?.version, latestVersions.redpanda?.latestRcRelease?.version],
|
|
166
|
+
['Connect', latestVersions.connect],
|
|
167
|
+
['Console', latestVersions.console?.latestStableRelease, latestVersions.console?.latestBetaRelease],
|
|
168
|
+
['Operator', latestVersions.operator?.latestStableRelease, latestVersions.operator?.latestBetaRelease],
|
|
169
|
+
['Helm chart', latestVersions.helmChart?.latestStableRelease, latestVersions.helmChart?.latestBetaRelease],
|
|
170
|
+
];
|
|
171
|
+
const unresolved = summary.filter(([, stableVersion]) => !stableVersion).map(([label]) => label);
|
|
172
|
+
if (unresolved.length) {
|
|
173
|
+
logger.error(`Could not resolve the latest version of: ${unresolved.join(', ')}. Pages that reference the matching attributes render the attribute name instead of a version unless antora.yml seeds a fallback.`);
|
|
174
|
+
logger.info('Updated Redpanda documentation versions with gaps:');
|
|
175
|
+
} else {
|
|
176
|
+
logger.info('Updated Redpanda documentation versions successfully:');
|
|
177
|
+
}
|
|
178
|
+
summary.forEach(([label, stableVersion, betaVersion]) => {
|
|
179
|
+
logger.info(`- ${label}: ${stableVersion || 'unknown'}${betaVersion ? ', beta: ' + betaVersion : ''}`);
|
|
180
|
+
});
|
|
147
181
|
} catch (error) {
|
|
148
182
|
logger.error(`Error updating versions: ${error}`);
|
|
149
183
|
}
|
|
150
184
|
});
|
|
151
185
|
|
|
152
|
-
// Helper function to set
|
|
186
|
+
// Helper function to set latest-*version, latest-*tag, and latest-*version-short attributes
|
|
153
187
|
function setVersionAndTagAttributes(asciidoc, baseName, versionData, name = '', version = '') {
|
|
154
188
|
if (versionData) {
|
|
155
189
|
const versionWithoutPrefix = sanitizeVersion(versionData);
|
|
156
190
|
asciidoc.attributes[`${baseName}-version`] = versionWithoutPrefix; // Without "v" prefix
|
|
157
191
|
asciidoc.attributes[`${baseName}-tag`] = `${versionData}`;
|
|
158
192
|
|
|
193
|
+
setShortVersionAttribute(asciidoc, `${baseName}-version`, versionWithoutPrefix);
|
|
194
|
+
|
|
159
195
|
if (name && version) {
|
|
160
196
|
logger.debug(`Set ${baseName}-version to ${versionWithoutPrefix} and ${baseName}-tag to ${versionData} in ${name} ${version}`);
|
|
161
197
|
} else {
|
|
@@ -164,6 +200,19 @@ module.exports.register = function ({ config }) {
|
|
|
164
200
|
}
|
|
165
201
|
}
|
|
166
202
|
|
|
203
|
+
// Helper function to set the major.minor sibling of a *-version attribute (for
|
|
204
|
+
// example, latest-operator-version v25.1.3 -> latest-operator-version-short
|
|
205
|
+
// 25.1). Release channels that are not versions (for example, nightly) get no
|
|
206
|
+
// short attribute rather than a misleading one.
|
|
207
|
+
function setShortVersionAttribute(asciidoc, versionKey, versionData) {
|
|
208
|
+
if (!versionData || typeof versionData !== 'string') return;
|
|
209
|
+
if (!versionKey.endsWith('-version')) return;
|
|
210
|
+
const shortVersion = toShortVersion(sanitizeVersion(versionData));
|
|
211
|
+
if (shortVersion) {
|
|
212
|
+
asciidoc.attributes[`${versionKey}-short`] = shortVersion;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
167
216
|
// Helper function to sanitize version by removing "v" prefix
|
|
168
217
|
function sanitizeVersion(version) {
|
|
169
218
|
return version.replace(/^v/, '');
|
|
@@ -174,6 +223,7 @@ module.exports.register = function ({ config }) {
|
|
|
174
223
|
mappings.forEach(({ condition, key, value }) => {
|
|
175
224
|
if (condition) {
|
|
176
225
|
asciidoc.attributes[key] = value;
|
|
226
|
+
setShortVersionAttribute(asciidoc, key, value);
|
|
177
227
|
}
|
|
178
228
|
});
|
|
179
229
|
}
|
package/package.json
CHANGED
package/tools/bundle-openapi.js
CHANGED
|
@@ -4,6 +4,7 @@ const fs = require('fs');
|
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const { execSync, spawnSync } = require('child_process');
|
|
6
6
|
const yaml = require('yaml');
|
|
7
|
+
const { getMajorMinor } = require('../cli-utils/version');
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Normalize a Git tag into a semantic version string.
|
|
@@ -39,36 +40,9 @@ function normalizeTag(tag) {
|
|
|
39
40
|
return tag;
|
|
40
41
|
}
|
|
41
42
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
* Accepts a semantic version like `25.1.1` and yields `25.1`. The special value
|
|
46
|
-
* `'dev'` is returned unchanged.
|
|
47
|
-
* @param {string} version - Semantic version (for example, `'25.1.1'`) or `'dev'`.
|
|
48
|
-
* @returns {string} The `major.minor` string (for example, `'25.1'`) or `'dev'`.
|
|
49
|
-
* @throws {Error} If `version` is not a non-empty string, lacks major/minor parts, or if major/minor are not numeric.
|
|
50
|
-
*/
|
|
51
|
-
function getMajorMinor(version) {
|
|
52
|
-
if (!version || typeof version !== 'string') {
|
|
53
|
-
throw new Error('Version must be a non-empty string');
|
|
54
|
-
}
|
|
55
|
-
|
|
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;
|
|
60
|
-
}
|
|
61
|
-
const parts = version.split('.');
|
|
62
|
-
if (parts.length < 2) {
|
|
63
|
-
throw new Error(`Invalid version format: ${version}. Expected X.Y.Z format`);
|
|
64
|
-
}
|
|
65
|
-
const major = parseInt(parts[0], 10);
|
|
66
|
-
const minor = parseInt(parts[1], 10);
|
|
67
|
-
if (isNaN(major) || isNaN(minor)) {
|
|
68
|
-
throw new Error(`Major and minor versions must be numbers: ${version}`);
|
|
69
|
-
}
|
|
70
|
-
return `${major}.${minor}`;
|
|
71
|
-
}
|
|
43
|
+
// `getMajorMinor` lives in cli-utils/version.js so the Antora version fetcher and
|
|
44
|
+
// this bundler share one major.minor derivation instead of drifting apart.
|
|
45
|
+
// That module also exports the lenient `toShortVersion` variant.
|
|
72
46
|
|
|
73
47
|
/**
|
|
74
48
|
* Produce a new value with object keys sorted recursively for deterministic output.
|