--- sidebar_position: 2 title: ローカルGitea × Webhook連携で、AIとの開発をもっと楽にしよう! description: GiteaのIssue/PR WebhookとOpenClawを連携し、実運用で壊れにくく回す開発プロセスを構築する実践記録 hide_table_of_contents: false displayed_sidebar: null --- # ローカルGitea × Webhook連携で、AIとの開発をもっと楽にしよう! ## はじめに 「Issue を立てるだけで、AI がレビューして修正提案まで返してくれたら最高なのに…」 そんな願望から始めたのが、**Gitea Webhook → OpenClaw** の自動レビュー連携です。 最初は「Issue 作成でAIを呼べればOK」と思っていたのですが、実運用に入るとすぐに壁に当たりました。 - `EOF` でWebhookが落ちる - PRを投げても `OK (ignored event)` - ブリッジの別機能改修で本線が壊れる - Gitが苦手なメンバーがブランチ運用で詰まる この記事は、その失敗込みで最終的に安定した **運用可能な形** をまとめたものです。 ## この記事でわかること - Issue / PR の両方をトリガーにする Webhook 設計 - bridge.py の実装で絶対外せない防御ポイント - systemd での安定運用 - 壊れにくいブランチ運用(Git弱者向け手順を毎回添える) - 機能混在で壊れたときの再発防止(リポジトリ分離) ## 全体構成(最新版) ``` ┌─────────┐ Webhook (issues / pull_request) ┌────────────────────┐ │ Gitea │ ────────────────────────────────────→ │ gitea-webhook-bridge │ └─────────┘ │ bridge.py │ └────────┬──────────┘ │ openclaw agent │ code-review-loop │ Issue/PRコメントで返却 ``` ## なぜ最初に壊れたのか(実話) ### 1) `EOF` でDelivery失敗 原因は、Gitea側ではなく受信側でした。`do_POST` 内で例外が出ているのに、HTTPレスポンスを返さず接続が閉じる。 Giteaから見ると `Post ... EOF` です。 **対策:** - `do_POST` 全体を `try/except` で囲む - 例外時も `500` を必ず返す ### 2) PRが無視される Issue対応だけ先に作ると、PRイベントは素通りします。 その結果 `OK (ignored event)`。 **対策:** - `issues` だけでなく `pull_request` も受理 - `opened / reopened / synchronize` を最低限処理 ### 3) 別用途改修でブリッジが壊れる Discord通知などを同じブリッジに混ぜると、修正の副作用でGitea連携が壊れやすい。 **対策:** - 役割ごとにリポジトリを分離 - `gitea-webhook-bridge` - `discord-notify-bridge` - systemdサービスも分離 ## bridge.py の実装指針 ### 受けるイベント - `issues` - `opened` - `pull_request` - `opened` - `reopened` - `synchronize` ### 最低限の処理順 1. 署名検証(`X-Gitea-Signature`) 2. イベント種別チェック 3. アクションチェック 4. タスク本文を整形 5. `openclaw agent` を非同期起動 6. すぐに `200 OK` を返す ### 署名検証は必須 :::warning ローカルネットワークでも署名検証は省略しない方が安全です。 Webhook URLを知っているだけで叩ける状態は避けましょう。 ::: ## Gitea側の設定 ### `ALLOWED_HOST_LIST` を忘れない ```ini title="app.ini" [webhook] ALLOWED_HOST_LIST = private ``` これを忘れると、プライベートIP向けWebhookがブロックされます。 ### Webhookの基本値 - URL: `http://:9876/webhook/gitea` - Content-Type: `application/json` - Secret: bridgeと一致 - Trigger: `issues`, `pull_request` ## systemd常駐(再起動に強い構成) ```ini title="/etc/systemd/system/gitea-webhook-bridge.service" [Unit] Description=Gitea Webhook Bridge for OpenClaw After=network.target [Service] Type=simple User=swallow WorkingDirectory=/home/swallow/gitea-webhook-bridge EnvironmentFile=/home/swallow/gitea-webhook-bridge/.env ExecStart=/usr/bin/python3 /home/swallow/gitea-webhook-bridge/bridge.py Restart=always RestartSec=5 [Install] WantedBy=multi-user.target ``` ```bash sudo systemctl daemon-reload sudo systemctl enable --now gitea-webhook-bridge sudo systemctl status gitea-webhook-bridge ``` ## 開発プロセス(ここが本体) 単にWebhookを動かすだけだと、チーム運用では破綻します。 最終的に安定したのは、以下のルールを固定したからです。 ### ルール1: ブランチ命名を固定 - `fix/issue-<番号>-<要約>` - `feat/issue-<番号>-<要約>` - `docs/issue-<番号>-<要約>` ### ルール2: Issueコメントに毎回「3点セット」 - ブランチ切替手順 - 検証コマンド - mainへの反映手順 これを毎回書くだけで、Gitに不慣れな人の詰まりが激減しました。 ### ルール3: PRイベントでも同じフローでレビュー IssueだけでなくPRでもレビューが走ると、 「修正は出たが最終反映前チェックが抜ける」問題を防げます。 ## Git弱者向けテンプレ(コピペ用) ### 1) 修正ブランチへ切替 ```bash git fetch origin git switch fix/issue-123-xxx # 古いgitなら: git checkout fix/issue-123-xxx ``` ### 2) 検証 ```bash python3 -m py_compile src/*.py app/*.py ``` ### 3) mainへ反映 ```bash git switch main git pull origin main git merge --no-ff fix/issue-123-xxx git push origin main ``` ### 4) 後片付け(任意) ```bash git branch -d fix/issue-123-xxx git push origin --delete fix/issue-123-xxx ``` ## 今後の拡張 - ラベル付きIssueのみ処理(`ai-review` など) - PRへの自動レビューコメント整形 - 失敗時の自動再試行と通知 - レビュー結果のダッシュボード化 ## まとめ Gitea × OpenClaw 連携は、作るだけなら簡単です。 でも、**壊れずに回す**には運用設計がすべてでした。 - Issue + PR イベント対応 - EOF対策(例外時も必ず応答) - ブリッジの責務分離 - ブランチ/手順テンプレの固定 この4点を押さえると、AI連携は実務で使えるレベルまで安定します。 --- *この記事は2026年2月時点の情報です。*