feat: add webhook support for GitHub events (AIE-13)#15
Merged
knechtionscoding merged 23 commits intoprodfrom Mar 26, 2026
Merged
feat: add webhook support for GitHub events (AIE-13)#15knechtionscoding merged 23 commits intoprodfrom
knechtionscoding merged 23 commits intoprodfrom
Conversation
Defines WebhookEvent custom resource for storing incoming webhooks. Uses CRD-based queue pattern consistent with Kelos architecture. Note: Requires 'make update' in Go environment to generate deepcopy and CRD manifests.
Implements HTTP endpoint at /webhook/:source that: - Receives webhook payloads - Validates GitHub signatures via HMAC-SHA256 - Creates WebhookEvent CRD instances - Returns 202 Accepted Supports multiple sources (github, slack, linear, etc.) via URL path.
Implements Source interface for webhook-based discovery: - Reads unprocessed WebhookEvent CRDs with source=github - Parses GitHub issue and pull_request webhook payloads - Converts to WorkItem format - Marks events as processed after discovery - Supports label-based filtering (client-side)
Adds githubWebhook field to TaskSpawner CRD allowing webhook-based discovery as an alternative to API polling. The spawner will watch WebhookEvent resources in the specified namespace and convert GitHub webhook payloads to tasks.
Updates spawner to create GitHubWebhookSource instances when TaskSpawner has githubWebhook configured. Passes k8s client to source so it can list and update WebhookEvent resources.
Includes: - Complete TaskSpawner example using githubWebhook - Webhook receiver deployment manifests - Architecture documentation explaining CRD-based queue - GitHub webhook setup instructions - Comparison with API polling approach
Marks completed phases and notes what still needs to be done: - CRD manifest generation (needs Go environment) - Unit and integration tests - Live cluster testing
Webhook receiver tests: - Valid/invalid GitHub signature validation - Missing signature header handling - No secret configured (dev mode) - HTTP method validation - Missing source in path GitHub webhook source tests: - Issue payload parsing - Pull request payload parsing - Closed issues/PRs are skipped - Label filtering (required, excluded, multiple) - End-to-end Discover with fake k8s client - Events marked as processed after discovery
- Fix logger type in webhook receiver (logr.Logger) - Add missing parameters to buildSource calls in tests - Remove field selectors for fake client compatibility Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Fix HMAC-SHA256 signature in webhook receiver test - Enable status subresource in fake client for webhook source test Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add webhookevents permissions to kelos-spawner-role - Create kelos-webhook-receiver-role for webhook receiver Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Remove mentions of future sources (Slack, Linear, etc.) - Remove comparison table with API polling - Keep documentation focused on current implementation Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Test WebhookEvent discovery and processing - Test label filtering (required and excluded labels) - Test issue and pull request payloads - Test source filtering (github vs other sources) - Test skipping closed issues/PRs - Verify events are marked as processed after discovery Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Mark all tasks as completed: - RBAC permissions added - Integration tests implemented - All tests passing Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Change from &eventList.Items[i] to DeepCopy() to fix status updates - Mark events as processed even when filtered out or invalid - Ensures all processed events have status updated in integration tests Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
knechtionscoding
approved these changes
Mar 26, 2026
Collaborator
knechtionscoding
left a comment
There was a problem hiding this comment.
Overall I think this is fine. Might need to think through the routing part of it (i.e. different ingresses pointing at different services)?
We may also want the taskspawner, if it is a webhook source, to create the service with specific overrides to allow for clusterIP vs load balancer, annotations and labels, etc.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What type of PR is this?
/kind feature
What this PR does / why we need it:
Adds webhook support for GitHub events to Kelos. TaskSpawners can now receive push notifications when issues or pull requests are created or updated, providing an alternative to API polling.
Which issue(s) this PR is related to:
Related to kelos-dev#687 (upstream Kelos webhook support request)
Linear ticket: AIE-13
Special notes for your reviewer:
Architecture: CRD-Based Queue
Webhook payloads are stored as
WebhookEventcustom resources in Kubernetes. This is consistent with Kelos' existing architecture where all state lives in Kubernetes CRDs backed by etcd.Alternative approaches considered:
The CRD-based approach provides:
kubectl get webhookevents)Components:
WebhookEvent CRD (
api/v1alpha1/webhookevent_types.go)Webhook Receiver (
cmd/kelos-webhook-receiver/main.go)/webhook/githubGitHub Webhook Source (
internal/source/github_webhook.go)source=githubTaskSpawner CRD Updates (
api/v1alpha1/taskspawner_types.go)githubWebhookfield toWhenstructUnit Tests
Documentation & Examples
docs/webhooks.md: Architecture overview and setup instructionsexamples/taskspawner-github-webhook.yaml: Complete example with receiver deploymentUsage example:
Compatibility with
main:This implementation is compatible with the upstream
mainbranch:githubWebhookfieldTODO before merging:
make updatein Go environment to generate:zz_generated.deepcopy.go)Does this PR introduce a user-facing change?