ci: name the commit that actually broke golden

Упавший тяжёлый гейт не пишет маркер переиспользования — и правильно, иначе
починка осталась бы незамеченной. Но следствие в том, что следующий коммит
гонит ту же job на тех же входах, падает так же, и письмо «Run failed»
называет его. 29 августа так был назван 0f7b6f5, документ ревью, который не
может изменить ни одного пикселя: сцену без эталона добавил dbbe94ae.

Теперь падение оставляет второй маркер — с тем же ключом, что у маркера
успеха. Совпадение ключа доказывает равенство входов, поэтому повторное
падение может честно сказать «красная с такого-то SHA, этот коммит её не
ронял», а первое — «причина здесь». Само падение по-прежнему не кэшируется:
job прогоняется всегда, меняется только формулировка в notice и summary.

Первопричина записывается только на первом падении: иначе SHA съехал бы на
свидетеля и сообщение перевернулось бы смыслом.

Issue: #386
User-Visible: no
This commit is contained in:
Matysh
2026-08-30 11:23:35 +03:00
parent 75d11d7c2e
commit fbbea47545
4 changed files with 218 additions and 3 deletions
+27
View File
@@ -537,6 +537,14 @@ jobs:
path: dist
- name: Разложить бандл по копиям
run: node scripts/bundle-sync.mjs
# Маркер предыдущего падения с ТЕМ ЖЕ ключом (#386). Восстанавливается до
# прогона, потому что после падения шаги кэша уже не помогут отличить
# виновника от свидетеля.
- name: Прежнее падение на тех же входах
uses: actions/cache/restore@v6
with:
path: .fail-marker
key: fail-golden-${{ needs.reuse.outputs.golden_key }}
- name: Capture or verify golden matrix
id: golden
run: |
@@ -553,6 +561,25 @@ jobs:
with:
name: golden-images
path: artifacts/golden
# Красная golden обязана сказать, ЧЕЙ это долг (#386). Без этого письмо
# «Run failed» называет коммит, который пушнули следующим: 29 августа так
# был назван документ ревью `0f7b6f5`, а сцену без эталона добавил
# `dbbe94ae`. Вердикт job не меняется — меняется только формулировка.
- name: Кто уронил golden
id: fail_note
if: failure()
env:
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: node scripts/gate-reuse.mjs --job=golden --note --marker=.fail-marker
- name: Запомнить первопричину
if: failure() && steps.fail_note.outputs.first == 'true'
# Гонка двух прогонов даёт «Cache already exists»; для маркера падения
# это тем более не отказ гейта — job и так красная по существу.
continue-on-error: true
uses: actions/cache/save@v6
with:
path: .fail-marker
key: fail-golden-${{ needs.reuse.outputs.golden_key }}
# Маркер пишется последним шагом: он существует только если всё выше
# прошло. Кэш сохраняется post-шагом, то есть тоже лишь при успехе job.
- name: Записать маркер успеха