@redpanda-data/docs-extensions-and-macros 4.2.0 → 4.2.2

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.
@@ -1,10 +1,12 @@
1
1
  /**
2
- * Fetches the latest version tag from Docker Hub for a given repository.
2
+ * Fetches the latest stable and beta version tags from Docker Hub for a given repository.
3
3
  *
4
+ * The function separates tags into stable (tags not including "-beta") and beta (tags including "-beta"),
5
+ * sorts each group by their major.minor version in descending order, and returns the top tag from each.
4
6
  *
5
7
  * @param {string} dockerNamespace - The Docker Hub namespace (organization or username)
6
8
  * @param {string} dockerRepo - The repository name on Docker Hub
7
- * @returns {Promise<string|null>} The latest version tag or null if none is found.
9
+ * @returns {Promise<{ latestStableRelease: string|null, latestBetaRelease: string|null }>}
8
10
  */
9
11
  module.exports = async (dockerNamespace, dockerRepo) => {
10
12
  const { default: fetch } = await import('node-fetch');
@@ -20,28 +22,23 @@ module.exports = async (dockerNamespace, dockerRepo) => {
20
22
 
21
23
  const data = await response.json();
22
24
 
23
- // Define a regular expression to capture the major and minor version numbers.
24
- // The regex /^v(\d+)\.(\d+)/ matches tags that start with "v", followed by digits (major),
25
- // a period, and more digits (minor). It works for tags like "v2.3.8-24.3.6" or "v25.1-k8s4".
25
+ // Regex to capture major and minor version numbers (e.g. "v2.3")
26
26
  const versionRegex = /^v(\d+)\.(\d+)/;
27
27
 
28
- // Filter the list of tags to include only those that match our expected version pattern.
29
- // This helps ensure we work only with tags that represent valid version numbers.
30
- let versionTags = data.results.filter(tag => versionRegex.test(tag.name));
28
+ // Filter tags to include only those matching the version pattern.
29
+ let tags = data.results.filter(tag => versionRegex.test(tag.name));
31
30
 
32
- // If the repository is "redpanda-operator", ignore any tags starting with the old "v22 or "v23" versions.
31
+ // For specific repositories (e.g. "redpanda-operator"), you might want to filter out certain versions.
33
32
  if (dockerRepo === 'redpanda-operator') {
34
- versionTags = versionTags.filter(tag => !/^(v22|v23)/.test(tag.name));
33
+ tags = tags.filter(tag => !/^(v22|v23)/.test(tag.name));
35
34
  }
36
35
 
37
- if (versionTags.length === 0) {
38
- console.warn('No version tags found.');
39
- return null;
40
- }
36
+ // Separate stable and beta tags.
37
+ const stableTags = tags.filter(tag => !tag.name.includes('-beta'));
38
+ const betaTags = tags.filter(tag => tag.name.includes('-beta'));
41
39
 
42
- // Sort the filtered tags in descending order based on their major and minor version numbers.
43
- // This sorting ignores any additional patch or suffix details and focuses only on the major.minor value.
44
- versionTags.sort((a, b) => {
40
+ // Helper function to sort tags in descending order based on major and minor version numbers.
41
+ const sortTags = (a, b) => {
45
42
  const aMatch = a.name.match(versionRegex);
46
43
  const bMatch = b.name.match(versionRegex);
47
44
  const aMajor = parseInt(aMatch[1], 10);
@@ -49,18 +46,28 @@ module.exports = async (dockerNamespace, dockerRepo) => {
49
46
  const bMajor = parseInt(bMatch[1], 10);
50
47
  const bMinor = parseInt(bMatch[2], 10);
51
48
 
52
- // Compare by major version first; if equal, compare by minor version.
53
49
  if (aMajor !== bMajor) {
54
50
  return bMajor - aMajor;
55
51
  }
56
52
  return bMinor - aMinor;
57
- });
53
+ };
54
+
55
+ const sortedStable = stableTags.sort(sortTags);
56
+ const sortedBeta = betaTags.sort(sortTags);
57
+
58
+ const latestStableReleaseVersion = sortedStable.length ? sortedStable[0].name : null;
59
+ const latestBetaReleaseVersion = sortedBeta.length ? sortedBeta[0].name : null;
58
60
 
59
- // Return the name of the tag with the highest major.minor version.
60
- return versionTags[0].name;
61
+ return {
62
+ latestStableRelease: latestStableReleaseVersion || null,
63
+ latestBetaRelease: latestBetaReleaseVersion || null
64
+ };
61
65
 
62
66
  } catch (error) {
63
- console.error('Error fetching latest Docker tag:', error);
64
- return null;
67
+ console.error('Error fetching Docker tags:', error);
68
+ return {
69
+ latestStableRelease: null,
70
+ latestBetaRelease: null
71
+ };
65
72
  }
66
73
  };
@@ -1,18 +1,122 @@
1
+ /**
2
+ * Fetches the latest Helm chart version from GitHub releases.
3
+ *
4
+ * This function looks for releases with tags following these patterns:
5
+ * - Stable: "redpanda-5.9.21" or "25.1-k8s4" (without "beta" anywhere)
6
+ * - Beta: "redpanda-5.9.21-beta", "redpanda-5.9.21-beta.1", or "25.1-k8s4-beta"
7
+ *
8
+ * It selects the highest version for each category, fetches the file at the provided path
9
+ * (typically Chart.yaml) using the tag as the Git ref, parses it, and returns an object with
10
+ * the chart version from the highest stable release and the highest beta release.
11
+ *
12
+ * @param {object} github - The GitHub API client.
13
+ * @param {string} owner - The repository owner.
14
+ * @param {string} repo - The repository name.
15
+ * @param {string} path - The path to the Chart.yaml file in the repository.
16
+ * @returns {Promise<{ latestStableRelease: string|null, latestBetaRelease: string|null }>}
17
+ */
1
18
  module.exports = async (github, owner, repo, path) => {
2
19
  const yaml = require('js-yaml');
3
20
  try {
4
- const response = await github.repos.getContent({
5
- owner: owner,
6
- repo: repo,
7
- path: path,
21
+ // Fetch up to 20 releases from GitHub.
22
+ const releasesResponse = await github.repos.listReleases({
23
+ owner,
24
+ repo,
25
+ per_page: 20,
8
26
  });
27
+ const releases = releasesResponse.data;
28
+
29
+ // Regex patterns:
30
+ // Stable regex: "redpanda-" prefix, then major.minor with an optional patch,
31
+ // and no "beta" anywhere in the tag.
32
+ const stableRegex = /^(?:redpanda-)(\d+)\.(\d+)(?:\.(\d+))?(?!.*beta)/i;
33
+ // Beta regex: "redpanda-" prefix, then major.minor with an optional patch,
34
+ // and later somewhere "beta" with an optional numeric qualifier.
35
+ const betaRegex = /^(?:redpanda-)(\d+)\.(\d+)(?:\.(\d+))?.*beta(?:\.(\d+))?$/i;
36
+
37
+ // Filter releases into stable and beta arrays based on tag matching.
38
+ const stableReleases = releases.filter(release => stableRegex.test(release.tag_name));
39
+ const betaReleases = releases.filter(release => betaRegex.test(release.tag_name));
40
+
41
+ // Sorting function for stable releases.
42
+ const sortStable = (a, b) => {
43
+ const aMatch = a.tag_name.match(stableRegex);
44
+ const bMatch = b.tag_name.match(stableRegex);
45
+ if (!aMatch || !bMatch) return 0;
46
+ const aMajor = parseInt(aMatch[1], 10);
47
+ const aMinor = parseInt(aMatch[2], 10);
48
+ const aPatch = aMatch[3] ? parseInt(aMatch[3], 10) : 0;
49
+ const bMajor = parseInt(bMatch[1], 10);
50
+ const bMinor = parseInt(bMatch[2], 10);
51
+ const bPatch = bMatch[3] ? parseInt(bMatch[3], 10) : 0;
52
+ if (aMajor !== bMajor) return bMajor - aMajor;
53
+ if (aMinor !== bMinor) return bMinor - aMinor;
54
+ return bPatch - aPatch;
55
+ };
56
+
57
+ // Sorting function for beta releases.
58
+ const sortBeta = (a, b) => {
59
+ const aMatch = a.tag_name.match(betaRegex);
60
+ const bMatch = b.tag_name.match(betaRegex);
61
+ if (!aMatch || !bMatch) return 0;
62
+ const aMajor = parseInt(aMatch[1], 10);
63
+ const aMinor = parseInt(aMatch[2], 10);
64
+ const aPatch = aMatch[3] ? parseInt(aMatch[3], 10) : 0;
65
+ // Optional beta number; if not provided, assume 0.
66
+ const aBeta = aMatch[4] ? parseInt(aMatch[4], 10) : 0;
67
+ const bMajor = parseInt(bMatch[1], 10);
68
+ const bMinor = parseInt(bMatch[2], 10);
69
+ const bPatch = bMatch[3] ? parseInt(bMatch[3], 10) : 0;
70
+ const bBeta = bMatch[4] ? parseInt(bMatch[4], 10) : 0;
71
+ if (aMajor !== bMajor) return bMajor - aMajor;
72
+ if (aMinor !== bMinor) return bMinor - aMinor;
73
+ if (aPatch !== bPatch) return bPatch - aPatch;
74
+ return bBeta - aBeta;
75
+ };
76
+
77
+ // Sort both arrays in descending order.
78
+ stableReleases.sort(sortStable);
79
+ betaReleases.sort(sortBeta);
80
+
81
+ // Get the highest tag from each group, if available.
82
+ const latestStableTag = stableReleases.length ? stableReleases[0].tag_name : null;
83
+ const latestBetaTag = betaReleases.length ? betaReleases[0].tag_name : null;
84
+
85
+ // Helper function to fetch and parse Chart.yaml from a given tag.
86
+ const fetchChartVersion = async (tag) => {
87
+ if (!tag) return null;
88
+ try {
89
+ const contentResponse = await github.repos.getContent({
90
+ owner,
91
+ repo,
92
+ path,
93
+ ref: tag,
94
+ });
95
+ const contentBase64 = contentResponse.data.content;
96
+ const contentDecoded = Buffer.from(contentBase64, 'base64').toString('utf8');
97
+ const chartYaml = yaml.load(contentDecoded);
98
+ return chartYaml.version || null;
99
+ } catch (error) {
100
+ console.error(`Failed to fetch Chart.yaml for tag ${tag}:`, error.message);
101
+ return null;
102
+ }
103
+ };
104
+
105
+ const [latestStableReleaseVersion, latestBetaReleaseVersion] = await Promise.all([
106
+ fetchChartVersion(latestStableTag),
107
+ fetchChartVersion(latestBetaTag)
108
+ ]);
109
+
110
+ return {
111
+ latestStableRelease: latestStableReleaseVersion,
112
+ latestBetaRelease: latestBetaReleaseVersion
113
+ };
9
114
 
10
- const contentBase64 = response.data.content;
11
- const contentDecoded = Buffer.from(contentBase64, 'base64').toString('utf8');
12
- const chartYaml = yaml.load(contentDecoded);
13
- return chartYaml.version;
14
115
  } catch (error) {
15
116
  console.error('Failed to fetch chart version:', error.message);
16
- return null
117
+ return {
118
+ latestStableRelease: null,
119
+ latestBetaRelease: null
120
+ };
17
121
  }
18
122
  };
@@ -50,8 +50,6 @@ module.exports.register = function ({ config }) {
50
50
  connect: latestConnectResult.status === 'fulfilled' ? latestConnectResult.value : undefined,
51
51
  };
52
52
 
53
- console.log(latestVersions)
54
-
55
53
  const components = await contentCatalog.getComponents();
56
54
  components.forEach(component => {
57
55
  const prerelease = component.latestPrerelease;
@@ -63,8 +61,8 @@ module.exports.register = function ({ config }) {
63
61
 
64
62
  // Set operator and helm chart attributes via helper function
65
63
  updateAttributes(asciidoc, [
66
- { condition: latestVersions.operator, key: 'latest-operator-version', value: latestVersions.operator },
67
- { condition: latestVersions.helmChart, key: 'latest-redpanda-helm-chart-version', value: latestVersions.helmChart }
64
+ { condition: latestVersions.operator, key: 'latest-operator-version', value: latestVersions.operator?.latestStableRelease },
65
+ { condition: latestVersions.helmChart, key: 'latest-redpanda-helm-chart-version', value: latestVersions.helmChart?.latestStableRelease }
68
66
  ]);
69
67
 
70
68
  // Set attributes for console and connect versions
@@ -80,9 +78,17 @@ module.exports.register = function ({ config }) {
80
78
  // Special handling for Redpanda RC versions if in beta
81
79
  if (latestVersions.redpanda?.latestRcRelease?.version) {
82
80
  setVersionAndTagAttributes(asciidoc, 'redpanda-beta', latestVersions.redpanda.latestRcRelease.version, name, version);
83
- setVersionAndTagAttributes(asciidoc, 'console-beta', latestVersions.console.latestBetaRelease, name, version);
84
81
  asciidoc.attributes['redpanda-beta-commit'] = latestVersions.redpanda.latestRcRelease.commitHash;
85
82
  }
83
+ if (latestVersions.console?.latestBetaRelease) {
84
+ setVersionAndTagAttributes(asciidoc, 'console-beta', latestVersions.console.latestBetaRelease, name, version);
85
+ }
86
+ if (latestVersions.operator?.latestBetaRelease) {
87
+ setVersionAndTagAttributes(asciidoc, 'operator-beta', latestVersions.operator.latestBetaRelease, name, version);
88
+ }
89
+ if (latestVersions.helmChart?.latestBetaRelease) {
90
+ setVersionAndTagAttributes(asciidoc, 'helm-beta', latestVersions.helmChart.latestBetaRelease, name, version);
91
+ }
86
92
  });
87
93
 
88
94
  if (!component.latest.asciidoc) component.latest.asciidoc = { attributes: {} };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redpanda-data/docs-extensions-and-macros",
3
- "version": "4.2.0",
3
+ "version": "4.2.2",
4
4
  "description": "Antora extensions and macros developed for Redpanda documentation.",
5
5
  "keywords": [
6
6
  "antora",