cc-haha/scripts/pr/run-server-tests.ts
程序员阿江(Relakkes) f6511ab278 Protect release confidence with live agent baselines
The desktop product needs a repeatable local gate that can prove the core Coding Agent loop still works after changes, not only that unit tests pass. This adds a quality-gate runner with PR, baseline, and release modes, structured reports, explicit quarantine metadata, and fixture-based live baseline cases that can run across provider/model targets.

Constraint: Existing check:pr and CI policy behavior must remain usable while the stronger baseline grows around it
Constraint: Default PR gates must not require real model credentials or provider quota
Rejected: Build a standalone QA platform first | too heavy before the baseline task shape is proven
Rejected: Keep unstable server exclusions hardcoded in run-server-tests | hides quarantine policy from reports and future review
Confidence: medium
Scope-risk: moderate
Directive: Expand baseline cases by adding focused fixtures and verifiers; do not make normal PR checks depend on live providers
Tested: bun test scripts/quality-gate/*.test.ts scripts/quality-gate/baseline/*.test.ts
Tested: bun run check:server
Tested: bun run quality:gate --mode baseline --allow-live --provider-model 2944f963-ce75-45b7-bac1-6e4f57df0970:kimi-k2.6:volc-kimi-k2.6 --provider-model 9c78d3df-7fb5-44c7-8436-3a41c3a59231:MiniMax-M2.7-highspeed:minimax-m2.7
Not-tested: desktop UI browser smoke and native release mode in this commit
2026-05-02 13:00:55 +08:00

54 lines
1.1 KiB
TypeScript

#!/usr/bin/env bun
import { readdirSync, statSync } from 'node:fs'
import { join, relative, sep } from 'node:path'
import { quarantinedPathSet } from '../quality-gate/quarantine'
const root = process.cwd()
const roots = ['src/server', 'src/tools', 'src/utils']
const excludedFiles = quarantinedPathSet()
function normalize(path: string) {
return relative(root, path).split(sep).join('/')
}
function walk(path: string, files: string[]) {
const stat = statSync(path)
if (stat.isDirectory()) {
for (const entry of readdirSync(path)) {
walk(join(path, entry), files)
}
return
}
if (!stat.isFile()) {
return
}
const normalized = normalize(path)
if (normalized.endsWith('.test.ts') && !excludedFiles.has(normalized)) {
files.push(normalized)
}
}
const testFiles: string[] = []
for (const testRoot of roots) {
walk(join(root, testRoot), testFiles)
}
testFiles.sort()
if (testFiles.length === 0) {
console.log('No server-side test files found.')
process.exit(0)
}
const proc = Bun.spawn(['bun', 'test', ...testFiles], {
cwd: root,
stdout: 'inherit',
stderr: 'inherit',
})
process.exit(await proc.exited)