الأكاديمية ← أدلة تطبيقيةتوثيق رسمي · إرشاد عربي

تعليقات GitHub تلقائية عبر Webhooks

Automated GitHub PR Comments with Webhooks

متوسط11 دقيقة قراءةالدرس 145 أسئلة✓ 2026-08-18
قبل أن تقرأ

ما هذه الصفحة، وماذا تحتوي.

الخطافات: أن تربط كودك بلحظة معيّنة: قبل تشغيل أداة، بعد انتهاء مهمة، عند وصول رسالة. تضيف تحقّقاتك وقيودك من دون تعديل Hermes نفسه. الصفحة فيها تحذير من المصدر، و11 دقيقة قراءة. انتبه: الخطاف يعمل في كل مرة يقع فيها الحدث. اجعله سريعًا، وتعامل مع فشله بوضوح.

14أقسام
13أمثلة برمجية
2جداول
2أوامر
1,892كلمة من المصدر
الوصف الرسمي في سطر

Connect Hermes to GitHub so it automatically fetches PR diffs, reviews code changes, and posts comments — triggered by webhooks with no manual prompting

ماذا ستستطيع بعدها

نتائج مأخوذة من هذه الصفحة، لا من قالب.

  • تعرف ما الخطافات ولماذا قد تحتاجه.
  • تنفّذ hermes gateway وhermes webhook subscribe وتفهم ما يحدث بعدها.
  • تقرأ الجدول وتأخذ منه السطر الذي يخصّك فقط.
  • تضبط HERMES_HOME في المكان الصحيح.
ما ستقابله من أسماء

كما تظهر تمامًا داخل Hermes.

الأوامر
  • hermes gateway
  • hermes webhook subscribe
متغيرات البيئة
  • HERMES_HOME
  • INSECURE_NO_AUTH
خريطة الصفحة

انتقل مباشرة إلى ما تحتاجه.

  1. 01Prerequisites
  2. 02Step 1 — Enable the webhook platform
  3. 03Step 2 — Start the gateway
  4. 04Step 3 — Register the webhook on GitHub
  5. 05Step 4 — Open a test PR
  6. 06Local testing with ngrok
  7. 07Filtering to specific actions
  8. 08Using a skill for consistent review style
  9. 09Sending responses to Slack or Discord instead
  10. 10GitLab support
  11. 11Security notes
  12. 12Troubleshooting
  13. 13Full config reference
  14. 14What's Next?
الصفحة الرسمية كاملة

بلا اختصار أو حذف.

النص أدناه منقول من المصدر الرسمي بالإنجليزية حتى تبقى الأوامر والأسماء دقيقة كما هي. قبل كل قسم شرح عربي يوضّح ما بداخله.

This guide walks you through connecting Hermes Agent to GitHub so it automatically fetches a pull request's diff, analyzes the code changes, and posts a comment — triggered by a webhook event with no manual prompting.

When a PR is opened or updated, GitHub sends a webhook POST to your Hermes instance. Hermes runs the agent with a prompt that instructs it to retrieve the diff via the gh CLI, and the response is posted back to the PR thread.

---

Prerequisites

أوامر تكتبها في الطرفية. افهم ما يفعله الأمر قبل نسخه. الأوامر هنا: hermes gateway.

  • Hermes Agent installed and running (hermes gateway)
  • gh CLI ↗ installed and authenticated on the gateway host (gh auth login)
  • A publicly reachable URL for your Hermes instance (see Local testing with ngrok ↗ if running locally)
  • Admin access to the GitHub repository (required to manage webhooks)

---

Step 1 — Enable the webhook platform

خطوات عملية بالترتيب. نفّذ خطوة وتأكد أنها نجحت قبل الانتقال للتالية.

Add the following to your ~/.hermes/config.yaml:

