GitHub Webhook Setup Skill
github-webhook-setup
Configures GitHub webhooks for auto-deployment by verifying secrets, checking endpoint accessibility, and guiding configuration. Use when you need to add a new repo for auto-deploy, configure GitHub webhooks, set up continuous deployment, or troubleshoot webhook issues. Triggers on "setup webhook...
SKILL.md
Full skill instructions
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
