You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by lh...@apache.org on 2026/10/14 07:14:04 UTC

(pulsar-site) 01/02: [improve][site] Point unsupported version docs to all supported versions

This is an automated email from the ASF dual-hosted git repository.

lhotari pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/pulsar-site.git

commit 0ba6256f8cb20a6c475b1dbb216c0e4c3ae549dc
Author: Lari Hotari <lh...@users.noreply.github.com>
AuthorDate: Wed Oct 14 10:03:27 2026 +0300

    [improve][site] Point unsupported version docs to all supported versions
    
    Derive the supported versions in the doc version banner from the release
    data instead of a hard-coded list, and tell readers of unsupported
    versions that the docs are no longer maintained, linking to every
    supported version's documentation.
---
 scripts/supported-versions.js                      |  48 +--------
 src/theme/DocVersionBanner/index.js                | 107 +++++++++++++--------
 .../utils/supportedVersions.js                     |  10 +-
 3 files changed, 77 insertions(+), 88 deletions(-)

diff --git a/scripts/supported-versions.js b/scripts/supported-versions.js
index c48a81e1445..9c2d340a187 100644
--- a/scripts/supported-versions.js
+++ b/scripts/supported-versions.js
@@ -1,47 +1,3 @@
-const releases = require('../data/release-pulsar.js');
-const moment = require('moment');
-const semver = require('semver/preload');
+const { getSupportedVersions } = require('../src/utils/supportedVersions.js');
 
