diff --git a/.htmltest.yml b/.htmltest.yml
index 84e17fd..c72ee0e 100644
--- a/.htmltest.yml
+++ b/.htmltest.yml
@@ -1,12 +1,17 @@
# cSpell:ignore github
CacheExpires: 9000h # ~ 12 months
-DirectoryPath: build
+DirectoryPath: dist
TestFilesConcurrently: true
+IgnoreCanonicalBrokenLinks: true
+IgnoreEmptyHref: true
+IgnoreAltEmpty: true
IgnoreDirs:
+ - analyses
IgnoreInternalURLs: # list of paths
IgnoreURLs: # list of regexes of URLs or path to be ignored
- ^https?://localhost
- \?no-link-check
+ - \?(_PROJECT|TODO)
# FIXME: temporary ignore rules
- assistance\.md
- LICENSE
diff --git a/astro.config.mjs b/astro.config.mjs
new file mode 100644
index 0000000..0cebcc4
--- /dev/null
+++ b/astro.config.mjs
@@ -0,0 +1,47 @@
+// @ts-check
+import { defineConfig } from 'astro/config';
+import starlight from '@astrojs/starlight';
+import { visit } from 'unist-util-visit';
+import { rewriteMdLinks } from './src/plugins/rewrite-md-links.mjs';
+
+// https://astro.build/config
+export default defineConfig({
+ // site: 'https://astro--cncf-techdocs.netlify.app/',
+ integrations: [
+ starlight({
+ title: 'CNCF Techdocs',
+ // favicon: 'static/img/cncf-icon-color.svg', // cSpell:disable-line
+ customCss: ['./src/css/custom.css'],
+ sidebar: [
+ {
+ label: 'Docs',
+ collapsed: true,
+ autogenerate: {
+ directory: 'docs',
+ },
+ },
+ {
+ label: 'Project Analyses',
+ collapsed: true,
+ autogenerate: {
+ directory: 'analyses',
+ },
+ },
+ ],
+ social: [
+ {
+ icon: 'github',
+ label: 'GitHub',
+ href: 'https://github.com/withastro/starlight',
+ },
+ ],
+ }),
+ ],
+ // Configure Astro's markdown handling
+ markdown: {
+ // Enable smartypants and other markdown features
+ // smartypants: true,
+ // Configure remark plugins
+ remarkPlugins: [rewriteMdLinks],
+ },
+});
diff --git a/netlify.toml b/netlify.toml
index cbdbceb..cab9b10 100644
--- a/netlify.toml
+++ b/netlify.toml
@@ -1,5 +1,5 @@
[build]
-publish = "build"
+publish = "dist"
command = "npm run build:preview"
[context.production]
diff --git a/package.json b/package.json
index 685fd9d..d491caa 100644
--- a/package.json
+++ b/package.json
@@ -2,8 +2,9 @@
"name": "techdocs",
"version": "0.0.0",
"description": "Resources provided by the CNCF Technical Documentation team.",
+ "type": "module",
"scripts": {
- "_build": "npm run docus:build",
+ "_build": "npm run astro:build -- --force",
"_check:format:any": "npx prettier --check --ignore-path ''",
"_check:format:delta": "npm run _check:format:any -- $(npm run -s _list:git:delta)",
"_check:format": "npx prettier --check .",
@@ -18,6 +19,12 @@
"_list:check:md": "find . -name '*.md' -not -path '*/node_modules/*' -a -not -path '*/.?*' | grep -Eve '/000|/0010'",
"_list:fix:*": "npm run --loglevel=warn | grep -Ee '^\\s*fix:[^:]+$' | grep -v 'fix:all'",
"_list:git:delta": "git diff --name-only --diff-filter=ACMR | grep -E '\\.(js|md|scss|yml|yaml)$'",
+ "add-frontmatter": "node scripts/add-frontmatter.mjs",
+ "astro:build": "astro build",
+ "astro:postbuild": "find dist -name \"*.html\" -exec perl -i -pe 's|||g' {} +",
+ "astro:dev": "astro dev",
+ "astro:preview": "astro preview",
+ "astro": "astro",
"build:preview": "npm run _build",
"build:production": "npm run _build",
"build": "BUILD_ENV=dev npm run _build",
@@ -26,6 +33,7 @@
"check:markdown": "npm run _check:markdown:all",
"check:spelling": "npx cspell --no-progress -c .cspell.yml analyses docs *.md",
"check": "npm run seq -- $(npm run -s _list:check:*)",
+ "postastro:build": "find dist -name \"*.html\" -exec perl -i -pe 's|||g' {} +",
"docus:build": "docusaurus build",
"docus:clear": "docusaurus clear",
"docus:deploy": "docusaurus deploy",
@@ -47,28 +55,34 @@
"author": "CNCF",
"license": "CC-BY-4.0",
"dependencies": {
+ "@astrojs/starlight": "^0.34.4",
"@docusaurus/core": "3.8.1",
"@docusaurus/preset-classic": "3.8.1",
"@mdx-js/react": "^3.1.0",
+ "astro": "^5.6.1",
"clsx": "^2.1.1",
"prism-react-renderer": "^2.4.1",
"react-dom": "^19.1.0",
- "react": "^19.1.0"
+ "react": "^19.1.0",
+ "sharp": "^0.32.5",
+ "unist-util-visit": "^5.0.0"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "3.8.1",
"@docusaurus/tsconfig": "3.8.1",
"@docusaurus/types": "3.8.1",
"cspell": "^9.1.1",
+ "glob": "^10.3.10",
"markdown-link-check": "3.13.7",
"markdownlint-cli": "^0.45.0",
"markdownlint": "^0.38.0",
"npm-check-updates": "^18.0.1",
"prettier": "^3.5.3",
- "typescript": "~5.8.3"
+ "typescript": "~5.8.3",
+ "yaml": "^2.4.0"
},
"private": true,
- "spelling": "cSpell:ignore ACMR docus HTMLTEST loglevel pkgs -",
+ "spelling": "cSpell:ignore ACMR docus frontmatter HTMLTEST loglevel pkgs postbuild -",
"prettier": {
"proseWrap": "always",
"singleQuote": true
diff --git a/public/favicon.svg b/public/favicon.svg
new file mode 120000
index 0000000..c90fbdf
--- /dev/null
+++ b/public/favicon.svg
@@ -0,0 +1 @@
+../static/img/cncf-icon-color.svg
\ No newline at end of file
diff --git a/src/content.config.ts b/src/content.config.ts
new file mode 100644
index 0000000..6a7b7a0
--- /dev/null
+++ b/src/content.config.ts
@@ -0,0 +1,7 @@
+import { defineCollection } from 'astro:content';
+import { docsLoader } from '@astrojs/starlight/loaders';
+import { docsSchema } from '@astrojs/starlight/schema';
+
+export const collections = {
+ docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }),
+};
diff --git a/src/content/docs/analyses b/src/content/docs/analyses
new file mode 120000
index 0000000..0aaea59
--- /dev/null
+++ b/src/content/docs/analyses
@@ -0,0 +1 @@
+../../../analyses
\ No newline at end of file
diff --git a/src/content/docs/docs b/src/content/docs/docs
new file mode 120000
index 0000000..48c4a0c
--- /dev/null
+++ b/src/content/docs/docs
@@ -0,0 +1 @@
+../../../docs
\ No newline at end of file
diff --git a/src/content/docs/index.mdx b/src/content/docs/index.mdx
new file mode 100644
index 0000000..344a77a
--- /dev/null
+++ b/src/content/docs/index.mdx
@@ -0,0 +1,20 @@
+---
+title: Welcome
+# description:
+template: splash
+hero:
+ tagline: Techdocs how-tos & project analyses
+ image:
+ file: ../../../static/img/cncf-icon-color.svg
+ actions:
+ - text: Docs
+ link: /docs/
+ # icon: right-arrow
+ - text: Project analyses
+ link: /analyses/
+ variant: secondary
+---
+
+import README from '../../../README.md';
+
+
diff --git a/src/css/custom.css b/src/css/custom.css
index 2bc6a4c..8169ae8 100644
--- a/src/css/custom.css
+++ b/src/css/custom.css
@@ -28,3 +28,7 @@
--ifm-color-primary-lightest: #4fddbf;
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3);
}
+
+.sl-heading-wrapper.level-h1 {
+ display: none;
+}
diff --git a/src/pages/index.mdx b/src/pages/index.mdx
deleted file mode 100644
index 28955dd..0000000
--- a/src/pages/index.mdx
+++ /dev/null
@@ -1,3 +0,0 @@
-import README from '../../README.md';
-
-
diff --git a/src/plugins/rewrite-md-links.mjs b/src/plugins/rewrite-md-links.mjs
new file mode 100644
index 0000000..29590d2
--- /dev/null
+++ b/src/plugins/rewrite-md-links.mjs
@@ -0,0 +1,46 @@
+import { visit } from 'unist-util-visit';
+
+/**
+ * A remark plugin that rewrites markdown links from GitHub-style `.md`
+ * references to relative paths without the `.md` extension, handling index
+ * files appropriately.
+ */
+export function rewriteMdLinks() {
+ return (tree, file) => {
+ // console.log('rewriteMdLinks: Processing file:', file.path);
+
+ // Check if this is an index.md file
+ const isIndexFile =
+ file.basename === 'index.md' || file.basename === 'README.md';
+
+ // Helper function to process .md links
+ const processMdLink = (node) => {
+ if (typeof node.url === 'string' && /\.md($|[\/#])/.test(node.url)) {
+ // if (node.url.startsWith('docs/assistance')) {
+ // console.log('rewriteMdLinks: Found .md link:', node.url, 'in file:', file.path);
+ // }
+
+ if (node.url.startsWith('http')) return;
+
+ // Remove .md extension
+ let url = node.url.replace(/(?:index)?\.md($|[\/#])/, '/$1');
+
+ // If it's a sibling file (no / or starts with ./), handle based on file type
+ if (true || /^([^\/]|\.\/)/.test(node.url)) {
+ if (url.startsWith('./')) url = url.slice(2);
+ if (!isIndexFile) {
+ url = '../' + url;
+ }
+ }
+ node.url = url;
+ //console.log('rewriteMdLinks: Rewrote link to:', node.url);
+ }
+ };
+
+ // Handle inline markdown links
+ visit(tree, 'link', processMdLink);
+
+ // Handle link definitions (reference-style links)
+ visit(tree, 'definition', processMdLink);
+ };
+}
diff --git a/static/refcache.json b/static/refcache.json
index 82bdf37..a642465 100644
--- a/static/refcache.json
+++ b/static/refcache.json
@@ -487,6 +487,10 @@
"StatusCode": 206,
"LastSeen": "2025-03-19T11:52:41.206262-04:00"
},
+ "https://github.com/withastro/starlight": {
+ "StatusCode": 206,
+ "LastSeen": "2025-06-18T06:17:48.988777-04:00"
+ },
"https://goharbor.io/": {
"StatusCode": 206,
"LastSeen": "2025-03-19T11:52:42.657248-04:00"
diff --git a/tsconfig.json b/tsconfig.json
index 920d7a6..8bf91d3 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,8 +1,5 @@
{
- // This file is not used in compilation. It is here just for a nice editor experience.
- "extends": "@docusaurus/tsconfig",
- "compilerOptions": {
- "baseUrl": "."
- },
- "exclude": [".docusaurus", "build"]
+ "extends": "astro/tsconfigs/strict",
+ "include": [".astro/types.d.ts", "**/*"],
+ "exclude": ["dist"]
}