From 84c30b680cb3bbd312047f09f4ea9681118a402f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Sun, 4 Oct 2026 15:29:16 +0800 Subject: [PATCH] =?UTF-8?q?=E9=85=8D=E7=BD=AE=EF=BC=9ACI=20=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E6=88=90=E5=8A=9F=E9=9D=99=E9=BB=98=E6=94=B9=E7=94=A8?= =?UTF-8?q?=20cargo/node=20=E5=8E=9F=E7=94=9F=20quiet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - .gitea/workflows/project-ci.yml:全局加 CARGO_TERM_QUIET=true,cargo test 成功只打点号、失败才列用例名。 - scripts/build-gitea-rust-cache.sh:预热脚本同步 CARGO_TERM_QUIET=true,与 workflow 的 Cargo 环境一致。 - package.json:agc:plugins:test 改用 node --test --test-reporter=dot。 - apps/ai-game-creator-shell/package.json:bundled-resources:test 改用 node --test --test-reporter=dot。 - scripts/check-native-shells.mjs:去掉每个 step 的成功进度标签,失败时才打印标签。 - scripts/project-ci-workflow.test.ts:移除 silent: true 守护用例。 - docs/project-memory/shared-memory/decision-log.md:移除本次静默决策条目。 - docs/project-memory/shared-memory/development-workflow.md:移除本次静默说明段落。 --- .gitea/workflows/project-ci.yml | 3 +++ apps/ai-game-creator-shell/package.json | 2 +- docs/project-memory/shared-memory/decision-log.md | 8 -------- .../shared-memory/development-workflow.md | 3 --- package.json | 2 +- scripts/build-gitea-rust-cache.sh | 2 +- scripts/check-native-shells.mjs | 5 ++++- scripts/project-ci-workflow.test.ts | 10 ---------- 8 files changed, 10 insertions(+), 25 deletions(-) diff --git a/.gitea/workflows/project-ci.yml b/.gitea/workflows/project-ci.yml index 5bde92df5..d56eba0f4 100644 --- a/.gitea/workflows/project-ci.yml +++ b/.gitea/workflows/project-ci.yml @@ -20,6 +20,9 @@ env: CARGO_HTTP_MULTIPLEXING: 'false' CARGO_NET_RETRY: '10' CARGO_TERM_COLOR: always + # 等价于给每条 `cargo test` 加 `-q`:通过的用例只打点号,失败的才按名字列出。 + # 对 npm 脚本、shard runner 里嵌套的 cargo 同样生效,避免逐条 `test ... ok` 刷屏。 + CARGO_TERM_QUIET: 'true' NPM_CONFIG_AUDIT: 'false' NPM_CONFIG_FETCH_RETRIES: '10' NPM_CONFIG_FETCH_RETRY_FACTOR: '2' diff --git a/apps/ai-game-creator-shell/package.json b/apps/ai-game-creator-shell/package.json index 0d3ec33c6..54a85623d 100644 --- a/apps/ai-game-creator-shell/package.json +++ b/apps/ai-game-creator-shell/package.json @@ -16,7 +16,7 @@ "bundled-resources:check": "node scripts/check-package-layout.mjs", "bundled-resources:sync": "node scripts/check-package-layout.mjs --write", "bundled-resources:prepare": "node scripts/prepare-bundled-resources.mjs", - "bundled-resources:test": "node --test scripts/prepare-bundled-resources.test.mjs", + "bundled-resources:test": "node --test --test-reporter=dot scripts/prepare-bundled-resources.test.mjs", "llm-status": "node scripts/run-cli-with-config.mjs --llm-status", "config": "node scripts/game-creator-config-wizard.mjs", "check:tests:types": "tsc -p tsconfig.tests.json --noEmit", diff --git a/docs/project-memory/shared-memory/decision-log.md b/docs/project-memory/shared-memory/decision-log.md index 6a39012a7..bf30e4c85 100644 --- a/docs/project-memory/shared-memory/decision-log.md +++ b/docs/project-memory/shared-memory/decision-log.md @@ -1,13 +1,5 @@ # 决策记录 -## 2026-10-04 CI 测试成功时静默(silent is gold) - -- 背景:`Frontend tests` 的 `npm run test:ci:frontend` 在成功 run 里仍回放被测代码的 console 输出——React `act(...)` 警告、`scripts/dev.test.ts` / `scripts/dev-all.test.ts` 的开发栈调度日志——把 CI 日志刷出大量与「红灯」无关的内容。 -- 决策:根 `vitest.config.ts` 固定 `test.silent: true`(`--silent` 的配置形态)。成功用例不再回放写进 stdout / stderr 的内容;reporter 仍输出每个文件一行进度与最终汇总,失败用例仍打印断言摘要与源码位置。`vitest.frontend-ci.config.ts` 通过 `mergeConfig` 继承该设置,AGC 与 repository checks 直接使用的根配置同样生效。本机排查用 `vitest run --silent=false` 覆盖。 -- 守护:`scripts/project-ci-workflow.test.ts` 新增用例钉住根配置的 `silent: true`,防止日后被顺手删掉。 -- 影响范围:`vitest.config.ts`、`scripts/project-ci-workflow.test.ts`、`docs/project-memory/shared-memory/development-workflow.md`、本文件。 -- 验证:`npx vitest run --config vitest.frontend-ci.config.ts`(243 files / 2761 passed,输出中 `stdout |` / `stderr |` 块与 `act(...)` 警告均为 0);定向 `scripts/{project-ci-workflow,dev,dev-all,dev-utils}.test.ts`(4 files / 114 passed);临时失败用例确认失败摘要仍打印;`--silent=false` 可恢复 console 输出;`git diff --check`、prettier、eslint `--max-warnings 0`(改动文件)通过。 - ## 2026-10-03 AGC 画布引用统一走「活跃聊天输入区」注册表(Issue 602) - 背景:画布的「引用」按钮与「拖拽批量引用」只派发 window 事件,消费者只有 `App.tsx` 一处,而它插的是绑在 `PlanningChatView` 上的 `chatComposerRef`;2026-09-22 DirectProject 拆分后普通项目走 `directProjectMode` 提前 return,渲染不到策划面 → ref 恒为 `null`,可选链静默吞掉点击(画布上是死按钮)。同一批合并冲突还丢了 `RESOURCE_REFERENCE_INSERT_MANY_EVENT` 的监听,批量引用连消费者都没有。 diff --git a/docs/project-memory/shared-memory/development-workflow.md b/docs/project-memory/shared-memory/development-workflow.md index f241edbfd..c4e72194e 100644 --- a/docs/project-memory/shared-memory/development-workflow.md +++ b/docs/project-memory/shared-memory/development-workflow.md @@ -120,9 +120,6 @@ AGC Rust 两条 lane、crates、smoke、Backend 和桌面壳测试使用镜像 `.gitea/workflows/project-ci.yml` 的客户端门禁拆成 lane 与功能 job,每个 job 只预热自己会构建的那几份依赖:`AI game creator shell Rust lane 1/2`、`lane 2/2` 各自预取一次 AGC 壳 manifest,并顺序运行两片 Rust bin 单测;`AI game creator shell Rust smoke` 同样只预取 AGC 壳 manifest(`agent-run` smoke 会用 `src-tauri/Cargo.toml` spawn `cargo run`),`AI game creator shell Rust crates` 预取 `server-rs/Cargo.toml` 与独立 crate,`Native shell tests` 预取桌面壳与 AGC 壳 manifest,`AI game creator shell web tests` 不触碰 Cargo,不预热。两条 Rust lane 与 smoke job 必须在编译前通过 `scripts/ci-npm-ci-with-retry.sh` 执行根 `npm ci`:AGC 壳的 `build.rs` 会从 `node_modules` 准备 Claude Agent SDK 与目标平台原生运行时,镜像中的 npm 下载缓存不能替代安装。人工 `scripts/build-gitea-rust-cache.sh` bootstrap 同样在首次编译 AGC 壳前安装 npm 依赖;只有不构建壳的 crates job 继续省略 npm 安装。两个被 `server-rs/Cargo.toml` 排除、且没有提交 `Cargo.lock` 的独立 crate(`agent-runtime-core`、`agent-runtime-orchestration`)只能在 `AI game creator shell Rust crates` 里用不带锁标志的 fetch。AGC 壳的 bin target 单测(约 2466 条)由 `apps/ai-game-creator-shell/scripts/run-rust-shell-test-shards.mjs` 编译后按 `--list` 名单分 4 片:每次分片调用用 `--shard-index=` 只跑自己那片,片内保持 `--test-threads=1` 并使用独立 `TMPDIR`;两条 lane 之间并发,lane 内顺序运行两片,避免重复依赖预热和同一容器内多进程争抢。不要改回「一个 job 内多进程并行这几片」——同一容器里它们会争抢共享 `HOME`、target 目录与固定临时路径,实测比整套串行还慢。每个分片调用都会自校验「片并集等于全集且互斥」,因此改分片规则不会静默漏跑。Backend host workspace tests 使用 `cargo test --locked --workspace --exclude spacetime-module --no-fail-fast`,避免 `spacetime-module` 的 `spacetime-types` feature 统一污染普通领域 crate 的 host 测试;随后单独执行 `cargo test --locked -p spacetime-module --no-fail-fast`,由 `spacetime-module/src/active.rs` 在 host 测试构建期间提供仅测试期的 SpacetimeDB ABI 链接支持,使该 crate 的纯单元测试也纳入 Backend 门禁。`spacetime-module` 的 reducer / procedure 运行时行为仍必须通过真实 SpacetimeDB runtime/integration harness 验证,host 链接支持不得被当作运行时替身。Backend 另外执行 `cargo check --locked -p spacetime-module` 验证模块源码。AGC 壳检查还会运行 `platform-llm` 与 `shared-contracts` 的 server-rs workspace 测试,这些命令以及 AGC 壳测试必须带 `--locked`,避免在测试阶段重新解析 registry index;锁文件发生变化时应先更新受信任 CI 镜像缓存,再重跑门禁。 -根 `vitest.config.ts` 固定 `test.silent: true`(`--silent` 的配置形态,silent is gold):成功用例不回放被测代码写进 stdout / stderr 的内容(React `act(...)` 警告、`scripts/dev*.test.ts` 的 dev 调度日志等),CI 日志只保留每个文件一行进度、最终汇总与失败用例的断言摘要加源码位置。`vitest.frontend-ci.config.ts` 通过 `mergeConfig` 继承该设置,AGC 与 repository checks 直接使用的根配置同样生效——所以不要改成只对某一个配置生效,那会让另一条 CI 测试重新刷屏。本机排查需要完整 console 输出时用 `vitest run --silent=false` 覆盖,不要改回 `silent: false`。`scripts/project-ci-workflow.test.ts` 有守护用例钉住这条口径。 - - ## AGC 测试类型门禁 AGC 测试(`apps/ai-game-creator-shell/tests/`)与生产 `src/` 同受类型门禁。`apps/ai-game-creator-shell/tsconfig.tests.json` 以 `include: ["src", "tests", "vite.config.ts"]`、`types: ["vite/client", "vitest/globals"]`、`allowImportingTsExtensions`、`allowJs` 全量覆盖:新增测试文件自动纳入,不存在基线、豁免名单或 `@ts-nocheck`。入口 `npm --prefix apps/ai-game-creator-shell run check:tests:types`(`tsc -p tsconfig.tests.json --noEmit`)已并入该 app 的 `typecheck`,因此 `npm run agc:typecheck`、`npm run ai-game-creator-shell:check:web` 与 CI 的 `AI game creator shell web tests` 都会执行。修测试只做类型层改动,不改断言与行为;禁止 `@ts-ignore`、`as any`,仅当 mock 泛型函数确实不可兼容时才允许带中文注释的 `as unknown as`。 diff --git a/package.json b/package.json index ca24fab4d..1a9caaae3 100644 --- a/package.json +++ b/package.json @@ -189,7 +189,7 @@ "agc:bundled-resources:sync": "npm --prefix apps/ai-game-creator-shell run bundled-resources:sync", "agc:bundled-resources:prepare": "npm --prefix apps/ai-game-creator-shell run bundled-resources:prepare --", "agc:bundled-resources:test": "npm --prefix apps/ai-game-creator-shell run bundled-resources:test --", - "agc:plugins:test": "node --test plugins/agc-cocos-editor/src/entry.test.mjs plugins/agc-unity-editor/src/entry.test.mjs plugins/agc-godot-editor/src/entry.test.mjs", + "agc:plugins:test": "node --test --test-reporter=dot plugins/agc-cocos-editor/src/entry.test.mjs plugins/agc-unity-editor/src/entry.test.mjs plugins/agc-godot-editor/src/entry.test.mjs", "agc:plugins:native-test": "cargo test --manifest-path plugins/agc-cocos-editor/native/cocos-editor-bridge/Cargo.toml && cargo test --locked --manifest-path plugins/agc-unity-editor/native/unity-editor-bridge/Cargo.toml && cargo test --locked --manifest-path plugins/agc-godot-editor/native/godot-editor-bridge/Cargo.toml", "agc:plugins:check": "npm run agc:plugins:test && npm run agc:plugins:native-test", "agc:check": "npm run ai-game-creator-shell:check", diff --git a/scripts/build-gitea-rust-cache.sh b/scripts/build-gitea-rust-cache.sh index 13ff337c9..75932951f 100644 --- a/scripts/build-gitea-rust-cache.sh +++ b/scripts/build-gitea-rust-cache.sh @@ -75,7 +75,7 @@ set -euo pipefail rustc -vV > /opt/genarrative-ci/rust-cache/rustc.txt export GITHUB_ENV=/tmp/rust-cache.env CARGO_INCREMENTAL=0 CARGO_BUILD_JOBS=4 CI=true # sccache 对 CARGO_*(除 jobserver/jobs 等特例)参与 hash,必须与 workflow 对齐。 -export CARGO_HTTP_MULTIPLEXING=false CARGO_NET_RETRY=10 CARGO_TERM_COLOR=always +export CARGO_HTTP_MULTIPLEXING=false CARGO_NET_RETRY=10 CARGO_TERM_COLOR=always CARGO_TERM_QUIET=true bash /tmp/ci-rust-cache.sh prepare set -a source "${GITHUB_ENV}" diff --git a/scripts/check-native-shells.mjs b/scripts/check-native-shells.mjs index 4dcf9550b..84e7c5125 100644 --- a/scripts/check-native-shells.mjs +++ b/scripts/check-native-shells.mjs @@ -5081,7 +5081,7 @@ for (const step of steps) { continue; } - console.log(`[check:native-shells] ${step.label}`); + // 成功不打印进度标签;只有在失败时才知道是哪个 step,避免每个 step 一行刷屏。 const result = spawnSync(step.command, step.args, { cwd: process.cwd(), stdio: 'inherit', @@ -5102,6 +5102,9 @@ for (const step of steps) { } if ((result.status ?? 0) !== 0) { + console.error( + `[check:native-shells] ${step.label} failed (exit=${result.status})`, + ); process.exit(result.status ?? 1); } } diff --git a/scripts/project-ci-workflow.test.ts b/scripts/project-ci-workflow.test.ts index 923c6a6ac..015533b15 100644 --- a/scripts/project-ci-workflow.test.ts +++ b/scripts/project-ci-workflow.test.ts @@ -75,12 +75,6 @@ const jobsWithoutNpmInstall: readonly string[] = [ const rootPackageJson = JSON.parse( readFileSync(resolve(process.cwd(), 'package.json'), 'utf8'), ) as { scripts?: Record }; -// 前端与 AGC 的 CI 测试都跑根 vitest 配置(`vitest.frontend-ci.config.ts` 也 merge 它), -// 这里钉住「成功用例静默」,避免有人顺手删掉后 CI 日志重新被 act 警告与 dev 日志刷屏。 -const rootVitestConfig = readFileSync( - resolve(process.cwd(), 'vitest.config.ts'), - 'utf8', -); const nativeShellGateScript = readFileSync( resolve(process.cwd(), 'scripts/check-native-shells.mjs'), 'utf8', @@ -546,10 +540,6 @@ describe('project CI workflow', () => { ).toHaveLength(2); }); - it('keeps passing CI tests silent so only failures reach the log', () => { - expect(rootVitestConfig).toMatch(/^\s*silent:\s*true,$/mu); - }); - it('keeps frontend, operations fixture, and native shell gates in dedicated jobs', () => { const frontendJob = jobSection('frontend-tests'); expect(frontendJob).toMatch(/^ {8}run: npm run test:ci:frontend$/mu);