This example demonstrates how to configure a TaskSpawner to respond to GitHub webhook events.
The GitHub webhook TaskSpawner triggers task creation based on GitHub repository events like:
- Issues being opened, closed, or commented on
- Pull requests being opened, reviewed, or merged
- Code being pushed to specific branches
- And many other GitHub events
- Webhook Server: Deploy the kelos-webhook-server with GitHub source configuration
- GitHub Webhook: Configure your GitHub repository to send webhooks to your Kelos instance
- Secret: Create a Kubernetes secret containing the webhook signing secret
kubectl create secret generic github-webhook-secret \
--from-literal=WEBHOOK_SECRET=your-github-webhook-secretIn your GitHub repository settings:
- Go to Settings → Webhooks → Add webhook
- Set Payload URL to:
https://your-kelos-instance.com/webhook/github - Set Content type to:
application/json - Set Secret to the same value as in your Kubernetes secret
- Select events you want to receive (or "Send me everything")
Apply the TaskSpawner configuration:
kubectl apply -f taskspawner.yamlThe example TaskSpawner demonstrates several filtering patterns:
- Event Types: Only responds to
issues,pull_request, andissue_commentevents - Action Filtering: Responds to specific actions like "opened", "created", etc.
- Label Requirements: Can require specific labels to be present
- Author Filtering: Can filter by the user who triggered the event
- Draft Filtering: Can exclude or include draft pull requests
GitHub webhook events provide rich template variables for task creation:
{{.Event}}- GitHub event type (e.g., "issues", "pull_request"){{.Action}}- Webhook action (e.g., "opened", "created", "submitted"){{.Sender}}- Username of person who triggered the event{{.ID}}- Issue/PR number as string{{.Title}}- Issue/PR title{{.Number}}- Issue/PR number as integer{{.Body}}- Issue/PR body text{{.URL}}- Issue/PR HTML URL{{.Branch}}- PR source branch or push branch{{.Ref}}- Git ref for push events
{{.Payload.*}}- Access any field from the GitHub webhook payload
Example template usage:
promptTemplate: |
A new {{.Event}} event occurred in the repository.
Event: {{.Event}}
Action: {{.Action}}
Triggered by: {{.Sender}}
{{with index . "Title"}}Title: {{.}}{{end}}
{{with index . "URL"}}URL: {{.}}{{end}}
Please investigate and take appropriate action.
branch: "webhook-{{.Event}}-{{.ID}}"The webhook server validates GitHub signatures using HMAC-SHA256:
- GitHub sends signatures in
X-Hub-Signature-256header withsha256=prefix - The server validates against the secret stored in
WEBHOOK_SECRETenv var - Invalid signatures result in HTTP 401 responses
- Set
maxConcurrencyto limit parallel tasks from webhook events - When exceeded, returns HTTP 503 with
Retry-Afterheader - GitHub will automatically retry failed webhook deliveries
- Webhook deliveries are tracked by
X-GitHub-Deliveryheader - Duplicate deliveries (e.g., retries) are ignored
- Delivery cache entries expire after 24 hours
- Per-source webhook servers provide fault isolation
- GitHub webhook failures don't affect Linear or other sources
- Each source can be scaled independently
-
Tasks not being created
- Check webhook server logs for signature validation errors
- Verify GitHub webhook is configured with correct URL and secret
- Check TaskSpawner event type and filter configuration
-
Signature validation failures
- Ensure WEBHOOK_SECRET matches GitHub webhook secret exactly
- Check for trailing newlines or encoding issues in secret
-
Max concurrency errors
- Increase maxConcurrency limit or reduce webhook frequency
- Check for stuck tasks that aren't completing
Enable verbose logging:
env:
- name: LOG_LEVEL
value: "debug"Check webhook deliveries in GitHub:
- Repository Settings → Webhooks → Recent Deliveries
- Shows request/response details and retry attempts