Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 49 additions & 12 deletions gatsby/URL_MAPPING_ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,25 @@ Rules are evaluated in order; the first matching rule wins.

---

### Rule 11: TiDB-in-Kubernetes with Branch Alias
### Rule 11: TiDB-in-Kubernetes Release Notes from Main

**Effect**: Publishes TiDB-in-Kubernetes release notes from `main` at stable URLs so they override the copies from the configured stable release branch.

**Source Pattern**: `/{lang}/tidb-in-kubernetes/main/releases/{filename}`

**Target Pattern**: `/{lang}/tidb-in-kubernetes/stable/{filename}`

**Example**:
- Source: `en/tidb-in-kubernetes/main/releases/release-2.0.0.md`
- Target: `/tidb-in-kubernetes/stable/release-2.0.0`
- Source: `zh/tidb-in-kubernetes/main/releases/release-2.0.0.md`
- Target: `/zh/tidb-in-kubernetes/stable/release-2.0.0`

**Use Case**: Release notes are maintained on `main`, but their canonical published URLs must resolve under `stable`. The earlier releases-index rule continues to map `_index.md` to `/releases/tidb-operator`.

---

### Rule 12: TiDB-in-Kubernetes with Branch Alias

**Effect**: Maps TiDB-in-Kubernetes pages with branch aliasing (main → dev, release-* → v*).

Expand All @@ -416,7 +434,7 @@ Rules are evaluated in order; the first matching rule wins.

---

### Rule 12: Fallback Rule
### Rule 13: Fallback Rule

**Effect**: Generic fallback for any remaining paths.

Expand Down Expand Up @@ -512,24 +530,43 @@ Rules are evaluated in order; the first matching rule wins.

### Rule 5: Links from TiDB Operator Releases Landing Page (Path-Based, /releases/*)

**Effect**: Resolves `/releases/*` links from the operator releases landing page to TiDB-in-Kubernetes `dev` branch URLs.
**Effect**: Resolves `/releases/*` links from the operator releases landing page to TiDB-in-Kubernetes `stable` URLs.

**Path Pattern**: `/{lang}/releases/tidb-operator/{...any}`

**Link Pattern**: `/releases/{docname}`

**Target Pattern**: `/{lang}/tidb-in-kubernetes/dev/{docname}`
**Target Pattern**: `/{lang}/tidb-in-kubernetes/stable/{docname}`

**Example**:
- Current Page: `/releases/tidb-operator`
- Link: `/releases/release-2.0.0`
- Result: `/tidb-in-kubernetes/dev/release-2.0.0` (or `/en/tidb-in-kubernetes/dev/release-2.0.0` if default language not omitted)
- Result: `/tidb-in-kubernetes/stable/release-2.0.0` (or `/en/tidb-in-kubernetes/stable/release-2.0.0` if default language not omitted)

**Use Case**: The operator releases landing page is under `/releases/`, while release notes from `main` are published under `/tidb-in-kubernetes/stable/*` to override the copies from the stable release branch.

---

### Rule 6: TiDB-in-Kubernetes Main TOC Release Links (Path-Based)

**Effect**: Resolves release-note links from the `main` TiDB-in-Kubernetes TOC to the stable URLs that publish the corresponding `main` release-note files.

**Path Pattern**: `/{lang}/tidb-in-kubernetes/dev/TOC-tidb-operator-releases`

**Link Pattern**: `/releases/{docname}`

**Target Pattern**: `/{lang}/tidb-in-kubernetes/stable/{docname}`

**Example**:
- Current TOC: `/tidb-in-kubernetes/dev/TOC-tidb-operator-releases`
- Link: `/releases/release-2.0.0`
- Result: `/tidb-in-kubernetes/stable/release-2.0.0`

