把两条路由门禁串进 npm run lint 并用 guardrail 锁住接线
Project CI / AI game creator shell Rust crates (push) Successful in 1m30s
Project CI / AI game creator shell Rust smoke (push) Successful in 2m2s
Project CI / Backend tests (push) Successful in 3m55s
Project CI / AI game creator shell Rust lane 2/2 (push) Has been cancelled
Project CI / Repository checks (push) Has been cancelled
Project CI / AI game creator shell web tests (push) Has been cancelled
Project CI / Frontend tests (push) Has been cancelled
Project CI / AI game creator shell Rust lane 1/2 (push) Has been cancelled
Project CI / Native shell tests (push) Has been cancelled
Project CI / AI game creator shell Rust crates (push) Successful in 1m30s
Project CI / AI game creator shell Rust smoke (push) Successful in 2m2s
Project CI / Backend tests (push) Successful in 3m55s
Project CI / AI game creator shell Rust lane 2/2 (push) Has been cancelled
Project CI / Repository checks (push) Has been cancelled
Project CI / AI game creator shell web tests (push) Has been cancelled
Project CI / Frontend tests (push) Has been cancelled
Project CI / AI game creator shell Rust lane 1/2 (push) Has been cancelled
Project CI / Native shell tests (push) Has been cancelled
- 根因:check:nginx-spa-routes 与 check:pingora-route-parity 从来没有自动调用方(只有切换期聚合门禁 check:pingora-release-readiness 含 parity,而它不在 CI 里跑),所以红了一个月也没人看见 - package.json 的 lint 链在 check:maintenance-page 之后接入 check:nginx-spa-routes 与 check:pingora-route-parity,因此 check:repository-ci、CI 与 pre-push 都会执行 - check-production-ops 新增两条 guardrail:断言 package.json 的 lint 链里必须出现 npm run check:nginx-spa-routes / npm run check:pingora-route-parity,删任一条立刻变红(变异验证已做) - 文档:索引第五节与 Pingora 试点文档更新为「已接进 CI」;pitfalls 新增「为什么以前会漏:加新门禁先问它有没有自动调用方」 - 验证:npm run lint 全绿(含两条新门禁 + eslint + typecheck)、check:production-ops OK、encoding / doc-index / diff / prettier / eslint 通过
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
- **事实**:主站 SPA 路由要三处同批更新才自洽——① 前端路由源 `src/routing/activeAppPageRoutes.ts` 的 `STAGE_ROUTE_ENTRIES` 与 `src/routing/activeAppRoutes.tsx`;② Nginx 三份模板(`deploy/nginx/genarrative.conf`、`deploy/nginx/genarrative-dev-http.conf`、`deploy/container/nginx.conf`)里 `# BEGIN GENARRATIVE MAIN SPA ROUTES` 的精确 allowlist;③ Pingora 网关 `server-rs/crates/pingora-gateway/src/main.rs` 的 `MAIN_SPA_PATHS`(精确匹配、大小写不敏感、允许一个尾部斜杠)。
|
||||
- **代价**:2026-08-26 加 `/components`、`/design-system` 时只加了前端路由,两个门禁红了一个月(生产深链会 404 而不是 `index.html`);2026-09-28(`87e52860a`「游戏发行入口改为平台同源路径」)补了 nginx 侧的 5 条 `/games*`,却漏了 Pingora 侧,`check:pingora-route-parity` 继续红到 2026-09-29 才补齐(`MAIN_SPA_PATHS` 5→12 条)。
|
||||
- **判据/入口**:`npm run check:nginx-spa-routes`(12 条路由 × 3 份模板;断言未知路径只读真实静态文件并 404、大小写与一个尾部斜杠容忍)与 `npm run check:pingora-route-parity`(同一套路由 + `MAIN_SPA_PATHS` 逐条相等)。后者还读 `deploy/pingora/nginx-route-parity.matrix.json`:新增路由要同时补矩阵用例,矩阵里的 `docs` 片段会去 `docs/technical/【开发运维】Pingora独立网关试点-2026-06-11.md` 里找,文档没写同样判红。2026-09-29 起它还做**反向覆盖**:两份 Nginx 模板里出现的每条 `location` 都必须被矩阵某条用例声明(变异验证:往生产模板插一条无矩阵声明的 `location` 即报「没有被矩阵覆盖」),所以「模板改了、矩阵和 Pingora 没跟上」这类漂移不会再漏过。
|
||||
- **为什么以前会漏**:这两条门禁原来**没有任何自动调用方**(只有 `check:pingora-release-readiness` 这个切换期聚合门禁含有 parity,而它不在 CI 里跑),所以红了一个月也没人看见。2026-09-29 起两条都串进 `npm run lint`(⇒ `check:repository-ci` ⇒ CI 与 pre-push),并且 `check:production-ops` 新增两条 guardrail 断言 `package.json` 的 lint 链里必须出现 `npm run check:nginx-spa-routes` / `npm run check:pingora-route-parity`——把任一条拿掉,`check:production-ops` 立刻报「package.json 缺少 npm run …」。加新门禁时先问一句:它有没有自动调用方?
|
||||
- **别踩**:`/games/game_<32 位小写十六进制 id>/…` **不是** SPA 深链,而是发行网关路由(Nginx 代理到 `/api/game-distribution/releases/<gameId><asset>` 并 `proxy_set_header Cookie ""`),Pingora 侧对应 `RouteDecision::ReleaseGateway`(重写上游路径、清空 Cookie、不进 SPA fallback、不套 `limit_conn`/`limit_req`、不受维护闸拦截)。把它写进 `MAIN_SPA_PATHS`,或让 SPA 正则吞掉它,都会破坏在线游玩入口。`check:pingora-gateway-smoke` 已覆盖「重写到发行网关 + 清空 Cookie + 形状不符仍 404」;本机跑它要先设 `OPENSSL_CONF`(见本文件另一条),且改过网关源码后**不能**加 `--skip-build`(会拿旧二进制得到假 404)。
|
||||
|
||||
## AGC 版本探测必须显式提供隔离用户目录
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
2. **Pingora 缺发行网关路由**:三份 nginx 模板早就把 `/games/game_<32 位十六进制 id>/…` 代理到发行网关(清 Cookie),Pingora 没有对应分支,切流后「立即玩」会 404。本轮实现 `RouteDecision::ReleaseGateway`(重写上游路径到 `/api/game-distribution/releases/<gameId><asset>`、清空 Cookie、不进 SPA fallback、不套接流保护、不受维护闸拦截),矩阵补 `games_release_gateway`(含 `upstreamPath` 期望)用例;`check:pingora-gateway-smoke` 新增三条断言(重写+清 Cookie、`/games/detail` 仍走 SPA、`/games/game/index.html` 仍真实 404)并通过。口径与三处真相源已写入 `docs/technical/【开发运维】Pingora独立网关试点-2026-06-11.md` 与 `pitfalls.md`。
|
||||
|
||||
- (2026-09-24 快照,已被上面 2026-09-29 重新盘点取代)74 份计划里 63 份为 `implemented-awaiting-runtime-acceptance`;当轮未勾选复选框从 85 条降到 43 条。
|
||||
- **路由类门禁已于 2026-09-29 转绿**:`npm run check:nginx-spa-routes` OK(12 路由 / 3 模板)、`npm run check:pingora-route-parity` OK(24 路由)。这条曾经红了一个月(`/components`、`/design-system`、5 条 `/games*` 的 SPA allowlist),收口记录见上面「已关闭」两条;同日还给 parity 门禁补了**反向覆盖**(两份 Nginx 模板里的每条 `location` 都必须被矩阵声明),并将 `check:pingora-gateway-smoke` 扩到覆盖发行网关重写与 Cookie 清空。两者仍不在 CI 与 `npm run lint` 的覆盖范围内,需要人工执行(判据与踩坑见 `pitfalls.md` 同日条目)。
|
||||
- **路由类门禁已于 2026-09-29 转绿并接进 CI**:`npm run check:nginx-spa-routes` OK(12 路由 / 3 模板)、`npm run check:pingora-route-parity` OK(24 路由)。这条曾经红了一个月(`/components`、`/design-system`、5 条 `/games*` 的 SPA allowlist),收口记录见上面「已关闭」两条;同日还给 parity 门禁补了**反向覆盖**(两份 Nginx 模板里的每条 `location` 都必须被矩阵声明),并将 `check:pingora-gateway-smoke` 扩到覆盖发行网关重写与 Cookie 清空。**根因修复**:两条门禁现在串进 `npm run lint`(⇒ `check:repository-ci` ⇒ CI 与 pre-push 都会跑;`npm run lint` 已实跑全绿),并且 `check:production-ops` 新增两条 guardrail 锁住这个接线——把任一条从 lint 链里拿掉都会立刻变红(变异验证通过)。判据与踩坑见 `pitfalls.md` 同日条目。
|
||||
- 其余门禁(2026-09-24 本机实跑):`ai-game-creator-shell:check:rust:crates` exit 0、`agc:plugins:test` 35 passed、`agc:plugins:native-test` 30 passed、`check:repository-ci origin/master` exit 0(含 admin-web typecheck 与生产构建)。
|
||||
- CI 全部 job 的命令(2026-09-24 起逐条对齐,本机实跑):AGC agent-run smoke `ai-game-creator-shell:agent-run:smoke` passed(本地 provider 桩,约 2.5 分钟);`cargo check --locked -p api-server --all-targets` 与 `-p spacetime-module` exit 0;两把 Cargo.lock 的「构建不改锁」判据以 `--locked` 全绿 + desktop 锁未被构建改动佐证。至此除「AGC Rust 四个分片跑全量(Windows 不实用)」与已记录的 Linux-only 门禁外,CI 每个 job 的命令都有本机结果。
|
||||
- CI 对齐的其余命令(2026-09-24 本机实跑):`npm run test:ci:frontend` 230 files / 2583 passed / 12 skipped、`npm run bgfilter-worker:smoke-test` 4 passed、`npm run build`(web + admin-web)exit 0;release 分组三步在 Windows 上全部可跑——`ai-game-creator-shell:build --no-bundle`(5m47s,产出 exe)、`desktop-shell:build --no-bundle`(1m29s)、`desktop-shell:stage-release-binary`(修掉 `new URL(...).pathname` 拼出 `F:\F:\…` 的 Windows 路径缺陷后通过)。
|
||||
|
||||
@@ -64,7 +64,7 @@ npm run check:pingora-release-readiness
|
||||
|
||||
`check:nginx-spa-routes` 从 `appPageRoutes.ts` 的 `STAGE_ROUTE_ENTRIES` / `APP_RUNTIME_ROUTES`、`appRoutes.tsx` 的精确路由判断和兼容恢复路径 `/creation/rpg/agent` 提取当前主站 SPA allowlist,确认生产、开发和容器三套 Nginx 模板集合一致,并验证大小写、尾部斜杠和 `/creation/not-exist`、`/runtime/not-exist`、`/puzzle/not-exist` 等未知反例。
|
||||
|
||||
`check:pingora-route-parity` 会先执行同一 Nginx SPA 路由门禁,再读取 `deploy/pingora/nginx-route-parity.matrix.json`,静态确认生产 / 开发 Nginx 模板、Pingora Rust 路由 allowlist / 单测和本文档都覆盖同一组核心路由。`cargo test -p pingora-gateway --manifest-path server-rs/Cargo.toml matches_nginx_route_parity_matrix` 会读取同一份矩阵,逐条断言 `classify_path` 的路由结果、body limit 和接流保护分组。
|
||||
`check:pingora-route-parity` 会先执行同一 Nginx SPA 路由门禁,再读取 `deploy/pingora/nginx-route-parity.matrix.json`,静态确认生产 / 开发 Nginx 模板、Pingora Rust 路由 allowlist / 单测和本文档都覆盖同一组核心路由,并做**反向覆盖**(模板里的每条 `location` 都必须被矩阵声明)。`cargo test -p pingora-gateway --manifest-path server-rs/Cargo.toml matches_nginx_route_parity_matrix` 会读取同一份矩阵,逐条断言 `classify_path` 的路由结果、body limit 和接流保护分组。`check:nginx-spa-routes` 与 `check:pingora-route-parity` 已串进 `npm run lint`(因此 `check:repository-ci`、CI 与 pre-push 都会执行),接线本身由 `check:production-ops` 的 guardrail 锁定。
|
||||
|
||||
`check:nginx-pingora-canary` 会静态校验 `deploy/nginx/snippets/genarrative-pingora-canary.conf` 的本机来源限制、handoff 响应头、probe token 占位、前缀 rewrite、低缓冲和 WebSocket Upgrade 设置,也会校验 `deploy/nginx/snippets/genarrative-pingora-realpath-canary.conf` 只能作为独立 loopback `server` 片段使用、默认监听 `127.0.0.1:18083`、写独立 access log、没有 rewrite、覆盖真实 `/api` / `/v1` / `/assets` 代表路径。本机安装了 Nginx 时脚本会额外把两个 snippet 包进临时 `http {}` 执行 `nginx -t`;需要在 CI / 目标 agent 上强制要求真实 Nginx 语法检查时执行 `node scripts/check-nginx-pingora-canary.mjs --require-nginx`。
|
||||
|
||||
|
||||
+1
-1
@@ -136,7 +136,7 @@
|
||||
"check:server-rs-ddd": "npm run check:spacetime-schema && npm run check:spacetime-runtime-access && npm run check:module-runtime-artifact && node scripts/check-server-rs-ddd-boundaries.mjs",
|
||||
"lint:eslint": "eslint . --ext .ts,.tsx,.js,.mjs,.cjs --max-warnings 0",
|
||||
"typecheck": "tsc -p tsconfig.typecheck-guardrails.json --noEmit",
|
||||
"lint": "npm run check:encoding && npm run check:doc-index && npm run check:npm-workspaces && npm run check:git-hooks && npm run check:rustfmt && npm run check:spacetime-schema && npm run check:generated-bindings && npm run check:game-distribution-dto-parity && npm run check:production-ops && npm run check:preview-deployer && npm run check:maintenance-page && npm run lint:eslint && npm run typecheck",
|
||||
"lint": "npm run check:encoding && npm run check:doc-index && npm run check:npm-workspaces && npm run check:git-hooks && npm run check:rustfmt && npm run check:spacetime-schema && npm run check:generated-bindings && npm run check:game-distribution-dto-parity && npm run check:production-ops && npm run check:preview-deployer && npm run check:maintenance-page && npm run check:nginx-spa-routes && npm run check:pingora-route-parity && npm run lint:eslint && npm run typecheck",
|
||||
"lint:fix": "eslint . --ext .ts,.tsx,.js,.mjs,.cjs --fix && prettier --write .",
|
||||
"format:rust": "cargo fmt --all --manifest-path server-rs/Cargo.toml && cargo fmt --all --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml && cargo fmt --all --manifest-path plugins/agc-unity-editor/native/unity-editor-bridge/Cargo.toml && cargo fmt --all --manifest-path plugins/agc-godot-editor/native/godot-editor-bridge/Cargo.toml",
|
||||
"format": "prettier --write . && npm run format:rust",
|
||||
|
||||
@@ -107,6 +107,18 @@ const checks = [
|
||||
includes: 'npm run lint:eslint',
|
||||
reason: 'Web 生产构建必须执行 ESLint 门禁。',
|
||||
},
|
||||
{
|
||||
file: 'package.json',
|
||||
includes: 'npm run check:nginx-spa-routes',
|
||||
reason:
|
||||
'仓库 lint 链必须包含主站 SPA allowlist 门禁:否则模板与前端路由源漂移只在人工执行时才可见(2026-08-26 起红了一个月就是没有调用方)。',
|
||||
},
|
||||
{
|
||||
file: 'package.json',
|
||||
includes: 'npm run check:pingora-route-parity',
|
||||
reason:
|
||||
'仓库 lint 链必须包含 Nginx/Pingora 路由矩阵 parity 门禁:否则模板新增 location 而矩阵与网关没跟上时,门禁不会在 CI 里跑(发行网关路由就是这么漏的)。',
|
||||
},
|
||||
{
|
||||
file: 'jenkins/Jenkinsfile.production-web-build',
|
||||
includes: 'npm run typecheck',
|
||||
|
||||
Reference in New Issue
Block a user