UNPKG

@redpanda-data/docs-extensions-and-macros

Version:

Antora extensions and macros developed for Redpanda documentation.

177 lines (155 loc) 8.99 kB
'use strict'; module.exports.register = function ({ config }) { const GetLatestRedpandaVersion = require('./get-latest-redpanda-version'); const GetLatestConsoleVersion = require('./get-latest-console-version'); const GetLatestDockerTag = require('./fetch-latest-docker-tag'); const GetLatestHelmChartVersionFromOperator = require('./get-latest-redpanda-helm-version-from-operator'); const GetLatestConnectVersion = require('./get-latest-connect'); const logger = this.getLogger('set-latest-version-extension'); const { getGitHubToken } = require('../../cli-utils/github-token'); const token = getGitHubToken(); if (!token) { logger.warn('GitHub token not set (REDPANDA_GITHUB_TOKEN, GITHUB_TOKEN, or GH_TOKEN). Attempting unauthenticated request.'); } this.on('contentClassified', async ({ contentCatalog }) => { const { Octokit } = await import("@octokit/rest"); const { retry } = await import("@octokit/plugin-retry"); const semver = await import("semver"); const OctokitWithRetries = Octokit.plugin(retry); const owner = 'redpanda-data'; const githubOptions = { userAgent: 'Redpanda Docs', baseUrl: 'https://api.github.com', auth: token || undefined, }; const github = new OctokitWithRetries(githubOptions); const dockerNamespace = 'redpandadata' try { const [ latestRedpandaResult, latestConsoleResult, latestOperatorResult, latestConnectResult, ] = await Promise.allSettled([ GetLatestRedpandaVersion(github, owner, 'redpanda', logger), GetLatestDockerTag(dockerNamespace, 'console', logger), GetLatestDockerTag(dockerNamespace, 'redpanda-operator', logger), GetLatestConnectVersion(github, owner, 'connect', logger), ]); // Get the Helm chart version after we have the operator version (for both stable and beta) let latestHelmChartResult = { status: 'rejected', reason: 'Operator result not fulfilled' }; if (latestOperatorResult.status === 'fulfilled') { try { const helmChartVersions = await GetLatestHelmChartVersionFromOperator( github, owner, 'redpanda-operator', latestOperatorResult.value?.latestStableRelease, latestOperatorResult.value?.latestBetaRelease, logger ); latestHelmChartResult = { status: 'fulfilled', value: helmChartVersions }; } catch (error) { latestHelmChartResult = { status: 'rejected', reason: error.message || 'Unknown error fetching Helm chart version' }; logger.error(`Helm chart lookup failed: ${error.message || error}`); } } else { logger.error(`Helm chart lookup failed: Operator version not available`); } const latestVersions = { redpanda: latestRedpandaResult.status === 'fulfilled' ? latestRedpandaResult.value : {}, console: latestConsoleResult.status === 'fulfilled' ? latestConsoleResult.value : undefined, operator: latestOperatorResult.status === 'fulfilled' ? latestOperatorResult.value : undefined, helmChart: latestHelmChartResult.status === 'fulfilled' ? latestHelmChartResult.value : undefined, connect: latestConnectResult.status === 'fulfilled' ? latestConnectResult.value : undefined, }; const components = await contentCatalog.getComponents(); components.forEach(component => { const prerelease = component.latestPrerelease; component.versions.forEach(({ name, version, asciidoc }) => { if (prerelease?.version === version) { asciidoc.attributes['page-component-version-is-prerelease'] = 'true'; } // Set operator and helm chart attributes via helper function updateAttributes(asciidoc, [ { condition: latestVersions.operator, key: 'latest-operator-version', value: latestVersions.operator?.latestStableRelease }, { condition: latestVersions.helmChart, key: 'latest-redpanda-helm-chart-version', value: latestVersions.helmChart?.latestStableRelease } ]); // Set attributes for console and connect versions [ { condition: latestVersions.console, baseName: 'latest-console', value: latestVersions.console?.latestStableRelease }, { condition: latestVersions.connect, baseName: 'latest-connect', value: latestVersions.connect } ].forEach(mapping => { if (mapping.condition && mapping.value) { setVersionAndTagAttributes(asciidoc, mapping.baseName, mapping.value, name, version); } }); // Special handling for Redpanda RC versions if in beta if (latestVersions.redpanda?.latestRcRelease?.version) { setVersionAndTagAttributes(asciidoc, 'redpanda-beta', latestVersions.redpanda.latestRcRelease.version, name, version); asciidoc.attributes['redpanda-beta-commit'] = latestVersions.redpanda.latestRcRelease.commitHash; } if (latestVersions.console?.latestBetaRelease) { setVersionAndTagAttributes(asciidoc, 'console-beta', latestVersions.console.latestBetaRelease, name, version); } if (latestVersions.operator?.latestBetaRelease) { setVersionAndTagAttributes(asciidoc, 'operator-beta', latestVersions.operator.latestBetaRelease, name, version); } if (latestVersions.helmChart?.latestBetaRelease) { setVersionAndTagAttributes(asciidoc, 'helm-beta', latestVersions.helmChart.latestBetaRelease, name, version); } }); if (!component.latest.asciidoc) component.latest.asciidoc = { attributes: {} }; // For Redpanda GA version, set both latest-redpanda-version and latest-redpanda-tag if available if (semver.valid(latestVersions.redpanda?.latestRedpandaRelease?.version)) { const currentVersion = component.latest.asciidoc.attributes['full-version'] || '0.0.0'; if (semver.gt(latestVersions.redpanda.latestRedpandaRelease.version, currentVersion)) { // Required for backwards compatibility. Some docs still use full-version component.latest.asciidoc.attributes['full-version'] = sanitizeVersion(latestVersions.redpanda.latestRedpandaRelease.version); setVersionAndTagAttributes(component.latest.asciidoc, 'latest-redpanda', latestVersions.redpanda.latestRedpandaRelease.version, component.latest.name, component.latest.version); component.latest.asciidoc.attributes['latest-release-commit'] = latestVersions.redpanda.latestRedpandaRelease.commitHash; } } }); logger.info('Updated Redpanda documentation versions successfully:'); logger.info(`- Redpanda: ${latestVersions.redpanda.latestRedpandaRelease.version}${latestVersions.redpanda.latestRcRelease ? ', beta: ' + latestVersions.redpanda.latestRcRelease.version : ''}`); logger.info(`- Connect: ${latestVersions.connect}`); logger.info(`- Console: ${latestVersions.console.latestStableRelease}${latestVersions.console.latestBetaRelease ? ', beta: ' + latestVersions.console.latestBetaRelease : ''}`); logger.info(`- Operator: ${latestVersions.operator?.latestStableRelease || 'unknown'}${latestVersions.operator?.latestBetaRelease ? ', beta: ' + latestVersions.operator.latestBetaRelease : ''}`); logger.info(`- Helm chart: ${latestVersions.helmChart?.latestStableRelease || 'unknown'}${latestVersions.helmChart?.latestBetaRelease ? ', beta: ' + latestVersions.helmChart.latestBetaRelease : ''}`); } catch (error) { logger.error(`Error updating versions: ${error}`); } }); // Helper function to set both latest-*version and latest-*tag attributes function setVersionAndTagAttributes(asciidoc, baseName, versionData, name = '', version = '') { if (versionData) { const versionWithoutPrefix = sanitizeVersion(versionData); asciidoc.attributes[`${baseName}-version`] = versionWithoutPrefix; // Without "v" prefix asciidoc.attributes[`${baseName}-tag`] = `${versionData}`; if (name && version) { logger.debug(`Set ${baseName}-version to ${versionWithoutPrefix} and ${baseName}-tag to ${versionData} in ${name} ${version}`); } else { logger.debug(`Updated ${baseName}-version to ${versionWithoutPrefix} and ${baseName}-tag to ${versionData}`); } } } // Helper function to sanitize version by removing "v" prefix function sanitizeVersion(version) { return version.replace(/^v/, ''); } // Helper function to update multiple attributes based on a list of mappings function updateAttributes(asciidoc, mappings) { mappings.forEach(({ condition, key, value }) => { if (condition) { asciidoc.attributes[key] = value; } }); } };