mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-16 13:03:31 +08:00
The live baseline previously accepted provider UUIDs, which made the gate hard to run on another contributor's machine. Add a local provider listing command and resolve quality-gate targets from stable provider-name selectors while keeping UUIDs and current runtime support. Constraint: Provider configuration is local machine state under CLAUDE_CONFIG_DIR and must not expose API keys. Rejected: Require contributors to inspect providers.json manually | too error-prone and leaks implementation detail into the workflow Confidence: high Scope-risk: narrow Directive: Keep live-provider baseline selection copyable from quality:providers before adding more live test lanes. Tested: bun test scripts/quality-gate/providerTargets.test.ts Tested: bun test scripts/quality-gate/*.test.ts scripts/quality-gate/baseline/*.test.ts Tested: bun run quality:providers Tested: bun run quality:gate --mode baseline --dry-run --provider-model codingplan:main --provider-model minimax:main Tested: bun run quality:gate --mode baseline --dry-run --provider-model custom:haiku Tested: bun run quality:gate --mode pr --dry-run Tested: bun run check:server
80 lines
2.3 KiB
TypeScript
80 lines
2.3 KiB
TypeScript
#!/usr/bin/env bun
|
|
|
|
import { runQualityGate } from './runner'
|
|
import { formatProviderTargets, loadProviderIndex, parseBaselineTargetValues } from './providerTargets'
|
|
import type { BaselineTarget, QualityGateMode } from './types'
|
|
|
|
function parseArgs(argv: string[]) {
|
|
const args = new Map<string, Array<string | boolean>>()
|
|
|
|
for (let index = 0; index < argv.length; index += 1) {
|
|
const arg = argv[index]
|
|
if (!arg.startsWith('--')) {
|
|
continue
|
|
}
|
|
|
|
const next = argv[index + 1]
|
|
if (next && !next.startsWith('--')) {
|
|
args.set(arg, [...(args.get(arg) ?? []), next])
|
|
index += 1
|
|
} else {
|
|
args.set(arg, [...(args.get(arg) ?? []), true])
|
|
}
|
|
}
|
|
|
|
return args
|
|
}
|
|
|
|
function firstArg(args: Map<string, Array<string | boolean>>, name: string) {
|
|
return args.get(name)?.[0]
|
|
}
|
|
|
|
function hasFlag(args: Map<string, Array<string | boolean>>, name: string) {
|
|
return args.has(name)
|
|
}
|
|
|
|
function readMode(value: string | boolean | undefined): QualityGateMode {
|
|
if (value === 'pr' || value === 'baseline' || value === 'release') {
|
|
return value
|
|
}
|
|
throw new Error('Usage: bun run quality:gate --mode <pr|baseline|release> [--dry-run] [--allow-live] [--provider-model provider:model[:label]]')
|
|
}
|
|
|
|
function readBaselineTargets(args: Map<string, Array<string | boolean>>): BaselineTarget[] {
|
|
const values = (args.get('--provider-model') ?? [])
|
|
.filter((value): value is string => typeof value === 'string')
|
|
|
|
return parseBaselineTargetValues(values)
|
|
}
|
|
|
|
const args = parseArgs(process.argv.slice(2))
|
|
|
|
if (hasFlag(args, '--list-providers')) {
|
|
console.log(formatProviderTargets(loadProviderIndex()))
|
|
process.exit(0)
|
|
}
|
|
|
|
const mode = readMode(firstArg(args, '--mode'))
|
|
const dryRun = hasFlag(args, '--dry-run')
|
|
const allowLive = hasFlag(args, '--allow-live')
|
|
const artifactsDir = typeof firstArg(args, '--artifacts-dir') === 'string'
|
|
? String(firstArg(args, '--artifacts-dir'))
|
|
: undefined
|
|
const baselineTargets = readBaselineTargets(args)
|
|
|
|
const { report, outputDir } = await runQualityGate({
|
|
mode,
|
|
dryRun,
|
|
allowLive,
|
|
baselineTargets,
|
|
rootDir: process.cwd(),
|
|
artifactsDir,
|
|
})
|
|
|
|
console.log(`Quality gate report: ${outputDir}/report.md`)
|
|
console.log(`Summary: passed=${report.summary.passed} failed=${report.summary.failed} skipped=${report.summary.skipped}`)
|
|
|
|
if (report.summary.failed > 0) {
|
|
process.exit(1)
|
|
}
|