mirror of
https://github.com/goauthentik/authentik.git
synced 2026-08-30 18:51:39 -07:00
website: Fix Markdown for release notes (#24516)
* website: Fix Markdown for release notes * r * e * website/docs: remove unrelated release link fix * Tidy predicate. --------- Co-authored-by: Teffen Ellis <592134+GirlBossRush@users.noreply.github.com>
This commit is contained in:
@@ -12,7 +12,7 @@ draft: true
|
||||
|
||||
## Upgrading
|
||||
|
||||
This release does not introduce any new requirements. You can follow the upgrade instructions below; for more detailed information about upgrading authentik, refer to our [Upgrade documentation](../../install-config/upgrade.mdx).
|
||||
This release does not introduce any new requirements. You can follow the upgrade instructions below; for more detailed information about upgrading authentik, refer to our [Upgrade documentation](../install-config/upgrade.mdx).
|
||||
|
||||
:::warning Upgrade in order and upgrade all components
|
||||
Upgrades MUST be performed sequentially by major version. If you are two or more major releases behind, you must first upgrade to each intermediate major release before upgrading to this one. Refer to our [Upgrade documentation](../../install-config/upgrade.mdx) for more information on upgrade sequence.
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
title: Release 2026.5
|
||||
slug: /releases/2026.5
|
||||
---
|
||||
|
||||
# Release 2026.5
|
||||
|
||||
Release notes with a route overridden by frontmatter.
|
||||
@@ -182,7 +182,7 @@ export function parseDocFile(filePath, baseDir) {
|
||||
const raw = readFileSync(filePath, "utf-8");
|
||||
const { frontMatter, content } = parseFileContentFrontMatter(raw);
|
||||
|
||||
if (frontMatter.draft === true) {
|
||||
if (frontMatter.draft) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -280,33 +280,6 @@ export function groupLabel(group, opts) {
|
||||
return humanizeSlug(group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a site-relative path to its rendered route URL.
|
||||
*
|
||||
* @param {string} relPathNoExt Site-relative path, POSIX, no extension.
|
||||
* @param {string[]} routesPaths Resolved routes from Docusaurus postBuild props.
|
||||
* @returns {string | undefined}
|
||||
*/
|
||||
export function resolveDocumentUrl(relPathNoExt, routesPaths) {
|
||||
if (!routesPaths || routesPaths.length === 0) return undefined;
|
||||
|
||||
// The root index page has the bare path "index" (no leading "/index" to
|
||||
// strip), so it never suffix-matches a route. Map it to the site root.
|
||||
if (relPathNoExt === "" || relPathNoExt === "index") {
|
||||
return routesPaths.includes("/") ? "/" : undefined;
|
||||
}
|
||||
|
||||
const tails = new Set([relPathNoExt]);
|
||||
tails.add(collapseMatchingTrailingSegment(relPathNoExt));
|
||||
tails.add(removeNumberedPrefixes(relPathNoExt));
|
||||
|
||||
for (const tail of tails) {
|
||||
const match = findMatchingRoute(routesPaths, tail);
|
||||
if (match) return match;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} routeBasePath
|
||||
* @returns {string}
|
||||
@@ -362,3 +335,42 @@ export function resolveDocumentUrlFromSource(doc, routeBasePath) {
|
||||
|
||||
return normalizeRoutePath(`${normalizeRouteBasePath(routeBasePath)}${doc.path}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a document to its rendered route URL.
|
||||
*
|
||||
* Prefer the route declared by the document's source metadata, including a
|
||||
* frontmatter slug override. Fall back to matching the source path for routes
|
||||
* transformed by Docusaurus conventions such as numbered prefixes.
|
||||
*
|
||||
* @param {LLMSDocInfo} doc
|
||||
* @param {string} routeBasePath
|
||||
* @param {string[]} routesPaths Resolved routes from Docusaurus postBuild props.
|
||||
* @returns {string | undefined}
|
||||
*/
|
||||
export function resolveDocumentUrl(doc, routeBasePath, routesPaths) {
|
||||
if (!routesPaths || routesPaths.length === 0) return undefined;
|
||||
|
||||
const sourceRoute = resolveDocumentUrlFromSource(doc, routeBasePath);
|
||||
const normalizedSourceRoute = trimTrailingSlashes(sourceRoute.toLowerCase());
|
||||
const exactRoute = routesPaths.find(
|
||||
(route) => trimTrailingSlashes(route.toLowerCase()) === normalizedSourceRoute,
|
||||
);
|
||||
if (exactRoute) return exactRoute;
|
||||
|
||||
// The root index page has the bare path "index" (no leading "/index" to
|
||||
// strip), so it never suffix-matches a route. Map it to the site root.
|
||||
if (doc.path === "" || doc.path === "index") {
|
||||
return routesPaths.includes("/") ? "/" : undefined;
|
||||
}
|
||||
|
||||
const tails = new Set([doc.path]);
|
||||
tails.add(collapseMatchingTrailingSegment(doc.path));
|
||||
tails.add(removeNumberedPrefixes(doc.path));
|
||||
|
||||
for (const tail of tails) {
|
||||
const match = findMatchingRoute(routesPaths, tail);
|
||||
if (match) return match;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ test("collectDocFiles finds md and mdx, excludes partials", () => {
|
||||
const rels = files.map((f) => f.slice(normalizePath(FIXTURE).length + 1)).sort();
|
||||
assert.deepEqual(rels, [
|
||||
"index.mdx",
|
||||
"releases/2026/v2026.5.md",
|
||||
"topic-a/index.mdx",
|
||||
"topic-a/page-one.md",
|
||||
"topic-b/page-two.mdx",
|
||||
@@ -111,22 +112,36 @@ test("parseDocFile strips inline links/emphasis and keeps the first sentence", (
|
||||
const ROUTES = ["/", "/topic-a/", "/topic-a/page-one/", "/topic-b/page-two/"];
|
||||
|
||||
test("resolveDocumentUrl matches a route by suffix", () => {
|
||||
assert.equal(resolveDocumentUrl("topic-a/page-one", ROUTES), "/topic-a/page-one/");
|
||||
assert.equal(
|
||||
resolveDocumentUrl(testDoc("topic-a/page-one"), "/", ROUTES),
|
||||
"/topic-a/page-one/",
|
||||
);
|
||||
});
|
||||
|
||||
test("resolveDocumentUrl strips numbered prefixes", () => {
|
||||
assert.equal(resolveDocumentUrl("topic-a/01-page-one", ROUTES), "/topic-a/page-one/");
|
||||
assert.equal(
|
||||
resolveDocumentUrl(testDoc("topic-a/01-page-one"), "/", ROUTES),
|
||||
"/topic-a/page-one/",
|
||||
);
|
||||
});
|
||||
|
||||
test("resolveDocumentUrl honors frontmatter slug overrides", () => {
|
||||
const routes = [...ROUTES, "/releases/2026.5/"];
|
||||
assert.equal(
|
||||
resolveDocumentUrl(testDoc("releases/2026/v2026.5", "/releases/2026.5"), "/", routes),
|
||||
"/releases/2026.5/",
|
||||
);
|
||||
});
|
||||
|
||||
test("resolveDocumentUrl returns undefined when no route matches", () => {
|
||||
assert.equal(resolveDocumentUrl("missing/page", ROUTES), undefined);
|
||||
assert.equal(resolveDocumentUrl(testDoc("missing/page"), "/", ROUTES), undefined);
|
||||
});
|
||||
|
||||
test("resolveDocumentUrl maps the root index page to /", () => {
|
||||
// The site's index.mdx has no trailing "/index" to strip, so its path is the
|
||||
// bare "index" — it must still resolve to the site root route.
|
||||
assert.equal(resolveDocumentUrl("index", ROUTES), "/");
|
||||
assert.equal(resolveDocumentUrl("", ROUTES), "/");
|
||||
assert.equal(resolveDocumentUrl(testDoc("index"), "/", ROUTES), "/");
|
||||
assert.equal(resolveDocumentUrl(testDoc(""), "/", ROUTES), "/");
|
||||
});
|
||||
|
||||
test("resolveDocumentUrlFromSource maps routeBasePath and index pages", () => {
|
||||
|
||||
@@ -88,11 +88,11 @@ export async function buildLLMSOutputs(ctx) {
|
||||
if (!parsed) continue;
|
||||
|
||||
const route = ctx.routesPaths.length
|
||||
? resolveDocumentUrl(parsed.path, ctx.routesPaths)
|
||||
? resolveDocumentUrl(parsed, section.routeBasePath, ctx.routesPaths)
|
||||
: resolveDocumentUrlFromSource(parsed, section.routeBasePath);
|
||||
if (!route) {
|
||||
// Expected for source files Docusaurus does not route (e.g.
|
||||
// historical release notes). Counted and summarized, not warned per-page.
|
||||
// Expected for source files Docusaurus does not route. Counted
|
||||
// and summarized, not warned per-page.
|
||||
skippedNoRoute++;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import { assignGroup, buildLLMSOutputs, groupLabel, resolveSiteUrl } from "./plu
|
||||
const __dirname = fileURLToPath(new URL(".", import.meta.url));
|
||||
const FIXTURE = resolve(__dirname, "__fixtures__", "site");
|
||||
|
||||
const ROUTES = ["/", "/topic-a/", "/topic-a/page-one/", "/topic-b/page-two/"];
|
||||
const ROUTES = ["/", "/releases/2026.5/", "/topic-a/", "/topic-a/page-one/", "/topic-b/page-two/"];
|
||||
|
||||
test("assignGroup uses first segment for topic grouping", () => {
|
||||
const doc = { path: "topic-a/page-one" };
|
||||
@@ -88,6 +88,8 @@ test("buildLLMSOutputs emits root, full, per-group, and per-page files", async (
|
||||
assert.ok(outputs.has("llms-full.txt"), "full text");
|
||||
assert.ok(outputs.has("topic-a/llms.txt"), "per-group index");
|
||||
assert.ok(outputs.has("topic-a/page-one.md"), "per-page payload");
|
||||
assert.ok(outputs.has("releases/2026.5.md"), "frontmatter-slugged per-page payload");
|
||||
assert.ok(!outputs.has("releases/2026.8.md"), "production output excludes drafts");
|
||||
|
||||
const root = outputs.get("llms.txt") ?? "";
|
||||
assert.ok(root.includes("## Topic A")); // title-cased section heading
|
||||
@@ -95,6 +97,9 @@ test("buildLLMSOutputs emits root, full, per-group, and per-page files", async (
|
||||
|
||||
const page = outputs.get("topic-a/page-one.md") ?? "";
|
||||
assert.ok(page.includes("First real paragraph of page one."));
|
||||
|
||||
const release = outputs.get("releases/2026.5.md") ?? "";
|
||||
assert.ok(release.includes("Release notes with a route overridden by frontmatter."));
|
||||
});
|
||||
|
||||
test("buildLLMSOutputs writes per-category index at the slug path with a label heading", async () => {
|
||||
|
||||
@@ -429,7 +429,7 @@ export function parseDocFile(filePath, baseDir) {
|
||||
const raw = readFileSync(filePath, "utf-8");
|
||||
const { frontMatter, content } = parseFileContentFrontMatter(raw);
|
||||
|
||||
if (frontMatter.draft === true) {
|
||||
if (frontMatter.draft) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user