diff --git a/app/api/controller/pullreq/comment_status.go b/app/api/controller/pullreq/comment_status.go index 574296604..f47d84977 100644 --- a/app/api/controller/pullreq/comment_status.go +++ b/app/api/controller/pullreq/comment_status.go @@ -22,6 +22,7 @@ import ( "github.com/harness/gitness/app/api/controller" "github.com/harness/gitness/app/api/usererror" "github.com/harness/gitness/app/auth" + events "github.com/harness/gitness/app/events/pullreq" "github.com/harness/gitness/types" "github.com/harness/gitness/types/enum" @@ -129,5 +130,16 @@ func (c *Controller) CommentStatus( log.Ctx(ctx).Warn().Err(err).Msg("failed to publish PR changed event") } + c.eventReporter.CommentStatusUpdated(ctx, &events.CommentStatusUpdatedPayload{ + Base: events.Base{ + PullReqID: pr.ID, + SourceRepoID: pr.SourceRepoID, + TargetRepoID: pr.TargetRepoID, + PrincipalID: session.Principal.ID, + Number: pr.Number, + }, + ActivityID: act.ID, + }) + return act, nil } diff --git a/app/events/pullreq/events_code_comment_status.go b/app/events/pullreq/events_code_comment_status.go new file mode 100644 index 000000000..d77fa0f34 --- /dev/null +++ b/app/events/pullreq/events_code_comment_status.go @@ -0,0 +1,55 @@ +// Copyright 2023 Harness, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package events + +import ( + "context" + + "github.com/harness/gitness/events" + + "github.com/rs/zerolog/log" +) + +const CommentStatusUpdatedEvent events.EventType = "comment-status-updated" + +type CommentStatusUpdatedPayload struct { + Base + ActivityID int64 `json:"activity_id"` +} + +func (r *Reporter) CommentStatusUpdated( + ctx context.Context, + payload *CommentStatusUpdatedPayload, +) { + if payload == nil { + return + } + + eventID, err := events.ReporterSendEvent(r.innerReporter, ctx, CommentStatusUpdatedEvent, payload) + if err != nil { + log.Ctx(ctx).Err(err).Msgf( + "failed to send pull request comment status updated event for event id '%s'", eventID) + return + } + + log.Ctx(ctx).Debug().Msgf("reported pull request comment status update event with id '%s'", eventID) +} + +func (r *Reader) RegisterCommentStatusUpdated( + fn events.HandlerFunc[*CommentStatusUpdatedPayload], + opts ...events.HandlerOption, +) error { + return events.ReaderRegisterEvent(r.innerReader, CommentStatusUpdatedEvent, fn, opts...) +} diff --git a/app/services/webhook/handler_pullreq.go b/app/services/webhook/handler_pullreq.go index 878f761b6..adc6c8a62 100644 --- a/app/services/webhook/handler_pullreq.go +++ b/app/services/webhook/handler_pullreq.go @@ -363,20 +363,12 @@ func (s *Service) handleEventPullReqComment( Created: activity.Created, Updated: activity.Updated, }, + CodeCommentInfo: extractCodeCommentInfoIfAvailable(activity), }, }, nil }) } -// PullReqCommentUpdatedPayload describes the body of the pullreq comment create trigger. -type PullReqCommentUpdatedPayload struct { - BaseSegment - PullReqSegment - PullReqTargetReferenceSegment - ReferenceSegment - PullReqCommentSegment -} - // handleEventPullReqCommentUpdated handles updated events for pull request comments. func (s *Service) handleEventPullReqCommentUpdated( ctx context.Context, @@ -399,7 +391,7 @@ func (s *Service) handleEventPullReqCommentUpdated( err, ) } - return &PullReqCommentUpdatedPayload{ + return &PullReqCommentPayload{ BaseSegment: BaseSegment{ Trigger: enum.WebhookTriggerPullReqCommentUpdated, Repo: targetRepoInfo, @@ -427,6 +419,7 @@ func (s *Service) handleEventPullReqCommentUpdated( ParentID: activity.ParentID, Created: activity.Created, Updated: activity.Updated, + Kind: activity.Kind, }, CodeCommentInfo: extractCodeCommentInfoIfAvailable(activity), }, @@ -555,6 +548,83 @@ func (s *Service) handleEventPullReqUpdated( }) } +// PullReqActivityStatusUpdatedPayload describes the body of the pullreq comment updated trigger. +type PullReqActivityStatusUpdatedPayload struct { + BaseSegment + PullReqSegment + PullReqTargetReferenceSegment + ReferenceSegment + PullReqCommentSegment + PullReqCommentStatusUpdatedSegment +} + +// handleEventPullReqCommentUpdated handles status updated events for pull request comments. +func (s *Service) handleEventPullReqCommentStatusUpdated( + ctx context.Context, + event *events.Event[*pullreqevents.CommentStatusUpdatedPayload], +) error { + return s.triggerForEventWithPullReq( + ctx, + enum.WebhookTriggerPullReqCommentStatusUpdated, + 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) + activity, err := s.activityStore.Find(ctx, event.Payload.ActivityID) + if err != nil { + return nil, fmt.Errorf( + "failed to get activity by id for acitivity id %d: %w", + event.Payload.ActivityID, + err, + ) + } + + status := enum.PullReqCommentStatusActive + if activity.Resolved != nil { + status = enum.PullReqCommentStatusResolved + } + + return &PullReqActivityStatusUpdatedPayload{ + BaseSegment: BaseSegment{ + Trigger: enum.WebhookTriggerPullReqCommentStatusUpdated, + 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, + }, + }, + PullReqCommentSegment: PullReqCommentSegment{ + CommentInfo: CommentInfo{ + ID: activity.ID, + Text: activity.Text, + Kind: activity.Kind, + ParentID: activity.ParentID, + Created: activity.Created, + Updated: activity.Updated, + }, + CodeCommentInfo: extractCodeCommentInfoIfAvailable(activity), + }, + PullReqCommentStatusUpdatedSegment: PullReqCommentStatusUpdatedSegment{ + Status: status, + }, + }, nil + }) +} + // PullReqReviewSubmittedPayload describes the body of the pullreq review submitted trigger. type PullReqReviewSubmittedPayload struct { BaseSegment diff --git a/app/services/webhook/service.go b/app/services/webhook/service.go index d98f66411..fda28dcd3 100644 --- a/app/services/webhook/service.go +++ b/app/services/webhook/service.go @@ -200,6 +200,7 @@ func NewService( _ = r.RegisterUpdated(service.handleEventPullReqUpdated) _ = r.RegisterLabelAssigned(service.handleEventPullReqLabelAssigned) _ = r.RegisterReviewSubmitted(service.handleEventPullReqReviewSubmitted) + _ = r.RegisterCommentStatusUpdated(service.handleEventPullReqCommentStatusUpdated) return nil }) diff --git a/app/services/webhook/types.go b/app/services/webhook/types.go index ff6a32db8..42b6d455f 100644 --- a/app/services/webhook/types.go +++ b/app/services/webhook/types.go @@ -81,10 +81,8 @@ type PullReqCommentSegment struct { *CodeCommentInfo } -// PullReqCommentUpdatedSegment contains details for pullreq text comment edited payloads for webhooks. -type PullReqCommentUpdatedSegment struct { - CommentInfo - *CodeCommentInfo +type PullReqCommentStatusUpdatedSegment struct { + Status enum.PullReqCommentStatus `json:"status"` } // PullReqLabelSegment contains details for all pull req label related payloads for webhooks. diff --git a/types/enum/webhook.go b/types/enum/webhook.go index 430b48c50..d988c7fc9 100644 --- a/types/enum/webhook.go +++ b/types/enum/webhook.go @@ -188,7 +188,6 @@ const ( WebhookTriggerPullReqUpdated WebhookTrigger = "pullreq_updated" // WebhookTriggerPullReqLabelAssigned gets triggered when a label is assigned to a pull request. WebhookTriggerPullReqLabelAssigned WebhookTrigger = "pullreq_label_assigned" - // WebhookTriggerPullReqReviewSubmitted gets triggered when a pull request review is submitted. WebhookTriggerPullReqReviewSubmitted = "pullreq_review_submitted" )