Files
wiki/tasks/orchestrator/DEV_TASK_GITEA_MERGE_GATE.md
2026-06-04 10:10:04 +03:00

6.0 KiB
Raw Permalink Blame History

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+mergedgitea.py мгновенно ставит done (за 33 сек), ПОКА deployer ещё работает 6 минут.
  • deployer затем пишет deploy_status: FAILED — но поздно, задача уже done.
  • check_deploy_status не вызывается вообще → фейк-done вернулся через merge-вебхук.

Файл

src/webhooks/gitea.py — единственный файл с изменениями кода.

Текущий код (конец обработчика pull_request, примерно стр. 336-339)

    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 — это легитимный путь, когда фичу мержат не из конвейера).

Требуемая логика

    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.