YAML35 سطرًا
platforms:
  webhook:
    enabled: true
    extra:
      port: 8644          # default; change if another service occupies this port
      rate_limit: 30      # max requests per minute per route (not a global cap)

      routes:
        github-pr-review:
          secret: "your-webhook-secret-here"   # must match the GitHub webhook secret exactly
          events:
            - pull_request

          # The agent is instructed to fetch the actual diff before reviewing.
          # {number} and {repository.full_name} are resolved from the GitHub payload.
          prompt: |
            A pull request event was received (action: {action}).

            PR #{number}: {pull_request.title}
            Author: {pull_request.user.login}
            Branch: {pull_request.head.ref} → {pull_request.base.ref}
            Description: {pull_request.body}
            URL: {pull_request.html_url}

            If the action is "closed" or "labeled", stop here and do not post a comment.

            Otherwise:
            1. Run: gh pr diff {number} --repo {repository.full_name}
            2. Review the code changes for correctness, security issues, and clarity.
            3. Write a concise, actionable review comment and post it.

          deliver: github_comment
          deliver_extra:
            repo: "{repository.full_name}"
            pr_number: "{number}"

Key fields:

FieldDescription
secret (route-level)HMAC secret for this route. Falls back to extra.secret global if omitted.
eventsList of X-GitHub-Event header values to accept. Empty list = accept all.
promptTemplate; {field} and {nested.field} resolve from the GitHub payload.
delivergithub_comment posts via gh pr comment. log just writes to the gateway log.
deliver_extra.repoResolves to e.g. org/repo from the payload.
deliver_extra.pr_numberResolves to the PR number from the payload.

---

Step 2 — Start the gateway

خطوات عملية بالترتيب. نفّذ خطوة وتأكد أنها نجحت قبل الانتقال للتالية. الأوامر هنا: hermes gateway.

Shellسطر واحد
hermes gateway

You should see:

Textسطر واحد
[webhook] Listening on 0.0.0.0:8644 — routes: github-pr-review

Verify it's running:

Shellسطران
curl http://localhost:8644/health
# {"status": "ok", "platform": "webhook"}

---

Step 3 — Register the webhook on GitHub

خطوات عملية بالترتيب. نفّذ خطوة وتأكد أنها نجحت قبل الانتقال للتالية.

  1. Go to your repository → Settings → Webhooks → Add webhook
  2. Fill in:
  3. Payload URL: https://your-public-url.example.com/webhooks/github-pr-review
  4. Content type: application/json
  5. Secret: the same value you set for secret in the route config
  6. Which events? → Select individual events → check Pull requests
  7. Click Add webhook

GitHub will immediately send a ping event to confirm the connection. It is safely ignored — ping is not in your events list — and returns {"status": "ignored", "event": "ping"}. It is only logged at DEBUG level, so it won't appear in the console at the default log level.

---

Step 4 — Open a test PR

خطوات عملية بالترتيب. نفّذ خطوة وتأكد أنها نجحت قبل الانتقال للتالية.

Create a branch, push a change, and open a PR. Within 30–90 seconds (depending on PR size and model), Hermes should post a review comment.

To follow the agent's progress in real time:

Shellسطر واحد
tail -f "${HERMES_HOME:-$HOME/.hermes}/logs/gateway.log"

---

Local testing with ngrok

إعدادات تضبطها مرة وتنساها. غيّر واحدًا في كل مرة حتى تعرف أثر كل تغيير. الأوامر هنا: hermes webhook subscribe. تضبط HERMES_HOME خارج المحادثة، في بيئة التشغيل.

If Hermes is running on your laptop, use ngrok ↗ to expose it:

Shellسطر واحد
ngrok http 8644

Copy the https://...ngrok-free.app URL and use it as your GitHub Payload URL. On the free ngrok tier the URL changes each time ngrok restarts — update your GitHub webhook each session. Paid ngrok accounts get a static domain.

You can smoke-test a static route directly with curl — no GitHub account or real PR needed.

Shell10 أسطر
SECRET="your-webhook-secret-here"
BODY='{"action":"opened","number":99,"pull_request":{"title":"Test PR","body":"Adds a feature.","user":{"login":"testuser"},"head":{"ref":"feat/x"},"base":{"ref":"main"},"html_url":"https://github.com/org/repo/pull/99"},"repository":{"full_name":"org/repo"}}'
SIG=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$SECRET" -hex | awk '{print "sha256="$2}')

