Files
HMDesign/scripts/verify-quality-regression.mjs
T

45 lines
4.0 KiB
JavaScript

import fs from 'node:fs';
import path from 'node:path';
import { spawnSync } from 'node:child_process';
const output = path.resolve('_local/quality-20261010');
fs.mkdirSync(output, { recursive: true });
const storybookBin = JSON.parse(fs.readFileSync('node_modules/storybook/package.json')).bin;
const jobs = [
['THEME_DEFAULTS', 'scripts/theme-defaults.mjs', ['--check']],
['TYPECHECK', 'node_modules/typescript/bin/tsc', ['-b']],
['UI_TYPECHECK', 'node_modules/typescript/bin/tsc', ['-p', 'packages/ui/tsconfig.json']],
['CENTER_TYPECHECK', 'node_modules/typescript/bin/tsc', ['-p', 'packages/center-graphic/tsconfig.json']],
['GENERATED_TYPECHECK', 'node_modules/typescript/bin/tsc', ['-p', 'examples/ai-quality/tsconfig.json']],
['PRODUCTION_BUILD', 'node_modules/vite/bin/vite.js', ['build']],
['DASHBOARD_BUILD', 'node_modules/vite/bin/vite.js', ['build', '--config', 'vite.dashboard-export.config.ts']],
['DASHBOARD_FINALIZE', 'scripts/finalize-dashboard-export.mjs', []],
['RECRUIT_BUILD', 'node_modules/vite/bin/vite.js', ['build', '--config', 'vite.recruit-export.config.ts']],
['PUBLISHER_BUILD', 'node_modules/vite/bin/vite.js', ['build', '--config', 'examples/publisher-list/vite.config.ts']],
['STORYBOOK_BUILD', path.join('node_modules/storybook', typeof storybookBin === 'string' ? storybookBin : storybookBin.storybook), ['build', '-o', 'storybook-static', '--disable-telemetry']],
['GUARD_TEST', null, ['--test', 'scripts/ai-generation-guard.test.mjs']],
['EVIDENCE_TEST', null, ['--test', 'scripts/guard-evidence.test.mjs']],
['COMPONENT_TEST', null, ['--test', 'scripts/publisher-components.test.mjs']],
['THEME_TEST', null, ['--test', 'scripts/theme-verification.test.mjs']],
['DOC_LINKS', 'scripts/check-doc-links.mjs', []],
['TOKEN_INVENTORY', 'scripts/public-theme-tokens.mjs', []],
['GUARD_FULL_SCREEN', 'scripts/ai-generation-guard.mjs', ['--target', '.', '--scope', 'FULL_SCREEN', '--mode', 'GNB_ONLY', '--result', 'index.html', '--json']],
['GUARD_PARTIAL', 'scripts/ai-generation-guard.mjs', ['--target', '.', '--scope', 'PARTIAL', '--mode', 'GNB_ONLY', '--files', 'src/index.css,tailwind.css', '--result', 'index.html', '--json']],
['GUARD_GENERATED_PARTIAL', 'scripts/ai-generation-guard.mjs', ['--target', 'examples/ai-quality/01', '--scope', 'PARTIAL', '--mode', 'GNB_ONLY', '--files', '../shared/SearchList.tsx', '--result', 'index.html', '--json']],
['GUARD_STORYBOOK', 'scripts/ai-generation-guard.mjs', ['--target', '.', '--scope', 'FULL_SCREEN', '--profile', 'STORYBOOK', '--json']],
['GUARD_STORYBOOK_PARTIAL', 'scripts/ai-generation-guard.mjs', ['--target', '.', '--scope', 'PARTIAL', '--profile', 'STORYBOOK', '--files', 'src/patterns/filter-bar.stories.tsx', '--json']],
];
const selected = process.argv.slice(2);
const results = [];
for (const [name, script, args] of jobs.filter(j => !selected.length || selected.includes(j[0]))) {
const begin = Date.now();
const r = spawnSync(process.execPath, [...(script ? [script] : []), ...args], { encoding: 'utf8', maxBuffer: 25 * 1024 * 1024 });
fs.writeFileSync(path.join(output, `${name}.stdout.log`), r.stdout ?? '');
fs.writeFileSync(path.join(output, `${name}.stderr.log`), r.stderr ?? '');
let report;
if (name.startsWith('GUARD_') && name !== 'GUARD_TEST') { try { report = JSON.parse(r.stdout); } catch {} }
const item = { name, command: [process.execPath, ...(script ? [script] : []), ...args], exit: r.status, result: report?.status ?? (r.status === 0 ? 'PASS' : 'FAIL'), ...(report ? { staticStatus: report.staticStatus, issueCounts: Object.fromEntries([...new Set(report.issues.map(i => i.code))].map(code => [code, report.issues.filter(i => i.code === code).length])) } : {}), durationMs: Date.now() - begin, error: r.error?.message };
results.push(item); console.log(JSON.stringify(item));
}
fs.writeFileSync(path.join(output, selected.length ? `regression-${selected.join('-')}.json` : 'regression.json'), JSON.stringify(results, null, 2));
if (results.some(r => r.exit !== 0)) process.exitCode = 1;