mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-09-10 22:43:40 +00:00
* chore(ci): reduce CI runner-minutes by consolidating parity and narrowing cross-platform
Scope-resolution parity previously spawned 9 separate GitHub Actions jobs
(one per migrated language), each doing full checkout + npm ci + build for
a single test file. Consolidate into one job running scripts/run-parity.ts
which loops through all migrated languages sequentially — same coverage,
~45 fewer runner-minutes of redundant setup per PR.
Cross-platform (Windows/macOS) previously ran the full 373-file test suite.
Narrow to 45 platform-sensitive files (native LadybugDB, process spawning,
path separators, worker threads, filesystem behavior). Full suite still runs
on Ubuntu with coverage.
Also adds 2 missing lbug integration tests (lbug-orphan-sidecar-recovery,
lbug-readonly-init) to the sequential lbug-db vitest project where they
belong, and rewrites TESTING.md to document all test lanes.
* fix: address code review findings on parity and cross-platform scripts
- Capture stderr in run-parity.ts (vitest writes diagnostics to stderr)
- Lower per-invocation timeout from 5min to 60s to stay within CI job limit
- Add --language flag validation (error on missing value)
- Add timeout diagnostic to run-cross-platform.ts catch block
- Add analyze-wal-checkpoint-failure.test.ts to lbug-db sequential project
- Expand cross-platform list: parser-loader, pipeline, pipeline-graph-golden,
setup-skills, cli/tool-no-index-stderr (51 files, was 45)
* fix: add shell:true for Windows npx resolution and simplify fs import
execFileSync('npx', ...) fails with ENOENT on Windows because npx is
npx.cmd — shell:true resolves this. Also replaces dynamic await
import('fs') with static import, and fixes timeout detection to use
err.killed instead of err.code.
* fix(ci): raise parity per-invocation timeout to 120s and job timeout to 30min
TypeScript and C++ resolver tests take 60-90s on CI runners, exceeding
the 60s per-invocation timeout. Raise to 120s. Also bump the job-level
timeout from 25 to 30 minutes for margin (realistic total is ~11 min).
* fix(ci): raise parity per-invocation timeout to 180s for C++ resolver
C++ resolver tests take 130-150s on CI runners due to template
metaprogramming, ADL, and SFINAE fixture volume. 120s was still too
tight. Realistic total across all 9 languages is ~12 min, well under
the 30-min job timeout.
* fix(ci): use stdio inherit for parity — no per-invocation timeout
Switch from piped stdio with per-invocation timeouts to stdio: 'inherit'.
Vitest output streams to CI console in real time, making failures
immediately visible. The CI job-level timeout (30 min) is the only
guard — no more artificial per-invocation timeouts that cut off slow
resolver tests like C++ (which genuinely takes 3+ minutes).
---------
Co-authored-by: Test <test@example.com>
128 lines
4 KiB
TypeScript
128 lines
4 KiB
TypeScript
/**
|
||
* Consolidated scope-resolution parity runner.
|
||
*
|
||
* Replaces the per-language matrix in ci-scope-parity.yml with a single
|
||
* job that runs all migrated languages sequentially in one process. This
|
||
* eliminates 8× redundant checkout + npm ci + build cycles (the old
|
||
* workflow created a separate GitHub Actions job per language).
|
||
*
|
||
* For each language in MIGRATED_LANGUAGES:
|
||
* 1. Run its resolver test with REGISTRY_PRIMARY_<LANG>=0 (legacy DAG)
|
||
* 2. Run its resolver test with REGISTRY_PRIMARY_<LANG>=1 (registry-primary)
|
||
*
|
||
* Both modes must pass. Failures are collected and reported at the end
|
||
* so all regressions are visible in a single CI run (equivalent to the
|
||
* old workflow's fail-fast: false behavior).
|
||
*
|
||
* Vitest output streams to the console in real time (stdio: 'inherit')
|
||
* so CI logs show the actual test output directly. No per-invocation
|
||
* timeout — the CI job-level timeout (30 min) is the outer guard.
|
||
*
|
||
* Usage:
|
||
* npx tsx scripts/run-parity.ts
|
||
* npx tsx scripts/run-parity.ts --language python # single language
|
||
*/
|
||
|
||
import { execFileSync } from 'child_process';
|
||
import fs from 'fs';
|
||
import path from 'path';
|
||
import { fileURLToPath } from 'url';
|
||
import { MIGRATED_LANGUAGES } from '../src/core/ingestion/registry-primary-flag.js';
|
||
|
||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||
const ROOT = path.resolve(__dirname, '..');
|
||
|
||
interface ParityFailure {
|
||
lang: string;
|
||
mode: 'legacy' | 'registry-primary';
|
||
}
|
||
|
||
function envVarName(slug: string): string {
|
||
return `REGISTRY_PRIMARY_${slug.toUpperCase().replace(/-/g, '_')}`;
|
||
}
|
||
|
||
function testFilePath(slug: string): string {
|
||
return `test/integration/resolvers/${slug}.test.ts`;
|
||
}
|
||
|
||
function runVitest(testFile: string, env: Record<string, string>): boolean {
|
||
try {
|
||
execFileSync('npx', ['vitest', 'run', testFile], {
|
||
cwd: ROOT,
|
||
env: { ...process.env, ...env },
|
||
stdio: 'inherit',
|
||
shell: true,
|
||
});
|
||
return true;
|
||
} catch {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
// Parse CLI args
|
||
const args = process.argv.slice(2);
|
||
const langFlag = args.indexOf('--language');
|
||
const singleLang = langFlag >= 0 ? args[langFlag + 1] : undefined;
|
||
|
||
if (langFlag >= 0 && singleLang === undefined) {
|
||
console.error('--language requires a value');
|
||
process.exit(1);
|
||
}
|
||
|
||
const languages = singleLang ? [singleLang] : [...MIGRATED_LANGUAGES].map(String);
|
||
|
||
// Verify test files exist before running
|
||
const missingFiles: string[] = [];
|
||
for (const lang of languages) {
|
||
const file = path.resolve(ROOT, testFilePath(lang));
|
||
try {
|
||
fs.accessSync(file);
|
||
} catch {
|
||
missingFiles.push(`${testFilePath(lang)} (${lang})`);
|
||
}
|
||
}
|
||
|
||
if (missingFiles.length > 0) {
|
||
console.error('Missing resolver test files:');
|
||
for (const f of missingFiles) console.error(` ${f}`);
|
||
process.exit(1);
|
||
}
|
||
|
||
console.log(`Scope-resolution parity: ${languages.length} language(s)`);
|
||
console.log(`Languages: ${languages.join(', ')}\n`);
|
||
|
||
const failures: ParityFailure[] = [];
|
||
|
||
for (const lang of languages) {
|
||
const file = testFilePath(lang);
|
||
const envVar = envVarName(lang);
|
||
|
||
console.log(`\n── ${lang} — legacy DAG (${envVar}=0) ──`);
|
||
if (!runVitest(file, { [envVar]: '0' })) {
|
||
failures.push({ lang, mode: 'legacy' });
|
||
}
|
||
|
||
console.log(`\n── ${lang} — registry-primary (${envVar}=1) ──`);
|
||
if (!runVitest(file, { [envVar]: '1' })) {
|
||
failures.push({ lang, mode: 'registry-primary' });
|
||
}
|
||
}
|
||
|
||
// Summary
|
||
const total = languages.length * 2;
|
||
const passed = total - failures.length;
|
||
|
||
console.log('\n═══════════════════════════════════════');
|
||
console.log('PARITY SUMMARY');
|
||
console.log('═══════════════════════════════════════');
|
||
console.log(`Passed: ${passed}/${total}`);
|
||
|
||
if (failures.length > 0) {
|
||
console.log(`\nFAILURES (${failures.length}):`);
|
||
for (const f of failures) {
|
||
console.log(` ✗ ${f.lang} [${f.mode}]`);
|
||
}
|
||
process.exit(1);
|
||
}
|
||
|
||
console.log('\nAll parity checks passed.');
|