mirror of
https://github.com/harness/drone.git
synced 2025-05-19 02:20:03 +08:00
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 assignment
This commit is contained in:
parent
1dbdccfe18
commit
c282082cde
@ -19,6 +19,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/harness/gitness/app/auth"
|
"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/app/services/label"
|
||||||
"github.com/harness/gitness/types"
|
"github.com/harness/gitness/types"
|
||||||
"github.com/harness/gitness/types/enum"
|
"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")
|
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
|
return out.PullReqLabel, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
55
app/events/pullreq/events_label_assigned.go
Normal file
55
app/events/pullreq/events_label_assigned.go
Normal file
@ -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)
|
sourceRepoInfo := repositoryInfoFrom(ctx, sourceRepo, s.urlProvider)
|
||||||
activity, err := s.activityStore.Find(ctx, event.Payload.ActivityID)
|
activity, err := s.activityStore.Find(ctx, event.Payload.ActivityID)
|
||||||
if err != nil {
|
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)
|
commitInfo, err := s.fetchCommitInfoForEvent(ctx, sourceRepo.GitUID, event.Payload.SourceSHA)
|
||||||
if err != nil {
|
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.
|
// PullReqUpdatedPayload describes the body of the pullreq updated trigger.
|
||||||
type PullReqUpdatedPayload struct {
|
type PullReqUpdatedPayload struct {
|
||||||
BaseSegment
|
BaseSegment
|
||||||
|
@ -91,6 +91,7 @@ type Service struct {
|
|||||||
principalStore store.PrincipalStore
|
principalStore store.PrincipalStore
|
||||||
git git.Interface
|
git git.Interface
|
||||||
activityStore store.PullReqActivityStore
|
activityStore store.PullReqActivityStore
|
||||||
|
labelStore store.LabelStore
|
||||||
encrypter encrypt.Encrypter
|
encrypter encrypt.Encrypter
|
||||||
|
|
||||||
secureHTTPClient *http.Client
|
secureHTTPClient *http.Client
|
||||||
@ -118,6 +119,8 @@ func NewService(
|
|||||||
principalStore store.PrincipalStore,
|
principalStore store.PrincipalStore,
|
||||||
git git.Interface,
|
git git.Interface,
|
||||||
encrypter encrypt.Encrypter,
|
encrypter encrypt.Encrypter,
|
||||||
|
labelStore store.LabelStore,
|
||||||
|
|
||||||
) (*Service, error) {
|
) (*Service, error) {
|
||||||
if err := config.Prepare(); err != nil {
|
if err := config.Prepare(); err != nil {
|
||||||
return nil, fmt.Errorf("provided webhook service config is invalid: %w", err)
|
return nil, fmt.Errorf("provided webhook service config is invalid: %w", err)
|
||||||
@ -142,6 +145,8 @@ func NewService(
|
|||||||
insecureHTTPClientInternal: newHTTPClient(config.AllowLoopback, true, true),
|
insecureHTTPClientInternal: newHTTPClient(config.AllowLoopback, true, true),
|
||||||
|
|
||||||
config: config,
|
config: config,
|
||||||
|
|
||||||
|
labelStore: labelStore,
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := gitReaderFactory.Launch(ctx, eventsReaderGroupName, config.EventReaderName,
|
_, err := gitReaderFactory.Launch(ctx, eventsReaderGroupName, config.EventReaderName,
|
||||||
@ -187,6 +192,7 @@ func NewService(
|
|||||||
_ = r.RegisterCommentCreated(service.handleEventPullReqComment)
|
_ = r.RegisterCommentCreated(service.handleEventPullReqComment)
|
||||||
_ = r.RegisterMerged(service.handleEventPullReqMerged)
|
_ = r.RegisterMerged(service.handleEventPullReqMerged)
|
||||||
_ = r.RegisterUpdated(service.handleEventPullReqUpdated)
|
_ = r.RegisterUpdated(service.handleEventPullReqUpdated)
|
||||||
|
_ = r.RegisterLabelAssigned(service.handleEventPullReqLabelAssigned)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
@ -80,6 +80,11 @@ type PullReqCommentSegment struct {
|
|||||||
CommentInfo CommentInfo `json:"comment"`
|
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.
|
// PullReqUpdateSegment contains details what has been updated in the pull request.
|
||||||
type PullReqUpdateSegment struct {
|
type PullReqUpdateSegment struct {
|
||||||
TitleChanged bool `json:"title_changed"`
|
TitleChanged bool `json:"title_changed"`
|
||||||
@ -293,3 +298,10 @@ type CommentInfo struct {
|
|||||||
ParentID *int64 `json:"parent_id,omitempty"`
|
ParentID *int64 `json:"parent_id,omitempty"`
|
||||||
Text string `json:"text"`
|
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,
|
principalStore store.PrincipalStore,
|
||||||
git git.Interface,
|
git git.Interface,
|
||||||
encrypter encrypt.Encrypter,
|
encrypter encrypt.Encrypter,
|
||||||
|
labelStore store.LabelStore,
|
||||||
) (*Service, error) {
|
) (*Service, error) {
|
||||||
return NewService(ctx, config, tx, gitReaderFactory, prReaderFactory,
|
return NewService(
|
||||||
webhookStore, webhookExecutionStore, spaceStore, repoStore, pullreqStore, activityStore,
|
ctx,
|
||||||
urlProvider, principalStore, git, encrypter)
|
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)
|
webhookConfig := server.ProvideWebhookConfig(config)
|
||||||
webhookStore := database.ProvideWebhookStore(db)
|
webhookStore := database.ProvideWebhookStore(db)
|
||||||
webhookExecutionStore := database.ProvideWebhookExecutionStore(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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -160,6 +160,8 @@ const (
|
|||||||
WebhookTriggerPullReqMerged WebhookTrigger = "pullreq_merged"
|
WebhookTriggerPullReqMerged WebhookTrigger = "pullreq_merged"
|
||||||
// WebhookTriggerPullReqUpdated gets triggered when a pull request gets updated.
|
// WebhookTriggerPullReqUpdated gets triggered when a pull request gets updated.
|
||||||
WebhookTriggerPullReqUpdated WebhookTrigger = "pullreq_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{
|
var webhookTriggers = sortEnum([]WebhookTrigger{
|
||||||
@ -176,4 +178,5 @@ var webhookTriggers = sortEnum([]WebhookTrigger{
|
|||||||
WebhookTriggerPullReqClosed,
|
WebhookTriggerPullReqClosed,
|
||||||
WebhookTriggerPullReqCommentCreated,
|
WebhookTriggerPullReqCommentCreated,
|
||||||
WebhookTriggerPullReqMerged,
|
WebhookTriggerPullReqMerged,
|
||||||
|
WebhookTriggerPullReqLabelAssigned,
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user