From 10ebdc97927e4eafa8ace474adb39b97b7737ef6 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 20 Sep 2026 23:29:51 +0300 Subject: [PATCH 1/2] =?UTF-8?q?ci:=20=D1=81=D0=B8=D0=BD=D1=85=D1=80=D0=BE?= =?UTF-8?q?=D0=BD=D0=B8=D0=B7=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D1=82=D1=8C=20?= =?UTF-8?q?mutation-gate.yml=20=D0=B2=20main=20(#601)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue: #601 User-Visible: no --- .github/workflows/mutation-gate.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/mutation-gate.yml b/.github/workflows/mutation-gate.yml index 6408f1da..79b434f9 100644 --- a/.github/workflows/mutation-gate.yml +++ b/.github/workflows/mutation-gate.yml @@ -8,7 +8,9 @@ name: Мутационный гейт # Прогон дорогой и проверяет не продукт, а тесты, поэтому он не входит ни в # Validate, ни в цикл разработки, ни в релизный гейт (#513, решение владельца # 09.09): каждую ночь по расписанию, отказ — issue с отчётом (#472). -# Мутанты, задетые диффом, конвейер ревью гоняет отдельно на кандидате (#510). +# Мутанты, задетые диффом, конвейер ревью и слияние гоняют отдельно на своём +# кандидате (#510); кандидат беты, `full=true` и ночной Validate их не +# запрашивают (#601) — ночью достаточно этого полного реестра. # Дешёвая половина — «якоря патчей живы, guard-файлы существуют» — идёт с # обычными юнитами: test/mutation-gate.test.mjs. # From 74fcff558c832aef19734f51bdb77ba6624c9334 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 21 Sep 2026 15:40:35 +0300 Subject: [PATCH 2/2] ci: mirror mutation gate workflow in main (#604) Issue: #604 User-Visible: no --- .github/workflows/mutation-gate.yml | 30 ++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/.github/workflows/mutation-gate.yml b/.github/workflows/mutation-gate.yml index 79b434f9..b1a8825d 100644 --- a/.github/workflows/mutation-gate.yml +++ b/.github/workflows/mutation-gate.yml @@ -67,15 +67,21 @@ jobs: echo "ref=${{ github.event_name == 'workflow_dispatch' && inputs.ref || 'dev' }}" >> "$GITHUB_OUTPUT" mutants: - name: "Мутанты: каждый обязан красить тесты (шард ${{ matrix.shard }} из 4)" + name: "Мутанты: каждый обязан красить тесты (шард ${{ matrix.shard }} из 6)" needs: material runs-on: ubuntu-latest strategy: fail-fast: false matrix: - shard: [1, 2, 3, 4] - # Шард ~64 мутантов × свой guard; бандл собирают только браузерные гварды. - # Час — потолок против зависшего Chromium. + shard: [1, 2, 3, 4, 5, 6] + # Шесть чересполосных шардов (#604): при четырёх шард нёс ~203 мутанта из + # 810 и рос с реестром — 42 мин 10.09, 57 мин 20.09, 61 мин 21.09, и шард + # 2/4 был снят по потолку без единого FAIL. Делитель тот же, что у + # `changed_mutants` в Validate; число шардов повторяется в `--shard=i/6`, + # `--shards=6` и имени job — тест `mutation-gate.test.mjs` держит их + # равными. Бандл собирают только браузерные гварды. Час — потолок против + # зависшего Chromium, а не бюджет шарда: шард, упёршийся в него, — сигнал + # снова делить, и отчёт (#472) называет такой шард прерванным, не «ok». timeout-minutes: 60 steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 @@ -124,10 +130,14 @@ jobs: # ЧТО сбежало. Без артефакта отказ безымянный. `PIPESTATUS` — чтобы # `tee` не съел код выхода раннера. - name: Каждый тест ловит свою поломку + id: gate run: | mkdir -p artifacts/mutation-shard-${{ matrix.shard }} set -o pipefail - node scripts/mutation-gate.mjs --shard=${{ matrix.shard }}/4 2>&1 | tee artifacts/mutation-shard-${{ matrix.shard }}/mutation-shard-${{ matrix.shard }}.log + node scripts/mutation-gate.mjs --shard=${{ matrix.shard }}/6 2>&1 | tee artifacts/mutation-shard-${{ matrix.shard }}/mutation-shard-${{ matrix.shard }}.log + # Исход шага едет в evidence (#604): снятый по timeout-minutes шаг даёт + # `cancelled`, и агрегатор отвергает такой шард как неполный — лог без + # строк FAIL сам по себе зелёным не считается. - name: Записать identity шарда if: always() run: | @@ -137,7 +147,8 @@ jobs: --tree=${{ needs.material.outputs.tree }} \ --workflow-sha=${{ github.workflow_sha }} \ --run-id=${{ github.run_id }} --run-attempt=${{ github.run_attempt }} \ - --shard=${{ matrix.shard }} --shards=4 + --shard=${{ matrix.shard }} --shards=6 \ + --outcome=${{ steps.gate.outcome }} - name: Сохранить лог и identity шарда if: always() uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 @@ -147,7 +158,8 @@ jobs: if-no-files-found: warn retention-days: 30 - # Результат нельзя приписывать material, пока не доказаны все четыре шарда. + # Результат нельзя приписывать material, пока не доказаны все шесть шардов — + # каждый с identity и с дошедшим до конца прогоном (#549, #604). # always() нужен при красном мутанте: лог красного шарда всё равно evidence. evidence: name: "Доказать единый material всех шардов" @@ -171,7 +183,7 @@ jobs: - name: Проверить полноту и identity run: | node scripts/mutation-gate-report.mjs --verify-only \ - --logs=artifacts/mutation-logs --shards=4 \ + --logs=artifacts/mutation-logs --shards=6 \ --sha=${{ needs.material.outputs.sha }} \ --tree=${{ needs.material.outputs.tree }} \ --workflow-sha=${{ github.workflow_sha }} \ @@ -214,7 +226,7 @@ jobs: run: | mkdir -p artifacts node scripts/mutation-gate-report.mjs \ - --require-evidence --logs=artifacts/mutation-logs --shards=4 \ + --require-evidence --logs=artifacts/mutation-logs --shards=6 \ --sha=${{ needs.material.outputs.sha }} \ --tree=${{ needs.material.outputs.tree }} \ --workflow-sha=${{ github.workflow_sha }} \