Testing GitHub Webhooks Locally: A Complete Guide
You want push events, PR notifications, or deploy triggers from GitHub to hit your local machine. Here's every way to do it.
Why GitHub Webhooks Locally?
Common use cases:
- CI/CD pipelines that trigger local builds
- AI agents that respond to code changes
- Bots that comment on PRs
- Deploy automation from push events
Method 1: GitHub CLI + Webhook Forwarding
GitHub doesn't have a built-in equivalent to stripe listen, but you can use their REST API to configure webhooks pointing at a tunnel.
Method 2: ngrok + GitHub Webhook
ngrok http 3000
# Copy the URL, e.g. https://abc123.ngrok.ioThen in GitHub repo settings:
- Go to Settings > Webhooks > Add webhook
- Payload URL:
https://abc123.ngrok.io/api/github-webhook - Content type:
application/json - Secret: generate a random string
- Select events you want
Problem: Free ngrok URLs change every restart. You'll need to update the GitHub webhook config each time.
Method 3: Tryb with Stable Subdomain
import tryb
client = tryb.connect(subdomain="my-gh-bot")
# URL is always: https://my-gh-bot.tryb.dev/hook/my-gh-botSet the webhook URL once in GitHub. It never changes. If your agent goes offline, events are queued for 24h.
Verifying GitHub Signatures
GitHub signs webhooks with HMAC-SHA256. Always verify:
import hmac
import hashlib
def verify_github_signature(payload, signature, secret):
expected = "sha256=" + hmac.new(
secret.encode(),
payload,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)Or let Tryb's firewall verify it automatically at the relay level.
Common GitHub Webhook Events
| Event | Trigger |
|---|---|
push | Code pushed to any branch |
pull_request | PR opened, closed, merged |
issues | Issue created or updated |
release | New release published |
workflow_run | GitHub Action completed |
Related
Ready to secure your agents?
Tryb gives you a firewall, a persistent event queue, and human-in-the-loop approvals. Free tier included -- no credit card required.