mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
ci: имена job validate.yml — контракт, сверяемый с файлом; шарды из матрицы (#622)
- scripts/workflow-jobs.mjs: разбор job-уровня validate.yml (id, name, inline matrix) без зависимостей; незнакомые формы — громкая ошибка. - ci-proof: JOB_RULES по id job с именем-контрактом; число и точные имена экземпляров — из матрицы YAML (константы count: 6 нет); resolveJobRules на каждом evaluateCiProof — переименование даёт failed с названной job; jobContractProblems — сверка в обе стороны, UNCONSUMED_JOBS для proof. - validate-gate: MUTANT_JOB_PREFIX — из контракта ci-proof. - e2e-gate: E2E_JOB_NAME — зеркало name: из houseplan-e2e e2e.yml (43899da5), распознавание выводится из шаблона; missing называет завершённые прогоны без job по контракту. - тесты: фикстуры имён выводятся из validate.yml; новый test/workflow-jobs.test.mjs; 5 мутантов в реестре. Issue: #622 User-Visible: no
This commit is contained in:
+34
-1
@@ -2,7 +2,9 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
|
||||
import { classifyRun, e2eGate, isOurRun, previousStable, realOps, TOKEN_HINT } from '../scripts/e2e-gate.mjs';
|
||||
import {
|
||||
classifyRun, E2E_JOB_NAME, e2eGate, e2eJobName, isNamedE2eJob, isOurRun, previousStable, realOps, TAG_SUITES, TOKEN_HINT,
|
||||
} from '../scripts/e2e-gate.mjs';
|
||||
|
||||
const TAG = 'v1.74.0';
|
||||
const ours = (suffix = '') => [{ name: `journeys · HP ${TAG} · HA stable${suffix}`, conclusion: 'success' }, { name: 'upgrade · HP stable · HA stable', conclusion: 'success' }];
|
||||
@@ -182,3 +184,34 @@ test('#540: without --ref the gate behaves exactly as before — the tag is the
|
||||
assert.equal(outcome.result, 'green');
|
||||
assert.deepEqual(fake.dispatched, [[TAG, 'v1.73.0']]);
|
||||
});
|
||||
|
||||
// #622: имя job живёт в чужом репозитории (Matysh/houseplan-e2e), поэтому
|
||||
// тест держит зеркало его строки `name:` и доказывает две вещи: гейт узнаёт
|
||||
// ровно те имена, которые этот шаблон порождает, и разрыв контракта виден
|
||||
// в исходе громко, а не как молчаливое «не появился».
|
||||
// Зеркало: houseplan-e2e .github/workflows/e2e.yml, job `e2e`, коммит 43899da5.
|
||||
const E2E_YML_NAME_LINE = ' name: "${{ matrix.suite }} · HP ${{ matrix.ref }} · HA ${{ matrix.ha }}"';
|
||||
|
||||
test('#622: the job-name contract mirrors houseplan-e2e e2e.yml and drives recognition', () => {
|
||||
assert.equal(` name: "${E2E_JOB_NAME}"`, E2E_YML_NAME_LINE, 'e2e-gate and the pinned e2e.yml line disagree — change both sides together');
|
||||
for (const suite of [...TAG_SUITES, 'upgrade']) {
|
||||
assert.equal(isNamedE2eJob({ name: e2eJobName({ suite, ref: TAG, ha: 'stable' }) }), true, suite);
|
||||
}
|
||||
assert.equal(isNamedE2eJob({ name: 'Матрица прогона' }), false);
|
||||
for (const suite of TAG_SUITES) {
|
||||
assert.equal(classifyRun([{ name: e2eJobName({ suite, ref: TAG, ha: '2026.9.1' }) }], TAG), 'ours', suite);
|
||||
}
|
||||
assert.equal(classifyRun([{ name: e2eJobName({ suite: 'upgrade', ref: TAG, ha: 'stable' }) }], TAG), 'foreign',
|
||||
'upgrade carries upgrade_from, not the candidate');
|
||||
assert.throws(() => e2eJobName({ suite: 'journeys', ref: TAG }), /no value for matrix\.ha/);
|
||||
});
|
||||
|
||||
test('#622: completed runs whose jobs do not follow the contract make «missing» name the broken contract', async () => {
|
||||
const renamed = run({ databaseId: 4, url: 'https://e2e/run/4' });
|
||||
const fake = fakeOps({ snapshots: [[renamed]], jobsById: { 4: [{ name: 'Матрица прогона' }, { name: `journeys / ${TAG} / stable`, conclusion: 'success' }] } });
|
||||
const outcome = await e2eGate({ tag: TAG, ops: fake.ops, appearMs: 5000, pollMs: 1000 });
|
||||
assert.equal(outcome.result, 'missing');
|
||||
assert.match(outcome.note, /1 завершённых прогона без job по контракту E2E_JOB_NAME/);
|
||||
const nothing = await e2eGate({ tag: TAG, ops: fakeOps({ snapshots: [[]] }).ops, appearMs: 5000, pollMs: 1000 });
|
||||
assert.doesNotMatch(nothing.note, /E2E_JOB_NAME/, 'no runs at all is plain missing');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user