Files
orchestrator/docs/SETUP_WEBHOOKS.md
Dev Agent b545665e2d feat: full pipeline fixes - CI status branch lookup, review webhook routing, auto-advance, plane sync
- handle_ci_status: fallback git branch -r --contains when branches[] empty
- webhook router: handle pull_request_approved event type
- handle_pr: map review.type to review.state for new Gitea format
- launcher: auto-advance stage after agent completion (_try_advance_stage)
- plane_sync: notify Plane on stage changes
- stages.py: stage machine with QG definitions
- notifications.py: stage change notifications
- safe.directory fix for container git operations
2026-05-22 01:57:02 +03:00

164 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Webhook Setup: Plane + Gitea → Orchestrator
## Архитектура
```
Gitea (push/PR/CI) ──→ Nginx proxy ──→ Orchestrator /webhook/gitea
Plane (work_item/comment) ──→ Nginx proxy ──→ Orchestrator /webhook/plane
```
External URL: `https://openclaw.mva154.duckdns.org/orchestrator/`
Internal URL: `http://127.0.0.1:8500/`
---
## Gitea Webhook
**Создан автоматически через API.**
- URL: `https://openclaw.mva154.duckdns.org/orchestrator/webhook/gitea`
- Events: `push`, `pull_request`, `status`
- Secret: значение `ORCH_GITEA_WEBHOOK_SECRET` в `.env`
- Signature header: `X-Gitea-Signature` (HMAC-SHA256 hex digest)
### Проверка
```bash
GITEA_TOKEN=$(grep ORCH_GITEA_TOKEN /home/slin/repos/orchestrator/.env | cut -d= -f2)
curl -s "http://localhost:3000/api/v1/repos/admin/enduro-trails/hooks" \
-H "Authorization: token ${GITEA_TOKEN}" | python3 -m json.tool
```
### Пересоздание (если нужно)
```bash
GITEA_WEBHOOK_SECRET=$(openssl rand -hex 20)
# Обновить в .env: ORCH_GITEA_WEBHOOK_SECRET=<new_secret>
curl -X POST "http://localhost:3000/api/v1/repos/admin/enduro-trails/hooks" \
-H "Authorization: token ${GITEA_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"type": "gitea",
"active": true,
"config": {
"url": "https://openclaw.mva154.duckdns.org/orchestrator/webhook/gitea",
"content_type": "json",
"secret": "'${GITEA_WEBHOOK_SECRET}'"
},
"events": ["push", "pull_request", "status"],
"branch_filter": "*"
}'
```
---
## Plane Webhook
**Создан напрямую в PostgreSQL** (Plane CE не экспортирует webhook API через внешний /api/v1/).
- URL: `https://openclaw.mva154.duckdns.org/orchestrator/webhook/plane`
- Events: `issue` (work_item.created), `issue_comment` (comment.created)
- Secret: значение `ORCH_PLANE_WEBHOOK_SECRET` в `.env`
- Signature header: `X-Plane-Signature` (HMAC-SHA256 hex digest)
### Проверка
```bash
docker exec -e PGPASSWORD=plane plane-app-plane-db-1 psql -U plane -d plane -c \
"SELECT id, url, is_active FROM webhooks;"
```
### Ручная настройка через UI (альтернатива)
1. Открыть `https://plane.mva154.duckdns.org`
2. Workspace Settings → Webhooks → Add Webhook
3. URL: `https://openclaw.mva154.duckdns.org/orchestrator/webhook/plane`
4. Secret: значение из `ORCH_PLANE_WEBHOOK_SECRET` в `.env`
5. Events: Issue, Issue Comment
6. Save
### Пересоздание через SQL
```bash
PLANE_WEBHOOK_SECRET=$(openssl rand -hex 20)
# Обновить в .env: ORCH_PLANE_WEBHOOK_SECRET=<new_secret>
WORKSPACE_ID=$(docker exec -e PGPASSWORD=plane plane-app-plane-db-1 psql -U plane -d plane -t -A -c \
"SELECT id FROM workspaces WHERE slug='ag_proj'")
WEBHOOK_ID=$(cat /proc/sys/kernel/random/uuid)
docker exec -e PGPASSWORD=plane plane-app-plane-db-1 psql -U plane -d plane -c "
INSERT INTO webhooks (id, created_at, updated_at, deleted_at, workspace_id, url, is_active, secret_key, project, issue, module, cycle, issue_comment, is_internal, version)
VALUES ('${WEBHOOK_ID}', NOW(), NOW(), NULL, '${WORKSPACE_ID}',
'https://openclaw.mva154.duckdns.org/orchestrator/webhook/plane',
true, '${PLANE_WEBHOOK_SECRET}', true, true, false, false, true, false, 'v1');
"
```
---
## HMAC Signature Verification
Оба handler'а проверяют подпись:
- Если secret пустой в `.env` — верификация пропускается (для dev/debug)
- Если secret задан — запрос без валидной подписи получает `401 Unauthorized`
### Формат подписи
| Source | Header | Algorithm | Format |
|--------|--------|-----------|--------|
| Gitea | `X-Gitea-Signature` | HMAC-SHA256 | hex digest (без префикса) |
| Plane | `X-Plane-Signature` | HMAC-SHA256 | hex digest |
### Тест подписи вручную
```bash
SECRET=$(grep ORCH_GITEA_WEBHOOK_SECRET /home/slin/repos/orchestrator/.env | cut -d= -f2)
BODY='{"ref":"refs/heads/test","repository":{"name":"enduro-trails"},"commits":[]}'
SIG=$(echo -n "${BODY}" | openssl dgst -sha256 -hmac "${SECRET}" | awk '{print $NF}')
curl -X POST http://localhost:8500/webhook/gitea \
-H "Content-Type: application/json" \
-H "X-Gitea-Event: push" \
-H "X-Gitea-Signature: ${SIG}" \
-d "${BODY}"
# Expected: {"status":"accepted"}
```
---
## Переменные окружения (.env)
| Переменная | Описание |
|-----------|----------|
| `ORCH_GITEA_WEBHOOK_SECRET` | HMAC secret для Gitea webhook |
| `ORCH_PLANE_WEBHOOK_SECRET` | HMAC secret для Plane webhook |
| `ORCH_GITEA_TOKEN` | API token для Gitea |
| `ORCH_PLANE_API_TOKEN` | API token для Plane |
---
## Troubleshooting
```bash
# Логи Orchestrator
docker logs orchestrator --tail 50 2>&1 | grep -i "webhook\|signature\|401"
# События в БД
docker exec orchestrator python3 -c "
import sqlite3
conn = sqlite3.connect('/app/data/orchestrator.db')
for r in conn.execute('SELECT id, source, event_type, timestamp FROM events ORDER BY id DESC LIMIT 10').fetchall():
print(r)
"
# Gitea webhook delivery history
# Gitea UI → Settings → Webhooks → click webhook → Recent Deliveries
```
---
*Создано: 2026-05-21 | Автор: Dev-агент*