curl -s -X POST http://localhost:8644/webhooks/github-pr-review \
  -H "Content-Type: application/json" \
  -H "X-GitHub-Event: pull_request" \
  -H "X-Hub-Signature-256: $SIG" \
  -d "$BODY"
# Expected: {"status":"accepted","route":"github-pr-review","event":"pull_request","delivery_id":"..."}

Then watch the agent run:

Shellسطر واحد
tail -f "${HERMES_HOME:-$HOME/.hermes}/logs/gateway.log"

---

Filtering to specific actions

فيه تحذير مهم. اقرأه قبل أن تنفّذ أي شيء من هذا القسم. نصّ التحذير من المصدر مذكور أسفل هذا الشرح.

GitHub sends pull_request events for many actions: opened, synchronize, reopened, closed, labeled, etc. The events list filters by the X-GitHub-Event header value, and route-level filters can narrow by payload fields such as action.

The prompt in Step 1 already handles this by instructing the agent to stop early for closed and labeled events.

There is no Jinja2 or conditional template syntax. {field} and {nested.field} are the only substitutions supported. Anything else is passed verbatim to the agent.

---

Using a skill for consistent review style

إعدادات تضبطها مرة وتنساها. غيّر واحدًا في كل مرة حتى تعرف أثر كل تغيير.

Load a Hermes skill to give the agent a consistent review persona. Add skills to your route inside platforms.webhook.extra.routes in config.yaml:

YAML25 سطرًا
platforms:
  webhook:
    enabled: true
    extra:
      routes:
        github-pr-review:
          secret: "your-webhook-secret-here"
          events: [pull_request]
          prompt: |
            A pull request event was received (action: {action}).
            PR #{number}: {pull_request.title} by {pull_request.user.login}
            URL: {pull_request.html_url}

            If the action is "closed" or "labeled", stop here and do not post a comment.

            Otherwise:
            1. Run: gh pr diff {number} --repo {repository.full_name}
            2. Review the diff using your review guidelines.
            3. Write a concise, actionable review comment and post it.
          skills:
            - review
          deliver: github_comment
          deliver_extra:
            repo: "{repository.full_name}"
            pr_number: "{number}"
Note: Only the first skill in the list that is found is loaded. Hermes does not stack multiple skills — subsequent entries are ignored.

---

Sending responses to Slack or Discord instead

إعدادات تضبطها مرة وتنساها. غيّر واحدًا في كل مرة حتى تعرف أثر كل تغيير.

Replace the deliver and deliver_extra fields inside your route with your target platform:

YAML11 سطرًا
# Inside platforms.webhook.extra.routes.<route-name>:

# Slack
deliver: slack
deliver_extra:
  chat_id: "C0123456789"   # Slack channel ID (omit to use the configured home channel)

# Discord
deliver: discord
deliver_extra:
  chat_id: "987654321012345678"  # Discord channel ID (omit to use home channel)

The target platform must also be enabled and connected in the gateway. If chat_id is omitted, the response is sent to that platform's configured home channel.

Valid deliver values: log · github_comment · telegram · discord · slack · signal · sms

---

GitLab support

إعدادات تضبطها مرة وتنساها. غيّر واحدًا في كل مرة حتى تعرف أثر كل تغيير.

The same adapter works with GitLab. GitLab uses X-Gitlab-Token for authentication (plain string match, not HMAC) — Hermes handles both automatically.

For event filtering, GitLab sets X-GitLab-Event to values like Merge Request Hook, Push Hook, Pipeline Hook. Use the exact header value in events:

YAMLسطران
events:
  - Merge Request Hook

GitLab payload fields differ from GitHub's — e.g. {object_attributes.title} for the MR title and {object_attributes.iid} for the MR number. The easiest way to discover the full payload structure is GitLab's Test button in your webhook settings, combined with the Recent Deliveries log. Alternatively, omit prompt from your route config — Hermes will then pass the full payload as formatted JSON directly to the agent, and the agent's response (visible in the gateway log with deliver: log) will describe its structure.

