docs: autoselect version (#344)

Define functions that can be used in mdx pages to dinamically choose the
correct version according to the documentation page viewed.

Closes #343

Signed-off-by: Francesco Canovai <francesco.canovai@enterprisedb.com>
Signed-off-by: Leonardo Cecchi <leonardo.cecchi@enterprisedb.com>
Signed-off-by: Armando Ruocco <armando.ruocco@enterprisedb.com>
Co-authored-by: Leonardo Cecchi <leonardo.cecchi@enterprisedb.com>
Co-authored-by: Armando Ruocco <armando.ruocco@enterprisedb.com>
This commit is contained in:
Francesco Canovai 2025-05-15 13:36:57 +02:00 committed by GitHub
parent 612064bae3
commit 12b92a66f1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 125 additions and 86 deletions

View File

@ -4,8 +4,6 @@ sidebar_position: 20
# Installation
<!-- SPDX-License-Identifier: CC-BY-4.0 -->
:::important
1. The plugin **must** be installed in the same namespace as the CloudNativePG
operator (typically `cnpg-system`).
@ -56,17 +54,12 @@ Both checks are required before proceeding with the installation.
## Installing the Barman Cloud Plugin
import { InstallationSnippet } from '@site/src/components/Installation';
Install the plugin using `kubectl` by applying the manifest for the latest
release:
<!-- x-release-please-start-version -->
```sh
kubectl apply -f \
https://github.com/cloudnative-pg/plugin-barman-cloud/releases/download/v0.4.0/manifest.yaml
```
<!-- x-release-please-end -->
<InstallationSnippet />
Example output:
@ -114,4 +107,3 @@ following command:
kubectl apply -f \
https://raw.githubusercontent.com/cloudnative-pg/plugin-barman-cloud/refs/heads/main/manifest.yaml
```

View File

@ -13,7 +13,7 @@ If you're currently relying on the built-in Barman Cloud integration, you can
migrate seamlessly to the new **plugin-based architecture** using the Barman
Cloud Plugin, with **no downtime**. Follow these steps:
- [Install the Barman Cloud Plugin](installation.md)
- [Install the Barman Cloud Plugin](installation.mdx)
- Create an `ObjectStore` resource by translating the contents of the
`.spec.backup.barmanObjectStore` section from your existing `Cluster`
definition

View File

@ -6,7 +6,7 @@ sidebar_position: 30
<!-- SPDX-License-Identifier: CC-BY-4.0 -->
After [installing the plugin](installation.md) in the same namespace as the
After [installing the plugin](installation.mdx) in the same namespace as the
CloudNativePG operator, enabling your PostgreSQL cluster to use the Barman
Cloud Plugin involves just a few steps:

View File

@ -0,0 +1,49 @@
import type {ComponentProps, ComponentType, ReactElement} from "react";
import clsx from "clsx";
import styles from "@site/src/components/HomepageFeatures/styles.module.css";
import Heading from "@theme/Heading";
type FeatureItem = {
title: string;
Svg: ComponentType<ComponentProps<'svg'>>;
description: string;
};
function Feature({title, Svg, description}: FeatureItem): ReactElement<FeatureItem> {
return (
<div className={clsx('col col--4')}>
<div className="text--center">
<Svg className={styles.featureSvg} role="img"/>
</div>
<div className="text--center padding-horiz--md">
<Heading as="h3">{title}</Heading>
<p>{description}</p>
</div>
</div>
);
}
export function FeatureList(): ReactElement<null> {
return (
<div className="row">
<Feature
title={'Backup your clusters'}
description={"Securely backup your CloudNativePG clusters to object storage with configurable retention " +
"policies and compression options"}
Svg={require('@site/static/img/undraw_going-up_g8av.svg').default}
/>
<Feature
title={'Restore to any point in time'}
description={"Perform flexible restores to any point in time using a combination of " +
"base backups and WAL archives."}
Svg={require('@site/static/img/undraw_season-change_ohe6.svg').default}
/>
<Feature
title={'Cloud-native architecture'}
description={"Seamlessly integrate with all major cloud providers and on-premises object storage solutions."}
Svg={require('@site/static/img/undraw_maintenance_rjtm.svg').default}
/>
</div>
)
}

View File

@ -1,71 +1,13 @@
import type {ReactNode} from 'react';
import clsx from 'clsx';
import Heading from '@theme/Heading';
import type {ReactElement} from 'react';
import styles from './styles.module.css';
import {FeatureList} from './feature';
type FeatureItem = {
title: string;
Svg: React.ComponentType<React.ComponentProps<'svg'>>;
description: ReactNode;
};
const FeatureList: FeatureItem[] = [
{
title: 'Backup your clusters',
Svg: require('@site/static/img/undraw_going-up_g8av.svg').default,
description: (
<>
Securely backup your CloudNativePG clusters to object storage with
configurable retention policies and compression options.
</>
),
},
{
title: 'Restore to any point in time',
Svg: require('@site/static/img/undraw_season-change_ohe6.svg').default,
description: (
<>
Perform flexible restores to any point in time using a combination of
base backups and WAL archives.
</>
),
},
{
title: 'Cloud-native architecture',
Svg: require('@site/static/img/undraw_maintenance_rjtm.svg').default,
description: (
<>
Seamlessly integrate with all major cloud providers and on-premises object storage
solutions.
</>
),
},
];
function Feature({title, Svg, description}: FeatureItem) {
return (
<div className={clsx('col col--4')}>
<div className="text--center">
<Svg className={styles.featureSvg} role="img" />
</div>
<div className="text--center padding-horiz--md">
<Heading as="h3">{title}</Heading>
<p>{description}</p>
</div>
</div>
);
}
export default function HomepageFeatures(): ReactNode {
return (
<section className={styles.features}>
<div className="container">
<div className="row">
{FeatureList.map((props, idx) => (
<Feature key={idx} {...props} />
))}
</div>
</div>
</section>
);
export default function HomepageFeatures(): ReactElement<null> {
return (
<section className={styles.features}>
<div className="container">
<FeatureList/>
</div>
</section>
);
}

View File

@ -0,0 +1,16 @@
import {ReactElement} from 'react';
import CodeBlock from '@theme/CodeBlock';
import {useCurrentVersion} from '@site/src/hooks/versions';
// InstallationSnippet is the kubectl incantation to install the lastest
// available version of the Barman Cloud Plugin.
export function InstallationSnippet(): ReactElement<null> {
const latest = useCurrentVersion('latestReleased');
return (
<CodeBlock language="sh">
{`kubectl apply -f \\
https://github.com/cloudnative-pg/plugin-barman-cloud/releases/download/v${latest}/manifest.yaml`}
</CodeBlock>
);
}

