GitHub Webhook Setup Skill
Configure GitHub webhooks for automatic deployment on push events.
Quick Start
To add a new repo for auto-deployment:
- •Provide the repository name (e.g., "my-project")
- •Confirm the local project path exists on the server
- •Follow the GitHub webhook configuration steps
Example: "Set up webhook for my-project repo"
Table of Contents
- •When to Use This Skill
- •What This Skill Does
- •Instructions
- •3.1 Verify WEBHOOK_SECRET
- •3.2 Check Endpoint Accessibility
- •3.3 Add Hook Configuration
- •3.4 Guide GitHub Setup
- •3.5 Test the Webhook
- •3.6 Verify Deployment
- •Supporting Files
- •Expected Outcomes
- •Requirements
- •Red Flags to Avoid
When to Use This Skill
Explicit Triggers:
- •"Set up webhook for [repo]"
- •"Add GitHub auto-deploy for [repo]"
- •"Configure webhook for [repository]"
- •"New repo needs auto-deployment"
Implicit Triggers:
- •Creating a new project that needs CI/CD
- •Setting up a new service in the infrastructure
- •Migrating a project to this server
Debugging Triggers:
- •"Webhook not triggering"
- •"Push event not deploying"
- •"GitHub webhook returning 403/401"
- •"Deployment not working"
What This Skill Does
- •Verifies Environment - Checks WEBHOOK_SECRET exists (generates if needed)
- •Tests Accessibility - Confirms webhook.temet.ai endpoint responds
- •Configures Hook - Adds entry to hooks.json for the new repo
- •Guides GitHub Setup - Provides exact steps for GitHub webhook configuration
- •Tests Integration - Validates webhook receives events correctly
- •Verifies Deployment - Confirms push triggers deployment script
Instructions
3.1 Verify WEBHOOK_SECRET
Check if WEBHOOK_SECRET exists in .env:
grep -E "^WEBHOOK_SECRET=" /home/dawiddutoit/projects/network/.env
If missing or placeholder value, generate a new secret:
openssl rand -hex 32
Add to .env:
WEBHOOK_SECRET=<generated-hex-string>
Important: After updating .env, restart the webhook container:
cd /home/dawiddutoit/projects/network && docker compose restart webhook
3.2 Check Endpoint Accessibility
Test the webhook health endpoint:
curl -I https://webhook.temet.ai/hooks/health
Expected response:
HTTP/2 200 content-type: text/plain; charset=utf-8
If not accessible:
- •Check Cloudflare tunnel is running:
docker ps | grep cloudflared - •Verify bypass policy exists for webhook.temet.ai
- •Check webhook container:
docker ps | grep webhook - •View webhook logs:
docker logs webhook --tail 50
3.3 Add Hook Configuration
Location: /home/dawiddutoit/projects/network/config/hooks.json
Template for new hook:
{
"id": "<repo-name>",
"execute-command": "/scripts/deploy.sh",
"command-working-directory": "/projects/<repo-name>",
"pass-arguments-to-command": [
{
"source": "payload",
"name": "repository.full_name"
}
],
"trigger-rule": {
"and": [
{
"match": {
"type": "payload-hmac-sha256",
"secret": "WEBHOOK_SECRET",
"parameter": {
"source": "header",
"name": "X-Hub-Signature-256"
}
}
},
{
"match": {
"type": "value",
"value": "refs/heads/main",
"parameter": {
"source": "payload",
"name": "ref"
}
}
}
]
},
"response-message": "Deployment triggered for <repo-name>"
}
Key Fields:
| Field | Description |
|---|---|
id | Hook identifier (used in webhook URL) |
command-working-directory | Path where repo is cloned on server |
trigger-rule.match[1].value | Branch to trigger on (usually refs/heads/main) |
Steps to add:
- •Read current hooks.json
- •Add new entry to the array (before closing
]) - •Restart webhook container:
docker compose restart webhook
3.4 Guide GitHub Setup
Provide these exact instructions to the user:
GITHUB WEBHOOK CONFIGURATION 1. Go to your repository on GitHub 2. Click: Settings -> Webhooks -> Add webhook 3. Configure the webhook: - Payload URL: https://webhook.temet.ai/hooks/<repo-name> - Content type: application/json - Secret: <value-from-WEBHOOK_SECRET-in-.env> - SSL verification: Enable SSL verification (checked) 4. Events: - Select: "Just the push event" 5. Active: Checked 6. Click "Add webhook"
Important: The secret in GitHub MUST match WEBHOOK_SECRET in .env exactly.
3.5 Test the Webhook
Option A: Push to trigger
# Make a small change and push to main branch git commit --allow-empty -m "Test webhook" git push origin main
Option B: GitHub UI test
- •Go to repo Settings -> Webhooks
- •Click on the webhook
- •Go to "Recent Deliveries" tab
- •Click "Redeliver" on any delivery (or wait for a push)
Check webhook received the event:
docker logs webhook --tail 20
Expected log output:
[webhook] incoming HTTP request from X.X.X.X POST /hooks/<repo-name> [webhook] <repo-name> got matched [webhook] executing /scripts/deploy.sh
3.6 Verify Deployment
Check deployment script executed:
# View deploy logs ls -la /tmp/deploy-*.log | tail -5 # Read latest deploy log cat $(ls -t /tmp/deploy-*.log | head -1)
Expected log content:
[timestamp] === Deployment triggered for: owner/repo-name === [timestamp] Working directory: /projects/<repo-name> [timestamp] Pulling latest changes... [timestamp] Services updated successfully [timestamp] === Deployment complete ===
Verify git pulled latest:
cd /projects/<repo-name> && git log -1 --oneline
Supporting Files
| File | Purpose |
|---|---|
references/reference.md | Complete hooks.json schema, troubleshooting guide |
examples/examples.md | Example configurations for different repo types |
Expected Outcomes
Success:
- •WEBHOOK_SECRET configured in .env
- •hooks.json updated with new entry
- •webhook.temet.ai/hooks/<repo-name> accessible
- •GitHub webhook created and delivering
- •Push events trigger deployment script
- •Latest code pulled to server
Partial Success:
- •Hook configured but GitHub not yet set up (user action needed)
- •Webhook receiving but deployment script failing (check logs)
Failure Indicators:
- •401/403 from webhook endpoint -> Secret mismatch
- •404 from webhook endpoint -> Hook ID not in hooks.json
- •"signature does not match" in logs -> Secret mismatch
- •Deployment not running -> Check container logs
Requirements
Environment:
- •Docker running with webhook container
- •Cloudflare tunnel connected
- •webhook.temet.ai with bypass authentication
- •WEBHOOK_SECRET in .env
Server Setup:
- •Repository cloned to /projects/<repo-name>
- •Git configured for pull operations
- •Docker compose available (if repo has docker-compose.yml)
GitHub:
- •Repository admin access (to create webhooks)
- •Main branch exists
Red Flags to Avoid
- • Do not commit WEBHOOK_SECRET to git
- • Do not use different secrets for different repos (one secret for all)
- • Do not forget to restart webhook container after hooks.json changes
- • Do not skip the health endpoint check
- • Do not use HTTP (always HTTPS via tunnel)
- • Do not add hooks for branches other than main without updating trigger-rule
- • Do not skip testing with an actual push event
- • Do not forget to clone the repo to /projects/ on the server first
Notes
- •The webhook container reads WEBHOOK_SECRET as environment variable, referenced in hooks.json as "WEBHOOK_SECRET" (not the actual value)
- •All repos share the same WEBHOOK_SECRET for simplicity
- •The deploy.sh script is generic and works for any repo with docker-compose.yml
- •Webhook endpoint has Cloudflare Access bypass (public access for GitHub)
- •Deploy logs are written to /tmp/ with timestamps
- •The health endpoint (/hooks/health) is useful for monitoring