From 87381af2ac9b00dcf39b40128fcaf5843660e478 Mon Sep 17 00:00:00 2001 From: ShobhitSingh11 <139750384+ShobhitSingh11@users.noreply.github.com> Date: Tue, 7 May 2024 21:05:06 +0530 Subject: [PATCH] =?UTF-8?q?fix:=20[CI-11840]:=20Added=20env=20variable=20t?= =?UTF-8?q?o=20control=20the=20event=20of=20inbound=20w=E2=80=A6=20(#3508)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Have added the env var "DRONE_INCOMING_WEBHOOK_EVENTS" (of type list of string) to control the event in case of incoming webhook. If no such env variable is provided then it will fallback to default behaviour. Below are the test cases - Case 1: When no env variable "DRONE_INCOMING_WEBHOOK_EVENTS" is present. https://github.com/harness/gitness/assets/139750384/ad228d61-2608-4756-abaa-b3397eba1fb7 - Case 2: When Deployment event is missing from env var. https://github.com/harness/gitness/assets/139750384/0faf2afc-9e0b-42f1-9327-8dc674ed112d - Case 3: When Deployment, pull_request events are missing from env var. https://github.com/harness/gitness/assets/139750384/29f40107-4b7a-4eae-afa8-464d78662e8b - Case 4: When Deployment and push events are only present in env var. https://github.com/harness/gitness/assets/139750384/b6cdec79-20bb-4d56-8fd0-f72cb9e57a8e Tested with few more combinations as well. --- cmd/drone-server/config/config.go | 19 +++++++---- cmd/drone-server/inject_service.go | 2 +- service/hook/hook.go | 21 ++++++++---- service/hook/hook_test.go | 51 +++++++++++++++++++++++++++--- 4 files changed, 73 insertions(+), 20 deletions(-) diff --git a/cmd/drone-server/config/config.go b/cmd/drone-server/config/config.go index fc4f06f75..68970f1f9 100644 --- a/cmd/drone-server/config/config.go +++ b/cmd/drone-server/config/config.go @@ -80,13 +80,14 @@ type ( Yaml Yaml // Remote configurations - Bitbucket Bitbucket - Gitea Gitea - Github Github - GitLab GitLab - Gogs Gogs - Stash Stash - Gitee Gitee + Bitbucket Bitbucket + Gitea Gitea + Github Github + GitLab GitLab + Gogs Gogs + Stash Stash + Gitee Gitee + IncomingWebhook IncomingWebhook } // Cloning provides the cloning configuration. @@ -443,6 +444,10 @@ type ( ContentSecurityPolicy string `envconfig:"DRONE_HTTP_CONTENT_SECURITY_POLICY"` ReferrerPolicy string `envconfig:"DRONE_HTTP_REFERRER_POLICY"` } + + IncomingWebhook struct { + Events []string `envconfig:"DRONE_INCOMING_WEBHOOK_EVENTS" default:"branch,deployment,push,tag,pull_request"` + } ) // Environ returns the settings from the environment. diff --git a/cmd/drone-server/inject_service.go b/cmd/drone-server/inject_service.go index 25c9b8eb8..82a1313fe 100644 --- a/cmd/drone-server/inject_service.go +++ b/cmd/drone-server/inject_service.go @@ -85,7 +85,7 @@ func provideContentService(client *scm.Client, renewer core.Renewer) core.FileSe // provideHookService is a Wire provider function that returns a // hook service based on the environment configuration. func provideHookService(client *scm.Client, renewer core.Renewer, config config.Config) core.HookService { - return hook.New(client, config.Proxy.Addr, renewer) + return hook.New(client, config.Proxy.Addr, renewer, config.IncomingWebhook.Events) } // provideNetrcService is a Wire provider function that returns diff --git a/service/hook/hook.go b/service/hook/hook.go index eb4641916..fe23258be 100644 --- a/service/hook/hook.go +++ b/service/hook/hook.go @@ -23,14 +23,15 @@ import ( ) // New returns a new HookService. -func New(client *scm.Client, addr string, renew core.Renewer) core.HookService { - return &service{client: client, addr: addr, renew: renew} +func New(client *scm.Client, addr string, renew core.Renewer, events []string) core.HookService { + return &service{client: client, addr: addr, renew: renew, events: events} } type service struct { renew core.Renewer client *scm.Client addr string + events []string } func (s *service) Create(ctx context.Context, user *core.User, repo *core.Repository) error { @@ -38,6 +39,12 @@ func (s *service) Create(ctx context.Context, user *core.User, repo *core.Reposi if err != nil { return err } + + eventsMap := make(map[string]bool) + for _, event := range s.events { + eventsMap[event] = true + } + ctx = context.WithValue(ctx, scm.TokenKey{}, &scm.Token{ Token: user.Token, Refresh: user.Refresh, @@ -48,11 +55,11 @@ func (s *service) Create(ctx context.Context, user *core.User, repo *core.Reposi Target: s.addr + "/hook", Secret: repo.Signer, Events: scm.HookEvents{ - Branch: true, - Deployment: true, - PullRequest: true, - Push: true, - Tag: true, + Branch: eventsMap["branch"], + Deployment: eventsMap["deployment"], + PullRequest: eventsMap["pull_request"], + Push: eventsMap["push"], + Tag: eventsMap["tag"], }, } return replaceHook(ctx, s.client, repo.Slug, hook) diff --git a/service/hook/hook_test.go b/service/hook/hook_test.go index 10bf069be..14dfdab5b 100644 --- a/service/hook/hook_test.go +++ b/service/hook/hook_test.go @@ -50,11 +50,52 @@ func TestCreate(t *testing.T) { mockRepos := mockscm.NewMockRepositoryService(controller) mockRepos.EXPECT().ListHooks(gomock.Any(), "octocat/hello-world", gomock.Any()).Return(mockHooks, nil, nil) mockRepos.EXPECT().CreateHook(gomock.Any(), "octocat/hello-world", hook).Return(nil, nil, nil) - client := new(scm.Client) client.Repositories = mockRepos - service := New(client, "https://drone.company.com", mockRenewer) + service := New(client, "https://drone.company.com", mockRenewer, []string{"branch", "deployment", "push", "tag", "pull_request"}) + err := service.Create(noContext, mockUser, mockRepo) + if err != nil { + t.Error(err) + } +} + +func TestCreateWithLimitedEvents(t *testing.T) { + controller := gomock.NewController(t) + defer controller.Finish() + + mockUser := &core.User{} + mockHooks := []*scm.Hook{} + mockRepo := &core.Repository{ + Namespace: "octocat", + Name: "hello-world", + Slug: "octocat/hello-world", + Signer: "abc123", + } + + hook := &scm.HookInput{ + Name: "drone", + Target: "https://drone.company.com/hook", + Secret: "abc123", + Events: scm.HookEvents{ + Branch: false, + Deployment: true, + PullRequest: true, + Push: false, + Tag: true, + }, + } + + mockRenewer := mock.NewMockRenewer(controller) + mockRenewer.EXPECT().Renew(gomock.Any(), mockUser, false).Return(nil) + + mockRepos := mockscm.NewMockRepositoryService(controller) + mockRepos.EXPECT().ListHooks(gomock.Any(), "octocat/hello-world", gomock.Any()).Return(mockHooks, nil, nil) + mockRepos.EXPECT().CreateHook(gomock.Any(), "octocat/hello-world", hook).Return(nil, nil, nil) + client := new(scm.Client) + client.Repositories = mockRepos + + service := New(client, "https://drone.company.com", mockRenewer, []string{"deployment", "tag", "pull_request"}) err := service.Create(noContext, mockUser, mockRepo) if err != nil { t.Error(err) @@ -70,7 +111,7 @@ func TestCreate_RenewErr(t *testing.T) { mockRenewer := mock.NewMockRenewer(controller) mockRenewer.EXPECT().Renew(gomock.Any(), mockUser, false).Return(scm.ErrNotAuthorized) - service := New(nil, "https://drone.company.com", mockRenewer) + service := New(nil, "https://drone.company.com", mockRenewer, []string{}) err := service.Create(noContext, mockUser, nil) if err != scm.ErrNotAuthorized { t.Errorf("Want not authorized error, got %v", err) @@ -106,7 +147,7 @@ func TestDelete(t *testing.T) { client := new(scm.Client) client.Repositories = mockRepos - service := New(client, "https://drone.company.com", mockRenewer) + service := New(client, "https://drone.company.com", mockRenewer, []string{}) err := service.Delete(noContext, mockUser, mockRepo) if err != nil { t.Error(err) @@ -122,7 +163,7 @@ func TestDelete_RenewErr(t *testing.T) { mockRenewer := mock.NewMockRenewer(controller) mockRenewer.EXPECT().Renew(gomock.Any(), mockUser, false).Return(scm.ErrNotAuthorized) - service := New(nil, "https://drone.company.com", mockRenewer) + service := New(nil, "https://drone.company.com", mockRenewer, []string{}) err := service.Delete(noContext, mockUser, nil) if err != scm.ErrNotAuthorized { t.Errorf("Want not authorized error, got %v", err)