diff --git a/app/services/webhook/handler_pullreq.go b/app/services/webhook/handler_pullreq.go index ca6433d25..7d14e0429 100644 --- a/app/services/webhook/handler_pullreq.go +++ b/app/services/webhook/handler_pullreq.go @@ -476,3 +476,66 @@ func (s *Service) handleEventPullReqUpdated( }, nil }) } + +// PullReqReviewSubmittedPayload describes the body of the pullreq review submitted trigger. +type PullReqReviewSubmittedPayload struct { + BaseSegment + PullReqSegment + PullReqTargetReferenceSegment + ReferenceSegment + PullReqReviewSegment +} + +// handleEventPullReqReviewSubmitted handles review events for pull requests +// and triggers pullreq review submitted webhooks for the target repo. +func (s *Service) handleEventPullReqReviewSubmitted( + ctx context.Context, + event *events.Event[*pullreqevents.ReviewSubmittedPayload], +) error { + return s.triggerForEventWithPullReq( + ctx, + enum.WebhookTriggerReviewSubmitted, + event.ID, event.Payload.PrincipalID, + event.Payload.PullReqID, + func( + principal *types.Principal, + pr *types.PullReq, + targetRepo, + sourceRepo *types.Repository, + ) (any, error) { + targetRepoInfo := repositoryInfoFrom(ctx, targetRepo, s.urlProvider) + sourceRepoInfo := repositoryInfoFrom(ctx, sourceRepo, s.urlProvider) + + reviewer, err := s.findPrincipalForEvent(ctx, event.Payload.ReviewerID) + if err != nil { + return nil, fmt.Errorf("failed to get reviewer by id for reviewer id %d: %w", event.Payload.ReviewerID, err) + } + + return &PullReqReviewSubmittedPayload{ + BaseSegment: BaseSegment{ + Trigger: enum.WebhookTriggerReviewSubmitted, + Repo: targetRepoInfo, + Principal: principalInfoFrom(principal.ToPrincipalInfo()), + }, + PullReqSegment: PullReqSegment{ + PullReq: pullReqInfoFrom(ctx, pr, targetRepo, s.urlProvider), + }, + PullReqTargetReferenceSegment: PullReqTargetReferenceSegment{ + TargetRef: ReferenceInfo{ + Name: gitReferenceNamePrefixBranch + pr.TargetBranch, + Repo: targetRepoInfo, + }, + }, + ReferenceSegment: ReferenceSegment{ + Ref: ReferenceInfo{ + Name: gitReferenceNamePrefixBranch + pr.SourceBranch, + Repo: sourceRepoInfo, + }, + }, + PullReqReviewSegment: PullReqReviewSegment{ + ReviewDecision: event.Payload.Decision, + ReviewerInfo: principalInfoFrom(reviewer.ToPrincipalInfo()), + }, + }, nil + }) +} diff --git a/app/services/webhook/service.go b/app/services/webhook/service.go index 909e3c056..9e74265a8 100644 --- a/app/services/webhook/service.go +++ b/app/services/webhook/service.go @@ -193,6 +193,7 @@ func NewService( _ = r.RegisterMerged(service.handleEventPullReqMerged) _ = r.RegisterUpdated(service.handleEventPullReqUpdated) _ = r.RegisterLabelAssigned(service.handleEventPullReqLabelAssigned) + _ = r.RegisterReviewSubmitted(service.handleEventPullReqReviewSubmitted) return nil }) diff --git a/app/services/webhook/types.go b/app/services/webhook/types.go index 05e09ea31..059d52c48 100644 --- a/app/services/webhook/types.go +++ b/app/services/webhook/types.go @@ -95,6 +95,11 @@ type PullReqUpdateSegment struct { DescriptionNew string `json:"description_new"` } +type PullReqReviewSegment struct { + ReviewDecision enum.PullReqReviewDecision `json:"review_decision"` + ReviewerInfo PrincipalInfo `json:"reviewer"` +} + // RepositoryInfo describes the repo related info for a webhook payload. // NOTE: don't use types package as we want webhook payload to be independent from API calls. type RepositoryInfo struct { diff --git a/types/enum/webhook.go b/types/enum/webhook.go index ef533f331..ae51ac6ac 100644 --- a/types/enum/webhook.go +++ b/types/enum/webhook.go @@ -162,6 +162,8 @@ const ( WebhookTriggerPullReqUpdated WebhookTrigger = "pullreq_updated" // WebhookTriggerPullReqLabelAssigned gets triggered when a label is assigned to a pull request. WebhookTriggerPullReqLabelAssigned WebhookTrigger = "pullreq_label_assigned" + + WebhookTriggerReviewSubmitted = "review_submitted" ) var webhookTriggers = sortEnum([]WebhookTrigger{