**Use Case**: The operator releases landing page is under `/releases/`, but the actual release notes pages are published under `/tidb-in-kubernetes/dev/*` (`main` is published as `dev`).
**Use Case**: `TOC-tidb-operator-releases.md` from `main` is resolved under the `dev` branch alias, but its `releases/release-*.md` entries are published under `/stable/*`. Other TOC links continue to resolve under `dev`, and versioned TOCs continue to preserve their version.

---

### Rule 6: Namespace Index Links (Direct Mapping)
### Rule 7: Namespace Index Links (Direct Mapping)

**Effect**: Resolves namespace index links (ending with `/_index`) to namespace URLs (published as `/developer`, `/best-practices`, `/api`, `/ai`, `/tidbcloud`, `/tidbcloudlake`).

Expand Down Expand Up @@ -559,7 +596,7 @@ Rules are evaluated in order; the first matching rule wins.

---

### Rule 7: Namespace Links (Direct Mapping)
### Rule 8: Namespace Links (Direct Mapping)

**Effect**: Resolves namespace links (`develop`, `best-practices`, `api`, `ai`, `tidb-cloud`, `tidb-cloud-lake`) to namespace URLs (published as `/developer`, `/best-practices`, `/api`, `/ai`, `/tidbcloud`, `/tidbcloudlake`).

Expand All @@ -586,7 +623,7 @@ Rules are evaluated in order; the first matching rule wins.

---

### Rule 8: TiDBCloud Page Links (Path-Based)
### Rule 9: TiDBCloud Page Links (Path-Based)

**Effect**: Resolves relative links from TiDBCloud pages to TiDBCloud URLs.

Expand All @@ -608,7 +645,7 @@ Rules are evaluated in order; the first matching rule wins.

---

### Rule 9: TiDB Cloud Lake Page Links (Path-Based)
### Rule 10: TiDB Cloud Lake Page Links (Path-Based)

**Effect**: Resolves relative links from TiDB Cloud Lake pages to `/tidbcloudlake/*` URLs.

Expand All @@ -627,7 +664,7 @@ Rules are evaluated in order; the first matching rule wins.

---

### Rule 10: Developer/Best-Practices/API/AI Namespace Page Links (Path-Based)
### Rule 11: Developer/Best-Practices/API/AI Namespace Page Links (Path-Based)

**Effect**: Resolves relative links from namespace pages to TiDB stable branch URLs.

Expand All @@ -651,7 +688,7 @@ Rules are evaluated in order; the first matching rule wins.

---

### Rule 11: TiDB/TiDB-in-Kubernetes Page Links (Path-Based)
### Rule 12: TiDB/TiDB-in-Kubernetes Page Links (Path-Based)

**Effect**: Resolves relative links from TiDB or TiDB-in-Kubernetes pages, preserving branch/version.

Expand Down
26 changes: 26 additions & 0 deletions gatsby/__tests__/get-files-from-tocs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,32 @@ describe("getFilesFromTocs TOC selection rules", () => {
]);
});