---

Security notes

إعدادات تضبطها مرة وتنساها. غيّر واحدًا في كل مرة حتى تعرف أثر كل تغيير. تضبط INSECURE_NO_AUTH خارج المحادثة، في بيئة التشغيل.

  • Never use INSECURE_NO_AUTH in production — it disables signature validation entirely. It is only for local development.
  • Rotate your webhook secret periodically and update it in both GitHub (webhook settings) and your config.yaml.
  • Rate limiting is 30 req/min per route by default (configurable via extra.rate_limit). Exceeding it returns 429.
  • Duplicate deliveries (webhook retries) are deduplicated via a 1-hour idempotency cache. The cache key is X-GitHub-Delivery if present, then X-Request-ID, then a millisecond timestamp. When neither delivery ID header is set, retries are not deduplicated.
  • Prompt injection: PR titles, descriptions, and commit messages are attacker-controlled. Malicious PRs could attempt to manipulate the agent's actions. Run the gateway in a sandboxed environment (Docker, VM) when exposed to the public internet.

---

Troubleshooting

قسم لحل المشكلات. ابحث فيه عن العطل الذي يشبه حالتك بدل قراءته كاملًا.

SymptomCheck
401 Invalid signatureSecret in config.yaml doesn't match GitHub webhook secret
404 Unknown routeRoute name in the URL doesn't match the key in routes:
429 Rate limit exceeded30 req/min per route exceeded — common when re-delivering test events from GitHub's UI; wait a minute or raise extra.rate_limit
No comment postedgh not installed, not on PATH, or not authenticated (gh auth login)
Agent runs but no commentCheck the gateway log — if the agent output was empty or just "SKIP", delivery is still attempted
Port already in useChange extra.port in config.yaml
Agent runs but reviews only the PR descriptionThe prompt isn't including the gh pr diff instruction — the diff is not in the webhook payload
Can't see the ping eventIgnored events return {"status":"ignored","event":"ping"} at DEBUG log level only — check GitHub's delivery log (repo → Settings → Webhooks → your webhook → Recent Deliveries)

GitHub's Recent Deliveries tab (repo → Settings → Webhooks → your webhook) shows the exact request headers, payload, HTTP status, and response body for every delivery. It is the fastest way to diagnose failures without touching your server logs.

---

Full config reference

إعدادات تضبطها مرة وتنساها. غيّر واحدًا في كل مرة حتى تعرف أثر كل تغيير.

YAML17 سطرًا
platforms:
  webhook:
    enabled: true
    extra:
      port: 8644               # listen port (default: 8644)
      secret: ""               # optional global fallback secret
      rate_limit: 30           # requests per minute per route
      max_body_bytes: 1048576  # payload size limit in bytes (default: 1 MB)

      routes:
        <route-name>:
          secret: "required-per-route"
          events: []            # [] = accept all; otherwise list X-GitHub-Event values
          prompt: ""            # {field} / {nested.field} resolved from payload
          skills: []            # first matching skill is loaded (only one)
          deliver: "log"        # log | github_comment | telegram | discord | slack | signal | sms
          deliver_extra: {}     # repo + pr_number for github_comment; chat_id for others

---

What's Next?

شرح للفكرة نفسها. اقرأه ببطء، فبقية الأقسام تبني عليه. تذكير: أن تربط كودك بلحظة معيّنة: قبل تشغيل أداة، بعد انتهاء مهمة، عند وصول رسالة.

اختبار الفهم

5 أسئلة إجاباتها كلها في هذه الصفحة.

كل خيار اسم حقيقي من توثيق Hermes. حتى الخيارات الخاطئة حقيقية، لكنها من صفحات أخرى.

1. في جدول هذا الدرس، ما «Description» المقابل لـ«prompt»؟
2. أي متغير بيئة من التالي يظهر فعليًا في هذا الدرس؟
3. ما التحذير الذي يذكره المصدر في هذا الدرس؟
4. أي عنوان من التالي لا يظهر في هذا الدرس؟
5. أي مفتاح إعداد يظهر في أمثلة هذا الدرس؟