36
web/src/hooks/versions.ts Normal file
View File

@ -0,0 +1,36 @@
import {useActiveVersion, useLatestVersion, useVersions} from '@docusaurus/plugin-content-docs/client';
export function useCurrentVersion(fallback: 'latest' | 'latestReleased' = 'latest'): string {
switch (fallback) {
case 'latestReleased':
return useLatestReleasedVersion();
case 'latest': {
const version = useActiveVersion('default');
return version?.name ?? useLatestVersion('default')?.name;
}
default:
// The following line ensures that if `fallback` is not 'latest' or 'latestReleased',
// an error is thrown. This can be useful for catching unexpected states.
throw new Error(`Unhandled fallback type: ${fallback}`);
}
}
export function useLatestReleasedVersion(): string {
const allVersions = useVersions('default');
// Filter out "current" to only consider versioned docs
const versionedDocs = allVersions.filter(version => version.name !== 'current');
// Handle the case where no versioned documents are found
if (versionedDocs.length === 0) {
return "unknown_version";
}
const sortedVersions = versionedDocs.sort((a, b) => {
return b.name.localeCompare(a.name, undefined, { numeric: true, sensitivity: 'base' });
});
// The latest version is the first in the sorted list since versionedDocs was not empty,
return sortedVersions[0].name;
}

View File

@ -1,4 +1,4 @@
import type {ReactNode} from 'react';
import type {ReactElement, ReactNode} from 'react';
import clsx from 'clsx';
import Link from '@docusaurus/Link';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
@ -8,7 +8,7 @@ import Heading from '@theme/Heading';
import styles from './index.module.css';
function HomepageHeader() {
function HomepageHeader(): ReactElement<null> {
const { siteConfig } = useDocusaurusContext();
return (
<header className={clsx('hero hero--primary', styles.heroBanner)}>
@ -21,7 +21,7 @@ function HomepageHeader() {
);
}
export default function Home(): ReactNode {
export default function Home(): ReactElement<null> {
const {siteConfig} = useDocusaurusContext();
return (
<Layout

View File

@ -2,7 +2,11 @@
// This file is not used in compilation. It is here just for a nice editor experience.
"extends": "@docusaurus/tsconfig",
"compilerOptions": {
"baseUrl": "."
"baseUrl": ".",
"strict": true
},
"exclude": [".docusaurus", "build"]
"exclude": [
".docusaurus",
"build"
]
}