auto-sync: 2026-06-04 10:10:01

This commit is contained in:
Stream
2026-06-04 10:10:04 +03:00
parent 09cabb1a27
commit 073af241be

View File

@@ -0,0 +1,85 @@
# DEV TASK: закрыть вторую дверь баг-8 — gitea PR-merged обходит deploy-QG
## Контекст / проблема
БАГ 8 (deploy без QG) был починен в `stage_engine.advance_stage` через `check_deploy_status`
(читает `deploy_status:` из frontmatter `14-deploy-log.md`). Но есть **вторая дверь**:
обработчик Gitea-вебхука `pull_request` при `action=closed & merged=true` **слепо** переводит
задачу в `done` для ЛЮБОЙ стадии, минуя QG.
Боевой инцидент (ET-012, task 30):
- deployer мержит PR в начале работы → прилетает webhook `closed+merged``gitea.py` мгновенно
ставит `done` (за 33 сек), ПОКА deployer ещё работает 6 минут.
- deployer затем пишет `deploy_status: FAILED` — но поздно, задача уже `done`.
- `check_deploy_status` **не вызывается вообще** → фейк-done вернулся через merge-вебхук.
## Файл
`src/webhooks/gitea.py` — единственный файл с изменениями кода.
## Текущий код (конец обработчика `pull_request`, примерно стр. 336-339)
```python
elif action == "closed" and pr.get("merged", False):
update_task_stage(task_id, "done")
notify_stage_change(task_id, current_stage, "done")
logger.info(f"Task {task_id}: PR merged, stage → done")
```
## Что нужно
Merge PR **не должен** напрямую ставить `done`, когда `current_stage == "deploy"`.
Для deploy финальный переход deploy→done обязан проходить через `check_deploy_status`
(вердикт deployer'а), как и задумано баг-8 фиксом. Для всех ОСТАЛЬНЫХ стадий — поведение
merge сохранить как есть (прямой `done` — это легитимный путь, когда фичу мержат не из конвейера).
### Требуемая логика
```python
elif action == "closed" and pr.get("merged", False):
# БАГ 8 (вторая дверь): для стадии deploy финальный done гейтится
# вердиктом deployer'а (check_deploy_status), а НЕ фактом merge PR.
# deployer мержит PR в начале работы — merge != успешный деплой.
if current_stage == "deploy":
logger.info(
f"Task {task_id}: PR merged at deploy stage — done gated by "
f"deployer verdict (check_deploy_status), not merge event. Ignoring merge-driven done."
)
return
update_task_stage(task_id, "done")
notify_stage_change(task_id, current_stage, "done")
logger.info(f"Task {task_id}: PR merged, stage → done")
```
**Обоснование игнора (а не вызова advance_stage):** на deploy стадии deployer-job
уже запущен через очередь (`enqueue_job` на входе стадии). Когда он завершится,
launcher вызовет `advance_stage`, который выполнит `check_deploy_status` и сам решит
done/rollback. Дублировать advance_stage из merge-вебхука НЕ нужно — это создаст гонку.
Merge-вебхук на deploy просто **молча игнорируется** (done решает только вердикт).
## ОГРАНИЧЕНИЯ (НЕ трогать)
- НЕ менять ветки `action == "reviewed"` (APPROVED / REQUEST_CHANGES) — они работают.
- НЕ менять HMAC, project-filter (`get_project_by_repo`), импорты кроме необходимого.
- НЕ трогать `stage_engine.py`, `launcher.py`, `checks.py`, `stages.py`, `conftest.py`.
- НЕ трогать nginx, openclaw.json, .env, queue, PLANE_STATES, gitea_public_url.
- Сохранить блок launcher.py:475.
## Тесты
- Добавить тест(ы) в существующий тест-файл вебхуков gitea (найти где тестируется
`pull_request` merged — вероятно `tests/.../test_gitea_webhook*.py` или аналог).
- Кейсы:
1. `closed+merged` при `current_stage="deploy"` → задача НЕ переходит в `done`
(остаётся на deploy), `update_task_stage(...,"done")` НЕ вызван.
2. `closed+merged` при `current_stage` НЕ deploy (например `review` или иной валидный) →
задача переходит в `done` (регрессия не сломана).
- Запустить полный `pytest`. Baseline: **227 passed + 10 failed** (10 failed = off-limits:
9 HMAC/401 + 1 webhook-POST — их НЕ чинить, они и должны падать).
Новые тесты должны дать **229+ passed, те же 10 failed**.
## Процесс сдачи
- Ветка от актуального main orchestrator: `fix/gitea-merge-deploy-gate`.
- Прямой push в main запрещён (pre-receive hook) → только через PR в Gitea.
- Gitea токен: `docker exec orchestrator printenv ORCH_GITEA_TOKEN`.
- Репо на проде: `/home/slin/repos/orchestrator` (slin@82.22.50.71, пароль в .env).
- В отчёте: commit-хеш, номер PR, вывод pytest (passed/failed), diff gitea.py.
- Отчёт положить в `tasks/orchestrator/reports/dev-2026-06-04-gitea-merge-gate.md`.
## Verify (после мержа PR)
1. Перезапустить контейнер orchestrator (подхватить новый код).
2. Прогнать любую задачу до deploy ИЛИ юнит-проверкой убедиться: merge-вебхук на deploy
не ставит done; done ставится только после deployer verdict через check_deploy_status.