Initial import with modified Dockerfile for env-based config generation
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
package webhook
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
// EventHandler processes webhook events
|
||||
type EventHandler interface {
|
||||
HandlePullRequest(event *PullRequestEvent)
|
||||
HandlePullRequestReview(event *PullRequestReviewEvent)
|
||||
HandlePullRequestComment(event *PullRequestCommentEvent)
|
||||
HandleIssue(event *IssueEvent)
|
||||
HandleIssueComment(event *IssueCommentEvent)
|
||||
}
|
||||
|
||||
// Handler handles incoming Gitea webhooks
|
||||
type Handler struct {
|
||||
validator *Validator
|
||||
eventHandler EventHandler
|
||||
logger zerolog.Logger
|
||||
}
|
||||
|
||||
// NewHandler creates a new webhook handler
|
||||
func NewHandler(secret string, eventHandler EventHandler, logger zerolog.Logger) *Handler {
|
||||
return &Handler{
|
||||
validator: NewValidator(secret),
|
||||
eventHandler: eventHandler,
|
||||
logger: logger.With().Str("component", "webhook").Logger(),
|
||||
}
|
||||
}
|
||||
|
||||
// ServeHTTP handles the webhook HTTP request
|
||||
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
// Only accept POST requests
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
// Get event metadata
|
||||
eventType := GetEventType(r)
|
||||
deliveryID := GetDeliveryID(r)
|
||||
|
||||
logger := h.logger.With().
|
||||
Str("delivery_id", deliveryID).
|
||||
Str("event_type", string(eventType)).
|
||||
Logger()
|
||||
|
||||
// Validate signature and read body
|
||||
body, err := h.validator.ValidateRequest(r)
|
||||
if err != nil {
|
||||
logger.Warn().Err(err).Msg("webhook validation failed")
|
||||
http.Error(w, "unauthorized", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
// Respond immediately with 200 OK
|
||||
// Process the event asynchronously
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(`{"status":"accepted"}`))
|
||||
|
||||
// Process the event in a goroutine
|
||||
go h.processEvent(logger, eventType, body)
|
||||
}
|
||||
|
||||
// processEvent parses and routes the event to the appropriate handler
|
||||
func (h *Handler) processEvent(logger zerolog.Logger, eventType GiteaEventType, body []byte) {
|
||||
var err error
|
||||
|
||||
switch eventType {
|
||||
case EventPullRequest:
|
||||
var event PullRequestEvent
|
||||
if err = json.Unmarshal(body, &event); err == nil {
|
||||
logger.Info().
|
||||
Str("action", event.Action).
|
||||
Int64("pr_number", event.Number).
|
||||
Str("repo", event.Repository.FullName).
|
||||
Msg("processing pull request event")
|
||||
h.eventHandler.HandlePullRequest(&event)
|
||||
}
|
||||
|
||||
case EventPullRequestReview:
|
||||
var event PullRequestReviewEvent
|
||||
if err = json.Unmarshal(body, &event); err == nil {
|
||||
logger.Info().
|
||||
Str("action", event.Action).
|
||||
Str("review_state", event.Review.State).
|
||||
Str("repo", event.Repository.FullName).
|
||||
Msg("processing pull request review event")
|
||||
h.eventHandler.HandlePullRequestReview(&event)
|
||||
}
|
||||
|
||||
case EventPullRequestComment:
|
||||
var event PullRequestCommentEvent
|
||||
if err = json.Unmarshal(body, &event); err == nil {
|
||||
logger.Info().
|
||||
Str("action", event.Action).
|
||||
Int64("pr_number", event.PullRequest.Number).
|
||||
Str("repo", event.Repository.FullName).
|
||||
Msg("processing pull request comment event")
|
||||
h.eventHandler.HandlePullRequestComment(&event)
|
||||
}
|
||||
|
||||
case EventIssues:
|
||||
var event IssueEvent
|
||||
if err = json.Unmarshal(body, &event); err == nil {
|
||||
logger.Info().
|
||||
Str("action", event.Action).
|
||||
Int64("issue_number", event.Issue.Number).
|
||||
Str("repo", event.Repository.FullName).
|
||||
Msg("processing issue event")
|
||||
h.eventHandler.HandleIssue(&event)
|
||||
}
|
||||
|
||||
case EventIssueComment:
|
||||
var event IssueCommentEvent
|
||||
if err = json.Unmarshal(body, &event); err == nil {
|
||||
logger.Info().
|
||||
Str("action", event.Action).
|
||||
Int64("issue_number", event.Issue.Number).
|
||||
Str("repo", event.Repository.FullName).
|
||||
Msg("processing issue comment event")
|
||||
h.eventHandler.HandleIssueComment(&event)
|
||||
}
|
||||
|
||||
default:
|
||||
logger.Debug().Msg("ignoring unknown event type")
|
||||
return
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
logger.Error().Err(err).Msg("failed to parse event payload")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user