diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..62cb79d
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,35 @@
+name: Pull request CI
+
+on:
+ pull_request:
+ branches:
+ - main
+ workflow_dispatch:
+
+permissions:
+ contents: read
+
+concurrency:
+ group: pull-request-ci-${{ github.event.pull_request.number || github.ref }}
+ cancel-in-progress: true
+
+jobs:
+ build:
+ name: Build site
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Set up Node
+ uses: actions/setup-node@v4
+ with:
+ node-version: 22
+ cache: npm
+
+ - name: Install dependencies
+ run: npm ci
+
+ - name: Build site
+ run: npm run build
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index d28dd5a..ecc8fad 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -44,16 +44,20 @@ governance, documentation, customer stories).
✅ Community resources that meet a high quality bar.
-❌ Internal-only material — anything requiring Microsoft corporate SSO,
-internal SharePoint, or any portco-internal authentication. This is a
-**public** hub.
+⚠️ Authenticated resources are exceptional. They must be clearly labeled with
+their sign-in requirement and paired with a public alternative or enough
+public context to remain useful.
+
+❌ Internal-only material presented without an access warning or public
+alternative. This is a **public** hub.
❌ Resources unrelated to GitHub, GitHub Copilot, or to enterprise adoption
thereof.
## Preview the GitHub Pages site
-The site renders `README.md` and `usage-based-billing/README.md` directly, so
+The site renders `README.md`, `build-days/README.md`,
+`csi-pricing/README.md`, and `usage-based-billing/README.md` directly, so
content changes stay synchronized between the repository and GitHub Pages.
Use Node.js 22 or later to run it locally:
diff --git a/README.md b/README.md
index 803f352..cd94c10 100644
--- a/README.md
+++ b/README.md
@@ -23,30 +23,16 @@
> 💡 **CSI portcos:** use your **large CSI discount** on GitHub
> Enterprise and GitHub Copilot when billed via your portfolio's (or CSI's)
> Azure subscription — **not** a credit card.
-> → [How to claim the discount](#-csi-pricing-via-azure-billing)
+> → [How to claim the discount](./csi-pricing/)
---
-
-
-
-
-
## 📅 CSI Build Days
-CSI Build Days is the GitHub & Microsoft @ CSI team's **bi-weekly developer event series**
-for engineers across the Constellation Software portfolio. Sessions cover
-GitHub fundamentals, migrations, Copilot enablement, agentic workflows,
-multi-part workshops, office hours, and Q&A with Microsoft and GitHub
-product teams.
-
-> 🎥 **Catch up on past sessions** — full CSI Build Days recording playlist →
-> [aka.ms/CSIDevDaysRecordings](https://aka.ms/CSIDevDaysRecordings)
+The GitHub & Microsoft @ CSI team's bi-weekly event series brings engineers
+across the portfolio together for hands-on sessions, workshops, office hours,
+and product-team Q&A.
-- **Upcoming sessions — register by track:**
- - **Developer Track** — Completed ✔️
- - **Product Track** — [Register on Teams](https://msit.events.teams.microsoft.com/event/msit.b8cadf85-d534-4ab5-858f-0f9c496a7ece@72f988bf-86f1-41af-91ab-2d7cd011db47)
- - **QA Track** — [Register on Teams](https://msit.events.teams.microsoft.com/event/msit.a2d45802-3163-4650-b8bf-11415c76ff8d@72f988bf-86f1-41af-91ab-2d7cd011db47)
- - **DevSecOps Track** — [Register on Teams](https://msit.events.teams.microsoft.com/event/msit.8099c99d-25de-42a3-b378-af01fe473797@72f988bf-86f1-41af-91ab-2d7cd011db47)
+**[Register for upcoming tracks and watch previous sessions →](./build-days/)**
---
@@ -81,101 +67,21 @@ development:
## 🏷 CSI Pricing via Azure Billing
-CSI portfolio companies qualify for a **large CSI discount on GitHub
-Enterprise Cloud and GitHub Copilot (Business and Enterprise)** — but **only
-when billing flows through an Azure subscription tied to your portco, your
-operating group, or CSI**.
-
-> 🏷 **What the discount covers:** a **large discount** on **GitHub** and
-> **GitHub Copilot**, including the usage-based **tokens from the default
-> models used in GitHub** — Anthropic Claude, OpenAI GPT, Google Gemini, MAI,
-> Kimi, and more.
-
-> 📧 **Want the discount amount and how to activate it?** Email
-> [DevsAtCSI@microsoft.com](mailto:DevsAtCSI@microsoft.com).
-> The GitHub @ CSI team will share the current CSI rate and walk you
-> through activation — primarily connecting an **Azure subscription tied
-> to a parent CSI entity** (your portco, your operating group, or CSI) to
-> your GitHub enterprise account.
-
-> ⚠️ **Credit-card billing on GitHub is NOT eligible for the CSI discount.**
-> Personal credit cards and PayPal payment methods on a GitHub enterprise
-> account do not qualify. To get the CSI rate, the GitHub enterprise account
-> must be connected to an **Azure subscription** owned by your portco, your
-> operating group, or CSI.
-
-> ✅ **Two benefits of the Azure-billed path:**
->
-> 1. **CSI portco discount** on GitHub Enterprise Cloud and GitHub Copilot
-> (Business / Enterprise) SKUs.
-> 2. **Prioritized GitHub support** — Azure-connected CSI enterprises are
-> routed through the GitHub @ CSI team at Microsoft, who can escalate
-> tickets and coordinate directly with GitHub product and support teams.
-> Enterprises billed outside this path do not get this CSI-routed
-> escalation benefit.
-
-#### Eligible SKUs
-
-- **GitHub Enterprise Cloud**
-- **GitHub Copilot Business**
-- **GitHub Copilot Enterprise**
-
-#### Connect your Azure subscription to GitHub
-
-See [Connecting an Azure subscription (docs.github.com)](https://docs.github.com/en/enterprise-cloud@latest/billing/how-tos/set-up-payment/connect-azure-sub) for the step-by-step procedure.
-
-#### Check whether your discount is active
-
-You can confirm the CSI discount is applied from the
-[Azure Pricing Calculator](https://azure.microsoft.com/en-us/pricing/calculator):
-
-1. Sign in with the account tied to your portfolio's Azure billing.
-2. Open the **Licensing program** dropdown.
-3. If the discount is active, your **licensing agreement with Microsoft — tied
- back to your portfolio** — appears as your selected agreement, similar to the
- example below.
-
-
-
-If you **don't** see a Microsoft licensing agreement tied to your portfolio,
-the discount isn't active yet. Email
-[DevsAtCSI@microsoft.com](mailto:DevsAtCSI@microsoft.com)
-and the GitHub @ CSI team will kick off the process to get it set up.
-
-#### Documentation
-
-- **About enterprise billing** — Concepts and supported payment methods. [docs.github.com](https://docs.github.com/en/enterprise-cloud@latest/enterprise-onboarding/getting-started-with-your-enterprise/about-enterprise-billing)
-- **Azure subscription payments (concept)** — How GitHub enterprise usage shows up on your Azure invoice. [docs.github.com](https://docs.github.com/en/enterprise-cloud@latest/billing/concepts/azure-subscriptions)
-- **Billing through Azure subscriptions (reference)** — Detailed reference for what's billable through Azure and how. [docs.github.com](https://docs.github.com/en/enterprise-cloud@latest/billing/reference/azure-billing)
-
-#### Cost management & chargeback
-
-For portcos that allocate GitHub costs back to teams or products on Azure:
-
-- **Azure Cost Management overview** — Cost analysis, budgets, alerts, and exports. [learn.microsoft.com](https://learn.microsoft.com/en-us/azure/cost-management-billing/costs/overview-cost-management)
-- **Tag your Azure resources** — Use tags on the Azure subscription / resource group to attribute GitHub line items to the right team, product, or cost center. [learn.microsoft.com](https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/tag-resources)
-
-#### Need help?
+CSI portfolio companies can receive a large discount on GitHub Enterprise and
+GitHub Copilot when billing is connected to an eligible CSI Azure
+subscription. Credit-card billing is not eligible.
-If you hit issues during the connect-to-Azure flow (admin consent,
-ownership mismatches, eligibility questions), email
-[DevsAtCSI@microsoft.com](mailto:DevsAtCSI@microsoft.com)
-and the GitHub @ CSI team will help unblock you.
+**[Review eligibility, activation, and discount verification →](./csi-pricing/)**
---
## 💳 Usage-Based Billing (UBB)
-Resources to help CSI portcos prepare for Copilot's move to usage-based
-billing on June 1.
+Prepare for Copilot usage-based billing with a practical five-step rollout
+plan, budget guidance, model-selection recommendations, and curated official
+resources.
-- **🌐 GitHub @ CSI team recommendations** — Practical playbook for CSI portcos: what's changing June 1, a 5-step rollout plan, what not to overreact to, how UBB interacts with the CSI Azure-billing discount, and curated UBB resources including interactive tools and checklists. [usage-based-billing/](./usage-based-billing/)
-- **Copilot Cost Compass (interactive tool)** — Animated UBB explainer, budget-flow scenarios, decision tree, budget calculator, and a model-selection playbook for token optimization. [aka.ms/ubb-tool](https://aka.ms/ubb-tool)
-- **Announcement (blog)** — GitHub Copilot is moving to usage-based billing. [github.blog](https://github.blog/news-insights/company-news/github-copilot-is-moving-to-usage-based-billing/)
-- **UBB documentation** — Concept docs for usage-based billing in organizations and enterprises. [docs.github.com](https://docs.github.com/en/copilot/concepts/billing/usage-based-billing-for-organizations-and-enterprises)
-- **UBB pricing & models** — Reference for Copilot billing models and pricing. [docs.github.com](https://docs.github.com/en/copilot/reference/copilot-billing/models-and-pricing)
-- **GitHub Community FAQ** — Discussion thread with frequently asked questions. [github.com/orgs/community/discussions/192948](https://github.com/orgs/community/discussions/192948)
-- **Copilot code review changelog** — Code review will start consuming GitHub Actions minutes on June 1, 2026. [github.blog/changelog](https://github.blog/changelog/2026-04-27-github-copilot-code-review-will-start-consuming-github-actions-minutes-on-june-1-2026/)
+**[Open the CSI usage-based billing playbook →](./usage-based-billing/)**
---
diff --git a/build-days/README.md b/build-days/README.md
new file mode 100644
index 0000000..ce7e517
--- /dev/null
+++ b/build-days/README.md
@@ -0,0 +1,47 @@
+# 📅 CSI Build Days
+
+> The GitHub & Microsoft @ CSI team's bi-weekly event series for engineers
+> across the Constellation Software portfolio.
+
+Sessions cover GitHub fundamentals, migrations, Copilot enablement, agentic
+workflows, hands-on workshops, office hours, and Q&A with Microsoft and GitHub
+product teams.
+
+[← Back to the resource hub](../README.md#-csi-build-days)
+
+---
+
+## Upcoming sessions
+
+| Track | Status | Next step |
+|---|---|---|
+| **Developer Track** | ✅ Completed | [Watch the recording](#previous-session-recordings) |
+| **Product Track** | ✅ Completed | [Watch the recording](#previous-session-recordings) |
+| **QA Track** | 🗓️ Registration open | [Register on Teams](https://msit.events.teams.microsoft.com/event/msit.a2d45802-3163-4650-b8bf-11415c76ff8d@72f988bf-86f1-41af-91ab-2d7cd011db47) |
+| **DevSecOps Track** | 🗓️ Registration open | [Register on Teams](https://msit.events.teams.microsoft.com/event/msit.8099c99d-25de-42a3-b378-af01fe473797@72f988bf-86f1-41af-91ab-2d7cd011db47) |
+
+> Registration links open Microsoft Teams Events. Share them with colleagues
+> across your CSI portfolio company who would benefit from the track.
+
+---
+
+## Previous session recordings
+
+> 🔐 **Microsoft sign-in required.** The individual recordings below are
+> hosted in Microsoft SharePoint and are not available anonymously.
+> For a public catch-up option, use the
+> [CSI Build Days recording playlist](https://aka.ms/CSIDevDaysRecordings).
+
+| Date | Session | Recording |
+|---|---|---|
+| **July 30, 2026** | Product Track | [Watch recording — sign-in required](https://microsoft-my.sharepoint.com/:v:/r/personal/sharmave_microsoft_com/_layouts/15/stream.aspx?id=%2Fpersonal%2Fsharmave%5Fmicrosoft%5Fcom%2FDocuments%2FRecordings%2FCSI%20Dev%20Days%21%20Product%20Track%2D20260730%5F143213UTC%2DMeeting%20Recording%2Emp4&share=cQrf0KCStc2mRYMUTCW6Nd%5FlEgUDGqZyUaYDs9FRjKt62Zb%5Few) |
+| **July 29, 2026** | Harris Frontline — Agentic Quality & Token Optimization | [Watch recording — sign-in required](https://microsoft-my.sharepoint.com/:v:/r/personal/sharmave_microsoft_com/_layouts/15/stream.aspx?id=%2Fpersonal%2Fsharmave%5Fmicrosoft%5Fcom%2FDocuments%2FRecordings%2FCSI%20Build%20Days%20%2D%20Harris%20Frontline%20Agentic%20Quality%20%5F%20Token%20Optimization%2D20260729%5F143054UTC%2DMeeting%20Recording%2Emp4&share=cQrqxmI%2D2BISTJFBJHdIVcn%2DEgUD%5FNYjvLYFbZJI8yCeGJ646g) |
+| **July 16, 2026** | Developer Track | [Watch recording — sign-in required](https://microsoft-my.sharepoint.com/:v:/r/personal/sharmave_microsoft_com/_layouts/15/stream.aspx?id=%2Fpersonal%2Fsharmave%5Fmicrosoft%5Fcom%2FDocuments%2FRecordings%2FCSI%20Dev%20Days%21%20%20%2D%20Developer%20Track%2D20260716%5F143244UTC%2DMeeting%20Recording%2Emp4&share=cQoO4RkI1buuQJU%5FPWkwjdqREgUDCvpQzU1yQXUPXxweVFQ3wQ) |
+| **June 4, 2026** | CSI Dev Days #1 — Portfolio kickoff | [Watch recording — sign-in required](https://microsoft-my.sharepoint.com/:v:/r/personal/sharmave_microsoft_com/_layouts/15/stream.aspx?id=%2Fpersonal%2Fsharmave_microsoft_com%2FDocuments%2FRecordings%2FCSI%20Dev%20Days!%20%231%20(Volaris%2C%20Harris%2C%20Jonas%2C%20Perseus%2C%20Vela%20-%20you%27re%20invited!)-20260604_140353UTC-Meeting%20Recording.mp4&share=cQrByaifEu4OR4Tc1vi1DmDPEgUD5cT_EGqfqCsYmv0aRrJGoA&nav=eyJyZWZlcnJhbEluZm8iOnsicmVmZXJyYWxBcHAiOiJPbmVEcml2ZUZvckJ1c2luZXNzIiwicmVmZXJyYWxBcHBQbGF0Zm9ybSI6IldlYiIsInJlZmVycmFsTW9kZSI6InZpZXciLCJyZWZlcnJhbFZpZXciOiJNeUZpbGVzTGlua0NvcHkifX0) |
+
+---
+
+## Get in touch
+
+Questions, session ideas, or workshop nominations? Email the GitHub @ CSI team
+at [DevsAtCSI@microsoft.com](mailto:DevsAtCSI@microsoft.com).
diff --git a/build-days/index.html b/build-days/index.html
new file mode 100644
index 0000000..c52733a
--- /dev/null
+++ b/build-days/index.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+ CSI Build Days | GitHub @ Constellation Software
+
+
+
+
+
+
diff --git a/csi-pricing/README.md b/csi-pricing/README.md
new file mode 100644
index 0000000..ad98a3b
--- /dev/null
+++ b/csi-pricing/README.md
@@ -0,0 +1,98 @@
+# 🏷 CSI Pricing via Azure Billing
+
+CSI portfolio companies qualify for a **large CSI discount on GitHub
+Enterprise Cloud and GitHub Copilot (Business and Enterprise)** — but **only
+when billing flows through an Azure subscription tied to your portco, your
+operating group, or CSI**.
+
+[← Back to the resource hub](../README.md#-csi-pricing-via-azure-billing)
+
+> 🏷 **What the discount covers:** a **large discount** on **GitHub** and
+> **GitHub Copilot**, including the usage-based **tokens from the default
+> models used in GitHub** — Anthropic Claude, OpenAI GPT, Google Gemini, MAI,
+> Kimi, and more.
+
+> 📧 **Want the discount amount and how to activate it?** Email
+> [DevsAtCSI@microsoft.com](mailto:DevsAtCSI@microsoft.com).
+> The GitHub @ CSI team will share the current CSI rate and walk you
+> through activation — primarily connecting an **Azure subscription tied
+> to a parent CSI entity** (your portco, your operating group, or CSI) to
+> your GitHub enterprise account.
+
+> ⚠️ **Credit-card billing on GitHub is NOT eligible for the CSI discount.**
+> Personal credit cards and PayPal payment methods on a GitHub enterprise
+> account do not qualify. To get the CSI rate, the GitHub enterprise account
+> must be connected to an **Azure subscription** owned by your portco, your
+> operating group, or CSI.
+
+> ✅ **Two benefits of the Azure-billed path:**
+>
+> 1. **CSI portco discount** on GitHub Enterprise Cloud and GitHub Copilot
+> (Business / Enterprise) SKUs.
+> 2. **Prioritized GitHub support** — Azure-connected CSI enterprises are
+> routed through the GitHub @ CSI team at Microsoft, who can escalate
+> tickets and coordinate directly with GitHub product and support teams.
+> Enterprises billed outside this path do not get this CSI-routed
+> escalation benefit.
+
+---
+
+## Eligible SKUs
+
+- **GitHub Enterprise Cloud**
+- **GitHub Copilot Business**
+- **GitHub Copilot Enterprise**
+
+## Connect your Azure subscription to GitHub
+
+See
+[Connecting an Azure subscription (docs.github.com)](https://docs.github.com/en/enterprise-cloud@latest/billing/how-tos/set-up-payment/connect-azure-sub)
+for the step-by-step procedure.
+
+## Check whether your discount is active
+
+You can confirm the CSI discount is applied from the
+[Azure Pricing Calculator](https://azure.microsoft.com/en-us/pricing/calculator):
+
+1. Sign in with the account tied to your portfolio's Azure billing.
+2. Open the **Licensing program** dropdown.
+3. If the discount is active, your **licensing agreement with Microsoft — tied
+ back to your portfolio** — appears as your selected agreement, similar to
+ the example below.
+
+
+
+If you **don't** see a Microsoft licensing agreement tied to your portfolio,
+the discount isn't active yet. Email
+[DevsAtCSI@microsoft.com](mailto:DevsAtCSI@microsoft.com)
+and the GitHub @ CSI team will kick off the process to get it set up.
+
+## Documentation
+
+- **About enterprise billing** — Concepts and supported payment methods.
+ [docs.github.com](https://docs.github.com/en/enterprise-cloud@latest/enterprise-onboarding/getting-started-with-your-enterprise/about-enterprise-billing)
+- **Azure subscription payments (concept)** — How GitHub enterprise usage
+ shows up on your Azure invoice.
+ [docs.github.com](https://docs.github.com/en/enterprise-cloud@latest/billing/concepts/azure-subscriptions)
+- **Billing through Azure subscriptions (reference)** — Detailed reference
+ for what's billable through Azure and how.
+ [docs.github.com](https://docs.github.com/en/enterprise-cloud@latest/billing/reference/azure-billing)
+
+## Cost management & chargeback
+
+For portcos that allocate GitHub costs back to teams or products on Azure:
+
+- **Azure Cost Management overview** — Cost analysis, budgets, alerts, and
+ exports.
+ [learn.microsoft.com](https://learn.microsoft.com/en-us/azure/cost-management-billing/costs/overview-cost-management)
+- **Tag your Azure resources** — Use tags on the Azure subscription or
+ resource group to attribute GitHub line items to the right team, product, or
+ cost center.
+ [learn.microsoft.com](https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/tag-resources)
+
+## Need help?
+
+If you hit issues during the connect-to-Azure flow (admin consent, ownership
+mismatches, eligibility questions), email
+[DevsAtCSI@microsoft.com](mailto:DevsAtCSI@microsoft.com)
+and the GitHub @ CSI team will help unblock you.
diff --git a/csi-pricing/index.html b/csi-pricing/index.html
new file mode 100644
index 0000000..bd11e70
--- /dev/null
+++ b/csi-pricing/index.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+ CSI Pricing | GitHub @ Constellation Software
+
+
+
+
+
+
diff --git a/images/reproduced_ea_1234567.png b/images/reproduced_ea_1234567.png
index a02a62d..008a36f 100644
Binary files a/images/reproduced_ea_1234567.png and b/images/reproduced_ea_1234567.png differ
diff --git a/src/App.tsx b/src/App.tsx
index 54212ec..2af2d68 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,8 +1,9 @@
-import {useMemo, useState} from 'react'
+import {useEffect, useMemo, useState} from 'react'
import type {ComponentPropsWithoutRef, ReactNode} from 'react'
import {
ArrowUpIcon,
BookIcon,
+ CalendarIcon,
CodeIcon,
CreditCardIcon,
DeviceDesktopIcon,
@@ -13,6 +14,7 @@ import {
MoonIcon,
RepoIcon,
SunIcon,
+ TagIcon,
} from '@primer/octicons-react'
import {BaseStyles, Button, IconButton, Label, Link, ThemeProvider} from '@primer/react'
import ReactMarkdown from 'react-markdown'
@@ -20,14 +22,17 @@ import rehypeRaw from 'rehype-raw'
import rehypeSanitize, {defaultSchema} from 'rehype-sanitize'
import rehypeSlug from 'rehype-slug'
import remarkGfm from 'remark-gfm'
-import {getTableOfContents, pages} from './content'
-import type {PageId} from './content'
+import {getTableOfContents, isPageId, pages} from './content'
+import type {PageId, TableOfContentsItem} from './content'
type ColorMode = 'auto' | 'day' | 'night'
+type MarkdownExtraProps = {node?: unknown}
const repositoryUrl = 'https://github.com/microsoft/github-constellation-software'
-const pageId = document.body.dataset.page === 'usage-based-billing' ? 'usage-based-billing' : 'home'
+const requestedPageId = document.body.dataset.page
+const pageId: PageId = isPageId(requestedPageId) ? requestedPageId : 'home'
const siteRoot = document.body.dataset.siteRoot ?? './'
+const themeStorageKey = 'github-csi-color-mode'
const imageModules = import.meta.glob('../images/**/*', {
eager: true,
import: 'default',
@@ -55,25 +60,68 @@ const themeOptions: Array<{
{mode: 'night', label: 'Use dark theme', icon: MoonIcon},
]
+const navigationItems: Array<{
+ id: PageId
+ description: string
+ icon: typeof HomeIcon
+}> = [
+ {id: 'home', description: 'Migrations, adoption, and scale', icon: HomeIcon},
+ {id: 'build-days', description: 'Sessions and recordings', icon: CalendarIcon},
+ {id: 'csi-pricing', description: 'Azure billing and discounts', icon: TagIcon},
+ {id: 'usage-based-billing', description: 'Copilot UBB playbook', icon: CreditCardIcon},
+]
+
+function getInitialThemeIndex() {
+ const storedMode = window.localStorage.getItem(themeStorageKey)
+ const storedIndex = themeOptions.findIndex(option => option.mode === storedMode)
+ return storedIndex >= 0 ? storedIndex : 0
+}
+
+function resolveRepositoryPath(href: string) {
+ const [path, fragment] = href.split('#', 2)
+ const sourceDirectory = pages[pageId].sourcePath.split('/').slice(0, -1)
+ const segments = [...sourceDirectory]
+
+ for (const segment of path.replace(/^\.\//, '').split('/')) {
+ if (!segment || segment === '.') {
+ continue
+ }
+ if (segment === '..') {
+ segments.pop()
+ } else {
+ segments.push(segment)
+ }
+ }
+
+ const resolvedPath = segments.join('/')
+ return `${repositoryUrl}/blob/main/${resolvedPath}${fragment ? `#${fragment}` : ''}`
+}
+
function normalizeHref(href: string | undefined) {
if (!href) {
return undefined
}
+ if (href.startsWith('#') || href.startsWith('mailto:') || href.startsWith('tel:')) {
+ return href
+ }
+
if (href.startsWith('../README.md')) {
return `${siteRoot}${href.slice('../README.md'.length)}`
}
- if (href === './usage-based-billing/' || href === 'usage-based-billing/') {
- return `${siteRoot}usage-based-billing/`
+ const pageRoute = href.match(/^(?:\.\/|\.\.\/)?(build-days|csi-pricing|usage-based-billing)\/?(#.*)?$/)
+ if (pageRoute) {
+ const [, route, fragment = ''] = pageRoute
+ return `${siteRoot}${route}/${fragment}`
}
if (href === '.github/ISSUE_TEMPLATE') {
return `${repositoryUrl}/issues/new/choose`
}
- if (/^(CONTRIBUTING|CODE_OF_CONDUCT|SECURITY|SUPPORT|LICENSE)\.md(?:#.*)?$/.test(href)) {
- return `${repositoryUrl}/blob/main/${href}`
+ if (/^(?:\.\/|\.\.\/)?[^?#]+\.md(?:#.*)?$/.test(href)) {
+ return resolveRepositoryPath(href)
}
return href
@@ -83,7 +131,12 @@ function isExternalHref(href: string | undefined) {
return Boolean(href && /^https?:\/\//.test(href))
}
-function MarkdownLink({href, children, ...props}: ComponentPropsWithoutRef<'a'>) {
+function MarkdownLink({
+ node: _node,
+ href,
+ children,
+ ...props
+}: ComponentPropsWithoutRef<'a'> & MarkdownExtraProps) {
const normalizedHref = normalizeHref(href)
const external = isExternalHref(normalizedHref)
@@ -100,7 +153,12 @@ function MarkdownLink({href, children, ...props}: ComponentPropsWithoutRef<'a'>)
)
}
-function MarkdownImage({src, alt, ...props}: ComponentPropsWithoutRef<'img'>) {
+function MarkdownImage({
+ node: _node,
+ src,
+ alt,
+ ...props
+}: ComponentPropsWithoutRef<'img'> & MarkdownExtraProps) {
const imageKey = src?.replace('../images/', './images/')
const resolvedSrc = (imageKey && localImages.get(imageKey)) || src
@@ -109,13 +167,14 @@ function MarkdownImage({src, alt, ...props}: ComponentPropsWithoutRef<'img'>) {
function AnchoredHeading({
as: Heading,
+ node: _node,
id,
children,
...props
}: ComponentPropsWithoutRef<'h2'> & {
as: 'h2' | 'h3'
children?: ReactNode
-}) {
+} & MarkdownExtraProps) {
return (
{children}
@@ -129,39 +188,24 @@ function AnchoredHeading({
}
function SiteNavigation({currentPage}: {currentPage: PageId}) {
- const links = [
- {
- id: 'home' as const,
- label: 'Resource hub',
- description: 'Migrations, adoption, and scale',
- href: siteRoot,
- icon: HomeIcon,
- },
- {
- id: 'usage-based-billing' as const,
- label: 'Usage-based billing',
- description: 'Copilot UBB playbook',
- href: `${siteRoot}usage-based-billing/`,
- icon: CreditCardIcon,
- },
- ]
-
return (