# ADR-059: Gitea Webhook 整合 (GitHub → Gitea 遷移) **日期**: 2026-04-05 (台北時區) **狀態**: ✅ 已批准 **決策者**: 首席架構師 + 統帥 --- ## 背景 Phase 13.1 實作了 GitHub Webhook → OpenClaw AI 代碼審查整合,但: 1. CI/CD 已於 ADR-039 全面遷移至 Gitea,GitHub 只剩唯讀備份 2. `GITHUB_WEBHOOK_SECRET` 從未注入 K8s Secrets,功能實際處於死路狀態 3. 代碼審查的觸發源應改為 Gitea(實際開發倉庫) --- ## 決策 **遷移至 Gitea Webhook,廢棄 GitHub Webhook 整合。** 採用最少改動策略 (Minimal Viable Change):Gitea 與 GitHub 的 webhook payload 欄位幾乎相同,差異只在 HTTP header 名稱,因此只做 Header 常數替換,業務邏輯層完全不動。 --- ## Header 差異對照 | 項目 | GitHub (廢棄) | Gitea (新) | |------|-------------|-----------| | 事件類型 Header | `X-GitHub-Event` | `X-Gitea-Event` | | 簽章 Header | `X-Hub-Signature-256` | `X-Gitea-Signature` | | 投遞 ID Header | `X-GitHub-Delivery` | `X-Gitea-Delivery` | | 簽章格式 | `sha256=` | `sha256=` ← **相同** | | Payload 欄位 | — | — ← **幾乎相同** | --- ## 支援事件 | 事件 | 說明 | |------|------| | `pull_request` | PR 代碼審查 (opened/synchronize/reopened) | | `push` | 主分支推送審查 | | `ping` | 連線測試 | | `workflow_run` | **廢棄** (CD pipeline 已有 Telegram 通知,重複覆蓋無必要) | --- ## 變更範圍 | 檔案 | 動作 | |------|------| | `src/api/v1/github_webhook.py` | 保留(歷史參考),不刪除 | | `src/api/v1/gitea_webhook.py` | 新建,Header 改 Gitea,移除 workflow_run handler | | `src/services/github_webhook_service.py` | 保留(歷史參考),不刪除 | | `src/services/gitea_webhook_service.py` | 新建,_fetch_pr_diff 改用直接 httpx(不依賴 github_api_service) | | `src/main.py` | 掛載 gitea_webhook_router,路徑 `/api/v1/webhooks/gitea` | | `src/core/config.py` | 新增 `GITEA_WEBHOOK_SECRET`、`GITEA_ALLOWED_REPOS` | | `k8s/awoooi-prod/03-secrets.yaml` | 新增 `GITEA_WEBHOOK_SECRET` 佔位 | | `.gitea/workflows/cd.yaml` | 新增 `GITEA_WEBHOOK_SECRET` 注入步驟 | | `tests/test_gitea_webhook.py` | 新建,Header 改 Gitea | | `tests/conftest.py` | `GITEA_WEBHOOK_SECRET`、`GITEA_ALLOWED_REPOS` 環境變數 | --- ## API 端點 ``` 新: POST /api/v1/webhooks/gitea 新: GET /api/v1/webhooks/gitea/reviews/{review_id} 舊: POST /api/v1/webhooks/github ← 仍掛載但未用 ``` --- ## 安全設計 - HMAC-SHA256 簽章驗證 (X-Gitea-Signature) - Fail-Closed: 生產環境未設 `GITEA_WEBHOOK_SECRET` → 直接拒絕 - 倉庫白名單: `GITEA_ALLOWED_REPOS`(預設 `wooo/awoooi`) - 所有欄位存取使用 `.get()` chain,防止 Gitea nullable 欄位 KeyError --- ## Gitea UI 設定 1. `http://192.168.0.110:3001/wooo/awoooi` → Settings → Webhooks → Add Webhook → Gitea 2. **Target URL**: `https://awoooi.wooo.work/api/v1/webhooks/gitea` 3. **Content Type**: `application/json` ← 必須明確選擇 4. **Secret**: 與 `GITEA_WEBHOOK_SECRET` K8s Secret 值相同 5. **Trigger On**: Pull Request events + Push events --- ## 後置待辦 - [ ] Gitea Actions secret `GITEA_WEBHOOK_SECRET` 設定(統帥操作) - [ ] Gitea UI Webhook 設定(統帥操作) - [ ] K8s Secret 手動 patch 首次注入 - [ ] E2E 驗證:觸發一次 PR → 收到 Telegram 代碼審查通知 --- ## 參考 - ADR-039: Gitea CI/CD 遷移 - ADR-029: CI/CD AI 整合架構 - Phase 13.1: GitHub PR Review 原始實作