bot: уведомления CI и CD — PipelineWatcher #11

Closed
opened 2026-10-12 19:33:54 +03:00 by Eleboba · 1 comment
Owner

Описание

Требования C-24, C-30…C-34 из SPEC §4.1, ARCHITECTURE §2.5; polling — ADR-003.

Желаемый результат

  • Сообщение о пуше обновляется: CI ⏳ → ✅/❌ → CD ⏳ → ✅/❌ (≤ 30 с после смены статуса).
  • Автору: «✅ CI пройден» + ссылка; «🚀 CD: сервисы … развёрнуты, ревизия sha»; при падении — упавший шаг и его лог.
  • Падение CD → событие для алертов всем (#15).
  • Опрос только при незавершённых пушах; таймаут 30 мин; после рестарта бота незавершённые подхватываются из БД.

Подзадачи

  • app/pipeline/watcher.py — сопоставление по sha; CI — Gitea Actions check, CD — бот через tgit-runner (ADR-016)
  • Таблица pipeline_runs, переходы pushes.ci_status/cd_status
  • Отправка лога упавшего шага (хвост в сообщении, длинный — файлом)
  • Тесты с фейковым клиентом: успех, падение CI, падение CD, таймаут, ошибки API

Анализ

Затрагиваемые файлы

Файл Что меняется
app/pipeline/ новый пакет
tests/pipeline/ новый

Ограничения и риски

«message is not modified» — не ошибка. Логи куба могут быть большими — файлом, не больше 5 МБ.

Как проверить

Пуш валидного сервиса → четыре обновления статуса и два уведомления; пуш с ошибкой ruff → «❌ CI» + лог.


Лог выполнения

2026-10-13

  • Задача переписана под SPEC v2 (QR-доступ, меню из 4 разделов, командная модель — ADR-011…013).

2026-10-19

  • CI загрузок — Gitea Actions (решение пользователя, ADR-016): репозиторий загрузок после ADR-015 живёт в Gitea, SourceCraft всё ещё не принимает ключ бота. У прогона Gitea есть head_sha — куб meta (ADR-014) не нужен. CD остаётся у бота: после зелёного check → tgit-runner (#13).
  • app/pipeline/: протокол CIProvider + gitea.py (runs по head_sha, джобы → упавший шаг, лог джоба без меток времени, ретраи на сеть/5xx); PipelineWatcher — состояние в БД, сообщение о push рендерится из неё, опрос только пока есть незавершённые push (иначе спит до wake()), бэкофф до 60 с, таймаут 30 мин; после рестарта ждёт CI дальше и повторяет прерванный деплой.
  • Прогоны CI могут закончиться не по порядку: старый push не разворачивает сервис, который развернёт более новый прошедший CI push (иначе откат).
  • CI_PROVIDER=none — прежнее поведение: деплой сразу после push.
  • Шаблон: infra/uploads-template/.gitea/workflows/check.yml (compile · ruff · bandit · pytest, последовательно — первый упавший шаг виден автору); .gitea/ защищён от правок из бота (C-16).
  • Миграция 0002 (только данные): старые push → skipped, иначе первый тик разослал бы авторам «таймаут CI».
  • Живая проверка: workflow установлен в HSE/tgit-uploads (540eaa4), прогон 5225 ✅ за 28 с, все 7 шагов, тест hello прошёл; GiteaCI.find(sha) с живым API видит running → success.
  • Найдено при тестах: в тестах SQLite — одно общее соединение (StaticPool), и опрос БД из теста параллельно с записью наблюдателя откатывал его UPDATE (воспроизводилось только под coverage). Тесты ждут задачи деплоя (drain()) и фейковый Telegram, а не БД.
  • 357 тестов (23 новых), покрытие 92 %, ruff, mypy strict.
  • Осталось на сервере: в /srv/tgit/dev/.env — CI_PROVIDER=gitea и CI_TOKEN (чтение HSE/tgit-uploads); без них бот деплоит как раньше.
## Описание Требования C-24, C-30…C-34 из [SPEC](https://gitea.24studbank.ru/HSE/tgit/src/branch/dev/docs/SPEC.md) §4.1, [ARCHITECTURE](https://gitea.24studbank.ru/HSE/tgit/src/branch/dev/docs/ARCHITECTURE.md) §2.5; polling — ADR-003. ## Желаемый результат - Сообщение о пуше обновляется: CI ⏳ → ✅/❌ → CD ⏳ → ✅/❌ (≤ 30 с после смены статуса). - Автору: «✅ CI пройден» + ссылка; «🚀 CD: сервисы … развёрнуты, ревизия sha»; при падении — упавший шаг и его лог. - Падение CD → событие для алертов всем (#15). - Опрос только при незавершённых пушах; таймаут 30 мин; после рестарта бота незавершённые подхватываются из БД. ## Подзадачи - [x] `app/pipeline/watcher.py` — сопоставление по sha; CI — Gitea Actions `check`, CD — бот через tgit-runner (ADR-016) - [x] Таблица `pipeline_runs`, переходы `pushes.ci_status/cd_status` - [x] Отправка лога упавшего шага (хвост в сообщении, длинный — файлом) - [x] Тесты с фейковым клиентом: успех, падение CI, падение CD, таймаут, ошибки API ## Анализ ### Затрагиваемые файлы | Файл | Что меняется | |------|--------------| | `app/pipeline/` | новый пакет | | `tests/pipeline/` | новый | ### Ограничения и риски «message is not modified» — не ошибка. Логи куба могут быть большими — файлом, не больше 5 МБ. ## Как проверить Пуш валидного сервиса → четыре обновления статуса и два уведомления; пуш с ошибкой ruff → «❌ CI» + лог. --- ## Лог выполнения ### 2026-10-13 - Задача переписана под SPEC v2 (QR-доступ, меню из 4 разделов, командная модель — ADR-011…013). ### 2026-10-19 - **CI загрузок — Gitea Actions** (решение пользователя, ADR-016): репозиторий загрузок после ADR-015 живёт в Gitea, SourceCraft всё ещё не принимает ключ бота. У прогона Gitea есть `head_sha` — куб `meta` (ADR-014) не нужен. CD остаётся у бота: после зелёного `check` → `tgit-runner` (#13). - `app/pipeline/`: протокол `CIProvider` + `gitea.py` (runs по `head_sha`, джобы → упавший шаг, лог джоба без меток времени, ретраи на сеть/5xx); `PipelineWatcher` — состояние в БД, сообщение о push рендерится из неё, опрос только пока есть незавершённые push (иначе спит до `wake()`), бэкофф до 60 с, таймаут 30 мин; после рестарта ждёт CI дальше и повторяет прерванный деплой. - Прогоны CI могут закончиться не по порядку: старый push не разворачивает сервис, который развернёт более новый прошедший CI push (иначе откат). - `CI_PROVIDER=none` — прежнее поведение: деплой сразу после push. - Шаблон: `infra/uploads-template/.gitea/workflows/check.yml` (compile · ruff · bandit · pytest, последовательно — первый упавший шаг виден автору); `.gitea/` защищён от правок из бота (C-16). - Миграция 0002 (только данные): старые push → `skipped`, иначе первый тик разослал бы авторам «таймаут CI». - **Живая проверка:** workflow установлен в `HSE/tgit-uploads` (`540eaa4`), прогон 5225 ✅ за 28 с, все 7 шагов, тест `hello` прошёл; `GiteaCI.find(sha)` с живым API видит `running` → `success`. - Найдено при тестах: в тестах SQLite — одно общее соединение (StaticPool), и опрос БД из теста параллельно с записью наблюдателя откатывал его UPDATE (воспроизводилось только под coverage). Тесты ждут задачи деплоя (`drain()`) и фейковый Telegram, а не БД. - 357 тестов (23 новых), покрытие 92 %, ruff, mypy strict. - **Осталось на сервере:** в `/srv/tgit/dev/.env` — `CI_PROVIDER=gitea` и `CI_TOKEN` (чтение `HSE/tgit-uploads`); без них бот деплоит как раньше.
Eleboba added this to the M1 · MVP: загрузка → коммит → CI milestone 2026-10-12 19:33:54 +03:00
Eleboba added the botfeaturesize/1 labels 2026-10-12 19:33:54 +03:00
Eleboba self-assigned this 2026-10-12 19:33:54 +03:00
Eleboba added a new dependency 2026-10-12 19:40:37 +03:00
Eleboba changed title from bot: CIWatcher — статус прогона в сообщении, логи падения, /runs to bot: уведомления CI и CD — PipelineWatcher 2026-10-13 22:53:20 +03:00
Author
Owner

Смержено в dev через PR #50 — закрываю.

Смержено в `dev` через PR #50 — закрываю.
Sign in to join this conversation.