-function resolveActiveSupport(ver, released) {
-  const support = moment(released);
-  
-  if (ver.compareMain('3.0.0') < 0) {
-    return support.add(12, 'months');
-  } else if (ver.minor > 0) {
-    return support.add(6, 'months');
-  } else {
-    // 36 months for security updates
-    return support.add(36, 'months');
-  }
-}
-
-function getSupportedVersionBranches(releases) {
-  const releaseList = releases
-    // skip pre-releases such as v5.0.0-M1, which semver.coerce would turn into 5.0.0
-    .filter(r => !semver.prerelease(r.tagName))
-    .map(r => ({
-      version: semver.coerce(r.tagName),
-      released: moment(r.publishedAt)
-    }));
-
-  const now = moment();
-  const supportedVersions = releaseList
-    .filter(release => {
-        if (release.version.patch === 0) {
-            const supportEnd = resolveActiveSupport(release.version, release.released);
-            return supportEnd.isAfter(now);
-        } else {
-            return false;
-        }
-    })
-    .sort((a, b) => semver.rcompare(b.version, a.version))
-    .map(release => `${release.version.major}.${release.version.minor}.x`);
-
-  const latestBranch = `${releaseList[0].version.major}.${releaseList[0].version.minor}.x`;
-  return supportedVersions.includes(latestBranch)
-    ? supportedVersions
-    : [...supportedVersions, latestBranch];
-}
-
-const supported = getSupportedVersionBranches(releases);
-console.log(supported.join(' '));
\ No newline at end of file
+console.log(getSupportedVersions().join(' '));
diff --git a/src/theme/DocVersionBanner/index.js b/src/theme/DocVersionBanner/index.js
index d0367da481d..dccc1e6690b 100644
--- a/src/theme/DocVersionBanner/index.js
+++ b/src/theme/DocVersionBanner/index.js
@@ -4,8 +4,9 @@ import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
 import Link from '@docusaurus/Link';
 import Translate from '@docusaurus/Translate';
 import {
+  useActiveDocContext,
   useActivePlugin,
-  useDocVersionSuggestions,
+  useVersions,
 } from '@docusaurus/plugin-content-docs/client';
 import {ThemeClassNames} from '@docusaurus/theme-common';
 import {
@@ -13,10 +14,11 @@ import {
   useDocsVersion,
 } from '@docusaurus/plugin-content-docs/client';
 import BrowserOnly from "@docusaurus/BrowserOnly";
+import { getSupportedVersions } from '../../utils/supportedVersions';
 let versions = require("../../../versions.json");
 const _latestVersion = versions[0];
 const _ltsVersion = '4.0.x';
-const _maintainedVersions = ['4.2.x', '4.0.x', '3.0.x'];
+const _maintainedVersions = getSupportedVersions();
 function UnreleasedVersionLabel({siteTitle, versionMetadata}) {
   return (
     <Translate
@@ -56,7 +58,7 @@ function UnmaintainedVersionLabel({ siteTitle, versionMetadata }) {
       }}
     >
       {
-        "This is documentation for Pulsar {versionLabel}, which is no longer actively maintained."
+        "This is documentation for Pulsar {versionLabel}, which is no longer supported. This documentation is no longer updated and may be outdated or inaccurate."
       }
     </Translate>
   );
@@ -81,49 +83,77 @@ function BannerLabel(props) {
   //   BannerLabelComponents[props.versionMetadata.banner];
   return <BannerLabelComponent {...props} />;
 }
-function LatestVersionSuggestionLabel({ versionLabel, to, onClick }) {
+function VersionLink({ version, to, onClick }) {
+  return (
+    <b>
+      <Link to={to} onClick={onClick}>
+        {version}
+      </Link>
+    </b>
+  );
+}
+// Joins links as "A", "A or B", or "A, B, or C".
+function joinWithOr(items) {
+  return items.map((item, i) => (
+    <React.Fragment key={i}>
+      {i > 0 && (i === items.length - 1 ? (items.length > 2 ? ", or " : " or ") : ", ")}
+      {item}
+    </React.Fragment>
+  ));
+}
+function LatestVersionSuggestionLabel({ versionLink }) {
   return (
     <Translate
       id="theme.docs.versions.latestVersionSuggestionLabel"
       description="The label used to tell the user to check the latest version"
-      values={{
-        versionLabel,
-        latestVersionLink: (
-          <b>
-            <Link to={to} onClick={onClick}>
-              {/* <Translate
-                id="theme.docs.versions.latestVersionLinkLabel"
-                description="The label used for the latest version suggestion link label"
-              > */}
-              {versionLabel}
-              {/* </Translate> */}
-            </Link>
-          </b>
-        ),
-      }}
+      values={{ latestVersionLink: versionLink }}
     >
       {"We recommend that you use the {latestVersionLink} documentation."}
     </Translate>
   );
 }
+function SupportedVersionsSuggestionLabel({ versionLinks }) {
+  return (
+    <Translate
+      id="theme.docs.versions.supportedVersionsSuggestionLabel"
+      description="The label used to point the user to the documentation of supported versions"
+      values={{ supportedVersionLinks: <>{joinWithOr(versionLinks)}</> }}
+    >
+      {"For maintained documentation, see the {supportedVersionLinks} documentation."}
+    </Translate>
+  );
+}
 function DocVersionBannerEnabled({ className, versionMetadata }) {
   const {
     siteConfig: { title: siteTitle },
   } = useDocusaurusContext();
   const { pluginId } = useActivePlugin({ failfast: true });
-  const getVersionMainDoc = (version) =>
-    version.docs.find((doc) => doc.id === version.mainDocId);
   const { savePreferredVersionName } = useDocsPreferredVersion(pluginId);
-  const { latestDocSuggestion, latestVersionSuggestion } =
-    useDocVersionSuggestions(pluginId);
-  // Try to link to same doc in latest version (not always possible), falling
-  // back to main doc of latest version
-  const latestVersionSuggestedDoc =
-    latestDocSuggestion ?? getVersionMainDoc(latestVersionSuggestion);
-
-  let path = latestVersionSuggestedDoc.path;
-  let reg = new RegExp("/" + versionMetadata.version + "/");
-  path = path.replace(reg, "/");
+  const { alternateDocVersions } = useActiveDocContext(pluginId);
+  const availableVersions = useVersions(pluginId);
+  // Link to the same doc in the target version when it exists, falling back to
+  // the main doc of that version
+  const versionLink = (version) => {
+    const versionData = availableVersions.find((v) => v.name === version);
+    const doc =
+      alternateDocVersions[version] ??
+      versionData?.docs.find((d) => d.id === versionData.mainDocId);
+    const to = doc?.path ?? `/docs/${version}/`;
+    return (
+      <VersionLink
+        key={version}
+        version={version}
+        to={to}
+        onClick={() => {
+          savePreferredVersionName(version);
+          window.location.href = to;
+        }}
+      />
+    );
+  };
+  const isUnmaintained =
+    versionMetadata.version !== "current" &&
+    !_maintainedVersions.includes(versionMetadata.version);
   return (
     <div
       className={clsx(
@@ -137,14 +167,13 @@ function DocVersionBannerEnabled({ className, versionMetadata }) {
         <BannerLabel siteTitle={siteTitle} versionMetadata={versionMetadata} />
       </div>
       <div className="margin-top--md">
-        <LatestVersionSuggestionLabel
-          versionLabel={_latestVersion}
-          to={path}
-          onClick={() => {
-            savePreferredVersionName(latestVersionSuggestion.name);
-            window.location.href = path;
-          }}
-        />
+        {isUnmaintained ? (
+          <SupportedVersionsSuggestionLabel
+            versionLinks={_maintainedVersions.map(versionLink)}
+          />
+        ) : (
+          <LatestVersionSuggestionLabel versionLink={versionLink(_latestVersion)} />
+        )}
       </div>
     </div>
   );
diff --git a/scripts/supported-versions.js b/src/utils/supportedVersions.js
similarity index 84%
copy from scripts/supported-versions.js
copy to src/utils/supportedVersions.js
index c48a81e1445..2e52d6af2fd 100644
--- a/scripts/supported-versions.js
+++ b/src/utils/supportedVersions.js
@@ -1,4 +1,4 @@
-const releases = require('../data/release-pulsar.js');
+const releases = require('../../data/release-pulsar.js');
 const moment = require('moment');
 const semver = require('semver/preload');
 
@@ -43,5 +43,9 @@ function getSupportedVersionBranches(releases) {
     : [...supportedVersions, latestBranch];
 }
 
-const supported = getSupportedVersionBranches(releases);
-console.log(supported.join(' '));
\ No newline at end of file
+// Supported release lines (e.g. ["4.0.x", "5.0.x"]), oldest first.
+function getSupportedVersions() {
+  return getSupportedVersionBranches(releases);
+}
+
+module.exports = { getSupportedVersions };
\ No newline at end of file