auto-sync: 2026-06-05 09:20:01

This commit is contained in:
Stream
2026-06-05 09:20:01 +03:00
parent 8cc1c80a39
commit 96bae96796
2 changed files with 115 additions and 0 deletions

View File

@@ -132,3 +132,64 @@
### Следующий шаг
Этап 3 (ORCH-33): тест-сьют staging — smoke + проверка доступов (Plane sandbox + Gitea sandbox реальными вызовами) + e2e (задача в SANDBOX → ветка в orchestrator-sandbox → статусы+комменты в Plane, верификация по API), режим full-real. Перед e2e: настроить Gitea-webhook sandbox-репо на localhost:8501. Это код для Dev (тест-скрипт) + моя инфра (webhook).
---
## Staging-среда orchestrator — Этапы 2-3 ВЫКАЧЕНЫ ✅ (05.06, утро)
### Этап 1 (ORCH-31) — закрыт
- **PR #28 смержен** в main, main HEAD `3b68a29` "Merge PR #28", коммит ORCH-31 `6c1e5ff` в main.
- ⚠️ Грабля мержа: заголовок авторизации Gitea при первом заходе пришёл как `***` (санитайзер) → HTTP 401 `token is required`. Фикс: явно `token <tok>` → HTTP 200 merged. Запомнить: при мерже через Gitea API проверять, что заголовок реально `token <значение>`, а не затёртый.
### Этап 2 (ORCH-32) — песочница создана + staging-контейнер ПОДНЯТ
- **Gitea-репо песочницы:** `admin/orchestrator-sandbox` (main, auto-init).
- **Plane-проект песочницы:** name "ORCH Sandbox" (Plane НЕ пускает дефис/спецсимволы в name → без дефиса), identifier `SANDBOX`, **project_id `8c5a3025-4f9d-4190-b79f-fa06276bb27e`**.
- **Токены — вариант 1 (решение Славы):** общие с продом, изоляция по проекту/репо + раздельная БД (НЕ отдельные токены).
- **Telegram staging — вариант 1 (решение Славы):** пустой/выключенный, staging молчит в телегу (смотрим по логам/API). Никакого спама в боевой канал.
- **`.env.staging` собран** на проде (`/home/slin/repos/orchestrator/.env.staging`, в .gitignore, НЕ коммитится): реестр `ORCH_PROJECTS_JSON` = ТОЛЬКО sandbox (боевые ET/ORCH → ignored фильтром ORCH-6), Telegram пустой, БД через volume, `ORCH_STAGING=true`. Прод `.env` (23 строки) цел, бэкап сделан.
- **Контейнер `orchestrator-staging` поднят на 8501** (`docker compose --profile staging up -d`), образ `orchestrator-orchestrator-staging:latest`. Проверено лично: `/health`=ok, `/queue`=ok (Claude Code 2.1.142 виден), прод `orchestrator` Up 16h БЕЗ рестарта.
- **Изоляция подтверждена:** staging знает ТОЛЬКО sandbox (`known_plane_project_ids()`={8c5a3025...}); боевые ORCH(8da6aa25)/ET(7a79f0a9) → False; БД физически раздельная `data/staging/orchestrator.db`.
### Webhook-изоляция (важная находка)
- **Gitea webhook прод-репо `orchestrator`** шлёт жёстко на `localhost:8500/webhook/gitea` (прод). Sandbox-репо пока БЕЗ хуков (правильно).
- **Plane webhooks через workspace API недоступны** (404) — настраиваются на уровне Plane-инстанса/UI (`plane-app-*` контейнеры). Прод-Plane шлёт на 8500. Staging боевые Plane-события НЕ получит, пока webhook в Plane не настроен на 8501.
- **Главный ключ изоляции:** `ORCH_PROJECTS_JSON` staging = только sandbox → даже если событие прилетит, всё не-sandbox → `ignored` (фильтр ORCH-6).
### Этап 3 (ORCH-33) — тест-сьют ГОТОВ, PR #29 (ждёт мержа)
- Dev написал `scripts/staging_check.py` (smoke A + доступы B + e2e C, exit-code, cleanup в finally) + `docs/STAGING_CHECK.md`. Ветка `feature/ORCH-33-staging-testsuite`. **PR #29 open.**
- **Проверено лично на проде: 10/10 PASS, exit 0.** Файлы только новые (src/tests/compose/.env не тронуты). Боевое НЕ задето (нет staging-check веток в orchestrator/enduro-trails, нет тест-задач в боевом ORCH). Песочница чиста после cleanup (sandbox-репо = только main, Plane SANDBOX = 0 задач). Прод 8500 жив.
- **Ключевое архитектурное знание (порядок старта конвейера):** при старте сначала resolve проекта → подтяг name/desc из Plane → QG-0 валидация → **создаётся work_item_id + ветка + начальные доки + строка задачи в БД** → ТОЛЬКО ПОТОМ enqueue аналитика (Claude CLI через launcher). Значит e2e проверяет РАННИЕ артефакты (ветка/доки) ДО запуска LLM — быстро, без расхода кредитов. Аналитика не ждём.
- **Режима заглушек агентов (гибрид C) в коде НЕТ** — но для e2e он и не нужен (проверяем раннюю стадию до LLM).
### Открытый нюанс (не блокер)
- Bot-токены агентов (`ORCH_PLANE_BOT_ANALYST` и пр.) НЕ добавлены членами в SANDBOX-проект → `add_comment` от их имени = 403. Dev заменил проверку «коммент в Plane» на надёжный ранний артефакт «analyst job в очереди». Чтобы закрыть полностью — добавить бот-аккаунты в SANDBOX через Plane API (моя инфра-работа, мелкая).
### Следующие шаги
1. Мерж PR #29 (Этап 3) — предложено + добавить ботов в SANDBOX.
2. **Этап 4 (ORCH-34):** хост-деплой-хук `orchestrator-deploy-hook.sh` (промоут staging→prod, health 10×6с=60с, auto-rollback PREV_IMG). Образец `/home/slin/bin/enduro-deploy-hook.sh`.
3. **Этап 5 (ORCH-35):** стадия `deploy-staging` перед `deploy-prod` в конвейере.
### Идентификаторы (Этап 2-3)
- Plane SANDBOX project_id: `8c5a3025-4f9d-4190-b79f-fa06276bb27e`, identifier `SANDBOX`
- Gitea sandbox-репо: `admin/orchestrator-sandbox`
- staging порт 8501, контейнер `orchestrator-staging`, профиль compose `staging`, образ `orchestrator-orchestrator-staging:latest`, БД `data/staging/orchestrator.db`, `.env.staging` (в .gitignore)
- main HEAD после Этапа 1: `3b68a29`; PR #28 merged, PR #29 open (Этап 3)
- ТЗ: `tasks/orchestrator/DEV_TASK_ORCH33_STAGING_TESTSUITE.md`; отчёт `tasks/orchestrator/reports/dev-2026-06-05-orch33-staging-testsuite.md`
---
## Этап 3 закрыт + боты в SANDBOX (05.06, продолжение)
### PR #29 смержен → Этап 3 в main
- **PR #29 merged** (HTTP 200, AUTH="token "+TOK — урок учтён). main HEAD `93169f1`, коммит сьюта `94334bd`.
### Нюанс с бот-комментами закрыт (Plane membership)
- **Корень 403 при `add_comment` бот-токеном:** бот-токен ВИДИТ проект (GET 200), но НЕ может постить комменты, пока его owner НЕ член проекта. Воспроизвела: бот POST comment=403, админ POST comment=201.
- **7 бот-аккаунтов Plane (workspace members):** Analyst `c925cbcd-a8dc-4506-978e-15354ce3ad31`, Developer `bfe59a48-a7cd-4ce1-a78b-83f8891a4aba`, Reviewer `9836a30d-1294-430d-8109-ceb3e784d1d8`, Tester `7cdfc9e7-c552-4fd1-b4a7-3b1f03e72751`, Architect `6d82b825-c8b2-447c-bca0-c4d34c6200ac`, Deployer `ebf17448-d544-465e-8b0e-57581f76507c`, Стрим `468040f8-f609-406a-84d2-a119880a5e8e`. (+ admin-токен owner = `mva154` daf4d3f4..., + системный `Plane` 43c79cc2...).
- **Identity бот-токена узнаётся через** `GET {PBASE}/users/me/` с `X-API-Key: <bot-token>` → возвращает id+display_name.
- **Добавление члена проекта Plane (РАБОЧИЙ формат):** `POST /workspaces/{slug}/projects/{pid}/members/` body `{"member": <user_id>, "role": 15}` ПООДИНОЧКЕ. ⚠️ Формат `{"members":[{...}]}` и `member_id` НЕ работают (400 "member: This field is required"). role 15 = member.
- **Все 7 ботов добавлены членами SANDBOX** (теперь 8 members). Верифицировано: Analyst и Developer боты постят комменты → HTTP 201. Нюанс Этапа 3 устранён.
### Дальше
Этап 4 (ORCH-34): хост-деплой-хук `orchestrator-deploy-hook.sh` (промоут staging→prod, health 10×6с=60с, auto-rollback по PREV_IMG). Образец `/home/slin/bin/enduro-deploy-hook.sh`.

