Files
wiki/tasks/multi-agent/DEV_TASK_DEPLOYER_AGENT.md
2026-06-01 09:20:23 +03:00

8.0 KiB
Raw Blame History

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 добавить:

"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

Изменить:

"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

Удалить блок:

            # If we just reached deploy, auto-merge PR
            if next_stage == "deploy":
                self._auto_merge_pr(repo, branch, task_id, work_item_id)
                return

Оставить только:

            # 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

Заменить содержимое на:

---
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

# Определить версию
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

cd /repos/enduro-trails
git fetch origin && git checkout main && git pull origin main
# Deploy зависит от проекта. Для enduro-trails:
# Файлы уже на месте после merge в main, nginx обслуживает static

4. Healthcheck (до 60 сек)

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

# Проверить ключевые ресурсы
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)

# Откатить к предыдущему тегу
git checkout $LAST_TAG
echo "ROLLED BACK to $LAST_TAG"
# Уведомить
exit 1

7. Финализация

  • Записать docs/work-items/<WORK_ITEM_ID>/14-deploy-log.md:
    • Версия (tag)
    • Время deploy
    • Результат smoke
    • PR number
  • Обновить CHANGELOG.md (новая запись сверху)
  • Commit + push в main

Формат 14-deploy-log.md

# Deploy Log — <WORK_ITEM_ID>

- **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

Проверка:

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