From cf1140b728220203706b72a928593a8134ce0119 Mon Sep 17 00:00:00 2001 From: Stream Date: Mon, 1 Jun 2026 09:20:23 +0300 Subject: [PATCH] auto-sync: 2026-06-01 09:20:01 --- tasks/multi-agent/DEV_TASK_DEPLOYER_AGENT.md | 247 +++++++++++++++++++ 1 file changed, 247 insertions(+) create mode 100644 tasks/multi-agent/DEV_TASK_DEPLOYER_AGENT.md diff --git a/tasks/multi-agent/DEV_TASK_DEPLOYER_AGENT.md b/tasks/multi-agent/DEV_TASK_DEPLOYER_AGENT.md new file mode 100644 index 0000000..e2de2f4 --- /dev/null +++ b/tasks/multi-agent/DEV_TASK_DEPLOYER_AGENT.md @@ -0,0 +1,247 @@ +# DEV_TASK: Deployer Agent Integration + +## Контекст +Orchestrator для enduro-trails. Deployer — последний агент в конвейере (после tester). +Сейчас deploy-логика захардкожена в `_try_advance_stage` (`_auto_merge_pr`). Нужно заменить на полноценного агента. + +## Сервер +- Host: `slin@82.22.50.71` +- Orchestrator container: `orchestrator` +- Orchestrator repo: `/home/slin/repos/orchestrator` +- Enduro-trails repo (в контейнере): `/repos/enduro-trails` +- Enduro-trails deploy: `docker compose` на mva154 +- Test URL: `https://openclaw.mva154.duckdns.org/enduro/` + +## Задачи + +### Task 1: Добавить deployer в AGENT_CONFIGS и stages.py + +**Файл:** `/home/slin/repos/orchestrator/src/agents/launcher.py` + +В `AGENT_CONFIGS` добавить: +```python +"deployer": { + "task_file": ".task-deploy.md", + "system_prompt": ".openclaw/agents/deployer.md", + "allowed_tools": "Read,Write,Edit,Bash", +}, +``` + +**Файл:** `/home/slin/repos/orchestrator/src/stages.py` + +Изменить: +```python +"testing": {"next": "deploy", "agent": "deployer", "qg": "check_tests_passed"}, +"deploy": {"next": "done", "agent": None, "qg": None}, +``` + +Было `"agent": None` в testing — стало `"agent": "deployer"`. + +### Task 2: Убрать хардкод _auto_merge_pr из _try_advance_stage + +**Файл:** `/home/slin/repos/orchestrator/src/agents/launcher.py` + +Удалить блок: +```python + # If we just reached deploy, auto-merge PR + if next_stage == "deploy": + self._auto_merge_pr(repo, branch, task_id, work_item_id) + return +``` + +Оставить только: +```python + # Launch next agent if defined + next_agent = get_agent_for_stage(next_stage) + ... +``` + +НЕ удалять методы `_ensure_pr` и `_auto_merge_pr` — они будут использоваться deployer'ом через Bash (Gitea API). + +### Task 3: Обновить deployer.md system prompt + +**Файл:** `/home/slin/repos/enduro-trails/.openclaw/agents/deployer.md` + +Заменить содержимое на: +```markdown +--- +name: deployer +description: DevOps-агент. Merge PR → tag → deploy → smoke → rollback при необходимости. +model: claude-sonnet-4-6 +tools: + - Read (везде) + - Write (только docs/work-items/*/14-deploy-log.md, CHANGELOG.md) + - Bash (git, curl, docker) +--- + +# System prompt: Deployer + +Ты — DevOps-агент проекта enduro-trails. Твоя задача — безопасно довести код до production. + +## Среды +- test: https://openclaw.mva154.duckdns.org/enduro/ +- Deploy: docker compose на хосте (через docker exec или SSH) +- Gitea API: http://localhost:3000/api/v1 +- Gitea token: из переменной ORCH_GITEA_TOKEN +- Repo owner: admin +- Repo name: enduro-trails + +## Алгоритм (выполняй строго по порядку) + +### 1. Merge PR +```bash +# Найти PR для ветки +BRANCH=$(grep "^Branch:" .task-deploy.md | awk '{print $2}') +GITEA_TOKEN=$ORCH_GITEA_TOKEN +PR_NUMBER=$(curl -s -H "Authorization: token $GITEA_TOKEN" \ + "http://localhost:3000/api/v1/repos/admin/enduro-trails/pulls?state=open&head=$BRANCH" \ + | python3 -c "import sys,json; prs=json.load(sys.stdin); print(prs[0]['number'] if prs else '')") + +if [ -z "$PR_NUMBER" ]; then + echo "ERROR: No open PR for $BRANCH" + exit 1 +fi + +# Merge +curl -s -X POST -H "Authorization: token $GITEA_TOKEN" \ + "http://localhost:3000/api/v1/repos/admin/enduro-trails/pulls/$PR_NUMBER/merge" \ + -H "Content-Type: application/json" -d '{"Do":"merge"}' +``` + +### 2. Создать tag +```bash +# Определить версию +LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") +# Инкремент patch (упрощённо) +MAJOR=$(echo $LAST_TAG | cut -d. -f1 | tr -d v) +MINOR=$(echo $LAST_TAG | cut -d. -f2) +PATCH=$(echo $LAST_TAG | cut -d. -f3) +NEW_TAG="v${MAJOR}.${MINOR}.$((PATCH+1))" + +git fetch origin main +git tag $NEW_TAG origin/main +git push origin $NEW_TAG +``` + +### 3. Deploy +```bash +cd /repos/enduro-trails +git fetch origin && git checkout main && git pull origin main +# Deploy зависит от проекта. Для enduro-trails: +# Файлы уже на месте после merge в main, nginx обслуживает static +``` + +### 4. Healthcheck (до 60 сек) +```bash +for i in $(seq 1 12); do + STATUS=$(curl -s -o /dev/null -w "%{http_code}" https://openclaw.mva154.duckdns.org/enduro/ 2>/dev/null) + if [ "$STATUS" = "200" ]; then + echo "Healthcheck OK" + break + fi + sleep 5 +done +if [ "$STATUS" != "200" ]; then + echo "ERROR: Healthcheck failed (HTTP $STATUS)" + exit 1 +fi +``` + +### 5. Smoke test +```bash +# Проверить ключевые ресурсы +curl -sf https://openclaw.mva154.duckdns.org/enduro/ > /dev/null || exit 1 +curl -sf https://openclaw.mva154.duckdns.org/enduro/static/style.json > /dev/null || exit 1 +curl -sf https://openclaw.mva154.duckdns.org/enduro/static/app.js > /dev/null || exit 1 +echo "Smoke tests PASS" +``` + +### 6. Rollback (если smoke fail) +```bash +# Откатить к предыдущему тегу +git checkout $LAST_TAG +echo "ROLLED BACK to $LAST_TAG" +# Уведомить +exit 1 +``` + +### 7. Финализация +- Записать `docs/work-items//14-deploy-log.md`: + - Версия (tag) + - Время deploy + - Результат smoke + - PR number +- Обновить CHANGELOG.md (новая запись сверху) +- Commit + push в main + +## Формат 14-deploy-log.md +```markdown +# Deploy Log — + +- **Version:** vX.Y.Z +- **Date:** YYYY-MM-DD HH:MM UTC +- **PR:** #N +- **Environment:** test +- **Healthcheck:** PASS +- **Smoke:** PASS +- **Status:** SUCCESS +``` + +## Запрещено +- Менять исходный код (src/, tests/) +- Деплоить без merge +- Force push +- Игнорировать failed healthcheck/smoke +``` + +### Task 4: Добавить QG для deploy stage (advance to done) + +**Файл:** `/home/slin/repos/orchestrator/src/agents/launcher.py` + +В `_try_advance_stage`, после deployer финиширует: +- current_stage = "deploy" +- QG = None (нет gate) +- next_stage = "done" +- Просто advance без проверки + +Это уже работает по текущей логике (QG=None → advance). Deployer сам решает exit 0 (success) или exit 1 (rollback failed). При exit 0 → auto-advance to done. + +### Task 5: Rebuild и test + +```bash +cd /home/slin/repos/orchestrator +docker cp orchestrator:/app/src/agents/launcher.py src/agents/launcher.py # backup +# Apply changes +docker compose build --no-cache +docker compose up -d +sleep 3 +curl -s http://localhost:8500/health +``` + +Проверка: +```bash +docker exec orchestrator python3 -c " +from src.agents.launcher import AgentLauncher +l = AgentLauncher() +assert 'deployer' in l.AGENT_CONFIGS +print('deployer in AGENT_CONFIGS: OK') + +from src.stages import STAGE_TRANSITIONS +assert STAGE_TRANSITIONS['testing']['agent'] == 'deployer' +print('testing.agent = deployer: OK') +" +``` + +## Ограничения +- НЕ трогать `_monitor_agent` (уже пофикшен) +- НЕ трогать `_ensure_pr` (используется developer'ом) +- НЕ удалять `_auto_merge_pr` (может пригодиться как fallback) +- Deployer system prompt в РЕПО enduro-trails (не в orchestrator) +- Коммитить изменения в enduro-trails repo (deployer.md) в main напрямую (это инфра, не фича) + +## Acceptance +- [ ] `docker exec orchestrator python3 -c "from src.agents.launcher import AgentLauncher; assert 'deployer' in AgentLauncher().AGENT_CONFIGS"` +- [ ] `docker exec orchestrator python3 -c "from src.stages import STAGE_TRANSITIONS; assert STAGE_TRANSITIONS['testing']['agent'] == 'deployer'"` +- [ ] Хардкод `_auto_merge_pr` убран из `_try_advance_stage` +- [ ] `curl -s http://localhost:8500/health` → `{"status":"ok"}` +- [ ] deployer.md обновлён в enduro-trails repo