mirror of https://github.com/harness/drone.git
feat: [CODE-2366]: new webhook event for label assignment (#2810)
* feat: [CODE-2336]: lint * Merge branch 'main' into akp/CODE-2336 * feat: [CODE-2336]: nit: lint * feat: [CODE-2336]: nit: rename * update event and webhook payload * fix: [CODE-2366]: undo css * feat: [CODE-2336]: remove service usage * feat: [CODE-2336]: remove service usage * Merge remote-tracking branch 'origin/akp/CODE-2336' into akp/CODE-2336 # Conflicts: # app/services/webhook/handler_pullreq.go * feat: [CODE-2336]: remove service usage * Apply suggestion from code review * feat: [CODE-2336]: update code to fetch label with values from service * feat: [CODE-2366]: lint * feat: [CODE-2366]: new webhook event for label assignmentpull/3576/head
parent
1dbdccfe18
commit
c282082cde
|
@ -19,6 +19,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/harness/gitness/app/auth"
|
||||
events "github.com/harness/gitness/app/events/pullreq"
|
||||
"github.com/harness/gitness/app/services/label"
|
||||
"github.com/harness/gitness/types"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
|
@ -69,6 +70,24 @@ func (c *Controller) AssignLabel(
|
|||
log.Ctx(ctx).Err(err).Msgf("failed to write pull request activity after label unassign")
|
||||
}
|
||||
|
||||
// if the label has no value, the newValueID will be nil
|
||||
var newValueID *int64
|
||||
if out.NewLabelValue != nil {
|
||||
newValueID = &out.NewLabelValue.ID
|
||||
}
|
||||
|
||||
c.eventReporter.LabelAssigned(ctx, &events.LabelAssignedPayload{
|
||||
Base: events.Base{
|
||||
PullReqID: pullreq.ID,
|
||||
SourceRepoID: pullreq.SourceRepoID,
|
||||
TargetRepoID: pullreq.TargetRepoID,
|
||||
PrincipalID: session.Principal.ID,
|
||||
Number: pullreq.Number,
|
||||
},
|
||||
LabelID: out.Label.ID,
|
||||
ValueID: newValueID,
|
||||
})
|
||||
|
||||
return out.PullReqLabel, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -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 LabelAssignedEvent events.EventType = "label-assigned"
|
||||
|
||||
type LabelAssignedPayload struct {
|
||||
Base
|
||||
LabelID int64 `json:"label_id"`
|
||||
ValueID *int64 `json:"value_id"`
|
||||
}
|
||||
|
||||
func (r *Reporter) LabelAssigned(
|
||||
ctx context.Context,
|
||||
payload *LabelAssignedPayload,
|
||||
) {
|
||||
if payload == nil {
|
||||
return
|
||||
}
|
||||
|
||||
eventID, err := events.ReporterSendEvent(r.innerReporter, ctx, LabelAssignedEvent, payload)
|
||||
if err != nil {
|
||||
log.Ctx(ctx).Err(err).Msgf("failed to send pull request label assigned event")
|
||||
return
|
||||
}
|
||||
|
||||
log.Ctx(ctx).Debug().Msgf("reported pull request label assigned event with id '%s'", eventID)
|
||||
}
|
||||
|
||||
func (r *Reader) RegisterLabelAssigned(
|
||||
fn events.HandlerFunc[*LabelAssignedPayload],
|
||||
opts ...events.HandlerOption,
|
||||
) error {
|
||||
return events.ReaderRegisterEvent(r.innerReader, LabelAssignedEvent, fn, opts...)
|
||||
}
|
|
@ -318,7 +318,11 @@ func (s *Service) handleEventPullReqComment(
|
|||
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)
|
||||
return nil, fmt.Errorf(
|
||||
"failed to get activity by id for acitivity id %d: %w",
|
||||
event.Payload.ActivityID,
|
||||
err,
|
||||
)
|
||||
}
|
||||
commitInfo, err := s.fetchCommitInfoForEvent(ctx, sourceRepo.GitUID, event.Payload.SourceSHA)
|
||||
if err != nil {
|
||||
|
@ -361,6 +365,64 @@ func (s *Service) handleEventPullReqComment(
|
|||
})
|
||||
}
|
||||
|
||||
// PullReqLabelAssignedPayload describes the body of the pullreq label assignment trigger.
|
||||
type PullReqLabelAssignedPayload struct {
|
||||
BaseSegment
|
||||
PullReqSegment
|
||||
PullReqLabelSegment
|
||||
}
|
||||
|
||||
func (s *Service) handleEventPullReqLabelAssigned(
|
||||
ctx context.Context,
|
||||
event *events.Event[*pullreqevents.LabelAssignedPayload],
|
||||
) error {
|
||||
return s.triggerForEventWithPullReq(
|
||||
ctx,
|
||||
enum.WebhookTriggerPullReqLabelAssigned,
|
||||
event.ID, event.Payload.PrincipalID,
|
||||
event.Payload.PullReqID,
|
||||
func(
|
||||
principal *types.Principal,
|
||||
pr *types.PullReq,
|
||||
targetRepo,
|
||||
_ *types.Repository,
|
||||
) (any, error) {
|
||||
label, err := s.labelStore.FindByID(ctx, event.Payload.LabelID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to find label by id: %w", err)
|
||||
}
|
||||
|
||||
var labelValueKey *string
|
||||
if event.Payload.ValueID != nil {
|
||||
value, err := s.labelStore.FindByID(ctx, *event.Payload.ValueID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to find label value by id: %d %w", *event.Payload.ValueID, err)
|
||||
}
|
||||
labelValueKey = &value.Key
|
||||
}
|
||||
|
||||
targetRepoInfo := repositoryInfoFrom(ctx, targetRepo, s.urlProvider)
|
||||
return &PullReqLabelAssignedPayload{
|
||||
BaseSegment: BaseSegment{
|
||||
Trigger: enum.WebhookTriggerPullReqCommentCreated,
|
||||
Repo: targetRepoInfo,
|
||||
Principal: principalInfoFrom(principal.ToPrincipalInfo()),
|
||||
},
|
||||
PullReqSegment: PullReqSegment{
|
||||
PullReq: pullReqInfoFrom(ctx, pr, targetRepo, s.urlProvider),
|
||||
},
|
||||
PullReqLabelSegment: PullReqLabelSegment{
|
||||
LabelInfo: LabelInfo{
|
||||
ID: event.Payload.LabelID,
|
||||
Key: label.Key,
|
||||
ValueID: event.Payload.ValueID,
|
||||
Value: labelValueKey,
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
})
|
||||
}
|
||||
|
||||
// PullReqUpdatedPayload describes the body of the pullreq updated trigger.
|
||||
type PullReqUpdatedPayload struct {
|
||||
BaseSegment
|
||||
|
|
|
@ -91,6 +91,7 @@ type Service struct {
|
|||
principalStore store.PrincipalStore
|
||||
git git.Interface
|
||||
activityStore store.PullReqActivityStore
|
||||
labelStore store.LabelStore
|
||||
encrypter encrypt.Encrypter
|
||||
|
||||
secureHTTPClient *http.Client
|
||||
|
@ -118,6 +119,8 @@ func NewService(
|
|||
principalStore store.PrincipalStore,
|
||||
git git.Interface,
|
||||
encrypter encrypt.Encrypter,
|
||||
labelStore store.LabelStore,
|
||||
|
||||
) (*Service, error) {
|
||||
if err := config.Prepare(); err != nil {
|
||||
return nil, fmt.Errorf("provided webhook service config is invalid: %w", err)
|
||||
|
@ -142,6 +145,8 @@ func NewService(
|
|||
insecureHTTPClientInternal: newHTTPClient(config.AllowLoopback, true, true),
|
||||
|
||||
config: config,
|
||||
|
||||
labelStore: labelStore,
|
||||
}
|
||||
|
||||
_, err := gitReaderFactory.Launch(ctx, eventsReaderGroupName, config.EventReaderName,
|
||||
|
@ -187,6 +192,7 @@ func NewService(
|
|||
_ = r.RegisterCommentCreated(service.handleEventPullReqComment)
|
||||
_ = r.RegisterMerged(service.handleEventPullReqMerged)
|
||||
_ = r.RegisterUpdated(service.handleEventPullReqUpdated)
|
||||
_ = r.RegisterLabelAssigned(service.handleEventPullReqLabelAssigned)
|
||||
|
||||
return nil
|
||||
})
|
||||
|
|
|
@ -80,6 +80,11 @@ type PullReqCommentSegment struct {
|
|||
CommentInfo CommentInfo `json:"comment"`
|
||||
}
|
||||
|
||||
// PullReqLabelSegment contains details for all pull req label related payloads for webhooks.
|
||||
type PullReqLabelSegment struct {
|
||||
LabelInfo LabelInfo `json:"label"`
|
||||
}
|
||||
|
||||
// PullReqUpdateSegment contains details what has been updated in the pull request.
|
||||
type PullReqUpdateSegment struct {
|
||||
TitleChanged bool `json:"title_changed"`
|
||||
|
@ -293,3 +298,10 @@ type CommentInfo struct {
|
|||
ParentID *int64 `json:"parent_id,omitempty"`
|
||||
Text string `json:"text"`
|
||||
}
|
||||
|
||||
type LabelInfo struct {
|
||||
ID int64 `json:"id"`
|
||||
Key string `json:"key"`
|
||||
ValueID *int64 `json:"value_id,omitempty"`
|
||||
Value *string `json:"value,omitempty"`
|
||||
}
|
||||
|
|
|
@ -50,8 +50,23 @@ func ProvideService(
|
|||
principalStore store.PrincipalStore,
|
||||
git git.Interface,
|
||||
encrypter encrypt.Encrypter,
|
||||
labelStore store.LabelStore,
|
||||
) (*Service, error) {
|
||||
return NewService(ctx, config, tx, gitReaderFactory, prReaderFactory,
|
||||
webhookStore, webhookExecutionStore, spaceStore, repoStore, pullreqStore, activityStore,
|
||||
urlProvider, principalStore, git, encrypter)
|
||||
return NewService(
|
||||
ctx,
|
||||
config,
|
||||
tx,
|
||||
gitReaderFactory,
|
||||
prReaderFactory,
|
||||
webhookStore,
|
||||
webhookExecutionStore,
|
||||
spaceStore, repoStore,
|
||||
pullreqStore,
|
||||
activityStore,
|
||||
urlProvider,
|
||||
principalStore,
|
||||
git,
|
||||
encrypter,
|
||||
labelStore,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -365,7 +365,7 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||
webhookConfig := server.ProvideWebhookConfig(config)
|
||||
webhookStore := database.ProvideWebhookStore(db)
|
||||
webhookExecutionStore := database.ProvideWebhookExecutionStore(db)
|
||||
webhookService, err := webhook.ProvideService(ctx, webhookConfig, transactor, readerFactory, eventsReaderFactory, webhookStore, webhookExecutionStore, spaceStore, repoStore, pullReqStore, pullReqActivityStore, provider, principalStore, gitInterface, encrypter)
|
||||
webhookService, err := webhook.ProvideService(ctx, webhookConfig, transactor, readerFactory, eventsReaderFactory, webhookStore, webhookExecutionStore, spaceStore, repoStore, pullReqStore, pullReqActivityStore, provider, principalStore, gitInterface, encrypter, labelStore)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -160,6 +160,8 @@ const (
|
|||
WebhookTriggerPullReqMerged WebhookTrigger = "pullreq_merged"
|
||||
// WebhookTriggerPullReqUpdated gets triggered when a pull request gets updated.
|
||||
WebhookTriggerPullReqUpdated WebhookTrigger = "pullreq_updated"
|
||||
// WebhookTriggerPullReqLabelAssigned gets triggered when a label is assigned to a pull request.
|
||||
WebhookTriggerPullReqLabelAssigned WebhookTrigger = "pullreq_label_assigned"
|
||||
)
|
||||
|
||||
var webhookTriggers = sortEnum([]WebhookTrigger{
|
||||
|
@ -176,4 +178,5 @@ var webhookTriggers = sortEnum([]WebhookTrigger{
|
|||
WebhookTriggerPullReqClosed,
|
||||
WebhookTriggerPullReqCommentCreated,
|
||||
WebhookTriggerPullReqMerged,
|
||||
WebhookTriggerPullReqLabelAssigned,
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue