From e7daa506924015bf061ebb96ec7601731a90b2db Mon Sep 17 00:00:00 2001 From: musistudio Date: Thu, 25 Jun 2026 19:53:49 +0800 Subject: [PATCH] Add GitHub Pages docs deployment --- .github/workflows/docs.yml | 48 +++++++++++++++++++++++++++++++ docs/README.md | 10 +++++++ docs/astro.config.mjs | 5 ++++ docs/src/content/docs/en/index.md | 16 +++++------ docs/src/content/docs/zh/index.md | 16 +++++------ docs/src/layouts/DocsLayout.astro | 46 +++++++++++++++++++++++------ 6 files changed, 117 insertions(+), 24 deletions(-) create mode 100644 .github/workflows/docs.yml diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000..e2f2965 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,48 @@ +name: Docs + +on: + push: + branches: + - main + paths: + - "docs/**" + - ".github/workflows/docs.yml" + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: pages + cancel-in-progress: false + +jobs: + build: + name: Build + runs-on: ubuntu-latest + steps: + - name: Check out repository + uses: actions/checkout@v6 + + - name: Build and upload docs + uses: withastro/action@v6 + env: + ASTRO_SITE: https://musistudio.github.io + ASTRO_BASE: /claude-code-router + with: + path: docs + node-version: 24 + + deploy: + name: Deploy + needs: build + runs-on: ubuntu-latest + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v5 diff --git a/docs/README.md b/docs/README.md index 01fe0b6..62ddfbd 100644 --- a/docs/README.md +++ b/docs/README.md @@ -13,6 +13,16 @@ npm run preview The local development server runs from this `docs` directory. +## GitHub Pages + +Docs are deployed from `.github/workflows/docs.yml` on pushes to `main` that change `docs/**` or the workflow itself. The default public URL is: + +```text +https://musistudio.github.io/claude-code-router/ +``` + +The Astro build reads `ASTRO_SITE` and `ASTRO_BASE`, defaulting to `https://musistudio.github.io` and `/claude-code-router`. + ## Content Docs pages are authored in Markdown: diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index dae317c..becf982 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -1,6 +1,11 @@ import { defineConfig } from "astro/config"; +const site = process.env.ASTRO_SITE ?? "https://musistudio.github.io"; +const base = process.env.ASTRO_BASE ?? "/claude-code-router"; + export default defineConfig({ + site, + base, output: "static", markdown: { shikiConfig: { diff --git a/docs/src/content/docs/en/index.md b/docs/src/content/docs/en/index.md index 35265d9..a7a44b0 100644 --- a/docs/src/content/docs/en/index.md +++ b/docs/src/content/docs/en/index.md @@ -245,14 +245,14 @@ Bots forward agent messages to instant-messaging platforms and can hand off acti CCR supports the following IM platforms for Bot relay. Each requires platform-specific setup described in its dedicated page: -- [DingTalk](/en/relay-agents-in-im-with-bots/dingtalk) -- [Discord](/en/relay-agents-in-im-with-bots/discord) -- [Feishu (Lark)](/en/relay-agents-in-im-with-bots/feishu) -- [LINE](/en/relay-agents-in-im-with-bots/line) -- [Slack](/en/relay-agents-in-im-with-bots/slack) -- [Telegram](/en/relay-agents-in-im-with-bots/telegram) -- [WeCom (Enterprise WeChat)](/en/relay-agents-in-im-with-bots/wecom) -- [Weixin (iLink)](/en/relay-agents-in-im-with-bots/weixin-ilink) +- [DingTalk](relay-agents-in-im-with-bots/dingtalk) +- [Discord](relay-agents-in-im-with-bots/discord) +- [Feishu (Lark)](relay-agents-in-im-with-bots/feishu) +- [LINE](relay-agents-in-im-with-bots/line) +- [Slack](relay-agents-in-im-with-bots/slack) +- [Telegram](relay-agents-in-im-with-bots/telegram) +- [WeCom (Enterprise WeChat)](relay-agents-in-im-with-bots/wecom) +- [Weixin (iLink)](relay-agents-in-im-with-bots/weixin-ilink) Each platform page covers: required credentials, where to obtain them in the platform's developer console, and common troubleshooting steps. diff --git a/docs/src/content/docs/zh/index.md b/docs/src/content/docs/zh/index.md index ba5fd3a..ec7cec5 100644 --- a/docs/src/content/docs/zh/index.md +++ b/docs/src/content/docs/zh/index.md @@ -307,14 +307,14 @@ Bot 能把 Agent 的消息转发到 IM,还能在你空闲一段时间后,把 每个平台的完整步骤(平台后台怎么建应用、字段对照、排查 FAQ)都有单独一篇: -- [Slack](/bot-与-im-接力-agent/slack) -- [Discord](/bot-与-im-接力-agent/discord) -- [Telegram](/bot-与-im-接力-agent/telegram) -- [LINE](/bot-与-im-接力-agent/line) -- [微信](/bot-与-im-接力-agent/weixin-ilink) -- [企业微信](/bot-与-im-接力-agent/wecom) -- [飞书](/bot-与-im-接力-agent/feishu) -- [钉钉](/bot-与-im-接力-agent/dingtalk) +- [Slack](bot-与-im-接力-agent/slack) +- [Discord](bot-与-im-接力-agent/discord) +- [Telegram](bot-与-im-接力-agent/telegram) +- [LINE](bot-与-im-接力-agent/line) +- [微信](bot-与-im-接力-agent/weixin-ilink) +- [企业微信](bot-与-im-接力-agent/wecom) +- [飞书](bot-与-im-接力-agent/feishu) +- [钉钉](bot-与-im-接力-agent/dingtalk) ## 遇到问题时,照着这个查 diff --git a/docs/src/layouts/DocsLayout.astro b/docs/src/layouts/DocsLayout.astro index 704f7ac..a55657e 100644 --- a/docs/src/layouts/DocsLayout.astro +++ b/docs/src/layouts/DocsLayout.astro @@ -41,7 +41,37 @@ const { }, } = Astro.props; -const homeHref = locale === "en" ? "/en/" : "/"; +const baseUrl = import.meta.env.BASE_URL ?? "/"; +const absoluteUrlPattern = /^[a-z][a-z\d+.-]*:/i; +const withBase = (href) => { + if (!href || href.startsWith("#") || href.startsWith("//") || absoluteUrlPattern.test(href)) { + return href; + } + + const basePath = baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`; + if (href === "/") { + return basePath; + } + + const normalizedHref = href.startsWith("/") ? href.slice(1) : href; + return `${basePath}${normalizedHref}`; +}; +const absoluteHref = (href) => { + const resolvedHref = withBase(href); + if (absoluteUrlPattern.test(resolvedHref) || !Astro.site) { + return resolvedHref; + } + + return new URL(resolvedHref, Astro.site).toString(); +}; +const resolvedLanguageOptions = languageOptions.map((option) => ({ + ...option, + href: withBase(option.href), + absoluteHref: absoluteHref(option.href), +})); +const homeHref = withBase(locale === "en" ? "/en/" : "/"); +const faviconHref = withBase("/favicon.svg"); +const logoSrc = withBase("/logo.png"); const sidebarIcons = { rocket: Rocket, book: BookOpen, @@ -81,13 +111,13 @@ const sidebarIcons = { } })(); - + { - languageOptions.map((option) => ( + resolvedLanguageOptions.map((option) => ( )) } @@ -97,7 +127,7 @@ const sidebarIcons = {
- + CCR docs @@ -108,7 +138,7 @@ const sidebarIcons = {
{ - languageOptions.map((option) => ( + resolvedLanguageOptions.map((option) => ( {childItems.map((child) => (
  • - + {child}
  • @@ -202,7 +232,7 @@ const sidebarIcons = { ) : ( {item}