it("tidb-in-kubernetes main reads the operator releases TOC", async () => {
const { getFilesFromTocs } = require("../toc-filter");

const graphql = jest.fn().mockResolvedValue({
data: {
allMdx: {
nodes: [
makeNode(
"en/tidb-in-kubernetes/main/TOC",
"docs/markdown-pages/en/tidb-in-kubernetes/main/TOC.md"
),
makeNode(
"en/tidb-in-kubernetes/main/TOC-tidb-operator-releases",
"docs/markdown-pages/en/tidb-in-kubernetes/main/TOC-tidb-operator-releases.md"
),
],
},
},
});
Comment on lines +116 to +131

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Populate the mocked TOCs with link nodes.

At Lines [120-127], both nodes use makeNode, which supplies mdxAST: { children: [] } at Lines [28-34]. getFilesFromTocs therefore extracts no filenames, but the assertion expects toc-only and operator-releases-only; this test will fail before validating TOC selection.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@gatsby/__tests__/get-files-from-tocs.test.ts` around lines 116 - 131, Update
the mocked nodes created in the getFilesFromTocs test with mdxAST link children
representing toc-only and operator-releases-only, rather than relying on
makeNode’s empty children. Preserve the existing TOC paths and ensure the links
expose the filenames that the assertion expects.


const { tocFilesMap } = await getFilesFromTocs(graphql);
expect(new Set(tocFilesMap.get("en/tidb-in-kubernetes/dev")!)).toEqual(
new Set(["toc-only", "operator-releases-only"])
);
});

it("tidbcloud always reads all TOCs under tidbcloud directory", async () => {
const { getFilesFromTocs } = require("../toc-filter");

Expand Down
50 changes: 50 additions & 0 deletions gatsby/__tests__/toc.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { mdxAstToToc } from "../toc";
import { extractFilesFromToc } from "../toc-filter";

describe("mdxAstToToc tag query parsing", () => {
it("does not emit a bogus ?undefined query when the image URL has no query string", () => {
Expand Down Expand Up @@ -100,3 +101,52 @@ describe("mdxAstToToc tag query parsing", () => {
});
});
});

describe("mdxAstToToc TiDB Operator releases navigation", () => {
it("maps main release TOC links to stable URLs and preserves TOC membership", () => {
const toc = mdxAstToToc(
[
{
type: "list",
children: [
{
type: "listItem",
children: [
{
type: "paragraph",
children: [{ type: "text", value: "v2.0" }],
},
{
type: "list",
children: [
{
type: "listItem",
children: [
{
type: "paragraph",
children: [
{
type: "link",
url: "releases/release-2.0.0.md",
children: [{ type: "text", value: "2.0 GA" }],
},
],
},
],
},
],
},
],
},
],
},
] as any,
"en/tidb-in-kubernetes/main/TOC-tidb-operator-releases"
);

expect(toc[0].children?.[0].link).toBe(
"/tidb-in-kubernetes/stable/release-2.0.0"
);
expect(extractFilesFromToc(toc)).toEqual(["release-2.0.0"]);
});
});
61 changes: 55 additions & 6 deletions gatsby/link-resolver/__tests__/link-resolver.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -355,47 +355,96 @@ describe("resolveMarkdownLink", () => {
"/releases/release-2.0.0",
"/en/releases/tidb-operator"
);
expect(result).toBe("/tidb-in-kubernetes/dev/release-2.0.0");
expect(result).toBe("/tidb-in-kubernetes/stable/release-2.0.0");
});

it("should resolve /releases/* links from releases/tidb-operator page (en - currentPageUrl without language prefix)", () => {
const result = resolveMarkdownLink(
"/releases/release-2.0.0",
"/releases/tidb-operator"
);
expect(result).toBe("/tidb-in-kubernetes/dev/release-2.0.0");
expect(result).toBe("/tidb-in-kubernetes/stable/release-2.0.0");
});

it("should resolve /releases/* links from releases/tidb-operator page (en - default language omitted)", () => {
const result = resolveMarkdownLink(
"/release-2.0.0",
"/en/releases/tidb-operator"
);
expect(result).toBe("/tidb-in-kubernetes/dev/release-2.0.0");
expect(result).toBe("/tidb-in-kubernetes/stable/release-2.0.0");
});

it("should resolve /releases/* links from releases/tidb-operator page (en - currentPageUrl without language prefix)", () => {
const result = resolveMarkdownLink(
"/release-2.0.0",
"/releases/tidb-operator"
);
expect(result).toBe("/tidb-in-kubernetes/dev/release-2.0.0");
expect(result).toBe("/tidb-in-kubernetes/stable/release-2.0.0");
});

it("should resolve /releases/* links from releases/tidb-operator page (zh - language prefix included)", () => {
const result = resolveMarkdownLink(
"/releases/release-2.0.0",
"/zh/releases/tidb-operator"
);
expect(result).toBe("/zh/tidb-in-kubernetes/dev/release-2.0.0");
expect(result).toBe("/zh/tidb-in-kubernetes/stable/release-2.0.0");
});

it("should resolve /releases/* links from releases/tidb-operator page (zh - language prefix included)", () => {
const result = resolveMarkdownLink(
"/release-2.0.0",
"/zh/releases/tidb-operator"
);
expect(result).toBe("/zh/tidb-in-kubernetes/dev/release-2.0.0");
expect(result).toBe("/zh/tidb-in-kubernetes/stable/release-2.0.0");
});

it("should resolve operator release links without a leading slash and preserve the hash", () => {
const result = resolveMarkdownLink(
"releases/release-2.0.0#upgrade",
"/ja/releases/tidb-operator"
);
expect(result).toBe(
"/ja/tidb-in-kubernetes/stable/release-2.0.0#upgrade"
);
});

it.each([
["en", "/tidb-in-kubernetes/stable/release-2.0.0"],
["zh", "/zh/tidb-in-kubernetes/stable/release-2.0.0"],
["ja", "/ja/tidb-in-kubernetes/stable/release-2.0.0"],
])(
"should resolve %s release links from the main tidb-in-kubernetes TOC to stable",
(lang, expected) => {
const result = resolveMarkdownLink(
"/releases/release-2.0.0",
`/${lang}/tidb-in-kubernetes/dev/TOC-tidb-operator-releases`
);
expect(result).toBe(expected);
}
);

it("should resolve TOC release links without a leading slash and preserve the hash", () => {
const result = resolveMarkdownLink(
"releases/release-2.0.0#upgrade",
"/tidb-in-kubernetes/dev/TOC-tidb-operator-releases"
);
expect(result).toBe("/tidb-in-kubernetes/stable/release-2.0.0#upgrade");
});

it("should keep non-release links from the main tidb-in-kubernetes TOC on dev", () => {
const result = resolveMarkdownLink(
"/deploy/deploy-tidb-on-kubernetes",
"/en/tidb-in-kubernetes/dev/TOC-tidb-operator-releases"
);
expect(result).toBe("/tidb-in-kubernetes/dev/deploy-tidb-on-kubernetes");
});

it("should preserve versioned tidb-in-kubernetes TOC release links", () => {
const result = resolveMarkdownLink(
"/releases/release-2.0.0",
"/zh/tidb-in-kubernetes/v2.0/TOC"
);
expect(result).toBe("/zh/tidb-in-kubernetes/v2.0/release-2.0.0");
});

it("should resolve releases namespace links (en - matches Rule 4, not Rule 1)", () => {
Expand Down
11 changes: 9 additions & 2 deletions gatsby/link-resolver/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,18 @@ export const defaultLinkResolverConfig: LinkResolverConfig = {
targetPattern: "/{lang}/tidb/stable/{docname}",
},
// Current page: /{lang}/releases/tidb-operator
// Link: /releases/{docname} -> /{lang}/tidb-in-kubernetes/dev/{docname}
// Link: /releases/{docname} -> /{lang}/tidb-in-kubernetes/stable/{docname}
{
pathPattern: "/{lang}/releases/tidb-operator",
linkPattern: "/{...any}/{docname}",
targetPattern: "/{lang}/tidb-in-kubernetes/dev/{docname}",
targetPattern: "/{lang}/tidb-in-kubernetes/stable/{docname}",
},
// Current TOC: /{lang}/tidb-in-kubernetes/dev/TOC-tidb-operator-releases
// Link: /releases/{docname} -> /{lang}/tidb-in-kubernetes/stable/{docname}
{
pathPattern: "/{lang}/tidb-in-kubernetes/dev/TOC-tidb-operator-releases",
linkPattern: "/releases/{docname}",
targetPattern: "/{lang}/tidb-in-kubernetes/stable/{docname}",
},
// Rule 1: Links starting with specific namespaces (direct link mapping)
// Special handling for namespace index links:
Expand Down
Loading