cc-haha/scripts/pr/test-environment.ts
程序员阿江(Relakkes) 173d6a84fc fix(ci): isolate deterministic PR test evidence
Run required server and contract suites in credential-free sandboxes, fail closed on incomplete coverage or test output, and preserve the desktop active-turn permission guard across stale tab interactions.\n\nTested: bun run check:policy (115 pass); bun run check:server (1605 pass before final runner evidence check); bun run check:desktop; bun run check:provider-contract; bun run check:chat-contract\nConfidence: high\nScope-risk: broad
2026-07-10 22:59:02 +08:00

84 lines
2.1 KiB
TypeScript

import { mkdirSync } from 'node:fs'
import { join } from 'node:path'
const SAFE_INHERITED_ENV_NAMES = new Set([
'CI',
'COMSPEC',
'GITHUB_ACTIONS',
'HOME',
'LANG',
'LC_ALL',
'LC_CTYPE',
'NUMBER_OF_PROCESSORS',
'OS',
'PATH',
'PATHEXT',
'PROCESSOR_ARCHITECTURE',
'PROCESSOR_IDENTIFIER',
'RUNNER_ARCH',
'RUNNER_OS',
'SHELL',
'SYSTEMROOT',
'TEMP',
'TERM',
'TMP',
'TMPDIR',
'TZ',
'USERPROFILE',
'WINDIR',
])
export function createOfflineTestEnvironment(
overrides: Record<string, string>,
source: NodeJS.ProcessEnv = process.env,
): Record<string, string> {
const environment: Record<string, string> = {}
for (const safeName of SAFE_INHERITED_ENV_NAMES) {
const entry = Object.entries(source).find(([name]) => name.toUpperCase() === safeName)
if (entry?.[1] !== undefined) {
environment[safeName] = entry[1]
}
}
return {
...environment,
...overrides,
}
}
export function createSandboxedTestEnvironment(
sandboxHome: string,
overrides: Record<string, string> = {},
source: NodeJS.ProcessEnv = process.env,
) {
const configHome = join(sandboxHome, '.config')
const dataHome = join(sandboxHome, '.local', 'share')
const cacheHome = join(sandboxHome, '.cache')
const stateHome = join(sandboxHome, '.local', 'state')
const tempHome = join(sandboxHome, 'tmp')
for (const directory of [configHome, dataHome, cacheHome, stateHome, tempHome]) {
mkdirSync(directory, { recursive: true })
}
return createOfflineTestEnvironment({
HOME: sandboxHome,
USERPROFILE: sandboxHome,
APPDATA: configHome,
LOCALAPPDATA: join(sandboxHome, '.local'),
XDG_CONFIG_HOME: configHome,
XDG_DATA_HOME: dataHome,
XDG_CACHE_HOME: cacheHome,
XDG_STATE_HOME: stateHome,
CODEX_HOME: join(sandboxHome, '.codex'),
GH_CONFIG_DIR: join(configHome, 'gh'),
CLAUDE_CONFIG_DIR: join(sandboxHome, '.claude'),
TEMP: tempHome,
TMP: tempHome,
TMPDIR: tempHome,
BUN_OPTIONS: '--no-env-file',
CC_HAHA_DISABLE_TERMINAL_SHELL_ENV: '1',
NODE_ENV: 'test',
...overrides,
}, source)
}