fix(release-gate): skip duplicate CI work and stop live LLM blowups
Shared paths like db.mjs were pulling PAGE/DATA live agent suites into every hotfix. Keep those cases for actual page-data changes, resume passed suites on the same artifact, and fail fast on Docker/port issues instead of rerunning 100+ scenarios. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+54
-5
@@ -6,7 +6,14 @@ import { assertPortalRuntimePath, hashArtifact, inspectPortalRuntime } from './a
|
||||
import { loadScenarioCatalog } from './catalog.mjs';
|
||||
import { AUTOMATION_SUITES, validateAutomationSuites } from './coverage.mjs';
|
||||
import { selectImpactScenarios } from './impact.mjs';
|
||||
import { preflightImpactSuites } from './preflight.mjs';
|
||||
import { loadActiveRegressionCorpus } from './regression-corpus.mjs';
|
||||
import {
|
||||
REPOSITORY_CHECK_IDS,
|
||||
carryForwardScenario,
|
||||
findImpactResumeReport,
|
||||
shouldRerunImpactSuite,
|
||||
} from './resume.mjs';
|
||||
import {
|
||||
buildIncrementalReport,
|
||||
findCarryForwardBaseline,
|
||||
@@ -419,24 +426,61 @@ export async function executeImpactReleaseGate(options) {
|
||||
const suites = AUTOMATION_SUITES.filter(
|
||||
(suite) => suite.scenarios.some((scenarioId) => selectedIds.has(scenarioId)),
|
||||
);
|
||||
const resume = await findImpactResumeReport({
|
||||
reportRoot: options.reportRoot,
|
||||
artifactSha256: artifact.sha256,
|
||||
commitSha,
|
||||
});
|
||||
let changedPathsSincePrevious = [];
|
||||
if (resume?.commitSha && resume.commitSha !== commitSha) {
|
||||
try {
|
||||
changedPathsSincePrevious = await listChangedPathsBetween(resume.commitSha, commitSha);
|
||||
} catch {
|
||||
changedPathsSincePrevious = ['release-gate/coverage.mjs'];
|
||||
}
|
||||
}
|
||||
const suitesToRun = suites.filter((suite) => shouldRerunImpactSuite({
|
||||
suite,
|
||||
selectedIds,
|
||||
previousReport: resume?.report ?? null,
|
||||
artifactSha256: artifact.sha256,
|
||||
commitSha,
|
||||
changedPathsSincePrevious,
|
||||
}));
|
||||
const skippedSuites = suites.filter((suite) => !suitesToRun.includes(suite));
|
||||
const previousById = new Map((resume?.report?.scenarios ?? []).map((scenario) => [scenario.id, scenario]));
|
||||
for (const suite of skippedSuites) {
|
||||
for (const scenarioId of suite.scenarios) {
|
||||
if (!selectedIds.has(scenarioId) || REPOSITORY_CHECK_IDS.has(scenarioId)) continue;
|
||||
const previous = previousById.get(scenarioId);
|
||||
if (!previous) continue;
|
||||
const current = byId.get(scenarioId);
|
||||
Object.assign(current, carryForwardScenario(previous));
|
||||
}
|
||||
}
|
||||
|
||||
if (suitesToRun.length > 0) {
|
||||
await preflightImpactSuites(suitesToRun);
|
||||
}
|
||||
const executions = await runSuitesWithConcurrency(
|
||||
suites,
|
||||
suitesToRun,
|
||||
options.suiteConcurrency,
|
||||
(suite) => runSuite(suite, outputDir, options.timeoutMs),
|
||||
);
|
||||
for (let index = 0; index < suites.length; index += 1) {
|
||||
const suite = suites[index];
|
||||
for (let index = 0; index < suitesToRun.length; index += 1) {
|
||||
const suite = suitesToRun[index];
|
||||
const execution = executions[index];
|
||||
for (const scenarioId of suite.scenarios) {
|
||||
if (!selectedIds.has(scenarioId)) continue;
|
||||
const scenario = byId.get(scenarioId);
|
||||
scenario.status = execution.code === 0 && !execution.timedOut ? 'passed' : 'failed';
|
||||
scenario.reason = scenario.status === 'passed' ? null : 'automation_suite_failed';
|
||||
scenario.evidence.push(
|
||||
scenario.evidence = [
|
||||
`suite=${suite.id}`,
|
||||
`log=${execution.logPath}`,
|
||||
...suite.cases[scenarioId].map((assertedCase) => `asserted_case=${assertedCase}`),
|
||||
);
|
||||
'carried_forward=false',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -457,6 +501,11 @@ export async function executeImpactReleaseGate(options) {
|
||||
startedAt,
|
||||
completedAt,
|
||||
});
|
||||
report.resume = {
|
||||
baseline_commit: resume?.commitSha ?? null,
|
||||
carried_suites: skippedSuites.map((suite) => suite.id),
|
||||
reran_suites: suitesToRun.map((suite) => suite.id),
|
||||
};
|
||||
await writeGateReport(report, outputDir);
|
||||
return { report, outputDir, selection };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user