View File

@@ -0,0 +1,54 @@
# DEV TASK — ORCH-34: хост-деплой-хук orchestrator с health-чеком и авто-rollback
**Проект:** orchestrator | **Сервер:** slin@82.22.50.71 (pw motoZ@yaz2010) | **Репо:** /home/slin/repos/orchestrator
**Ветка:** `feature/ORCH-34-deploy-hook` из свежего origin/main. `git fetch origin && git checkout main && git pull --ff-only && git checkout -b feature/ORCH-34-deploy-hook`.
**Этап:** 4 из 5 (после Этапов 1-3: staging живой на 8501, песочница рабочая, тест-сьют в main).
## ЦЕЛЬ
Написать деплой-хук `scripts/orchestrator-deploy-hook.sh` — bash-скрипт, который продвигает (промоутит) orchestrator на новый образ С HEALTH-ЧЕКОМ и АВТОМАТИЧЕСКИМ ОТКАТОМ, если новый контейнер не поднялся. Это аналог `/home/slin/bin/enduro-deploy-hook.sh`, НО с обязательным health-циклом + auto-rollback (которого у enduro-хука НЕТ).
⚠️ **ВАЖНО ПРО БЕЗОПАСНОСТЬ:** на Этапе 4 хук тестируется ТОЛЬКО на STAGING-контейнере (`orchestrator-staging`, порт 8501). Боевой прод (`orchestrator`, 8500) хук на этом этапе НЕ ТРОГАЕТ. Поэтому скрипт ДОЛЖЕН быть параметризован по цели (service name + порт health) через аргументы/env, дефолт — БЕЗОПАСНЫЙ (staging), а не прод. Переключение на прод — осознанный шаг Этапа 5 / ручной запуск Славой, НЕ в этом ТЗ.
## ОБРАЗЕЦ (изучить, повторить паттерн PREV_IMG)
`/home/slin/bin/enduro-deploy-hook.sh` (прочитай его на хосте). Из него берём:
- режим `--rollback`: восстановить образ из `$PREV_IMAGE_FILE` (retag PREV_IMG → APP_IMAGE, `docker compose up -d --no-build`), если файла нет — exit !=0.
- normal deploy: захватить ТЕКУЩИЙ образ контейнера ДО рестарта в `$PREV_IMAGE_FILE` (best-effort, не падать), `git pull`, `docker compose up -d`.
- логирование с UTC-таймстампами в лог-файл.
## ЧЕГО У ОБРАЗЦА НЕТ И ЧТО ДОБАВИТЬ (суть ORCH-34)
После рестарта целевого контейнера — **HEALTH-ЦИКЛ**: опрашивать `http://localhost:<PORT>/health` **10 попыток × 6 секунд = до 60с**. Критерий успеха: HTTP 200 И тело содержит `"status":"ok"`.
- Если health стал ok в пределах 60с → деплой успешен, exit 0.
- Если за 60с health НЕ поднялся → **АВТОМАТИЧЕСКИЙ ROLLBACK**: вызвать собственную rollback-ветку (восстановить PREV_IMG, рестарт, и ещё раз health-чек восстановленного — короткий, напр. 5×3с). Залогировать «deploy FAILED, rolled back to PREV_IMG». exit !=0 (чтобы вызывающий конвейер знал о фейле).
- Если и после rollback health не поднялся → залогировать критично «ROLLBACK ALSO FAILED», exit !=0.
## ПАРАМЕТРИЗАЦИЯ (обязательно — для безопасности)
Скрипт принимает (через env-переменные с дефолтами ИЛИ флаги — на твоё усмотрение, задокументируй):
- `TARGET_SERVICE` (имя docker-compose сервиса) — **дефолт `orchestrator-staging`** (НЕ прод!).
- `TARGET_PORT` (порт health) — **дефолт `8501`** (staging).
- `TARGET_IMAGE` (образ для retag при rollback) — дефолт образа staging (узнай реальный: `docker inspect orchestrator-staging --format '{{.Config.Image}}'`).
- `COMPOSE_PROFILE` — для staging нужен профиль `staging` (иначе compose не видит сервис). Учти: `docker compose --profile staging up -d --no-build <svc>`.
- `PREV_IMAGE_FILE` — отдельный файл для staging (напр. `$REPO/.deploy-prev-image-staging`), чтобы НЕ пересекаться с прод-файлом enduro/орка.
- `LOG` — отдельный лог (напр. `/var/log/orchestrator/deploy-hook.log`, создать каталог; если нет прав — fallback в `$REPO/deploy-hook.log`).
- режимы: `--deploy` (дефолт, можно без флага) и `--rollback`.
⚠️ Прод-значения (service `orchestrator`, порт 8500, образ `orchestrator-orchestrator`) скрипт ПОДДЕРЖИВАЕТ через переопределение env, но ДЕФОЛТ — staging. В коде НЕ хардкодить прод как дефолт.
## ⛔ OFF-LIMITS / ПРАВИЛА
- НЕ трогать src/, tests/, docker-compose.yml, .env, .env.staging, существующий `/home/slin/bin/enduro-deploy-hook.sh`. Только НОВЫЙ файл `scripts/orchestrator-deploy-hook.sh` + `docs/DEPLOY_HOOK.md` (как работает, переменные, примеры запуска для staging И прода).
- Тестировать ТОЛЬКО на `orchestrator-staging` (8501). Боевой прод `orchestrator` (8500) НЕ рестартить, НЕ трогать. Если тест может задеть прод — СТОП, отчёт.
- НЕ менять `DEPLOY_HOOK_SCRIPT` в .env прода (переключение хука — Этап 5, не сейчас).
- НЕ регистрировать раннеров, НЕ nohup долгих процессов. Раннер mva154-runner-orch уже есть.
- PR push в main ЗАПРЕЩЁН. НЕ мержить — коммит в ветку + PR.
- Если факт разошёлся с ТЗ — СТОП, отчёт, не угадывать.
## ПРОВЕРКА (обязательный пруф в отчёт) — всё на STAGING
Скрипт лежит в репо (`scripts/`), но для теста его надо запускать НА ХОСТЕ (он дёргает docker compose). Тестовый прогон:
1. **Happy-path:** запустить хук в `--deploy` против staging (TARGET_SERVICE=orchestrator-staging, PORT=8501, profile staging). Показать лог: захват PREV_IMG → рестарт → health стал ok за N секунд → exit 0. После — `curl localhost:8501/health` = ok.
2. **Rollback-path (САМОЕ ВАЖНОЕ):** сэмулировать НЕработающий деплой и доказать авто-откат. Безопасный способ: запустить хук с заведомо «битым» образом ИЛИ временно подменить health-цель на несуществующий порт, чтобы health-цикл провалился → хук должен сам откатиться на PREV_IMG и поднять staging обратно. Показать лог: «health failed after 60s → ROLLBACK → restored PREV_IMG → staging ok again», exit !=0. ПОСЛЕ теста staging ОБЯЗАН быть жив (`curl localhost:8501/health` = ok). Опиши ТОЧНО, как симулировал фейл (чтобы воспроизводимо и без риска проду).
3. **Прод не задет:** `curl localhost:8500/health` = ok, `docker ps` показывает прод `orchestrator` Up без рестарта (сравни uptime до/после).
4. `git log --oneline origin/main..origin/feature/ORCH-34-deploy-hook` — коммит виден ПОСЛЕ push.
⚠️ Если для rollback-теста придётся пересобирать/портить staging-образ — делай это ОБРАТИМО и в самом конце верни staging в рабочее состояние (health ok). НЕ оставляй staging сломанным.
## РЕЗУЛЬТАТ
Новые файлы: `scripts/orchestrator-deploy-hook.sh` (deploy + rollback + health-цикл 10×6с + auto-rollback, параметризован, дефолт staging) + `docs/DEPLOY_HOOK.md`. Оба тест-прогона (happy + rollback) зелёные на staging, прод цел. PR в Gitea. Отчёт → `tasks/orchestrator/reports/dev-2026-06-05-orch34-deploy-hook.md`. Коммит: `feat(staging): add orchestrator deploy hook with health-check and auto-rollback (ORCH-34)`.