chore(ci): не проглатывать падение сборки + починить самолечение buildcache #2890

Merged
lekss361 merged 2 commits from chore/ci-gates-runner-and-deploy into main 2026-08-15 16:20:20 +00:00

2 commits

Author SHA1 Message Date
bot-backend
8bce8cf5ae fix(ci): fail-safe registry verification + real cache self-heal + honest health-check (#2841 R2)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI / changes (pull_request) Successful in 9s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
Ревью R2 нашёл, что вся безопасность предыдущего фикса держалась на
недоказанной поддержке act_runner'ом steps.<id>.outcome: если раннер его
не заполняет, retry-шаг молча не бежит, continue-on-error проглатывает
падение сборки, job зелёный — а деплой тянет старый :latest на прод.

- Добавлен engine-agnostic verify-шаг после каждого retry (6 мест,
  deploy.yml + deploy-tradein.yml): `docker buildx imagetools inspect
  <image>:<sha>` без continue-on-error. Не зависит от того, поддерживает
  ли раннер outcome — проверяет реальное состояние registry напрямую.
  Если ни build, ни retry реально не запушили образ — шаг падает и job
  честно FAILURE независимо от семантики outcome.
- Вернул `cache-to` в retry-шаги (6 мест): без него битый buildcache-тег
  никогда не перезаписывался — retry всегда собирал без cache-to, значит
  cache-to не выполнялся НИКОГДА, и каждый следующий прогон снова падал
  на том же cache-from. Заявленное самолечение не работало ни разу.
- Health-check в deploy.yml (main-стек) под `set -e` не мог упасть:
  `curl ... && break` — curl не последняя команда &&-списка, POSIX
  освобождает такие команды от errexit, цикл дохаживал до sleep (exit 0)
  даже если curl ни разу не отдал 200. Приведено к паттерну
  deploy-tradein.yml: явный флаг healthy + `exit 1` после цикла.
  Подтверждено локальным bash-репро (mock curl, всегда failure): старая
  версия — exit 0, новая — exit 1; позитивный сценарий не сломан.

docker rm -f без -v в SSH-скриптах деплоя не тронут.
2026-08-15 18:44:48 +03:00
bot-backend
9b3889bb36 ci(deploy): честный статус деплоя + нефатальный buildcache (#2841)
Зелёная галка прогона не отличима от пропущенного деплоя: если build падает
из-за битого blob в удалённом buildcache, шаг deploy молча пропускается
(if-условие даёт result=skipped), а прогон в целом не подсвечен как FAILED.

- deploy-status: новая job в конце deploy.yml и deploy-tradein.yml, всегда
  бежит (if: always() && !cancelled()) и падает явно, если deploy.result !=
  success — неважно, пропущен он (upstream build/test упал) или упал сам.
- cache-from нефатален: каждый build-push-action-шаг получил id + continue-
  on-error, и ретрай без cache-from/cache-to при steps.build.outcome ==
  'failure'. Битый remote-кеш больше не роняет саму сборку; следующий
  успешный прогон с кешем перезаписывает buildcache-тег целиком (mode=max)
  и самолечит порчу. Реальные ошибки сборки (не кеш) по-прежнему валят job
  на ретрае — deploy-status их тоже поймает.

Гейт против публикации services-портов на VPS (та же задача, проблема 1)
уже покрыт scripts/check-workflow-ports.py + шагом в ci.yml (#2757/#2759,
слит ранее) — сканирует все .forgejo/workflows/*.yml, включая эти два файла;
новых правок не потребовалось.

docker rm -f БЕЗ -v в SSH-скриптах деплоя не тронут — эти вызовы намеренно
без -v (боевые тома), правка их не касается.
2026-08-15 17:55:17 +03:00