diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 4e5776ad..c605ee82 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -780,10 +780,14 @@ jobs: node scripts/no-new-any.mjs --base "$base" --head "$HEAD_SHA" || status=1 node scripts/no-new-private-writes.mjs --base "$base" --head "$HEAD_SHA" || status=1 exit "$status" - - name: Unit tests - run: npm test - name: Build run: npm run build + # Часть unit-контрактов проверяет размеры реально поставляемых графов в + # dist/ (#438, #593, #627). В issue-ветке закоммиченный dist законно + # отстаёт от исходников (#657), поэтому юниты обязаны читать свежую + # сборку — тот же порядок закреплён локальным gate:small. + - name: Unit tests + run: npm test # Entry, manifest and every content-hashed chunk are one artifact (#337). # #657: the committed bundle changes only in a release candidate, so the # fresh build must equal it only there; elsewhere the committed copy diff --git a/test/monolith-metrics.test.mjs b/test/monolith-metrics.test.mjs index 4fb63892..987d80e4 100644 --- a/test/monolith-metrics.test.mjs +++ b/test/monolith-metrics.test.mjs @@ -154,8 +154,8 @@ test('#624 живое дерево: база равна текущим числ const { metrics, violations } = collectMetrics(root); assert.deepEqual(violations, [], 'мёртвый код по noUnusedLocals вне порта и харнесса'); const { grown, shrunk } = compareWithBaseline(metrics, baseline); - // bundleBytes судит гейт после сборки (Validate: Unit tests идут до Build, - // локально dist может быть от другого дерева) — здесь пять чисел исходника. + // bundleBytes судит гейт после сборки; здесь пять чисел исходника, а + // фактический свежий dist отдельно проверяют bundle-budget и lint:unused. const source = (list) => list.filter((s) => s.name !== 'bundleBytes'); assert.deepEqual(source(grown), [], 'связность выросла — вернуть или обосновать'); assert.deepEqual(source(shrunk), [], 'связность упала — опустить базу: node scripts/unused-locals-gate.mjs --update'); diff --git a/test/validate-workflow.test.mjs b/test/validate-workflow.test.mjs index 0d0da46a..919407df 100644 --- a/test/validate-workflow.test.mjs +++ b/test/validate-workflow.test.mjs @@ -68,6 +68,16 @@ test('бандл собирается один раз и приезжает бр assert.equal(workflow.match(/node scripts\/bundle-sync\.mjs/g)?.length, 3); }); +test('frontend собирает свежий dist до unit-контрактов бюджета (#663)', () => { + const workflow = read('validate.yml'); + const frontend = workflow.slice(workflow.indexOf('\n frontend:\n'), workflow.indexOf('\n dev_build:\n')); + const build = frontend.indexOf('- name: Build'); + const unit = frontend.indexOf('- name: Unit tests'); + assert.ok(build >= 0 && unit >= 0, 'в frontend должны существовать Build и Unit tests'); + assert.ok(build < unit, + 'unit-контракты читают dist/ и обязаны идти после свежей сборки, как в gate:small'); +}); + test('#657 копии бандла сверяются только на релизном коммите, стенд dev — из артефакта', () => { const workflow = read('validate.yml'); const frontend = workflow.slice(workflow.indexOf('\n frontend:\n'), workflow.indexOf('\n dev_build:\n'));