cc-haha/scripts/pr/run-server-tests.ts
程序员阿江(Relakkes) 435e4ccc9f ci: harden deterministic PR quality gates
Route required checks by changed surface, add offline provider and chat contracts, and keep fork PRs independent of live credentials. Layer agent guidance by subtree and enforce a compact instruction budget.

Tested: bun run check:policy
Confidence: high
Scope-risk: broad
2026-07-10 20:29:01 +08:00

58 lines
1.4 KiB
TypeScript

#!/usr/bin/env bun
import { readdirSync, statSync } from 'node:fs'
import { join, relative, sep } from 'node:path'
import { loadQuarantineManifest, quarantinedPathSet } from '../quality-gate/quarantine'
const root = process.cwd()
// The root runtime is wider than src/server: CLI commands, query handling,
// shared services, tools, and utils all ship in the same Bun product. Keeping a
// single src root prevents approved CLI/core changes from receiving a green
// server check without their existing tests ever being discovered.
const roots = ['src']
const excludedFiles = quarantinedPathSet(loadQuarantineManifest())
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)