mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-03 05:08:53 +00:00
fix(ci): стабилизировать релизный proof на main (#619)
Issue: #619 User-Visible: no
This commit is contained in:
@@ -133,6 +133,8 @@ test('#541 AC: full red followed by light green still blocks release; a later fu
|
||||
assert.equal(selectCiProofVerdict([light, red]).status, 'failed');
|
||||
const newerFull = evaluateCiProof({ ...proofFixture({ id: 22 }), policy: CI_PROOF_POLICIES.release });
|
||||
assert.equal(selectCiProofVerdict([newerFull, light, red]).status, 'green');
|
||||
assert.equal(selectCiProofVerdict([red, newerFull]).status, 'green',
|
||||
'#619: a failed duplicate cannot hide a complete green proof for the same candidate');
|
||||
});
|
||||
|
||||
test('#601 AC3: release policy accepts a full proof without requested mutants; light stays stale; review/merge still demand them', () => {
|
||||
|
||||
@@ -111,6 +111,18 @@ test('#541: a later complete full proof refreshes an older red release candidate
|
||||
assert.equal(verdict.url, 'https://run/12');
|
||||
});
|
||||
|
||||
test('#619: any complete green proof on the exact SHA survives a newer failed duplicate', async () => {
|
||||
const older = proofContext({ id: 13 });
|
||||
const newer = proofContext({ id: 14, conclusion: 'failure' });
|
||||
const contexts = new Map([[13, older.context], [14, newer.context]]);
|
||||
const verdict = await classifyValidateProofs({
|
||||
runs: [newer.run, older.run], repo: 'x/y', sha: SHA, tree: TREE, token: 'x',
|
||||
loadContext: async (run) => contexts.get(run.databaseId),
|
||||
});
|
||||
assert.equal(verdict.status, 'green');
|
||||
assert.equal(verdict.url, 'https://run/13');
|
||||
});
|
||||
|
||||
test('release gate can target the dedicated exact-SHA performance workflow', () => {
|
||||
assert.equal(
|
||||
workflowRunsUrl({ repo: 'Matysh/houseplan-card', workflow: 'performance.yml', sha: 'abc/123' }),
|
||||
@@ -121,7 +133,7 @@ test('release gate can target the dedicated exact-SHA performance workflow', ()
|
||||
test('#541: the release documents describe proof semantics', () => {
|
||||
const development = readFileSync(new URL('../docs/DEVELOPMENT.md', import.meta.url), 'utf8');
|
||||
assert.match(development, /requires a complete Validate proof for its SHA and\nGit tree/);
|
||||
assert.match(development, /cancelled or light run is not a release verdict and cannot hide an older full\nfailure/);
|
||||
assert.match(development, /Any complete green full proof on the exact SHA\n\s*is sufficient/);
|
||||
assert.match(development, /Review, merge and release use the\nsame `missing` \/ `pending` \/ `cancelled` \/ `stale` \/ `failed` state machine/);
|
||||
const performance = readFileSync(new URL('../demo/performance/README.md', import.meta.url), 'utf8');
|
||||
assert.match(performance, /latest\nnon-cancelled run on the SHA/);
|
||||
|
||||
@@ -167,9 +167,9 @@ test('классификация опирается на завершённый
|
||||
assert.match(changes, /actions: read/, 'чтение прогонов требует прав');
|
||||
// У PR диапазон задан событием, считать его нечем и незачем.
|
||||
assert.match(changes, /if: github\.event_name != 'pull_request'/);
|
||||
// На dev классификации нет вовсе — там всё true; шаг там считает базу
|
||||
// диапазона для другого потребителя (#388), и это разные выходы.
|
||||
assert.match(changes, /dev: без фильтров, всё true/);
|
||||
// На dev/main классификации нет вовсе — там всё true; шаг там считает базу
|
||||
// диапазона для другого потребителя (#388, #619), и это разные выходы.
|
||||
assert.match(changes, /dev\/main: без фильтров, всё true/);
|
||||
assert.match(changes, /--name=range_base/);
|
||||
// Пустая база означает «доказательства нет» и обязана вести к полному
|
||||
// прогону, а не к пустому диффу, который выглядел бы как «ничего не менялось».
|
||||
@@ -178,6 +178,23 @@ test('классификация опирается на завершённый
|
||||
'без базы классификация обязана раскрываться в полный прогон');
|
||||
});
|
||||
|
||||
test('#619: Validate на main раскрывает полный набор так же, как на dev', () => {
|
||||
const workflow = read('validate.yml');
|
||||
const changes = workflow.slice(
|
||||
workflow.indexOf('\n changes:\n'), workflow.indexOf('\n reuse:\n'),
|
||||
);
|
||||
const integrationRefs = /\[ "\$REF" = "refs\/heads\/dev" \] \|\| \[ "\$REF" = "refs\/heads\/main" \]/g;
|
||||
assert.equal(changes.match(integrationRefs)?.length, 2,
|
||||
'base и classify обязаны одинаково распознавать dev/main');
|
||||
assert.match(changes, /dev\/main: без фильтров, всё true/);
|
||||
|
||||
const frontend = workflow.slice(
|
||||
workflow.indexOf('\n frontend:\n'), workflow.indexOf('\n smoke:\n'),
|
||||
);
|
||||
assert.match(frontend, integrationRefs,
|
||||
'no-new-any на main обязан судить диапазон от доказанного предка, а не HEAD..HEAD');
|
||||
});
|
||||
|
||||
test('перф-смок добавляет профиль ровно при своём выходе changes (#473 AC3)', () => {
|
||||
const workflow = read('validate.yml');
|
||||
const changes = workflow.slice(workflow.indexOf('\n changes:\n'), workflow.indexOf('\n reuse:\n'));
|
||||
|
||||
Reference in New Issue
Block a user