mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
ci: правка реестра мутантов сама запускает гейт по диффу (#475 r1)
Классификатор отдаёт выход mutants по scripts/mutation-gate.mjs, job changed_mutants получает третий дизъюнкт из ТЗ §2; fallback-ветки выставляют mutants=true. Тест AC7 отбирает бэкенд-мутанты по файлу патча. Issue: #475 User-Visible: no
This commit is contained in:
@@ -209,9 +209,9 @@ jobs:
|
||||
frontend: ${{ steps.classify.outputs.frontend }}
|
||||
backend: ${{ steps.classify.outputs.backend }}
|
||||
integration: ${{ steps.classify.outputs.integration }}
|
||||
# Диффозависимые профили перф-смока (#473 §5).
|
||||
perf_iso: ${{ steps.classify.outputs.perf_iso }}
|
||||
perf_iso: ${{ steps.classify.outputs.perf_iso }} # #473 §5
|
||||
perf_interaction: ${{ steps.classify.outputs.perf_interaction }}
|
||||
mutants: ${{ steps.classify.outputs.mutants }}
|
||||
# Тяжёлые job только на кандидате/по кнопке/на PR (#479), см. шаг heavy.
|
||||
heavy: ${{ steps.heavy.outputs.heavy }}
|
||||
base: ${{ steps.base.outputs.base }}
|
||||
@@ -459,7 +459,7 @@ jobs:
|
||||
changed_mutants:
|
||||
name: "Мутанты по диффу: затронутые свидетели краснеют"
|
||||
needs: changes
|
||||
if: needs.changes.outputs.frontend == 'true' || needs.changes.outputs.backend == 'true'
|
||||
if: needs.changes.outputs.frontend == 'true' || needs.changes.outputs.backend == 'true' || needs.changes.outputs.mutants == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
|
||||
@@ -25,6 +25,9 @@ export const CLASSIFIERS = {
|
||||
// Только `src/**`: тесты и демо кадр не замедляют.
|
||||
perf_iso: /^src\/iso-[^/]+\.ts$/,
|
||||
perf_interaction: /^src\/(live-[^/]+|render-[^/]+|houseplan-render-lifecycle|houseplan-card)\.ts$/,
|
||||
// Реестр мутантов сам по себе — вход гейта по диффу (#475 ревью r1): новый
|
||||
// свидетель без правки в src/test иначе не проверялся бы до понедельника.
|
||||
mutants: /^scripts\/mutation-gate\.mjs$/,
|
||||
};
|
||||
|
||||
export const OUTPUTS = Object.keys(CLASSIFIERS);
|
||||
|
||||
@@ -35,13 +35,21 @@ test('тесты и демо перф-профили не включают: ка
|
||||
assert.equal(out.perf_interaction, 'false');
|
||||
});
|
||||
|
||||
test('правка реестра мутантов даёт mutants=true и только его (#475 r1)', () => {
|
||||
const out = classifyChanges(['scripts/mutation-gate.mjs']);
|
||||
assert.equal(out.mutants, 'true');
|
||||
assert.equal(out.frontend, 'false');
|
||||
assert.equal(classifyChanges(['scripts/mutation-gate-report.mjs']).mutants, 'false');
|
||||
assert.equal(classifyChanges(['src/x.ts']).mutants, 'false');
|
||||
});
|
||||
|
||||
test('прежние три выхода классифицируются как в inline-shell до выноса', () => {
|
||||
assert.deepEqual(classifyChanges(['custom_components/houseplan/frontend_registration.py']),
|
||||
{ frontend: 'false', backend: 'true', integration: 'true', perf_iso: 'false', perf_interaction: 'false' });
|
||||
{ frontend: 'false', backend: 'true', integration: 'true', perf_iso: 'false', perf_interaction: 'false', mutants: 'false' });
|
||||
assert.deepEqual(classifyChanges(['custom_components/houseplan/frontend/houseplan-card.js']),
|
||||
{ frontend: 'true', backend: 'false', integration: 'false', perf_iso: 'false', perf_interaction: 'false' });
|
||||
{ frontend: 'true', backend: 'false', integration: 'false', perf_iso: 'false', perf_interaction: 'false', mutants: 'false' });
|
||||
assert.deepEqual(classifyChanges(['hacs.json', 'tsconfig.json']),
|
||||
{ frontend: 'true', backend: 'false', integration: 'true', perf_iso: 'false', perf_interaction: 'false' });
|
||||
{ frontend: 'true', backend: 'false', integration: 'true', perf_iso: 'false', perf_interaction: 'false', mutants: 'false' });
|
||||
assert.equal(classifyChanges(['scripts/support-relay/x.py']).backend, 'true');
|
||||
assert.equal(classifyChanges(['']).frontend, 'false');
|
||||
});
|
||||
|
||||
@@ -319,8 +319,12 @@ test('#475 AC6: воспроизведение #467 — дифф по src/wall-t
|
||||
test('#475 AC7: воспроизведение находки ревью — бэкенд-мутанты отбираются по .py гарду и патчу', () => {
|
||||
const byGuard = selectChangedMutants(MUTANTS, ['tests_backend/test_ha_frontend_registration.py']).map((m) => m.id);
|
||||
const byPatch = selectChangedMutants(MUTANTS, ['custom_components/houseplan/frontend_registration.py']).map((m) => m.id);
|
||||
const registration = MUTANTS.filter((m) => m.id.startsWith('frontend-registration-')).map((m) => m.id);
|
||||
assert.ok(registration.length >= 3, 'в реестре есть бэкенд-мутанты регистрации');
|
||||
// Отбор по патчу, а не по префиксу id (ревью r1: `frontend-reload-notice-*`
|
||||
// патчит тот же файл и обязан попасть в набор).
|
||||
const registration = MUTANTS
|
||||
.filter((m) => m.patches.some((patch) => patch.file === 'custom_components/houseplan/frontend_registration.py'))
|
||||
.map((m) => m.id);
|
||||
assert.ok(registration.length >= 4, 'в реестре есть бэкенд-мутанты регистрации');
|
||||
for (const id of registration) {
|
||||
assert.ok(byGuard.includes(id), `${id} не отобран по гарду`);
|
||||
assert.ok(byPatch.includes(id), `${id} не отобран по патчу`);
|
||||
|
||||
@@ -368,7 +368,12 @@ test('мутанты по диффу гоняются на каждом пуше
|
||||
const job = workflow.slice(start, workflow.indexOf('\n frontend:\n', start));
|
||||
// Триггер — и фронтенд, и бэкенд: бэкенд-мутанты патчат .py и охраняются
|
||||
// pytest, а дифф только по ним даёт backend=true без frontend=true (ревью r1).
|
||||
assert.match(job, /if: needs\.changes\.outputs\.frontend == 'true' \|\| needs\.changes\.outputs\.backend == 'true'/);
|
||||
assert.match(job, /if: needs\.changes\.outputs\.frontend == 'true' \|\| needs\.changes\.outputs\.backend == 'true' \|\| needs\.changes\.outputs\.mutants == 'true'/);
|
||||
// Третий дизъюнкт (ТЗ §2, ревью r1): правка одного реестра мутантов — тоже
|
||||
// вход гейта, классификатор обязан выдавать `mutants` по этому файлу.
|
||||
assert.match(workflow, /mutants: \$\{\{ steps\.classify\.outputs\.mutants \}\}/);
|
||||
// Сам шаблон и fallback `--all` проверяет test/classify-changes.test.mjs
|
||||
// (после #473 классификация живёт в scripts/classify-changes.mjs).
|
||||
// База диапазона — та же, что у остальных гейтов ветки (#387/#388).
|
||||
assert.match(job, /PROVEN_BASE: \$\{\{ needs\.changes\.outputs\.range_base \}\}/);
|
||||
assert.match(job, /git merge-base origin\/dev "\$HEAD_SHA"/);
|
||||
|
||||
Reference in New Issue
Block a user