diff --git a/scm/driver/azure/repo.go b/scm/driver/azure/repo.go index 3e729b33..a590bffe 100644 --- a/scm/driver/azure/repo.go +++ b/scm/driver/azure/repo.go @@ -21,8 +21,8 @@ type RepositoryService struct { func (s *RepositoryService) Find(ctx context.Context, repo string) (*scm.Repository, *scm.Response, error) { // https://docs.microsoft.com/en-us/rest/api/azure/devops/git/repositories/get?view=azure-devops-rest-4.1 if s.client.project == "" { - return nil, nil, ProjectRequiredError() - } + return nil, nil, ProjectRequiredError() + } endpoint := fmt.Sprintf("%s/%s/_apis/git/repositories/%s?api-version=6.0", s.client.owner, s.client.project, repo) out := new(repository) @@ -59,12 +59,16 @@ func (s *RepositoryService) List(ctx context.Context, opts scm.ListOptions) ([]* func (s *RepositoryService) ListHooks(ctx context.Context, repo string, opts scm.ListOptions) ([]*scm.Hook, *scm.Response, error) { // https://docs.microsoft.com/en-us/rest/api/azure/devops/hooks/subscriptions/list?view=azure-devops-rest-6.0 if s.client.project == "" { - return nil, nil, ProjectRequiredError() - } + return nil, nil, ProjectRequiredError() + } + projectID, projErr := s.getProjectIDFromProjectName(ctx, s.client.project) + if projErr != nil { + return nil, nil, fmt.Errorf("ListHooks was unable to look up the project's projectID, %s", projErr) + } endpoint := fmt.Sprintf("%s/_apis/hooks/subscriptions?api-version=6.0", s.client.owner) out := new(subscriptions) res, err := s.client.do(ctx, "GET", endpoint, nil, &out) - return convertHookList(out.Value, repo), res, err + return convertHookList(out.Value, projectID, repo), res, err } // ListStatus returns a list of commit statuses. @@ -76,8 +80,8 @@ func (s *RepositoryService) ListStatus(ctx context.Context, repo, ref string, op func (s *RepositoryService) CreateHook(ctx context.Context, repo string, input *scm.HookInput) (*scm.Hook, *scm.Response, error) { // https://docs.microsoft.com/en-us/rest/api/azure/devops/hooks/subscriptions/create?view=azure-devops-rest-6.0 if s.client.project == "" { - return nil, nil, ProjectRequiredError() - } + return nil, nil, ProjectRequiredError() + } endpoint := fmt.Sprintf("%s/_apis/hooks/subscriptions?api-version=6.0", s.client.owner) in := new(subscription) in.Status = "enabled" @@ -129,8 +133,8 @@ func (s *RepositoryService) UpdateHook(ctx context.Context, repo, id string, inp func (s *RepositoryService) DeleteHook(ctx context.Context, repo, id string) (*scm.Response, error) { // https://docs.microsoft.com/en-us/rest/api/azure/devops/hooks/subscriptions/delete?view=azure-devops-rest-6.0 if s.client.project == "" { - return nil, ProjectRequiredError() - } + return nil, ProjectRequiredError() + } endpoint := fmt.Sprintf("%s/_apis/hooks/subscriptions/%s?api-version=6.0", s.client.owner, id) return s.client.do(ctx, "DELETE", endpoint, nil, nil) } @@ -262,10 +266,10 @@ func convertRepository(from *repository) *scm.Repository { } } -func convertHookList(from []*subscription, repositoryFilter string) []*scm.Hook { +func convertHookList(from []*subscription, projectFilter string, repositoryFilter string) []*scm.Hook { to := []*scm.Hook{} for _, v := range from { - if repositoryFilter != "" && repositoryFilter == v.PublisherInputs.Repository { + if repositoryFilter != "" && projectFilter == v.PublisherInputs.ProjectID && repositoryFilter == v.PublisherInputs.Repository { to = append(to, convertHook(v)) } } diff --git a/scm/driver/azure/repo_test.go b/scm/driver/azure/repo_test.go index 48663e64..f2bd509d 100644 --- a/scm/driver/azure/repo_test.go +++ b/scm/driver/azure/repo_test.go @@ -83,6 +83,43 @@ func TestRepositoryHookCreate(t *testing.T) { } } +func TestHooksList(t *testing.T) { + defer gock.Off() + + gock.New("https:/dev.azure.com/"). + Get("/ORG/_apis/projects"). + Reply(201). + Type("application/json"). + File("testdata/projects.json") + + gock.New("https:/dev.azure.com/"). + Get("/ORG/_apis/hooks/subscriptions"). + Reply(200). + Type("application/json"). + File("testdata/hooks.json") + + client := NewDefault("ORG", "test_project") + repoID := "fde2d21f-13b9-4864-a995-83329045289a" + + got, _, err := client.Repositories.ListHooks(context.Background(), repoID, scm.ListOptions{}) + if err != nil { + t.Error(err) + return + } + + want := []*scm.Hook{} + raw, _ := ioutil.ReadFile("testdata/hooks.json.golden") + jsonErr := json.Unmarshal(raw, &want) + if jsonErr != nil { + t.Error(jsonErr) + } + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } +} + func TestRepositoryHookDelete(t *testing.T) { defer gock.Off() diff --git a/scm/driver/azure/testdata/hooks.json b/scm/driver/azure/testdata/hooks.json new file mode 100644 index 00000000..76efd534 --- /dev/null +++ b/scm/driver/azure/testdata/hooks.json @@ -0,0 +1,121 @@ +{ + "count": 2, + "value": [ + { + "id": "d455cb11-20a0-4b15-b546-7e9fb9973cc6", + "url": "https://dev.azure.com/tphoney/_apis/hooks/subscriptions/d455cb11-20a0-4b15-b546-7e9fb9973cc6", + "status": "enabled", + "publisherId": "tfs", + "eventType": "git.pullrequest.created", + "subscriber": null, + "resourceVersion": "1.0", + "eventDescription": "Repository test_repo2", + "consumerId": "webHooks", + "consumerActionId": "httpRequest", + "actionDescription": "To host www.bla.com", + "probationRetries": 1, + "createdBy": { + "displayName": "tp", + "id": "3ff4a20f-306e-677e-8a01-57f35e71f109", + "uniqueName": "tp@harness.io", + "descriptor": "msa.M2ZmNGEyMGYtMzA2ZS03NzdlLThhMDEtNTdmMzVlNzFmMTA5" + }, + "createdDate": "2022-03-25T13:28:12.39Z", + "modifiedBy": { + "displayName": "tp", + "id": "3ff4a20f-306e-677e-8a01-57f35e71f109", + "uniqueName": "tp@harness.io", + "descriptor": "msa.M2ZmNGEyMGYtMzA2ZS03NzdlLThhMDEtNTdmMzVlNzFmMTA5" + }, + "modifiedDate": "2022-03-29T10:39:13.813Z", + "lastProbationRetryDate": "2022-03-28T10:44:51.093Z", + "publisherInputs": { + "branch": "", + "projectId": "d350c9c0-7749-4ff8-a78f-f9c1f0e56729", + "pullrequestCreatedBy": "", + "pullrequestReviewersContains": "", + "repository": "fde2d21f-13b9-4864-a995-83329045289a", + "tfsSubscriptionId": "4ce8d6c4-f655-418d-8eb6-9462dd01ff39" + }, + "consumerInputs": { + "acceptUntrustedCerts": "true", + "url": "http://www.bla.com" + }, + "_links": { + "self": { + "href": "https://dev.azure.com/tphoney/_apis/hooks/subscriptions/d455cb11-20a0-4b15-b546-7e9fb9973cc6" + }, + "consumer": { + "href": "https://dev.azure.com/tphoney/_apis/hooks/consumers/webHooks" + }, + "actions": { + "href": "https://dev.azure.com/tphoney/_apis/hooks/consumers/webHooks/actions" + }, + "notifications": { + "href": "https://dev.azure.com/tphoney/_apis/hooks/subscriptions/d455cb11-20a0-4b15-b546-7e9fb9973cc6/notifications" + }, + "publisher": { + "href": "https://dev.azure.com/tphoney/_apis/hooks/publishers/tfs" + } + } + }, + { + "id": "d455cb11-20a0-4b15-b546-7e9fb9973cc7", + "url": "https://dev.azure.com/tphoney/_apis/hooks/subscriptions/d455cb11-20a0-4b15-b546-7e9fb9973cc7", + "status": "enabled", + "publisherId": "tfs", + "eventType": "git.pullrequest.merged", + "subscriber": null, + "resourceVersion": "1.0", + "eventDescription": "Repository test_repo2", + "consumerId": "webHooks", + "consumerActionId": "httpRequest", + "actionDescription": "To host www.bla.com", + "probationRetries": 1, + "createdBy": { + "displayName": "tp", + "id": "3ff4a20f-306e-677e-8a01-57f35e71f109", + "uniqueName": "tp@harness.io", + "descriptor": "msa.M2ZmNGEyMGYtMzA2ZS03NzdlLThhMDEtNTdmMzVlNzFmMTA5" + }, + "createdDate": "2022-03-25T13:28:12.39Z", + "modifiedBy": { + "displayName": "tp", + "id": "3ff4a20f-306e-677e-8a01-57f35e71f109", + "uniqueName": "tp@harness.io", + "descriptor": "msa.M2ZmNGEyMGYtMzA2ZS03NzdlLThhMDEtNTdmMzVlNzFmMTA5" + }, + "modifiedDate": "2022-03-29T10:39:13.813Z", + "lastProbationRetryDate": "2022-03-28T10:44:51.093Z", + "publisherInputs": { + "branch": "", + "projectId": "d350c9c0-7749-4ff8-a78f-f9c1f0e56729", + "pullrequestCreatedBy": "", + "pullrequestReviewersContains": "", + "repository": "fde2d21f-13b9-4864-a995-83329045289a", + "tfsSubscriptionId": "4ce8d6c4-f655-418d-8eb6-9462dd01ff39" + }, + "consumerInputs": { + "acceptUntrustedCerts": "true", + "url": "http://www.bla.com" + }, + "_links": { + "self": { + "href": "https://dev.azure.com/tphoney/_apis/hooks/subscriptions/d455cb11-20a0-4b15-b546-7e9fb9973cc7" + }, + "consumer": { + "href": "https://dev.azure.com/tphoney/_apis/hooks/consumers/webHooks" + }, + "actions": { + "href": "https://dev.azure.com/tphoney/_apis/hooks/consumers/webHooks/actions" + }, + "notifications": { + "href": "https://dev.azure.com/tphoney/_apis/hooks/subscriptions/d455cb11-20a0-4b15-b546-7e9fb9973cc7/notifications" + }, + "publisher": { + "href": "https://dev.azure.com/tphoney/_apis/hooks/publishers/tfs" + } + } + } + ] +} \ No newline at end of file diff --git a/scm/driver/azure/testdata/hooks.json.golden b/scm/driver/azure/testdata/hooks.json.golden new file mode 100644 index 00000000..78d873eb --- /dev/null +++ b/scm/driver/azure/testdata/hooks.json.golden @@ -0,0 +1,22 @@ +[ + { + "ID": "d455cb11-20a0-4b15-b546-7e9fb9973cc6", + "Name": "", + "Target": "http://www.bla.com", + "Events": [ + "git.pullrequest.created" + ], + "Active": true, + "SkipVerify": true + }, + { + "ID": "d455cb11-20a0-4b15-b546-7e9fb9973cc7", + "Name": "", + "Target": "http://www.bla.com", + "Events": [ + "git.pullrequest.merged" + ], + "Active": true, + "SkipVerify": true + } +] \ No newline at end of file