文档站点运维
目的
本文是 ViewCompose 托管文档系统的运维指南。内容规则以文档治理规范 为准,平台选择与取舍记录在 ADR-0001。
构建流水线
生产产物通过七个明确阶段组装:
verifyDocumentLanguages检查权威页与本地化页的标题和叙述符合目录语言,并确认每个有效 公共页面都有必需 locale 镜像。verifyDocumentationStructure检查源码位置、目录一致性、可达性和仓库链接。verify:translations检查必需中文覆盖、英文源指纹、显式过期状态和过期警告。verifyCompleteViewComposeApiDocs按 source revision 对不可变发布分组,校验精确条目集合以及 每个生成文件的大小和 SHA-256。有效组直接复用;陈旧、格式错误、缺项、多项、符号链接或摘要 不匹配的组会在临时工作区重建,再校验路由、别名、manifest 和固定源码。缺失 revision 只按 完整 SHA 获取。历史工作区只接收本组发布记录;早于当前构建契约的源码只使用不发布的兼容垫片。- 站点生成器读取发布元数据、不可变注册表和
docs/modules/README.md,从同一冻结 Git revision 生成目录和每个已发布制品/版本的模块手册快照,不维护第二份注册表。无论不可变 API 产物来自恢复还是重建,生成器都会先按精确完整 SHA 解析每个唯一冻结 revision,再读取快照。 - Docusaurus type-check 并构建手写文档、站点界面、生成 API、本地化搜索索引和兼容重定向,
同时输出
en与zh-CN到website/build/;坏链和坏锚点均为错误。Docusaurus 解析slug等展示字段后,Remark Transform 会从浏览器页面 Chunk 中移除 Governance V2 所有权字段与翻译 审核指纹,并把已验证、指向docs/外仓库文件的链接改写为 GitHub 源码 URL。源 Markdown 继续使用仓库相对链接并保持权威,生产与测试源码不再复制进站点产物;生成的 Capability Reference 仍是公开关系模型。 - 构建 wrapper 验证跨语言站点外壳行为,审核 Docusaurus 自有 HTML 无障碍,并限制构建时间、 总产物、JavaScript、CSS 和各语言搜索索引。Dokka HTML 由 API 生成器独立保证完整性,不混入 站点模板无障碍门禁。
从仓库根目录运行完整本地验证:
./gradlew verifyDocumentationStructure verifyCompleteViewComposeApiDocs
cd website
npm ci
npm run test:scripts
npm run verify:languages
npm run verify:translations
npm run typecheck
npm run build
npm run build 包含无障碍和预算门禁;npm run verify:site 可在不重建时复查现有
website/build/。
质量报告位于 build/reports/documentation/site-quality-report.json,不进入部署/预算树;复查
website/build/ 会重现构建结果。
本地迭代可用 -PviewComposeDocsModules=artifact-a,artifact-b 限制 Dokka 制品集合,生产构建
不得使用该捷径。
build/versioned-api-cache/integrity-manifest.json 是生成的缓存状态,不是第二份发布注册表,也不是
可部署 API 资源。完整缓存键由
逐 revision 指纹派生;每个 revision 指纹覆盖不可变的产物/版本/源码三元组集合和当前生成器实现。
别名及未发布工作树 current 明确不参与不可变复用,每次装配都会重建。
VIEWCOMPOSE_API_DOCS_MAX_PARALLEL_REVISIONS 只接受 1 或 2;在获得可接受的托管 runner
进程树内存测量、确认两个 2 GiB Gradle/Dokka 进程可以并行前,CI 固定为 1。
Governance V2 资产是仓库输入,不是第二份站点注册表:schema 与确定性发现共同输入 compiled
零 Exception strict gate,所有 issue 都会阻断。已提交的
website/src/data/capability-reference.json 数据集只能通过
./gradlew updateDocumentationCapabilityReference 主动重写;校验会独立派生并逐字节比较预期
模型。本地化 /reference/ 页面消费这一棵树,/api/ 则继续提供按产物和版本生成的完整
Dokka 输出。
React、navbar、footer 或 sidebar 新增消息 key 时运行 npm run write-translations。它只补充
缺失 JSON,不覆盖已审阅中文。Markdown 镜像、源指纹、必需层级和恢复流程见
本地化工作流。
搜索、重定向与质量预算
每个 Locale 都从渲染文档生成无需凭据的本地搜索索引,并保留页面摘要、标题、公共契约和命令
指南。穷举证据表和日期台账只有在保留相邻可搜索标题与摘要时才能使用
search-partition-detail;API 契约、命令参考和面向读者的指南不得使用该分区。搜索 UI 文案继续
由标准 zh-CN 消息目录审阅。
搜索产物按公共顶级路由实施结构化分段:文档总览、AI 接入、教程、指南、架构、迁移、模块、工具与 项目维护。导航栏只加载当前路由所在分段,搜索结果页提供本地化分段选择器。这样,每份公共文档仍可 搜索,同时不再要求每个 Locale 生成一个单体索引。预算门禁对每个分段继续使用不变的单文件上限, 并强制生成完整的 Locale 与分段组合;缺少翻译分段或意外退回单索引都会导致 CI 失败。
当活动计划索引保留可搜索的目的与范围摘要,并且所有长期公共契约和命令仍位于可搜索的 owner 文档
时,体积特别大的临时执行计划保持为仓库专属 production draft。Canonical 索引继续使用仓库相对
源码链接,保证文档图完整;严格 Markdown link hook 只在确认目标包含 draft: true 后,于站点构建
期间把链接改写为精确 GitHub 源码 URL。因此读者仍能从公共索引评审目标,同时临时执行状态不会进入
渲染产物、locale fallback、搜索或 sitemap。目标缺失、非 draft 坏链或其他未解析路由仍会使构建失败。
每个分段、每个 Locale 的搜索预算为 6.25 MiB。经过审阅的双语架构与公共契约曾把它从 4 逐步 调整到 6 MiB;Lazy Collection 分支先对穷举计划与 Benchmark 明细分区,才形成最终 6.25 MiB 上限。精确转换证据收敛在下方。再次触顶时必须实施结构化索引分段,不能继续只做内容分区或提高 阈值;API 与命令指南继续参与搜索。
渲染后的代码块仍完整保留在 Owner 页面并保留可编译源码链接,但本地全文搜索只索引周边解释,不再 重复每个代码 Token。精确公共 Symbol 仍可通过模块 API 清单和生成式 Reference 发现。该边界在不 隐藏页面、样例、命令契约或迁移路由的前提下减少双语索引重复;若某条命令或 Symbol 只存在于代码 围栏,应该把名称补入 Owner 正文,而不是让全部代码正文重新进入索引。
兼容重定向保留 /docs、/getting-started、/compose-migration、
/migrate-from-compose,以及有效计划归档前已经公开的路径,包括 locale 前缀形式。只为明确
的历史或推广路由增加重定向,权威文档路径仍是唯一真相源。
全局侧边栏链接“架构决策记录”和“已发布模块”目录,不在每一个渲染页面重复所有条目。 每份双语目录仍完整且有序;各项决策和当前模块手册仍可直接访问、搜索,并由所属目录链接。 模块链接在本地构建和托管站点中都保持所选语言。仓库文件链接转换器识别权威英文和本地化 Markdown 根目录,交由 Docusaurus 解析手册链接;仅源码文件继续使用仓库 URL。 这样,新增目录条目不会把导航标签成倍复制到整个站点产物中。
2026-09-08,在相同双语语料、Node 24.19.0、Docusaurus 3.10.2 和六个不可变 API 源码版本 下,集成后的框架契约候选在目录及链接修正前生成 50,585,643 个非 API 字节,修正后为 49,275,384 字节,变化为 -1,310,259 字节(-2.59%)。结论是产物体积和本地化导航改善。 84 项站点脚本测试、两种语言下的 39 个当前模块路由、133 个不可变 API 版本及其双语手册、 无障碍、外壳,以及不变的 47.8 MiB/120 秒预算均通过。该测量只说明部署字节数,不代表 浏览器交互延迟;后续目录增长继续执行完整双语路由与体积门禁。
版本化阈值位于 website/site-budgets.json。不可变 Dokka 只以 /api/** 为权威路径;受支持
构建会删除 Locale API 副本和冗余社交卡片,因为本地化页面使用权威 API 树和同一个绝对社交卡 URL。
不可变模块手册快照以只读静态 HTML 保留本地化路由、服务端内容、样式、链接和色彩模式初始化, 但不保留重复 Hydration Script 或路由 Chunk;当前手册仍可 Hydration。门禁强制整页导航、静态 Marker 和 Script 删除。构建后 Dokka 压缩只删除生成缩进,逐字节保留字面量元素正文;不可变源码 Manifest 与缓存完整性仍位于上游。
预算模型把合法发布历史增长与真正回归分开。当前上限为:非 API 产物 47.8 MiB、 API 树平均 4.5 MiB/单树 24 MiB、API 路由开销 1 MiB、JavaScript 总计 8 MiB/单文件 768 KiB、CSS 128 KiB、单 Locale 搜索分段 6.25 MiB,以及 Docusaurus 构建 120 秒。 仍然禁止生成带 Locale 前缀的 API 副本。
上限从 41 MiB 调整到 46.9 MiB 前均经过成对归因和内容收敛。2026-08-30 的一次已审阅例外把它 调整为 47.1 MiB:必需的顶级双语“AI 接入”章节已从两条路由收敛为一条,但仍超过此前上限。 搜索分段验收把该上限调整为 47.8 MiB,棘轮从此处重新生效:新增其他路由前必须通过结构优化恢复 容量;只能删除重复部署表示,不能删除当前契约或有效发布历史。已有受测试保护的 Transform 会移除 无用 Locale 副本、仅机器读取的治理/翻译 Front Matter、不可变手册 Hydration 和生成缩进,同时 保持路由与可读内容不变。历史 同语料测量及限制保留在下方源码中,不再重复进入公共运维契约。
无障碍检查覆盖站点自有英文与本地化页面,检查文档语言、title/main landmark、标题顺序、 accessible name、图片替代文本、表头、iframe title 和重复 ID;重定向 stub 与 Dokka 生成页 不在范围内。改变 Dokka 模板时单独审查生成 API 无障碍,不得削弱当前门禁。
站点外壳检查要求两种语言的主页使用同一个显式浏览器存储 namespace,确保切换语言时保留读者
选择的亮色或暗色模式;同时拒绝在任一主页重新出现已删除的独立 Maven 坐标横幅。同一门禁还会检查
最终打包的样式表,禁止在 .navbar 根节点上设置滤镜、变换、containment 或相关属性,因为它们会把
Docusaurus 的 fixed 移动端侧栏和遮罩限制在导航栏高度内。同一限制也适用于导航栏伪元素:部分
浏览器的合成顺序会把定位滤镜层绘制到普通流中的菜单按钮与品牌标题上方,同时仍显示定位的搜索框。
因此导航栏只使用普通背景,不再增加模糊图层。
发布版本与别名
不可变 API 路径为 /api/<artifact>/<version>/。current 跟随仓库当前登记版本;产物首次发布
前,current 直接包含从工作树生成的 Dokka,且不存在版本化路由。latest 只为稳定版本生成,
alpha、beta、RC、snapshot、preview、development 和 EAP 不得成为 latest。
不可变模块手册快照路径为 /modules/<artifact>/<version>;无版本路径继续指向当前维护手册。
历史手册只生成权威英文快照,包括等价的 zh-CN 路由,避免 locale 路径冒充未经审阅的历史
翻译。
历史手册指向另一个已发布模块的相对链接会改写为该模块的版本化路由;指向临时执行计划的链接 则固定到 GitHub 上的手册 Source Revision,确保计划完成或归档后不会破坏不可变手册快照。
只追加的发布注册表把每个版本与完整不可变源码 SHA 配对;缺失或可移动链接会失败。先冻结源码和 手册,再在第二个提交追加注册表/版本元数据。冻结 SHA 必须保持可达,不能替换为 squash 提交。
release.retiredModules 在活动目录外保留被替代历史;release.unpublishedModules 只允许首发前
的工作树 current,追加第一条不可变记录时必须移除对应产物。
verifyAssembledViewComposeApiDocs 接受本地显式子集;部署使用完整验证器并检查两个 Locale 的
全部 API/手册路由。当前预发布模块不生成 latest。
生成产物不提交。干净 Checkout 从注册 Revision 恢复历史,只补取缺失的精确 SHA,不依赖临时分支。
每次模块发布:
- 在一个提交冻结待发布源码、源码注释、编译样例和模块手册;
- 在仅含元数据的提交追加注册表并更新发布版本与
sourceRevision; - 发布前运行 publishing 配置门禁、完整 API 验证器和生产站点构建。
持续集成与部署
.github/workflows/documentation.yml 对每个 PR 都保持存在。独立影响规划 Job 只配置
tools/viewcompose-quality-build,在 Job Summary 公布源码归属分类,并且只有文档、website、发布
模块生产输入或保守全量回退才选择高成本文档子任务。稳定的 Build documentation Context 是
always() 结果门面:只有规划成功且明确未选择子任务时,跳过才成功;规划失败或已选子任务失败仍会
阻断。推送到 main 或在 main 手工运行时始终选择完整子任务,只有它验证过的 Pages 产物才能通过
受保护的 github-pages environment 部署。
已选文档子任务会在恢复 website/generated/api 前计算不可变生成器指纹和完整历史指纹。PR 只读
缓存,只有成功的 main 子任务可以写入。主键按运行唯一,因此损坏恢复后可以用同一指纹的新键替代
旧归档;有序恢复前缀先匹配同一完整指纹,再匹配同一生成器产生的最新缓存。任何恢复都不能只凭键
名信任。由于生成器指纹包含实际 Java 与 Node runtime,工作流固定它们的完整发行版本,而不使用
浮动 major selector;变更任一版本都属于显式缓存迁移。装配器逐组验证,并在 Job Summary 输出
hit、partial、miss、recovery、生成组、无效组、
并行度和耗时。源码/语言/翻译门禁只运行一次,目录只生成一次,随后 CI 调用 prepared type-check 与
站点构建入口,避免 npm 生命周期钩子重复同一批预构建工作。缓存服务恢复或保存失败时会降级为完整
生成或跳过写入,不会绕过校验器,也不会阻断原本有效的 Pages 产物。
部署只有在正式域名冒烟测试访问两个 Locale 的目录、全部当前手册和代表性无尾斜杠路由后才成功。 HTTP、渲染 Not Found、错误插件或目录缺项在有界 CDN 重试后仍会令部署失败。
仓库 Pages source 必须设置为 GitHub Actions。入库 CNAME 声明
docs.viewcompose.com;DNS 将 docs CNAME 指向 viewcompose.github.io,GitHub 验证域名后
再启用 HTTPS 强制。
Maven Central、签名、域名注册商、分析或搜索管理凭据均不得入库。部署使用 GitHub 短期 Pages identity token。
故障恢复
- 源验证失败时修复权威文档或目录,不削弱门禁。
- 发布历史失败时追加缺失的不可变记录或修正未发布元数据,不重写已发布制品/版本。
- Dokka 失败时用制品子集复现并修复源码/API 配置。
- API 缓存组完整性失败时保留自动逐组重建;不得手工修改 manifest、接受只命中键名的结果、从 PR
保存缓存或绕过完整 API 校验。恢复成功的
main会为同一指纹写入更新的唯一键。 - Docusaurus 坏链/锚点保持严格;只有生成的静态 API 链接享受明确豁免。
- 预算失败时区分非 API 产物、API 树平均值、单个不可变或未发布
currentAPI 树、路由开销 和 locale 重复副本;修复回归,或记录并审查确有必要的阈值变化。不得恢复会因合法追加 不可变发布记录而失败的固定总产物上限。 - 无障碍失败时修复页面或主题,不削弱门禁。
- 语言或翻译验证失败时先审阅和同步中文语义,再更新指纹;必需页面不得过期。
- 语言放置验证失败时修正文叙述位置或缺失的必需镜像;真实外语 UI 字面量使用代码格式,不得 削弱分类器。
- 部署失败时保留上一次 Pages 版本,检查设置和 environment 后再重跑。
- Pages 产物健康但自定义域名失败时,单独诊断 DNS 与域名验证。
最近验证
当前生产契约提供 133 个不可变 API 版本、模块手册和中文回退路由。协同发布收尾审计 522 页,
总输出 468.9 MiB、非 API 为 46.7/46.9 MiB;两个精确缓存命中运行复用 6/6 组,分别耗时
47.3 s 和 43.0 s。缓存正确性与延迟为无实质变化,新增历史与更窄余量为混合。
后续同语料收敛把非 API 从 49,208,553 降到 49,086,492 字节(-122,061,
-0.248%),在 524 个无障碍页面下属于表示改善。这些本地/托管观察环境不一致,不构成
稳态基准;本地缓存还缺六组,完整缓存 CI 仍是版本路由验收门禁。详细证据见
PR 门禁计划
和 Governance V2 归档。
2026-08-29,独立双语 XML 迁移路由产生 49,373,569 个非 API 字节,超过不变上限 195,354.6
字节。撤回与已链接本地工具契约重复的路由,并收敛本运维页后,同一语料降至 49,171,339 字节:
相对被拒候选减少 202,230 字节(-0.4096%),相对无新增路由的 49,195,449 字节尝试减少
24,110 字节(-0.0490%)。一次构建留下 6,875.4 字节余量,审计 526 页;已接受的本地热构建
耗时 34.2–59.8 s。
表示结论为改善,路由、搜索契约与工具行为无实质变化。这只是本地热构建;未来新增
独立路由前必须先恢复其已测容量。
2026-08-30,必需的顶级双语“AI 接入”章节把概述和接入步骤收敛为一条路由后,产生 49,238,608
个非 API 字节。上一次通过的完整站点产物为 49,042,390 字节,因此该章节增加 196,218 字节
(+0.4001%),体积结论为回归;功能、版本历史、无障碍、语言、翻译和路由检查均保持成功。
因此上限经审阅调整为 47.1 MiB,留下 149,321.6 字节余量。该证据只覆盖一次本地生产构建,并且
测量未压缩输出,而不是传输体积、运行时间或查询延迟;不据此宣称性能改善。下一步保持该上限、
复用单条 AI 路由,并在增加其他 AI 文档页面前恢复已测容量。
2026-09-07,同语料单体构建产生 49,280,799 个非 API 字节,英文与中文搜索索引分别为
6,014,297 和 6,618,181 字节;中文索引超过不变的 6.25 MiB 上限 64,581 字节。按九个公共顶级
路由分段后,最大索引为 2,048,055 字节,读者单次最大下载减少 4,570,126 字节(69.0541%)。
分段索引增加了 776,685 字节(6.1483%)的索引元数据,并把非 API 总产物增至 50,060,856
字节,即增加 780,057 字节(1.5829%)。结论为混合:按需搜索负载和各区域未来容量得到
改善,但未压缩总产物回归。经审阅的 47.8 MiB 非 API 上限只接受这部分实测分段开销;所有公共
路由与搜索内容都保持存在。这两次本地构建未测量传输压缩、查询延迟或托管 Runner 差异。下一步是
托管 PR 构建,并继续强制完整的 Locale 与分段组合。