Commit Graph
4 Commits
Author SHA1 Message Date
Matysh e98f869826 ci: name the right issue in the range summary
Живой прогон #2157 показал огрех формулировки: база диапазона (#388)
представилась заголовком «База классификации (#387)». Текст верный, ссылка
чужая — читатель уходит не в тот issue разбираться, почему диапазон такой.

Заголовок теперь следует режиму, а не общей ветке кода. Закреплено тестом на
оба режима и обе формулировки.

Issue: #388
User-Visible: no
2026-08-30 19:05:24 +03:00
Matysh 66db451280 ci: prove the range by judgement, not by a green verdict
Правка #388 уронила dev, и виновата подмена предиката. Я взял доказательством
`conclusion=success`, то есть оправдательный вердикт. Гейтам диапазона нужен
другой факт: судили ли этот коммит вообще. Упавший прогон коммит судил —
вердикт вынесен, автор его видел; переоткрывать такой коммит диапазоном не
надо. Не судил только отменённый.

Цена ошибки была наглядной. Backend на dev красный несколько дней по своей
причине (test_ha_import_export), успешных прогонов нет вовсе, поэтому база
уезжала на десятки коммитов назад. На 83d646c — docs-коммите — гейт
«новый код не добавляет any» предъявил 5 чужих находок из e4e1e370 и
8d431d6d и уронил frontend. Ровно тот сценарий обвинения невиновного, ради
которого делался #386, только устроенный мной.

Теперь `judgedShas` считает судимыми завершённые прогоны с любым вердиктом,
кроме cancelled, а `greenShas` остаётся для классификации (#387): там вопрос
другой — доказано ли, что тяжёлые гейты на этом дереве ПРОШЛИ. Два вопроса,
два предиката, и путать их дорого.

Запрос к API стал `status=completed` — надмножество, нужный предикат
применяет скрипт.

Issue: #388
User-Visible: no
2026-08-30 17:11:53 +03:00
Matysh 65339f63ad ci: judge the push range from the last proven-green ancestor
#387 закрыл классификацию — какие job запускать. Здесь остаток того же
дефекта: гейты, которые судят сам диапазон коммитов. Провенанс, процессный
гейт и «новый код не добавляет any» брали диапазон от головы предыдущего
пуша, а concurrency отменяет прогон предыдущего пуша штатно. Тогда его
коммиты не судит никто: свой прогон отменён, а следующий пуш сравнивает уже
с ними. Окно не закрывается никогда.

Уязвим был прямой пуш в dev — основной режим конвейера. На ветках дефекта
нет: no-new-any там всегда считает от merge-base, а resolveValidationRange
подменяет осиротевший before на origin/dev (#315).

База стала последним предком с успешно завершённым Validate. Фолбэк, когда
такого нет, сознательно оставлен прежним — before, но с пометкой в summary
«диапазон недоказуем». Расширять диапазон здесь нельзя: гейт, который сам
красит прогон, лишил бы следующий пуш зелёного предка и запер dev в
красноте навсегда. Фолбэк обязан не зависеть от собственного успеха гейта.
Дыра сужается с «всегда, когда прогон предыдущего пуша отменён» до «когда
во всём окне обхода нет ни одного успешного прогона».

Находки no-new-any теперь называют коммит, добавивший строку: диапазон стал
шире, и без имени источника сообщение обвиняло бы того, кто пушнул
следующим, — ровно то, что чинили в #386 для golden.

Issue: #388
User-Visible: no
2026-08-30 15:55:08 +03:00
Matysh 50851dc3f9 ci: classify against the last proven-green ancestor
Диапазон классификации брался от `github.event.before` — головы предыдущего
пуша. Это допущение «до этого уже проверено», и оно неверно ровно тогда,
когда прогон предыдущего пуша не завершился. А не завершается он штатно:
concurrency отменяет его следующим пушем.

На #86 (r5) это дало ложный зелёный: push 04da7eb1 тронул dist/** и
frontend/**, его прогон отменили через три минуты; следующий push fa146fb1
тронул только docs/images/**, классификация сравнила эти два коммита и
выставила frontend=false. Job «Фронтенд», а за ней golden, smoke и backend
оказались skipped — прогон при этом success. Маркеры переиспользования эти
гейты тоже не подтверждали: `Cache not found` по всем четырём.

Теперь база — самый новый предок HEAD, для которого Validate ДЕЙСТВИТЕЛЬНО
завершился успешно; если такого нет, диапазон расширяется до merge-base с
dev, то есть до всего вклада ветки. Работает по индукции: цепочка узких
диффов покрывает всё изменённое с последней настоящей проверки, а одно
незавершённое звено теперь расширяет диапазон, а не сужает.

Недоступность API не роняет job: пустой ответ опускает базу до merge-base,
то есть в сторону большего объёма проверок.

Защита от force-push (#347) сохранена: механизм, из-за которого merge-base
врал на переписанной истории, до конца не разобран, и снимать защиту, не
объяснив её, — способ получить #347 второй раз.

Issue: #387
User-Visible: no
2026-08-30 15:35:56 +03:00