From 9319edfe72fce92577b16b06be41248b4ac4d132 Mon Sep 17 00:00:00 2001 From: Adelina Simion <43963729+addetz@users.noreply.github.com> Date: Wed, 12 Jun 2024 19:24:41 +0200 Subject: [PATCH 1/6] docs: add versioning logic to partials DOC-1198 (#3035) --- .gitignore | 1 + Makefile | 2 +- README.md | 11 +++-- scripts/generate-partials.sh | 6 ++- scripts/versions.sh | 10 ++++ .../PartialsComponent/GetAllVersions.tsx | 16 ++++++ .../PartialsComponent/GetVersion.tsx | 10 ++++ .../PartialsComponent-Versioned.test.tsx | 47 ++++++++++++++++++ .../PartialsComponent.test.tsx | 16 ++++-- .../PartialsComponent/PartialsComponent.tsx | 31 ++++++++++-- .../PartialsComponent/PartialsImporter.tsx | 49 ++++++++++++++++--- 11 files changed, 177 insertions(+), 22 deletions(-) create mode 100644 src/components/PartialsComponent/GetAllVersions.tsx create mode 100644 src/components/PartialsComponent/GetVersion.tsx create mode 100644 src/components/PartialsComponent/PartialsComponent-Versioned.test.tsx diff --git a/.gitignore b/.gitignore index 0b62a66222..2ca1efff5e 100644 --- a/.gitignore +++ b/.gitignore @@ -44,6 +44,7 @@ docs/api-content/api-docs/edge-v1/sidebar.* versions.json versioned_docs/ versioned_sidebars/ +versioned_partials/ api_versions.json api_versioned_docs/ api_versioned_sidebars/ diff --git a/Makefile b/Makefile index 53ee1da193..89160dcfac 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ deep-clean: ## Clean all artifacts clean-versions: ## Clean Docusarus content versions @echo "cleaning versions" - rm -rf api_versions.json versions.json versioned_docs versioned_sidebars api_versioned_sidebars api_versioned_docs + rm -rf api_versions.json versions.json versioned_docs versioned_sidebars api_versioned_sidebars api_versioned_docs versioned_partials git checkout -- docusaurus.config.js static/robots.txt clean-api: ## Clean API docs diff --git a/README.md b/README.md index 0cc8232b57..7fe0feb179 100644 --- a/README.md +++ b/README.md @@ -585,13 +585,16 @@ category and name of the partial: ```md ``` -Note that the `cloud` field corresponds to the `{props.cloud}` reference in the `*.mdx` file. +The snippet above will work with the example partial we have in our repository, so you can use it for testing. + +Note that the `message` field corresponds to the `{props.message}` reference in the `_partials/_partial_example.mdx` +file. ### Internal Links diff --git a/scripts/generate-partials.sh b/scripts/generate-partials.sh index a2e14dc9ee..12968d7c84 100755 --- a/scripts/generate-partials.sh +++ b/scripts/generate-partials.sh @@ -12,6 +12,9 @@ rm -f _partials/index.ts mkdir -p _partials touch _partials/index.ts +# Make the versioned partials folder to satisfy compiler. +mkdir -p versioned_partials + # Create the file and add the generated warning. echo "// This file is generated. DO NOT EDIT!" >> _partials/index.ts @@ -20,7 +23,8 @@ echo "// This file is generated. DO NOT EDIT!" >> _partials/index.ts find _partials -name "*.mdx" -print0 | while read -d $'\0' path do module_name=$(basename ${path} .mdx | tr -d '_' | tr -d '-') - echo "export * as ${module_name}${RANDOM} from '@site/${path}';" >> _partials/index.ts + file_name=$(basename ${path}) + echo "export * as ${module_name}${RANDOM} from './${file_name}';" >> _partials/index.ts done echo "Completed generation of _partials/index.ts." diff --git a/scripts/versions.sh b/scripts/versions.sh index b03dae2712..f6070c0f5c 100755 --- a/scripts/versions.sh +++ b/scripts/versions.sh @@ -53,12 +53,15 @@ for b in $branches; do git fetch origin $b:$b done +# Make sure we are in a clean state for repeatable runs. +make clean-versions # Remove the existing versioned directories in the temp directory. rm -rf $tempdir/staging_docs rm -rf $tempdir/staging_api_docs rm -rf $tempdir/staging_sidebars rm -rf $tempdir/staging_api_docs_sidebars +rm -rf $tempdir/staging_partials rm -rf $tempdir/temp_versions.json rm -rf $tempdir/temp_api_versions.json @@ -68,6 +71,7 @@ mkdir -p $tempdir/staging_docs mkdir -p $tempdir/staging_api_docs mkdir -p $tempdir/staging_sidebars mkdir -p $tempdir/staging_api_docs_sidebars +mkdir -p $tempdir/staging_partials touch $tempdir/temp_versions.json touch $tempdir/temp_api_versions.json echo '[]' > $tempdir/temp_versions.json # Initialize as an empty array if it doesn't exist @@ -119,6 +123,9 @@ for item in $(git branch --format '%(refname:short)'); do # Pull the latest changes git pull origin $item + # Generate the partials once we are on the version branch + make generate-partials + # Run the npm command echo "Running: npm run docusaurus docs:version $extracted_versionX" npm run docusaurus docs:version $extracted_versionX @@ -139,6 +146,8 @@ for item in $(git branch --format '%(refname:short)'); do cp -R api_versioned_docs/version-$extracted_versionX $tempdir/staging_api_docs/ cp -R api_versioned_sidebars/version-$extracted_versionX $tempdir/staging_api_docs_sidebars/ || true cp api_versioned_sidebars/version-$extracted_versionX-sidebars.json $tempdir/staging_api_docs_sidebars/version-$extracted_versionX-sidebars.json + # Copy the partials folder + cp -R _partials $tempdir/staging_partials/version-$extracted_versionX rm -rf versioned_docs/ @@ -163,6 +172,7 @@ cp -R $tempdir/staging_docs $baseDir/versioned_docs cp -R $tempdir/staging_sidebars $baseDir/versioned_sidebars cp -R $tempdir/staging_api_docs $baseDir/api_versioned_docs cp -R $tempdir/staging_api_docs_sidebars $baseDir/api_versioned_sidebars +cp -R $tempdir/staging_partials/. $baseDir/versioned_partials # Remove the existing versions.json if it exists [ -e versions.json ] && rm versions.json diff --git a/src/components/PartialsComponent/GetAllVersions.tsx b/src/components/PartialsComponent/GetAllVersions.tsx new file mode 100644 index 0000000000..b356171045 --- /dev/null +++ b/src/components/PartialsComponent/GetAllVersions.tsx @@ -0,0 +1,16 @@ +import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; +import { Config } from "@docusaurus/types"; + +export default function GetVersions(): string[] { + const { siteConfig } = useDocusaurusContext(); + const cfg = siteConfig as Config; + if (cfg.presets != undefined) { + // Linting is disabled for next line, as there is no type for docs config. + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-argument + const versions = cfg.presets[0][1]["docs"]["versions"] as object; + const versionNames: string[] = Object.keys(versions); + return versionNames; + } + // if no presets, then default to "current" + return ["current"]; +} diff --git a/src/components/PartialsComponent/GetVersion.tsx b/src/components/PartialsComponent/GetVersion.tsx new file mode 100644 index 0000000000..7087305f99 --- /dev/null +++ b/src/components/PartialsComponent/GetVersion.tsx @@ -0,0 +1,10 @@ +import { useActivePluginAndVersion } from "@docusaurus/plugin-content-docs/client"; + +export default function GetVersion(): string { + const activePlugin = useActivePluginAndVersion(); + if (activePlugin != undefined && activePlugin.activeVersion != undefined) { + return activePlugin.activeVersion.name; + } + + return ""; +} diff --git a/src/components/PartialsComponent/PartialsComponent-Versioned.test.tsx b/src/components/PartialsComponent/PartialsComponent-Versioned.test.tsx new file mode 100644 index 0000000000..35664bbdca --- /dev/null +++ b/src/components/PartialsComponent/PartialsComponent-Versioned.test.tsx @@ -0,0 +1,47 @@ +import React, { FunctionComponent } from "react"; +import { render, screen } from "@testing-library/react"; + +let category = "testCat1"; +let name = "nameCat1"; +let propValue = "testValue1"; + +const Partial: React.FunctionComponent<{}> = ({}) => ( +
+

{category}

+

{name}

+

{propValue}

+
+); + +jest.mock("./PartialsImporter", () => { + return jest.fn(() => { + const allPartials: PartialsMap = {}; + const mapKey = "version-4.3.x".concat("#").concat(category).concat("#").concat(name); + allPartials[mapKey] = Partial as FunctionComponent; + return allPartials; + }); +}); + +jest.mock("./GetVersion", () => { + return jest.fn(() => { + return "4.3.x"; + }); +}); + +import PartialsComponent from "./PartialsComponent"; +import { PartialsMap } from "./PartialsImporter"; + +describe("Partials Component", () => { + it("partial exists", () => { + render(); + expect(screen.getByText(category)).toBeInTheDocument(); + expect(screen.getByText(name)).toBeInTheDocument(); + expect(screen.getByText(propValue)).toBeInTheDocument(); + }); + + it("partial does not exist", () => { + expect(() => render()).toThrow( + "No partial found for name unknownName in category unknownCat for version 4.3.x." + ); + }); +}); diff --git a/src/components/PartialsComponent/PartialsComponent.test.tsx b/src/components/PartialsComponent/PartialsComponent.test.tsx index ca1588ab16..6f1d8ad8f6 100644 --- a/src/components/PartialsComponent/PartialsComponent.test.tsx +++ b/src/components/PartialsComponent/PartialsComponent.test.tsx @@ -15,10 +15,16 @@ const Partial: React.FunctionComponent<{}> = ({}) => ( jest.mock("./PartialsImporter", () => { return jest.fn(() => { - const mapKey = category.concat("#").concat(name); - const pmap: PartialsMap = {}; - pmap[mapKey] = Partial as FunctionComponent; - return pmap; + const allPartials: PartialsMap = {}; + const mapKey = "current".concat("#").concat(category).concat("#").concat(name); + allPartials[mapKey] = Partial as FunctionComponent; + return allPartials; + }); +}); + +jest.mock("./GetVersion", () => { + return jest.fn(() => { + return "current"; }); }); @@ -35,7 +41,7 @@ describe("Partials Component", () => { it("partial does not exist", () => { expect(() => render()).toThrow( - "No partial found for name unknownName in category unknownCat." + "No partial found for name unknownName in category unknownCat for version current." ); }); }); diff --git a/src/components/PartialsComponent/PartialsComponent.tsx b/src/components/PartialsComponent/PartialsComponent.tsx index 3c5b180109..5e344ca134 100644 --- a/src/components/PartialsComponent/PartialsComponent.tsx +++ b/src/components/PartialsComponent/PartialsComponent.tsx @@ -1,18 +1,34 @@ import React from "react"; -import ImportPartials from "./PartialsImporter"; +import ImportPartials, { PartialsMap } from "./PartialsImporter"; +import GetVersion from "./GetVersion"; interface ComponentProperties { [key: string]: string; } -const AllPartials = ImportPartials(); +let AllPartials: PartialsMap = {}; +let firstLoad = true; export default function PartialsComponent(details: ComponentProperties): React.ReactElement { - const mapKey = details.category.concat("#").concat(details.name); + // Hooks can only be invoked inside the body of the component, so we cannot load this beforehand. + if (firstLoad) { + AllPartials = ImportPartials(); + firstLoad = false; + } + // Get the version this page is on. + const ver: string = GetVersion(); + // Construct the map key including the version + const mapKey = getMapKey(ver, details.category, details.name); if (!AllPartials[mapKey]) { throw new Error( - "No partial found for name ".concat(details.name).concat(" in category ").concat(details.category).concat(".") + "No partial found for name " + .concat(details.name) + .concat(" in category ") + .concat(details.category) + .concat(" for version ") + .concat(ver) + .concat(".") ); } @@ -28,3 +44,10 @@ export default function PartialsComponent(details: ComponentProperties): React.R return React.createElement(AllPartials[mapKey], propAttribute); } + +function getMapKey(ver: string, category: string, name: string): string { + if (ver == "current") { + return ver.concat("#").concat(category).concat("#").concat(name); + } + return "version-".concat(ver).concat("#").concat(category).concat("#").concat(name); +} diff --git a/src/components/PartialsComponent/PartialsImporter.tsx b/src/components/PartialsComponent/PartialsImporter.tsx index b9441d67a7..7f05b8893c 100644 --- a/src/components/PartialsComponent/PartialsImporter.tsx +++ b/src/components/PartialsComponent/PartialsImporter.tsx @@ -1,12 +1,11 @@ import { FunctionComponent } from "react"; -// Import all the partials as one module. -import * as PartialModules from "@site/_partials"; +import GetAllVersions from "./GetAllVersions"; export interface PartialsMap { [key: string]: FunctionComponent; } -interface Modules { +export interface Modules { [key: string]: Module; } @@ -20,12 +19,46 @@ interface Module { export default function ImportPartials(): PartialsMap { const pmap: PartialsMap = {}; - const allPartialModules: Modules = PartialModules; + const versions: string[] = GetAllVersions(); + versions.map((ver) => { + if (ver == "current") { + importLatestHelper(ver, pmap); + } else { + //Import all the versioned partials if this is the first time we visit this version. + importVersionedHelper("version-" + ver, pmap); + } + }); + + return pmap; +} + +function importLatestHelper(prefix: string, existingPartials: PartialsMap) { + try { + // Linting is disabled for next line, as we need the ability to dynamically import partials. + // eslint-disable-next-line @typescript-eslint/no-var-requires + const modules: Modules = require("@site/_partials"); + MapPartials(prefix, modules, existingPartials); + } catch { + console.log("No partials found for " + prefix + ". Skipping imports for it."); + } +} + +function importVersionedHelper(prefix: string, existingPartials: PartialsMap) { + try { + // Linting is disabled for next line, as we need the ability to dynamically import partials. + // eslint-disable-next-line @typescript-eslint/no-var-requires + const modules: Modules = require("@site/versioned_partials/" + prefix + "/"); + MapPartials(prefix, modules, existingPartials); + } catch { + console.log("No partials found for " + prefix + ". Skipping imports for it."); + } +} +export function MapPartials(ver: string, module: Modules, pmap: PartialsMap) { // The keys are the names of each exported module in _partials/index.ts - const partialKeys: string[] = Object.keys(allPartialModules); + const partialKeys: string[] = Object.keys(module); partialKeys.map(function (pkey) { - const currentPartial: Module = allPartialModules[pkey]; + const currentPartial: Module = module[pkey]; const catFrontMatter = currentPartial.frontMatter.partial_category; const nameFrontMatter = currentPartial.frontMatter.partial_name; @@ -33,13 +66,15 @@ export default function ImportPartials(): PartialsMap { throw new Error("Please specify partial_category and partial_name for ".concat(pkey).concat(".")); } - const mapKey = catFrontMatter.concat("#").concat(nameFrontMatter); + const mapKey = ver.concat("#").concat(catFrontMatter).concat("#").concat(nameFrontMatter); if (pmap[mapKey]) { throw new Error( "Duplicate partial defined for name " .concat(nameFrontMatter) .concat(" in category ") .concat(catFrontMatter) + .concat("for version") + .concat(ver) .concat(".") ); } From 5d41527d4c4227eacffaccc3d6ae7e9544f8257e Mon Sep 17 00:00:00 2001 From: Karl Cardenas Date: Thu, 13 Jun 2024 09:32:27 -0700 Subject: [PATCH 2/6] ci: update Vale (#3075) --- .github/workflows/pull_request.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull_request.yaml b/.github/workflows/pull_request.yaml index 8fc96bdbe5..6d15e4a710 100644 --- a/.github/workflows/pull_request.yaml +++ b/.github/workflows/pull_request.yaml @@ -50,7 +50,7 @@ jobs: reporter: github-pr-review vale_flags: --glob=*.{md} --minAlertLevel=error fail_on_error: false - version: 3.2.1 + version: 3.5.0 env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} From 18a73c002a14ee9fa7c0182c98095aebdecc18b6 Mon Sep 17 00:00:00 2001 From: Karl Cardenas Date: Thu, 13 Jun 2024 11:04:31 -0700 Subject: [PATCH 3/6] docs: DOC-1229 (#3074) --- docs/docs-content/clusters/edge/networking/vxlan-overlay.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs-content/clusters/edge/networking/vxlan-overlay.md b/docs/docs-content/clusters/edge/networking/vxlan-overlay.md index dcd7ed45ad..73b45a4713 100644 --- a/docs/docs-content/clusters/edge/networking/vxlan-overlay.md +++ b/docs/docs-content/clusters/edge/networking/vxlan-overlay.md @@ -62,7 +62,7 @@ server. The region experiences a bad weather event that causes a sustained outag ## Prerequisites - At least one Edge host registered with your Palette account. -- Your cluster profile must have K3s as its Kubernetes distribution. +- Your cluster profile must have K3s or RKE2 as its Kubernetes distribution. - All Edge hosts must be on the same Layer-2 network. - If you are launching your Edge hosts in virtual machine environments and you are using either Cilium or Flannel as your container network interface (CNI), ensure that you add the following commands in the **user-data** file at the From 8993bfa02295149543d573c1085348524e6f3957 Mon Sep 17 00:00:00 2001 From: Lenny Chen <55669665+lennessyy@users.noreply.github.com> Date: Thu, 13 Jun 2024 11:30:25 -0700 Subject: [PATCH 4/6] docs: remove overlay known issue (#3082) Co-authored-by: Lenny Chen --- docs/docs-content/clusters/edge/networking/vxlan-overlay.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/docs/docs-content/clusters/edge/networking/vxlan-overlay.md b/docs/docs-content/clusters/edge/networking/vxlan-overlay.md index 73b45a4713..c815e61cf0 100644 --- a/docs/docs-content/clusters/edge/networking/vxlan-overlay.md +++ b/docs/docs-content/clusters/edge/networking/vxlan-overlay.md @@ -53,12 +53,6 @@ server. The region experiences a bad weather event that causes a sustained outag - When adding multiple Edge hosts to an existing cluster with overlay enabled, failure to add one host will block the addition of the other hosts. -- When a cluster has overlay enabled, you cannot delete an Edge host that has the `palette-webhook` pod on it, or the - Edge host will be stuck in the deleting state. You can use the command - `kubectl get pods --all-namespaces --output wide` to identify which node `palette-webhook` is on. If you need to - remove an Edge host that has the `palette-webhook` pod on it, please reach out to our support team by opening a ticket - through our [support page](http://support.spectrocloud.io/). - ## Prerequisites - At least one Edge host registered with your Palette account. From 2b9f14236a070d7624ad8673f1a03bdc13dc5888 Mon Sep 17 00:00:00 2001 From: Karl Cardenas Date: Thu, 13 Jun 2024 11:58:38 -0700 Subject: [PATCH 5/6] docs: Update colon.yml (#3084) --- vale/styles/spectrocloud/colon.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/vale/styles/spectrocloud/colon.yml b/vale/styles/spectrocloud/colon.yml index b93711c7fa..7facf72223 100644 --- a/vale/styles/spectrocloud/colon.yml +++ b/vale/styles/spectrocloud/colon.yml @@ -5,7 +5,9 @@ nonword: true level: error scope: raw tokens: - - '(? Date: Thu, 13 Jun 2024 14:19:54 -0700 Subject: [PATCH 6/6] docs: updated VMware permissions (#3090) * docs: updated VMware permissions * chore: add missing section --- docs/docs-content/clusters/data-center/vmware/permissions.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs-content/clusters/data-center/vmware/permissions.md b/docs/docs-content/clusters/data-center/vmware/permissions.md index 3ffe56b768..417b1962d9 100644 --- a/docs/docs-content/clusters/data-center/vmware/permissions.md +++ b/docs/docs-content/clusters/data-center/vmware/permissions.md @@ -48,7 +48,7 @@ vSphere version you are using to view the required privileges for the spectro ro - + | **vSphere Object** | **Privileges** | | -------------------------- | -------------------------------------------------- | @@ -154,7 +154,7 @@ Virtual Machines. - + | **vSphere Object** | **Privileges** | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |