feat: add GitHub and GitLab webhook support
All checks were successful
Check / check (pull_request) Successful in 1m50s

Add auto-detection of webhook source (Gitea, GitHub, GitLab) by
examining HTTP headers (X-Gitea-Event, X-GitHub-Event, X-Gitlab-Event).

Parse push webhook payloads from all three platforms into a normalized
PushEvent type for unified processing. Each platform's payload format
is handled by dedicated parser functions with correct field mapping
and commit URL extraction.

The webhook handler now detects the source automatically — existing
Gitea webhooks continue to work unchanged, while GitHub and GitLab
webhooks are parsed with their respective payload formats.

Includes comprehensive tests for source detection, event type
extraction, payload parsing for all three platforms, commit URL
fallback logic, and integration tests via HandleWebhook.
This commit is contained in:
user
2026-03-17 02:37:29 -07:00
parent fd110e69db
commit 0c5c727e01
6 changed files with 1104 additions and 186 deletions

View File

@@ -7,12 +7,14 @@ import (
"github.com/go-chi/chi/v5"
"sneak.berlin/go/upaas/internal/models"
"sneak.berlin/go/upaas/internal/service/webhook"
)
// maxWebhookBodySize is the maximum allowed size of a webhook request body (1MB).
const maxWebhookBodySize = 1 << 20
// HandleWebhook handles incoming Gitea webhooks.
// HandleWebhook handles incoming webhooks from Gitea, GitHub, or GitLab.
// The webhook source is auto-detected from HTTP headers.
func (h *Handlers) HandleWebhook() http.HandlerFunc {
return func(writer http.ResponseWriter, request *http.Request) {
secret := chi.URLParam(request, "secret")
@@ -50,16 +52,17 @@ func (h *Handlers) HandleWebhook() http.HandlerFunc {
return
}
// Get event type from header
eventType := request.Header.Get("X-Gitea-Event")
if eventType == "" {
eventType = "push"
}
// Auto-detect webhook source from headers
source := webhook.DetectWebhookSource(request.Header)
// Extract event type based on detected source
eventType := webhook.DetectEventType(request.Header, source)
// Process webhook
webhookErr := h.webhook.HandleWebhook(
request.Context(),
application,
source,
eventType,
body,
)