From 0977df075836a5971398bea9c375c0031def3ca8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 15 Apr 2026 19:40:03 +0000 Subject: [PATCH 1/3] Remove redundant Overview headings and add docs guardrail Agent-Logs-Url: https://github.com/microsoft/aspire.dev/sessions/f4bf8607-2b13-4b2b-b41e-ae87dc850586 Co-authored-by: IEvangelist <7679720+IEvangelist@users.noreply.github.com> --- .github/skills/doc-writer/SKILL.md | 6 ++ .../docs/deployment/custom-deployments.mdx | 2 - .../src/content/docs/deployment/pipelines.mdx | 2 +- .../azure-container-registry-get-started.mdx | 2 +- .../azure-container-registry-host.mdx | 2 +- .../tests/unit/filetree-format.vitest.test.ts | 55 +++++++++++++++++++ 6 files changed, 64 insertions(+), 5 deletions(-) diff --git a/.github/skills/doc-writer/SKILL.md b/.github/skills/doc-writer/SKILL.md index 74965854a..39346eedb 100644 --- a/.github/skills/doc-writer/SKILL.md +++ b/.github/skills/doc-writer/SKILL.md @@ -192,6 +192,12 @@ Python specific content here. If a heading needs to appear in the **On this page** table of contents, keep the heading outside the `Pivot` content and put only the variant-specific body content inside each `Pivot`. +#### On this page and "Overview" headings + +When a page shows the **On this page** table of contents (the default behavior unless `tableOfContents: false` is set), do **not** add an explicit `## Overview` heading. The docs site already provides an implicit overview link to the top of the page, so an explicit `Overview` section becomes redundant. + +If your opening section is truly introductory, keep it as body copy without an `Overview` heading. If that section has a more specific purpose, use a descriptive heading such as `Key concepts`, `Prerequisites`, or another topic-specific label. + For Aspire AppHost docs, use a single page-level `PivotSelector` with `key="aspire-lang"` when the surrounding section flow should switch as one unit. If a page would otherwise need multiple `aspire-lang` selectors, keep the page-level selector for the main flow and use synced `Tabs`/`TabItem` with `syncKey='aspire-lang'` for repeated language-specific examples later on the page. ```mdx diff --git a/src/frontend/src/content/docs/deployment/custom-deployments.mdx b/src/frontend/src/content/docs/deployment/custom-deployments.mdx index 179cff43e..f9d8ccad8 100644 --- a/src/frontend/src/content/docs/deployment/custom-deployments.mdx +++ b/src/frontend/src/content/docs/deployment/custom-deployments.mdx @@ -8,8 +8,6 @@ import LearnMore from '@components/LearnMore.astro'; Aspire provides powerful APIs for building container images from your resources during publishing and deployment operations. This article covers the key components that enable programmatic container image creation and progress reporting. -## Overview - During publishing and deployment, the container image builder is available to create images for resources that need them. Aspire uses this builder when a resource requires a container image, such as when publishing with Docker Compose. The process involves two main components: - `IResourceContainerImageBuilder`: The service that turns resource definitions into runnable container images. diff --git a/src/frontend/src/content/docs/deployment/pipelines.mdx b/src/frontend/src/content/docs/deployment/pipelines.mdx index 4c319d906..a160a5ba2 100644 --- a/src/frontend/src/content/docs/deployment/pipelines.mdx +++ b/src/frontend/src/content/docs/deployment/pipelines.mdx @@ -49,7 +49,7 @@ Aspire uses a pipeline-based deployment system that enables extensible, composab functionality may change in future releases. -## Pipeline model +## Pipeline deployment model The pipeline deployment system provides a flexible, concurrent model for deploying cloud applications. Pipelines break deployment into discrete, well-defined steps that can be optimized for performance and reliability while maintaining clear visibility into the deployment process. diff --git a/src/frontend/src/content/docs/integrations/cloud/azure/azure-container-registry/azure-container-registry-get-started.mdx b/src/frontend/src/content/docs/integrations/cloud/azure/azure-container-registry/azure-container-registry-get-started.mdx index 3f8693ede..3e8428fde 100644 --- a/src/frontend/src/content/docs/integrations/cloud/azure/azure-container-registry/azure-container-registry-get-started.mdx +++ b/src/frontend/src/content/docs/integrations/cloud/azure/azure-container-registry/azure-container-registry-get-started.mdx @@ -26,7 +26,7 @@ In this introduction, you'll see how to install and use the Aspire Azure Contain To follow this guide, you must have created an Aspire solution to work with. To learn how to do that, see [Build your first Aspire app](/get-started/first-app/). -## Overview +## Key capabilities Aspire apps often build and run container images locally but require secure registries for staging and production environments. The Azure Container Registry integration provides the following capabilities: diff --git a/src/frontend/src/content/docs/integrations/cloud/azure/azure-container-registry/azure-container-registry-host.mdx b/src/frontend/src/content/docs/integrations/cloud/azure/azure-container-registry/azure-container-registry-host.mdx index 2db5cc38a..d27b6634a 100644 --- a/src/frontend/src/content/docs/integrations/cloud/azure/azure-container-registry/azure-container-registry-host.mdx +++ b/src/frontend/src/content/docs/integrations/cloud/azure/azure-container-registry/azure-container-registry-host.mdx @@ -20,7 +20,7 @@ import containerRegistryIcon from '@assets/icons/azure-container-registry-icon.s [Azure Container Registry](https://learn.microsoft.com/azure/container-registry) is a managed Docker container registry service that simplifies the storage, management, and deployment of container images. The Aspire integration allows you to provision or reference an existing Azure Container Registry and seamlessly integrate it with your app's compute environments. -## Overview +## Key capabilities Aspire apps often build and run container images locally but require secure registries for staging and production environments. The Azure Container Registry integration provides the following capabilities: diff --git a/src/frontend/tests/unit/filetree-format.vitest.test.ts b/src/frontend/tests/unit/filetree-format.vitest.test.ts index 434b82506..7e0c76978 100644 --- a/src/frontend/tests/unit/filetree-format.vitest.test.ts +++ b/src/frontend/tests/unit/filetree-format.vitest.test.ts @@ -7,6 +7,7 @@ const testsDir = path.dirname(fileURLToPath(import.meta.url)); const frontendRoot = path.resolve(testsDir, '..', '..'); const docsRoot = path.join(frontendRoot, 'src', 'content', 'docs'); const fileTreeBlockPattern = /]*>([\s\S]*?)<\/FileTree>/g; +const frontmatterPattern = /^---\r?\n([\s\S]*?)\r?\n---/; function collectDocs(dirPath: string): string[] { const entries = readdirSync(dirPath, { withFileTypes: true }); @@ -78,6 +79,46 @@ function findFileTreeIssues(source: string): Array<{ line: number; reason: strin return issues; } +function isTableOfContentsEnabled(source: string): boolean { + const frontmatterMatch = source.match(frontmatterPattern); + const frontmatter = frontmatterMatch?.[1] ?? ''; + + return !/^\s*tableOfContents\s*:\s*false\b/m.test(frontmatter); +} + +function findOverviewHeadingIssues(source: string): Array<{ line: number; reason: string }> { + if (!isTableOfContentsEnabled(source)) { + return []; + } + + const issues: Array<{ line: number; reason: string }> = []; + const lines = source.split(/\r?\n/); + let currentFence: string | null = null; + + for (const [index, line] of lines.entries()) { + const fenceMatch = line.match(/^\s*(```+|~~~+)/); + if (fenceMatch) { + const fence = fenceMatch[1][0]; + currentFence = currentFence === fence ? null : fence; + continue; + } + + if (currentFence) { + continue; + } + + if (/^\s*##+\s+Overview\s*$/.test(line)) { + issues.push({ + line: index + 1, + reason: + 'TOC-enabled pages must not include an explicit "Overview" heading; use intro text or a more specific heading.', + }); + } + } + + return issues; +} + test('FileTree markdown lists remain newline-delimited in docs source', () => { const docPaths = collectDocs(docsRoot); const failures = docPaths.flatMap((docPath) => { @@ -91,3 +132,17 @@ test('FileTree markdown lists remain newline-delimited in docs source', () => { expect(failures, failures.join('\n')).toEqual([]); }); + +test('TOC-enabled docs do not include an explicit Overview heading', () => { + const docPaths = collectDocs(docsRoot); + const failures = docPaths.flatMap((docPath) => { + const source = readFileSync(docPath, 'utf8'); + const relativePath = path.relative(frontendRoot, docPath).replaceAll(path.sep, '/'); + + return findOverviewHeadingIssues(source).map( + ({ line, reason }) => `${relativePath}:${line} ${reason}` + ); + }); + + expect(failures, failures.join('\n')).toEqual([]); +}); From e6db30dab5c28798ed86a305fdd3fdc3440dc3cf Mon Sep 17 00:00:00 2001 From: David Pine Date: Fri, 17 Apr 2026 09:26:28 -0500 Subject: [PATCH 2/3] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../tests/unit/filetree-format.vitest.test.ts | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/frontend/tests/unit/filetree-format.vitest.test.ts b/src/frontend/tests/unit/filetree-format.vitest.test.ts index 7e0c76978..7e8b2d920 100644 --- a/src/frontend/tests/unit/filetree-format.vitest.test.ts +++ b/src/frontend/tests/unit/filetree-format.vitest.test.ts @@ -7,7 +7,7 @@ const testsDir = path.dirname(fileURLToPath(import.meta.url)); const frontendRoot = path.resolve(testsDir, '..', '..'); const docsRoot = path.join(frontendRoot, 'src', 'content', 'docs'); const fileTreeBlockPattern = /]*>([\s\S]*?)<\/FileTree>/g; -const frontmatterPattern = /^---\r?\n([\s\S]*?)\r?\n---/; +const frontmatterPattern = /^\uFEFF?\s*---\r?\n([\s\S]*?)\r?\n---/; function collectDocs(dirPath: string): string[] { const entries = readdirSync(dirPath, { withFileTypes: true }); @@ -93,14 +93,24 @@ function findOverviewHeadingIssues(source: string): Array<{ line: number; reason const issues: Array<{ line: number; reason: string }> = []; const lines = source.split(/\r?\n/); - let currentFence: string | null = null; + let currentFence: { char: '`' | '~'; length: number } | null = null; for (const [index, line] of lines.entries()) { - const fenceMatch = line.match(/^\s*(```+|~~~+)/); + const fenceMatch = line.match(/^\s*((`{3,})|(~{3,}))/); if (fenceMatch) { - const fence = fenceMatch[1][0]; - currentFence = currentFence === fence ? null : fence; - continue; + const fenceDelimiter = fenceMatch[1]; + const fenceChar = fenceDelimiter[0] as '`' | '~'; + const fenceLength = fenceDelimiter.length; + + if (!currentFence) { + currentFence = { char: fenceChar, length: fenceLength }; + continue; + } + + if (currentFence.char === fenceChar && fenceLength >= currentFence.length) { + currentFence = null; + continue; + } } if (currentFence) { From 40de7e85d7b4e5b392947157e83cfca3c6179985 Mon Sep 17 00:00:00 2001 From: David Pine Date: Fri, 17 Apr 2026 09:46:29 -0500 Subject: [PATCH 3/3] Clarify guidelines on using "Overview" headings in documentation to prevent redundancy --- .github/skills/doc-writer/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/skills/doc-writer/SKILL.md b/.github/skills/doc-writer/SKILL.md index 39346eedb..dd2c6a266 100644 --- a/.github/skills/doc-writer/SKILL.md +++ b/.github/skills/doc-writer/SKILL.md @@ -194,7 +194,7 @@ If a heading needs to appear in the **On this page** table of contents, keep the #### On this page and "Overview" headings -When a page shows the **On this page** table of contents (the default behavior unless `tableOfContents: false` is set), do **not** add an explicit `## Overview` heading. The docs site already provides an implicit overview link to the top of the page, so an explicit `Overview` section becomes redundant. +When a page shows the **On this page** table of contents (the default behavior unless `tableOfContents: false` is set), do **not** add an `Overview` heading at any level (`##`, `###`, etc.). The docs site already provides an implicit overview link to the top of the page, so an explicit `Overview` heading becomes redundant. If your opening section is truly introductory, keep it as body copy without an `Overview` heading. If that section has a more specific purpose, use a descriptive heading such as `Key concepts`, `Prerequisites`, or another topic-specific label.