From 5d281171c83e54260e673c9c1bde4f132d4e2b2a Mon Sep 17 00:00:00 2001 From: Matysh Date: Sun, 6 Sep 2026 21:44:09 +0300 Subject: [PATCH] ci: shard changed mutants before release Issue: #480 User-Visible: no Release: v1.73.0-beta.2 --- .github/workflows/validate.yml | 15 +++++++++++---- test/validate-workflow.test.mjs | 8 +++++++- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 3cc5834e..38919154 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -457,12 +457,18 @@ jobs: # файл, который он патчит, либо изменился его гард. `--check` этого не # видит — он проверяет существование якоря, а не достижимость ветки. # Полный прогон раз в неделю ловит гниль с опозданием до релиза (#466, - # #467). Здесь гоняются только затронутые мутанты — единицы, минуты — - # с той же базы диапазона, что и остальные гейты ветки (#387/#388). + # #467). Здесь гоняются только затронутые мутанты с той же базы диапазона, + # что и остальные гейты ветки (#387/#388). Релизный диапазон всё же может + # задеть сотню свидетелей, поэтому #480 делит тот же набор на три + # детерминированных непересекающихся шарда вместо ослабления проверки. changed_mutants: - name: "Мутанты по диффу: затронутые свидетели краснеют" + name: "Мутанты по диффу (${{ matrix.shard }}/3): затронутые свидетели краснеют" needs: changes if: needs.changes.outputs.frontend == 'true' || needs.changes.outputs.backend == 'true' || needs.changes.outputs.mutants == 'true' + strategy: + fail-fast: false + matrix: + shard: [1, 2, 3] runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -495,6 +501,7 @@ jobs: PROVEN_BASE: ${{ needs.changes.outputs.range_base }} HEAD_SHA: ${{ github.sha }} REF: ${{ github.ref }} + SHARD: ${{ matrix.shard }} run: | set -euo pipefail git fetch -q origin dev @@ -513,7 +520,7 @@ jobs: fi echo "диапазон: $base..$HEAD_SHA" npx tsc -p tsconfig.test.json && node scripts/fix-test-build.mjs - node scripts/mutation-gate.mjs --changed="$base..$HEAD_SHA" + node scripts/mutation-gate.mjs --changed="$base..$HEAD_SHA" --shard="$SHARD/3" frontend: name: "Фронтенд: типы, юниты, мутанты, синхрон бандла" diff --git a/test/validate-workflow.test.mjs b/test/validate-workflow.test.mjs index 7df130d1..982eed74 100644 --- a/test/validate-workflow.test.mjs +++ b/test/validate-workflow.test.mjs @@ -377,7 +377,13 @@ test('мутанты по диффу гоняются на каждом пуше // База диапазона — та же, что у остальных гейтов ветки (#387/#388). assert.match(job, /PROVEN_BASE: \$\{\{ needs\.changes\.outputs\.range_base \}\}/); assert.match(job, /git merge-base origin\/dev "\$HEAD_SHA"/); - assert.match(job, /node scripts\/mutation-gate\.mjs --changed="\$base\.\.\$HEAD_SHA"/); + // #480: один широкий релизный диапазон отобрал 129 свидетелей и упёрся в + // 30-минутный timeout. Тот же набор теперь делится существующим + // детерминированным shardMutants без пропусков и пересечений. + assert.match(job, /fail-fast: false/); + assert.match(job, /shard: \[1, 2, 3\]/); + assert.match(job, /SHARD: \$\{\{ matrix\.shard \}\}/); + assert.match(job, /node scripts\/mutation-gate\.mjs --changed="\$base\.\.\$HEAD_SHA" --shard="\$SHARD\/3"/); // pytest-гарды исполнимы: Python и зависимости ставятся, как в mutation-gate.yml. assert.match(job, /pip install -r tests_backend\/requirements\.txt/); // Блокирующая job: свидетель, разучившийся краснеть, — отказ, а не предупреждение.