From 9acf83b318465a6842e02a6b4fcecaee08b0f490 Mon Sep 17 00:00:00 2001 From: raghavharness Date: Wed, 1 Jun 2022 17:38:13 +0530 Subject: [PATCH 001/195] [CI-4621]: Added PR find and listCommits API support in go-scm --- scm/driver/azure/integration/pr_test.go | 51 ++++++++++++++++++++++++ scm/driver/azure/pr.go | 14 ++++++- scm/driver/azure/pr_test.go | 53 +++++++++++++++++++++++++ 3 files changed, 116 insertions(+), 2 deletions(-) diff --git a/scm/driver/azure/integration/pr_test.go b/scm/driver/azure/integration/pr_test.go index 941b30526..ea755f04f 100644 --- a/scm/driver/azure/integration/pr_test.go +++ b/scm/driver/azure/integration/pr_test.go @@ -40,3 +40,54 @@ func TestCreatePR(t *testing.T) { t.Errorf("PullRequests.Create does not have the correct title %v", outputPR.Title) } } + +func TestPullRequestFind(t *testing.T) { + if token == "" { + t.Skip("Skipping, Acceptance test") + } + client = azure.NewDefault(organization, project) + client.Client = &http.Client{ + Transport: &transport.Custom{ + Before: func(r *http.Request) { + r.Header.Set("Authorization", fmt.Sprintf("Basic %s", token)) + }, + }, + } + outputPR, response, err := client.PullRequests.Find(context.Background(), repoID, 1) + if err != nil { + t.Errorf("PullRequests.Find got an error %v", err) + } + if response.Status != http.StatusOK { + t.Errorf("PullRequests.Find did not get a 200 back %v", response.Status) + } + if outputPR.Title != "test_pr" { + t.Errorf("PullRequests.Find does not have the correct title %v", outputPR.Title) + } +} + +func TestPullRequestCommits(t *testing.T) { + if token == "" { + t.Skip("Skipping, Acceptance test") + } + client = azure.NewDefault(organization, project) + client.Client = &http.Client{ + Transport: &transport.Custom{ + Before: func(r *http.Request) { + r.Header.Set("Authorization", fmt.Sprintf("Basic %s", token)) + }, + }, + } + commits, response, err := client.PullRequests.ListCommits(context.Background(), repoID, 1, scm.ListOptions{}) + if err != nil { + t.Errorf("PullRequests.ListCommits got an error %v", err) + } + if response.Status != http.StatusOK { + t.Errorf("PullRequests.ListCommits did not get a 200 back %v", response.Status) + } + if len(commits) < 1 { + t.Errorf("PullRequests.ListCommits there should be at least 1 commit %d", len(commits)) + } + if commits[0].Sha == "" { + t.Errorf("PullRequests.ListCommits first entry did not get a sha back %v", commits[0].Sha) + } +} \ No newline at end of file diff --git a/scm/driver/azure/pr.go b/scm/driver/azure/pr.go index 647332899..0a221b117 100644 --- a/scm/driver/azure/pr.go +++ b/scm/driver/azure/pr.go @@ -17,7 +17,12 @@ type pullService struct { } func (s *pullService) Find(ctx context.Context, repo string, number int) (*scm.PullRequest, *scm.Response, error) { - return nil, nil, scm.ErrNotSupported + // https://docs.microsoft.com/en-us/rest/api/azure/devops/git/pull-requests/get-pull-request?view=azure-devops-rest-6.0 + endpoint := fmt.Sprintf("%s/%s/_apis/git/repositories/%s/pullrequests/%d?api-version=6.0", + s.client.owner, s.client.project, repo, number) + out := new(pr) + res, err := s.client.do(ctx, "GET", endpoint, nil, out) + return convertPullRequest(out), res, err } func (s *pullService) List(ctx context.Context, repo string, opts scm.PullRequestListOptions) ([]*scm.PullRequest, *scm.Response, error) { @@ -29,7 +34,12 @@ func (s *pullService) ListChanges(ctx context.Context, repo string, number int, } func (s *pullService) ListCommits(ctx context.Context, repo string, number int, opts scm.ListOptions) ([]*scm.Commit, *scm.Response, error) { - return nil, nil, scm.ErrNotSupported + // https://docs.microsoft.com/en-us/rest/api/azure/devops/git/pull-request-commits/get-pull-request-commits?view=azure-devops-rest-6.0 + endpoint := fmt.Sprintf("%s/%s/_apis/git/repositories/%s/pullRequests/%d/commits?api-version=6.0", + s.client.owner, s.client.project, repo, number) + out := new(commitList) + res, err := s.client.do(ctx, "GET", endpoint, nil, out) + return convertCommitList(out.Value), res, err } func (s *pullService) Merge(ctx context.Context, repo string, number int) (*scm.Response, error) { diff --git a/scm/driver/azure/pr_test.go b/scm/driver/azure/pr_test.go index afddc8da7..a54031cd2 100644 --- a/scm/driver/azure/pr_test.go +++ b/scm/driver/azure/pr_test.go @@ -48,3 +48,56 @@ func TestPullCreate(t *testing.T) { t.Log(diff) } } + +func TestPullFind(t *testing.T) { + defer gock.Off() + + gock.New("https:/dev.azure.com/"). + Get("/ORG/PROJ/_apis/git/repositories/REPOID/pullrequests/1"). + Reply(200). + Type("application/json"). + File("testdata/pr.json") + + + client := NewDefault("ORG", "PROJ") + got, _, err := client.PullRequests.Find(context.Background(), "REPOID", 1) + if err != nil { + t.Error(err) + return + } + + want := new(scm.PullRequest) + raw, _ := ioutil.ReadFile("testdata/pr.json.golden") + _ = json.Unmarshal(raw, want) + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } +} + +func TestPullListCommits(t *testing.T) { + defer gock.Off() + + gock.New("https:/dev.azure.com/"). + Get("/ORG/PROJ/_apis/git/repositories/REPOID/pullRequests/1/commits"). + Reply(200). + Type("application/json"). + File("testdata/commits.json") + + client := NewDefault("ORG", "PROJ") + got, _, err := client.PullRequests.ListCommits(context.Background(), "REPOID", 1, scm.ListOptions{}) + if err != nil { + t.Error(err) + return + } + + want := []*scm.Commit{} + raw, _ := ioutil.ReadFile("testdata/commits.json.golden") + _ = json.Unmarshal(raw, &want) + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } +} \ No newline at end of file From 2cc03ad3449d20ddd3d41e6eb2e2e3833b4214f1 Mon Sep 17 00:00:00 2001 From: raghavharness Date: Wed, 1 Jun 2022 19:25:45 +0530 Subject: [PATCH 002/195] [CI-4621]: go mod change --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 1a7e7c5ea..0bf3fae57 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/drone/go-scm +module github.com/raghavharness/go-scm require ( github.com/google/go-cmp v0.2.0 From 71867bca7c8e56aa1123dee5307631e588d87be8 Mon Sep 17 00:00:00 2001 From: raghavharness Date: Thu, 2 Jun 2022 11:39:51 +0530 Subject: [PATCH 003/195] revert --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 0bf3fae57..1a7e7c5ea 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/raghavharness/go-scm +module github.com/drone/go-scm require ( github.com/google/go-cmp v0.2.0 From 0dd92782c45468f27c0a05f0a1c1de13bf043c23 Mon Sep 17 00:00:00 2001 From: raghavharness Date: Thu, 2 Jun 2022 12:41:29 +0530 Subject: [PATCH 004/195] go fmt --- scm/driver/azure/integration/pr_test.go | 2 +- scm/driver/azure/pr.go | 8 ++++---- scm/driver/azure/pr_test.go | 3 +-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/scm/driver/azure/integration/pr_test.go b/scm/driver/azure/integration/pr_test.go index ea755f04f..b82307340 100644 --- a/scm/driver/azure/integration/pr_test.go +++ b/scm/driver/azure/integration/pr_test.go @@ -90,4 +90,4 @@ func TestPullRequestCommits(t *testing.T) { if commits[0].Sha == "" { t.Errorf("PullRequests.ListCommits first entry did not get a sha back %v", commits[0].Sha) } -} \ No newline at end of file +} diff --git a/scm/driver/azure/pr.go b/scm/driver/azure/pr.go index 0a221b117..2d9282892 100644 --- a/scm/driver/azure/pr.go +++ b/scm/driver/azure/pr.go @@ -18,8 +18,8 @@ type pullService struct { func (s *pullService) Find(ctx context.Context, repo string, number int) (*scm.PullRequest, *scm.Response, error) { // https://docs.microsoft.com/en-us/rest/api/azure/devops/git/pull-requests/get-pull-request?view=azure-devops-rest-6.0 - endpoint := fmt.Sprintf("%s/%s/_apis/git/repositories/%s/pullrequests/%d?api-version=6.0", - s.client.owner, s.client.project, repo, number) + endpoint := fmt.Sprintf("%s/%s/_apis/git/repositories/%s/pullrequests/%d?api-version=6.0", + s.client.owner, s.client.project, repo, number) out := new(pr) res, err := s.client.do(ctx, "GET", endpoint, nil, out) return convertPullRequest(out), res, err @@ -35,8 +35,8 @@ func (s *pullService) ListChanges(ctx context.Context, repo string, number int, func (s *pullService) ListCommits(ctx context.Context, repo string, number int, opts scm.ListOptions) ([]*scm.Commit, *scm.Response, error) { // https://docs.microsoft.com/en-us/rest/api/azure/devops/git/pull-request-commits/get-pull-request-commits?view=azure-devops-rest-6.0 - endpoint := fmt.Sprintf("%s/%s/_apis/git/repositories/%s/pullRequests/%d/commits?api-version=6.0", - s.client.owner, s.client.project, repo, number) + endpoint := fmt.Sprintf("%s/%s/_apis/git/repositories/%s/pullRequests/%d/commits?api-version=6.0", + s.client.owner, s.client.project, repo, number) out := new(commitList) res, err := s.client.do(ctx, "GET", endpoint, nil, out) return convertCommitList(out.Value), res, err diff --git a/scm/driver/azure/pr_test.go b/scm/driver/azure/pr_test.go index a54031cd2..42b60dfe7 100644 --- a/scm/driver/azure/pr_test.go +++ b/scm/driver/azure/pr_test.go @@ -58,7 +58,6 @@ func TestPullFind(t *testing.T) { Type("application/json"). File("testdata/pr.json") - client := NewDefault("ORG", "PROJ") got, _, err := client.PullRequests.Find(context.Background(), "REPOID", 1) if err != nil { @@ -100,4 +99,4 @@ func TestPullListCommits(t *testing.T) { t.Errorf("Unexpected Results") t.Log(diff) } -} \ No newline at end of file +} From 74701d04a2c01775b4edf5c126015916b9578982 Mon Sep 17 00:00:00 2001 From: Aman Singh Date: Sun, 5 Jun 2022 20:45:10 +0530 Subject: [PATCH 005/195] remove slash from list commits api --- scm/driver/github/pr.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm/driver/github/pr.go b/scm/driver/github/pr.go index 2dc083b4c..74da3bbf2 100644 --- a/scm/driver/github/pr.go +++ b/scm/driver/github/pr.go @@ -39,7 +39,7 @@ func (s *pullService) ListChanges(ctx context.Context, repo string, number int, } func (s *pullService) ListCommits(ctx context.Context, repo string, number int, opts scm.ListOptions) ([]*scm.Commit, *scm.Response, error) { - path := fmt.Sprintf("/repos/%s/pulls/%d/commits?%s", repo, number, encodeListOptions(opts)) + path := fmt.Sprintf("repos/%s/pulls/%d/commits?%s", repo, number, encodeListOptions(opts)) out := []*commit{} res, err := s.client.do(ctx, "GET", path, nil, &out) return convertCommitList(out), res, err From 4c30731be442baccbbfd47bfd974f711d4b9788c Mon Sep 17 00:00:00 2001 From: Brad Rydzewski Date: Sun, 5 Jun 2022 12:02:26 -0400 Subject: [PATCH 006/195] fix dupes in pagination --- scm/traverse/repos.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm/traverse/repos.go b/scm/traverse/repos.go index dcad3ddd6..c417d2704 100644 --- a/scm/traverse/repos.go +++ b/scm/traverse/repos.go @@ -22,7 +22,7 @@ func Repos(ctx context.Context, client *scm.Client) ([]*scm.Repository, error) { } for _, src := range result { if src != nil { - list = append(list, result...) + list = append(list, src) } } opts.Page = meta.Page.Next From 63b6fb0f3b3e982075110c73270f3de14486d41f Mon Sep 17 00:00:00 2001 From: Raghav Date: Mon, 6 Jun 2022 13:38:10 +0530 Subject: [PATCH 007/195] Using target commit instead of source in base info for azure (#189) * Using target commit instead of source in base info * added pr status information for azure --- scm/driver/azure/git.go | 2 ++ scm/driver/azure/pr.go | 25 +++++++++++-------- scm/driver/azure/testdata/commit.json.golden | 4 +-- scm/driver/azure/testdata/commits.json.golden | 12 ++++----- scm/driver/azure/testdata/pr.json | 3 ++- scm/driver/azure/testdata/pr.json.golden | 11 ++++---- 6 files changed, 33 insertions(+), 24 deletions(-) diff --git a/scm/driver/azure/git.go b/scm/driver/azure/git.go index e61ec6236..435023ab9 100644 --- a/scm/driver/azure/git.go +++ b/scm/driver/azure/git.go @@ -221,11 +221,13 @@ func convertCommit(from *gitCommit) *scm.Commit { Sha: from.CommitID, Link: from.URL, Author: scm.Signature{ + Login: from.Author.Name, Name: from.Author.Name, Email: from.Author.Email, Date: from.Author.Date, }, Committer: scm.Signature{ + Login: from.Committer.Name, Name: from.Committer.Name, Email: from.Committer.Email, Date: from.Committer.Date, diff --git a/scm/driver/azure/pr.go b/scm/driver/azure/pr.go index 2d9282892..a5bb93479 100644 --- a/scm/driver/azure/pr.go +++ b/scm/driver/azure/pr.go @@ -10,6 +10,7 @@ import ( "time" "github.com/drone/go-scm/scm" + "github.com/drone/go-scm/scm/driver/internal/null" ) type pullService struct { @@ -99,13 +100,14 @@ type pr struct { URL string `json:"url"` ImageURL string `json:"imageUrl"` } `json:"createdBy"` - CreationDate time.Time `json:"creationDate"` - Title string `json:"title"` - Description string `json:"description"` - SourceRefName string `json:"sourceRefName"` - TargetRefName string `json:"targetRefName"` - MergeStatus string `json:"mergeStatus"` - MergeID string `json:"mergeId"` + CreationDate time.Time `json:"creationDate"` + ClosedDate null.String `json:"closedDate"` + Title string `json:"title"` + Description string `json:"description"` + SourceRefName string `json:"sourceRefName"` + TargetRefName string `json:"targetRefName"` + MergeStatus string `json:"mergeStatus"` + MergeID string `json:"mergeId"` LastMergeSourceCommit struct { CommitID string `json:"commitId"` URL string `json:"url"` @@ -163,15 +165,18 @@ func convertPullRequest(from *pr) *scm.PullRequest { Title: from.Title, Body: from.Description, Sha: from.LastMergeSourceCommit.CommitID, - Source: from.SourceRefName, - Target: from.TargetRefName, + Source: scm.TrimRef(from.SourceRefName), + Target: scm.TrimRef(from.TargetRefName), Link: from.URL, + Closed: from.ClosedDate.Valid, + Merged: from.Status == "completed", + Ref: fmt.Sprintf("refs/pull/%d/merge", from.PullRequestID), Head: scm.Reference{ Sha: from.LastMergeSourceCommit.CommitID, }, Base: scm.Reference{ - Sha: from.LastMergeSourceCommit.CommitID, + Sha: from.LastMergeTargetCommit.CommitID, }, Author: scm.User{ Login: from.CreatedBy.UniqueName, diff --git a/scm/driver/azure/testdata/commit.json.golden b/scm/driver/azure/testdata/commit.json.golden index 36b73b3cf..1659822a9 100644 --- a/scm/driver/azure/testdata/commit.json.golden +++ b/scm/driver/azure/testdata/commit.json.golden @@ -5,14 +5,14 @@ "Name": "tp", "Email": "tp@harness.io", "Date": "2022-03-15T17:08:22Z", - "Login": "", + "Login": "tp", "Avatar": "" }, "Committer": { "Name": "tp", "Email": "tp@harness.io", "Date": "2022-03-15T17:08:22Z", - "Login": "", + "Login": "tp", "Avatar": "" }, "Link": "https://dev.azure.com/tphoney/d350c9c0-7749-4ff8-a78f-f9c1f0e56729/_apis/git/repositories/fde2d21f-13b9-4864-a995-83329045289a/commits/14897f4465d2d63508242b5cbf68aa2865f693e7" diff --git a/scm/driver/azure/testdata/commits.json.golden b/scm/driver/azure/testdata/commits.json.golden index 7f2eb4a47..a42699cf2 100644 --- a/scm/driver/azure/testdata/commits.json.golden +++ b/scm/driver/azure/testdata/commits.json.golden @@ -6,14 +6,14 @@ "Name": "tp", "Email": "tp@harness.io", "Date": "2022-03-04T12:19:58Z", - "Login": "", + "Login": "tp", "Avatar": "" }, "Committer": { "Name": "tp", "Email": "tp@harness.io", "Date": "2022-03-04T12:19:58Z", - "Login": "", + "Login": "tp", "Avatar": "" }, "Link": "https://dev.azure.com/tphoney/d350c9c0-7749-4ff8-a78f-f9c1f0e56729/_apis/git/repositories/fde2d21f-13b9-4864-a995-83329045289a/commits/e0aee6aa543294d62520fb906689da6710af149c" @@ -25,14 +25,14 @@ "Name": "tp", "Email": "tp@harness.io", "Date": "2022-03-04T12:19:57Z", - "Login": "", + "Login": "tp", "Avatar": "" }, "Committer": { "Name": "tp", "Email": "tp@harness.io", "Date": "2022-03-04T12:19:57Z", - "Login": "", + "Login": "tp", "Avatar": "" }, "Link": "https://dev.azure.com/tphoney/d350c9c0-7749-4ff8-a78f-f9c1f0e56729/_apis/git/repositories/fde2d21f-13b9-4864-a995-83329045289a/commits/1fe456794debece7c4125b9e283b601c974977a9" @@ -44,14 +44,14 @@ "Name": "tp", "Email": "tp@harness.io", "Date": "2022-03-04T12:19:56Z", - "Login": "", + "Login": "tp", "Avatar": "" }, "Committer": { "Name": "tp", "Email": "tp@harness.io", "Date": "2022-03-04T12:19:56Z", - "Login": "", + "Login": "tp", "Avatar": "" }, "Link": "https://dev.azure.com/tphoney/d350c9c0-7749-4ff8-a78f-f9c1f0e56729/_apis/git/repositories/fde2d21f-13b9-4864-a995-83329045289a/commits/dc49e8e6e22bb3456366a09365ce9e72912f26b5" diff --git a/scm/driver/azure/testdata/pr.json b/scm/driver/azure/testdata/pr.json index b721e0dae..e419af010 100644 --- a/scm/driver/azure/testdata/pr.json +++ b/scm/driver/azure/testdata/pr.json @@ -15,7 +15,7 @@ }, "pullRequestId": 19, "codeReviewId": 19, - "status": "active", + "status": "completed", "createdBy": { "id": "3ff4a20f-306e-677e-8a01-57f35e71f109", "displayName": "tp", @@ -24,6 +24,7 @@ "imageUrl": "https://dev.azure.com/tphoney/_api/_common/identityImage?id=3ff4a20f-306e-677e-8a01-57f35e71f109" }, "creationDate": "2022-03-04T13:34:54.3177724Z", + "closedDate": "2022-06-03T06:33:42.2405472Z", "title": "test_pr", "description": "test_pr_body", "sourceRefName": "refs/heads/pr_branch", diff --git a/scm/driver/azure/testdata/pr.json.golden b/scm/driver/azure/testdata/pr.json.golden index 291b6f063..5e59c583b 100644 --- a/scm/driver/azure/testdata/pr.json.golden +++ b/scm/driver/azure/testdata/pr.json.golden @@ -4,17 +4,18 @@ "Body": "test_pr_body", "Sha": "01768d964c03e97260af0bd8cd9e5cd1f9ac6356", "Ref": "", - "Source": "refs/heads/pr_branch", - "Target": "refs/heads/main", + "Source": "pr_branch", + "Target": "main", + "Ref": "refs/pull/19/merge", "Fork": "", "Link": "https://dev.azure.com/tphoney/d350c9c0-7749-4ff8-a78f-f9c1f0e56729/_apis/git/repositories/fde2d21f-13b9-4864-a995-83329045289a/pullRequests/19", "Diff": "", - "Closed": false, - "Merged": false, + "Closed": true, + "Merged": true, "Base": { "Name": "", "Path": "", - "Sha": "01768d964c03e97260af0bd8cd9e5cd1f9ac6356" + "Sha": "b748ab7eb49b8627214f22f631f878c4af9893b5" }, "Head": { "Name": "", From 424d106097528828e40ca749aaafdcc5bf833836 Mon Sep 17 00:00:00 2001 From: TP Honey Date: Tue, 7 Jun 2022 13:06:23 +0100 Subject: [PATCH 008/195] release_prep_v1.24.0 --- CHANGELOG.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e0bc4f5c..cdb448dfd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # Changelog +## [v1.24.0](https://github.com/drone/go-scm/tree/v1.24.0) (2022-06-07) + +[Full Changelog](https://github.com/drone/go-scm/compare/v1.23.0...v1.24.0) + +**Implemented enhancements:** + +- Added PR find and listCommit API support for Azure [\#188](https://github.com/drone/go-scm/pull/188) ([raghavharness](https://github.com/raghavharness)) + +**Fixed bugs:** + +- remove redundant slash from list commits api [\#190](https://github.com/drone/go-scm/pull/190) ([aman-harness](https://github.com/aman-harness)) +- Using target commit instead of source in base info for azure [\#189](https://github.com/drone/go-scm/pull/189) ([raghavharness](https://github.com/raghavharness)) + +**Closed issues:** + +- gitee client pagination bug [\#187](https://github.com/drone/go-scm/issues/187) + ## [v1.23.0](https://github.com/drone/go-scm/tree/v1.23.0) (2022-05-23) [Full Changelog](https://github.com/drone/go-scm/compare/v1.22.0...v1.23.0) @@ -13,6 +30,10 @@ - Remove the null value de-reference issue when the bitbucket server url is nil [\#183](https://github.com/drone/go-scm/pull/183) ([DeepakPatankar](https://github.com/DeepakPatankar)) - \[PL-24913\]: Handle the error raised while creating a multipart input [\#181](https://github.com/drone/go-scm/pull/181) ([DeepakPatankar](https://github.com/DeepakPatankar)) +**Merged pull requests:** + +- Upgrade the scm version [\#185](https://github.com/drone/go-scm/pull/185) ([DeepakPatankar](https://github.com/DeepakPatankar)) + ## [v1.22.0](https://github.com/drone/go-scm/tree/v1.22.0) (2022-05-10) [Full Changelog](https://github.com/drone/go-scm/compare/v1.21.1...v1.22.0) From 5c53bd59c4bab4c85a10723089c1f56c980600cd Mon Sep 17 00:00:00 2001 From: raghavharness Date: Sat, 11 Jun 2022 14:04:18 +0530 Subject: [PATCH 009/195] [CI-4622]: Added projectFilter for ListHooks API for Azure --- scm/driver/azure/repo.go | 26 +++-- scm/driver/azure/repo_test.go | 37 ++++++ scm/driver/azure/testdata/hooks.json | 121 ++++++++++++++++++++ scm/driver/azure/testdata/hooks.json.golden | 22 ++++ 4 files changed, 195 insertions(+), 11 deletions(-) create mode 100644 scm/driver/azure/testdata/hooks.json create mode 100644 scm/driver/azure/testdata/hooks.json.golden diff --git a/scm/driver/azure/repo.go b/scm/driver/azure/repo.go index 3e729b336..a590bffee 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 48663e64c..f2bd509db 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 000000000..76efd534c --- /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 000000000..78d873eb2 --- /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 From f5cea0ee897ce9ed2a7ea445958636ccae7c8303 Mon Sep 17 00:00:00 2001 From: Bhavya Agrawal Date: Wed, 15 Jun 2022 12:24:37 +0530 Subject: [PATCH 010/195] [PL-25889]: fix list branches Azure API --- scm/driver/azure/git.go | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/scm/driver/azure/git.go b/scm/driver/azure/git.go index 435023ab9..5aa41b07f 100644 --- a/scm/driver/azure/git.go +++ b/scm/driver/azure/git.go @@ -19,8 +19,8 @@ type gitService struct { func (s *gitService) CreateBranch(ctx context.Context, repo string, params *scm.CreateBranch) (*scm.Response, error) { // https://docs.microsoft.com/en-us/rest/api/azure/devops/git/refs/update-refs?view=azure-devops-rest-6.0 if s.client.project == "" { - return nil, ProjectRequiredError() - } + return nil, ProjectRequiredError() + } endpoint := fmt.Sprintf("%s/%s/_apis/git/repositories/%s/refs?api-version=6.0", s.client.owner, s.client.project, repo) in := make(crudBranch, 1) @@ -32,16 +32,16 @@ func (s *gitService) CreateBranch(ctx context.Context, repo string, params *scm. func (s *gitService) FindBranch(ctx context.Context, repo, name string) (*scm.Reference, *scm.Response, error) { if s.client.project == "" { - return nil, nil, ProjectRequiredError() - } + return nil, nil, ProjectRequiredError() + } return nil, nil, scm.ErrNotSupported } func (s *gitService) FindCommit(ctx context.Context, repo, ref string) (*scm.Commit, *scm.Response, error) { // https://docs.microsoft.com/en-us/rest/api/azure/devops/git/commits/get?view=azure-devops-rest-6.0#get-by-id if s.client.project == "" { - return nil, nil, ProjectRequiredError() - } + return nil, nil, ProjectRequiredError() + } endpoint := fmt.Sprintf("%s/%s/_apis/git/repositories/%s/commits/%s?api-version=6.0", s.client.owner, s.client.project, repo, ref) out := new(gitCommit) res, err := s.client.do(ctx, "GET", endpoint, nil, out) @@ -55,9 +55,9 @@ func (s *gitService) FindTag(ctx context.Context, repo, name string) (*scm.Refer func (s *gitService) ListBranches(ctx context.Context, repo string, _ scm.ListOptions) ([]*scm.Reference, *scm.Response, error) { // https://docs.microsoft.com/en-us/rest/api/azure/devops/git/refs/list?view=azure-devops-rest-6.0 if s.client.project == "" { - return nil, nil, ProjectRequiredError() - } - endpoint := fmt.Sprintf("%s/%s/_apis/git/repositories/%s/refs?api-version=6.0", s.client.owner, s.client.project, repo) + return nil, nil, ProjectRequiredError() + } + endpoint := fmt.Sprintf("%s/%s/_apis/git/repositories/%s/refs?includeMyBranches=true&api-version=6.0", s.client.owner, s.client.project, repo) out := new(branchList) res, err := s.client.do(ctx, "GET", endpoint, nil, &out) return convertBranchList(out.Value), res, err @@ -66,8 +66,8 @@ func (s *gitService) ListBranches(ctx context.Context, repo string, _ scm.ListOp func (s *gitService) ListCommits(ctx context.Context, repo string, opts scm.CommitListOptions) ([]*scm.Commit, *scm.Response, error) { // https://docs.microsoft.com/en-us/rest/api/azure/devops/git/commits/get-commits?view=azure-devops-rest-6.0 if s.client.project == "" { - return nil, nil, ProjectRequiredError() - } + return nil, nil, ProjectRequiredError() + } endpoint := fmt.Sprintf("%s/%s/_apis/git/repositories/%s/commits?", s.client.owner, s.client.project, repo) if opts.Ref != "" { endpoint += fmt.Sprintf("searchCriteria.itemVersion.version=%s&", opts.Ref) @@ -93,8 +93,8 @@ func (s *gitService) ListChanges(ctx context.Context, repo, ref string, _ scm.Li func (s *gitService) CompareChanges(ctx context.Context, repo, source, target string, _ scm.ListOptions) ([]*scm.Change, *scm.Response, error) { // https://docs.microsoft.com/en-us/rest/api/azure/devops/git/diffs/get?view=azure-devops-rest-6.0 if s.client.project == "" { - return nil, nil, ProjectRequiredError() - } + return nil, nil, ProjectRequiredError() + } endpoint := fmt.Sprintf("%s/%s/_apis/git/repositories/%s/diffs/commits?", s.client.owner, s.client.project, repo) // add base endpoint += fmt.Sprintf("baseVersion=%s&baseVersionType=commit&", source) From b62b9fc45b290836a777ac17b46ef25b8484387b Mon Sep 17 00:00:00 2001 From: Rutvij Mehta Date: Tue, 14 Jun 2022 11:21:48 -0700 Subject: [PATCH 011/195] Support parsing Gitlab Note Hook event --- ...json => merge_request_comment_create.json} | 0 .../merge_request_comment_create.json.golden | 94 ++++++ .../pull_request_comment_create.json.golden | 0 scm/driver/gitlab/user.go | 1 + scm/driver/gitlab/webhook.go | 271 ++++++++++++------ scm/driver/gitlab/webhook_test.go | 14 +- 6 files changed, 279 insertions(+), 101 deletions(-) rename scm/driver/gitlab/testdata/webhooks/{pull_request_comment_create.json => merge_request_comment_create.json} (100%) create mode 100644 scm/driver/gitlab/testdata/webhooks/merge_request_comment_create.json.golden delete mode 100644 scm/driver/gitlab/testdata/webhooks/pull_request_comment_create.json.golden diff --git a/scm/driver/gitlab/testdata/webhooks/pull_request_comment_create.json b/scm/driver/gitlab/testdata/webhooks/merge_request_comment_create.json similarity index 100% rename from scm/driver/gitlab/testdata/webhooks/pull_request_comment_create.json rename to scm/driver/gitlab/testdata/webhooks/merge_request_comment_create.json diff --git a/scm/driver/gitlab/testdata/webhooks/merge_request_comment_create.json.golden b/scm/driver/gitlab/testdata/webhooks/merge_request_comment_create.json.golden new file mode 100644 index 000000000..3b84d1116 --- /dev/null +++ b/scm/driver/gitlab/testdata/webhooks/merge_request_comment_create.json.golden @@ -0,0 +1,94 @@ +{ + "Action": "created", + "Repo": { + "ID": "4861503", + "Namespace": "gitlab-org", + "Name": "hello-world", + "Perm": null, + "Branch": "master", + "Archived": false, + "Private": false, + "Visibility": 0, + "Clone": "https://gitlab.com/gitlab-org/hello-world.git", + "CloneSSH": "git@gitlab.com:gitlab-org/hello-world.git", + "Link": "https://gitlab.com/gitlab-org/hello-world", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Issue": { + "Number": 1, + "Title": "update readme", + "Body": "update readme", + "Link": "https://gitlab.com/gitlab-org/hello-world", + "Labels": null, + "Closed": false, + "Locked": false, + "Author": { + "Login": "sytses", + "Name": "Sid Sijbrandij", + "Email": "", + "Avatar": "https://secure.gravatar.com/avatar/8c58a0be77ee441bb8f8595b7f1b4e87?s=80\u0026d=identicon", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "PullRequest": { + "Number": 1, + "Title": "update readme", + "Body": "adding build instructions to readme", + "Sha": "c4c79227ed610f1151f05bbc5be33b4f340d39c8", + "Ref": "refs/merge-requests/1/head", + "Source": "feature", + "Target": "master", + "Fork": "", + "Link": "https://gitlab.com/gitlab-org/hello-world", + "Diff": "", + "Closed": false, + "Merged": false, + "Base": { + "Name": "", + "Path": "", + "Sha": "" + }, + "Head": { + "Name": "", + "Path": "", + "Sha": "" + }, + "Author": { + "Login": "sytses", + "Name": "Sid Sijbrandij", + "Email": "", + "Avatar": "https://secure.gravatar.com/avatar/8c58a0be77ee441bb8f8595b7f1b4e87?s=80\u0026d=identicon", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Created": "2017-12-10T17:01:11Z", + "Updated": "2017-12-10T17:05:14Z", + "Labels": null + }, + "Created": "2017-12-10T17:05:14Z", + "Updated": "2017-12-10T17:05:14Z" + }, + "Comment": { + "ID": 50772616, + "Body": "lgtm", + "Author": { + "Login": "sytses", + "Name": "Sid Sijbrandij", + "Email": "", + "Avatar": "https://secure.gravatar.com/avatar/8c58a0be77ee441bb8f8595b7f1b4e87?s=80\u0026d=identicon", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Created": "2017-12-10T17:05:14Z", + "Updated": "2017-12-10T17:05:14Z" + }, + "Sender": { + "Login": "sytses", + "Name": "Sid Sijbrandij", + "Email": "", + "Avatar": "https://secure.gravatar.com/avatar/8c58a0be77ee441bb8f8595b7f1b4e87?s=80\u0026d=identicon", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + } +} \ No newline at end of file diff --git a/scm/driver/gitlab/testdata/webhooks/pull_request_comment_create.json.golden b/scm/driver/gitlab/testdata/webhooks/pull_request_comment_create.json.golden deleted file mode 100644 index e69de29bb..000000000 diff --git a/scm/driver/gitlab/user.go b/scm/driver/gitlab/user.go index fa8c2f9c1..7f182bfca 100644 --- a/scm/driver/gitlab/user.go +++ b/scm/driver/gitlab/user.go @@ -49,6 +49,7 @@ func (s *userService) ListEmail(ctx context.Context, opts scm.ListOptions) ([]*s } type user struct { + ID int `json:"id"` Username string `json:"username"` Name string `json:"name"` Email null.String `json:"email"` diff --git a/scm/driver/gitlab/webhook.go b/scm/driver/gitlab/webhook.go index e3ee5ad73..b50f8d904 100644 --- a/scm/driver/gitlab/webhook.go +++ b/scm/driver/gitlab/webhook.go @@ -11,6 +11,7 @@ import ( "io/ioutil" "net/http" "strconv" + "time" "github.com/drone/go-scm/scm" ) @@ -35,6 +36,8 @@ func (s *webhookService) Parse(req *http.Request, fn scm.SecretFunc) (scm.Webhoo return nil, scm.ErrUnknownEvent case "Merge Request Hook": hook, err = parsePullRequestHook(data) + case "Note Hook": + hook, err = parseIssueCommentHook(data) default: return nil, scm.ErrUnknownEvent } @@ -59,6 +62,19 @@ func (s *webhookService) Parse(req *http.Request, fn scm.SecretFunc) (scm.Webhoo return hook, nil } +func parseIssueCommentHook(data []byte) (scm.Webhook, error) { + src := new(commentHook) + err := json.Unmarshal(data, src) + if err != nil { + return nil, err + } + dst, err := convertCommentHook(src) + if err != nil { + return nil, err + } + return dst, nil +} + func parsePushHook(data []byte) (scm.Webhook, error) { src := new(pushHook) err := json.Unmarshal(data, src) @@ -202,6 +218,77 @@ func converBranchHook(src *pushHook) *scm.BranchHook { } } +func convertCommentHook(src *commentHook) (*scm.IssueCommentHook, error) { + var issue scm.Issue + var comment scm.Comment + + switch src.ObjectAttributes.NoteableType { + case "Commit", "Issue", "Snippet": + return nil, scm.ErrUnknownEvent + case "MergeRequest": + pr := scm.PullRequest{ + Number: src.MergeRequest.Iid, + Title: src.MergeRequest.Title, + Body: src.MergeRequest.Description, + Sha: src.MergeRequest.LastCommit.ID, + Ref: fmt.Sprintf("refs/merge-requests/%d/head", src.MergeRequest.Iid), + Source: src.MergeRequest.SourceBranch, + Target: src.MergeRequest.TargetBranch, + Link: src.Project.WebURL, + Closed: src.MergeRequest.State != "opened", + Merged: src.MergeRequest.State == "merged", + Author: *convertUser(&src.User), + Created: parseTimeString(src.MergeRequest.CreatedAt), + Updated: parseTimeString(src.MergeRequest.UpdatedAt), + } + for _, l := range src.MergeRequest.Labels { + label := scm.Label { + Name: l.Title, + Color: l.Color, + } + pr.Labels = append(pr.Labels, label) + } + issue = scm.Issue{ + Number: src.MergeRequest.Iid, + Title: src.MergeRequest.Title, + Body: src.MergeRequest.Title, + Link: src.Project.WebURL, + Author: *convertUser(&src.User), + PullRequest: pr, + Created: parseTimeString(src.ObjectAttributes.CreatedAt), + Updated: parseTimeString(src.ObjectAttributes.UpdatedAt), + } + comment = scm.Comment{ + ID: src.ObjectAttributes.ID, + Body: src.ObjectAttributes.Note, + Author: *convertUser(&src.User), + Created: parseTimeString(src.ObjectAttributes.CreatedAt), + Updated: parseTimeString(src.ObjectAttributes.UpdatedAt), + } + default: + return nil, scm.ErrUnknownEvent + } + + namespace, _ := scm.Split(src.Project.PathWithNamespace) + dst := scm.IssueCommentHook{ + Action: scm.ActionCreate, + Repo: scm.Repository{ + ID: strconv.Itoa(src.Project.ID), + Namespace: namespace, + Name: src.Repository.Name, + Clone: src.Project.GitHTTPURL, + CloneSSH: src.Project.GitSSHURL, + Link: src.Project.WebURL, + Branch: src.Project.DefaultBranch, + Private: false, // TODO how do we correctly set Private vs Public? + }, + Issue: issue, + Comment: comment, + Sender: *convertUser(&src.User), + } + return &dst, nil +} + func convertTagHook(src *pushHook) *scm.TagHook { action := scm.ActionCreate commit := src.After @@ -296,6 +383,13 @@ func convertPullRequestHook(src *pullRequestHook) *scm.PullRequestHook { } } +func parseTimeString(timeString string) (time.Time) { + layout := "2006-01-02 15:04:05 UTC" + // Returns zero value of time in case of an error 0001-01-01 00:00:00 +0000 UTC + t, _ := time.Parse(layout, timeString) + return t +} + type ( pushHook struct { ObjectKind string `json:"object_kind"` @@ -356,13 +450,10 @@ type ( commentHook struct { ObjectKind string `json:"object_kind"` - User struct { - Name string `json:"name"` - Username string `json:"username"` - AvatarURL string `json:"avatar_url"` - } `json:"user"` - ProjectID int `json:"project_id"` - Project struct { + EventType string `json:"event_type"` + User user `json:"user"` + ProjectID int `json:"project_id"` + Project struct { ID int `json:"id"` Name string `json:"name"` Description string `json:"description"` @@ -380,93 +471,76 @@ type ( SSHURL string `json:"ssh_url"` HTTPURL string `json:"http_url"` } `json:"project"` - ObjectAttributes struct { - ID int `json:"id"` - Note string `json:"note"` - NoteableType string `json:"noteable_type"` - AuthorID int `json:"author_id"` - CreatedAt string `json:"created_at"` - UpdatedAt string `json:"updated_at"` - ProjectID int `json:"project_id"` - Attachment interface{} `json:"attachment"` - LineCode string `json:"line_code"` - CommitID string `json:"commit_id"` - NoteableID int `json:"noteable_id"` - StDiff interface{} `json:"st_diff"` - System bool `json:"system"` - UpdatedByID interface{} `json:"updated_by_id"` - Type string `json:"type"` - Position struct { - BaseSha string `json:"base_sha"` - StartSha string `json:"start_sha"` - HeadSha string `json:"head_sha"` - OldPath string `json:"old_path"` - NewPath string `json:"new_path"` - PositionType string `json:"position_type"` - OldLine interface{} `json:"old_line"` - NewLine int `json:"new_line"` - } `json:"position"` - OriginalPosition struct { - BaseSha string `json:"base_sha"` - StartSha string `json:"start_sha"` - HeadSha string `json:"head_sha"` - OldPath string `json:"old_path"` - NewPath string `json:"new_path"` - PositionType string `json:"position_type"` - OldLine interface{} `json:"old_line"` - NewLine int `json:"new_line"` - } `json:"original_position"` - ResolvedAt interface{} `json:"resolved_at"` - ResolvedByID interface{} `json:"resolved_by_id"` - DiscussionID string `json:"discussion_id"` - ChangePosition struct { - BaseSha interface{} `json:"base_sha"` - StartSha interface{} `json:"start_sha"` - HeadSha interface{} `json:"head_sha"` - OldPath interface{} `json:"old_path"` - NewPath interface{} `json:"new_path"` - PositionType string `json:"position_type"` - OldLine interface{} `json:"old_line"` - NewLine interface{} `json:"new_line"` - } `json:"change_position"` - ResolvedByPush interface{} `json:"resolved_by_push"` - URL string `json:"url"` + ObjectAttributes struct { + ID int `json:"id"` + Note string `json:"note"` + NoteableType string `json:"noteable_type"` + AuthorID int `json:"author_id"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` + ProjectID int `json:"project_id"` + Attachment interface{} `json:"attachment"` + LineCode string `json:"line_code"` + CommitID string `json:"commit_id"` + NoteableID int `json:"noteable_id"` + StDiff interface{} `json:"st_diff"` + System bool `json:"system"` + ResolvedAt interface{} `json:"resolved_at"` + ResolvedByID interface{} `json:"resolved_by_id"` + ResolvedByPush interface{} `json:"resolved_by_push"` + DiscussionID string `json:"discussion_id"` + URL string `json:"url"` + Position interface{} `json:"position"` + OriginalPosition interface{} `json:"original_position"` + ChangePosition interface{} `json:"change_position"` + Type interface{} `json:"type"` + Description string `json:"description"` } `json:"object_attributes"` - Repository struct { + Repository struct { Name string `json:"name"` URL string `json:"url"` Description string `json:"description"` Homepage string `json:"homepage"` } `json:"repository"` - MergeRequest struct { - AssigneeID interface{} `json:"assignee_id"` - AuthorID int `json:"author_id"` - CreatedAt string `json:"created_at"` - DeletedAt interface{} `json:"deleted_at"` - Description string `json:"description"` - HeadPipelineID interface{} `json:"head_pipeline_id"` - ID int `json:"id"` - Iid int `json:"iid"` - LastEditedAt interface{} `json:"last_edited_at"` - LastEditedByID interface{} `json:"last_edited_by_id"` - MergeCommitSha interface{} `json:"merge_commit_sha"` - MergeError interface{} `json:"merge_error"` - MergeParams interface{} `json:"-"` - MergeStatus string `json:"merge_status"` - MergeUserID interface{} `json:"merge_user_id"` - MergeWhenPipelineSucceeds bool `json:"merge_when_pipeline_succeeds"` - MilestoneID interface{} `json:"milestone_id"` - SourceBranch string `json:"source_branch"` - SourceProjectID int `json:"source_project_id"` - State string `json:"state"` - TargetBranch string `json:"target_branch"` - TargetProjectID int `json:"target_project_id"` - TimeEstimate int `json:"time_estimate"` - Title string `json:"title"` - UpdatedAt string `json:"updated_at"` - UpdatedByID interface{} `json:"updated_by_id"` - URL string `json:"url"` - Source struct { + MergeRequest struct { + AssigneeID interface{} `json:"assignee_id"` + AuthorID int `json:"author_id"` + CreatedAt string `json:"created_at"` + DeletedAt interface{} `json:"deleted_at"` + Description string `json:"description"` + HeadPipelineID interface{} `json:"head_pipeline_id"` + ID int `json:"id"` + Iid int `json:"iid"` + LastEditedAt interface{} `json:"last_edited_at"` + LastEditedByID interface{} `json:"last_edited_by_id"` + MergeCommitSha interface{} `json:"merge_commit_sha"` + MergeError interface{} `json:"merge_error"` + MergeParams interface{} `json:"-"` + MergeStatus string `json:"merge_status"` + MergeUserID interface{} `json:"merge_user_id"` + MergeWhenPipelineSucceeds bool `json:"merge_when_pipeline_succeeds"` + MilestoneID interface{} `json:"milestone_id"` + SourceBranch string `json:"source_branch"` + SourceProjectID int `json:"source_project_id"` + StateID int `json:"state_id"` + State string `json:"state"` + TargetBranch string `json:"target_branch"` + TargetProjectID int `json:"target_project_id"` + TimeEstimate int `json:"time_estimate"` + Title string `json:"title"` + UpdatedAt string `json:"updated_at"` + UpdatedByID interface{} `json:"updated_by_id"` + URL string `json:"url"` + WorkInProgress bool `json:"work_in_progress"` + TimeChange int `json:"time_change"` + HumanTimeChange int `json:"human_time_change"` + TotalTimeSpent int `json:"total_time_spent"` + HumanTotalTimeSpent interface{} `json:"human_total_time_spent"` + HumanTimeEstimate interface{} `json:"human_time_estimate"` + Action string `json:"action"` + AssigneeIDs interface{} `json:"assignee_ids"` + BlockingDiscussionResolved bool `json:"blocking_discussions_resolved"` + Source struct { ID int `json:"id"` Name string `json:"name"` Description string `json:"description"` @@ -484,7 +558,7 @@ type ( SSHURL string `json:"ssh_url"` HTTPURL string `json:"http_url"` } `json:"source"` - Target struct { + Target struct { ID int `json:"id"` Name string `json:"name"` Description string `json:"description"` @@ -502,7 +576,7 @@ type ( SSHURL string `json:"ssh_url"` HTTPURL string `json:"http_url"` } `json:"target"` - LastCommit struct { + LastCommit struct { ID string `json:"id"` Message string `json:"message"` Timestamp string `json:"timestamp"` @@ -512,10 +586,19 @@ type ( Email string `json:"email"` } `json:"author"` } `json:"last_commit"` - WorkInProgress bool `json:"work_in_progress"` - TotalTimeSpent int `json:"total_time_spent"` - HumanTotalTimeSpent interface{} `json:"human_total_time_spent"` - HumanTimeEstimate interface{} `json:"human_time_estimate"` + Labels []struct { + ID int `json:"id"` + Title string `json:"title"` + Color string `json:"color"` + ProjectID int `json:"project_id"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` + Template bool `json:"template"` + Description string `json:"description"` + Type string `json:"type"` + GroupID interface{} `json:"group_id"` + } `json:"labels"` + } `json:"merge_request"` } diff --git a/scm/driver/gitlab/webhook_test.go b/scm/driver/gitlab/webhook_test.go index 1f153f20d..1eb6cf527 100644 --- a/scm/driver/gitlab/webhook_test.go +++ b/scm/driver/gitlab/webhook_test.go @@ -109,13 +109,13 @@ func TestWebhooks(t *testing.T) { after: "testdata/webhooks/pull_request_merge.json.golden", obj: new(scm.PullRequestHook), }, - // // pull request comment hooks - // { - // event: "issue_comment", - // before: "testdata/webhooks/pull_request_comment_created.json", - // after: "testdata/webhooks/pull_request_comment_created.json.golden", - // obj: new(scm.PullRequestCommentHook), - // }, + // Note hook for Gitlab Merge Request comment + { + event: "Note Hook", + before: "testdata/webhooks/merge_request_comment_create.json", + after: "testdata/webhooks/merge_request_comment_create.json.golden", + obj: new(scm.IssueCommentHook), + }, } for _, test := range tests { From c9023cd2de44b91acf2b2295a38e98a9be08812c Mon Sep 17 00:00:00 2001 From: Rutvij Mehta Date: Thu, 16 Jun 2022 03:43:35 -0700 Subject: [PATCH 012/195] Update scm version 1.25.0 --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cdb448dfd..642d37d15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## [v1.25.0](https://github.com/drone/go-scm/tree/v1.25.0) (2022-06-16) + +[Full Changelog](https://github.com/drone/go-scm/compare/v1.24.0...v1.25.0) + +**Implemented enhancements:** + +- Support parsing Gitlab Note Hook event [\#194](https://github.com/drone/go-scm/pull/194) ([rutvijmehta-harness](https://github.com/rutvijmehta-harness)) + +**Fixed bugs:** + +- \[PL-25889\]: fix list branches Azure API [\#195](https://github.com/drone/go-scm/pull/195) ([bhavya181](https://github.com/bhavya181)) +- Return project specific hooks only in ListHooks API for Azure. [\#192](https://github.com/drone/go-scm/pull/192) ([raghavharness](https://github.com/raghavharness)) + ## [v1.24.0](https://github.com/drone/go-scm/tree/v1.24.0) (2022-06-07) [Full Changelog](https://github.com/drone/go-scm/compare/v1.23.0...v1.24.0) @@ -17,6 +30,10 @@ - gitee client pagination bug [\#187](https://github.com/drone/go-scm/issues/187) +**Merged pull requests:** + +- release\_prep\_v1.24.0 [\#191](https://github.com/drone/go-scm/pull/191) ([tphoney](https://github.com/tphoney)) + ## [v1.23.0](https://github.com/drone/go-scm/tree/v1.23.0) (2022-05-23) [Full Changelog](https://github.com/drone/go-scm/compare/v1.22.0...v1.23.0) From c7f09d3e2a5c85978b0fbebe222bcb7e85077607 Mon Sep 17 00:00:00 2001 From: raghavharness Date: Sun, 19 Jun 2022 12:29:24 +0530 Subject: [PATCH 013/195] [CI-4623] - Azure webhook parseAPI changes --- .../azure/testdata/webhooks/pr_created.json | 3 +- .../testdata/webhooks/pr_created.json.golden | 18 ++-- .../azure/testdata/webhooks/pr_merged.json | 3 +- .../testdata/webhooks/pr_merged.json.golden | 18 ++-- .../azure/testdata/webhooks/pr_updated.json | 3 +- .../testdata/webhooks/pr_updated.json.golden | 18 ++-- .../azure/testdata/webhooks/push.json.golden | 31 ++++-- scm/driver/azure/webhook.go | 98 ++++++++++++++----- 8 files changed, 129 insertions(+), 63 deletions(-) diff --git a/scm/driver/azure/testdata/webhooks/pr_created.json b/scm/driver/azure/testdata/webhooks/pr_created.json index 746cacec8..9b544c962 100644 --- a/scm/driver/azure/testdata/webhooks/pr_created.json +++ b/scm/driver/azure/testdata/webhooks/pr_created.json @@ -24,7 +24,8 @@ "url": "https://dev.azure.com/fabrikam/DefaultCollection/_apis/projects/6ce954b1-ce1f-45d1-b94d-e6bf2464ba2c", "state": "wellFormed" }, - "defaultBranch": "refs/heads/master", + "sshUrl": "git@ssh.dev.azure.com:v3/fabrikam/DefaultCollection/Fabrikam", + "webUrl": "https://dev.azure.com/fabrikam/DefaultCollection/_git/Fabrikam", "remoteUrl": "https://dev.azure.com/fabrikam/DefaultCollection/_git/Fabrikam" }, "pullRequestId": 1, diff --git a/scm/driver/azure/testdata/webhooks/pr_created.json.golden b/scm/driver/azure/testdata/webhooks/pr_created.json.golden index 3ca595b6c..e081e85fa 100644 --- a/scm/driver/azure/testdata/webhooks/pr_created.json.golden +++ b/scm/driver/azure/testdata/webhooks/pr_created.json.golden @@ -1,17 +1,17 @@ { - "Action": "opened", + "Action": "created", "Repo": { "ID": "4bc14d40-c903-45e2-872e-0462c7748079", "Namespace": "Fabrikam", - "Name": "4bc14d40-c903-45e2-872e-0462c7748079", + "Name": "Fabrikam", "Perm": null, "Branch": "", "Archived": false, "Private": false, "Visibility": 0, - "Clone": "", - "CloneSSH": "", - "Link": "https://dev.azure.com/fabrikam/DefaultCollection/_apis/repos/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079", + "Clone": "https://dev.azure.com/fabrikam/DefaultCollection/_git/Fabrikam", + "CloneSSH": "git@ssh.dev.azure.com:v3/fabrikam/DefaultCollection/Fabrikam", + "Link": "https://dev.azure.com/fabrikam/DefaultCollection/_git/Fabrikam", "Created": "0001-01-01T00:00:00Z", "Updated": "0001-01-01T00:00:00Z" }, @@ -19,10 +19,10 @@ "Number": 1, "Title": "my first pull request", "Body": " - test2\r\n", - "Sha": "a10bb228-6ba6-4362-abd7-49ea21333dbd", + "Sha": "53d54ac915144006c2c9e90d2c7d3880920db49c", "Ref": "refs/heads/mytopic", - "Source": "refs/heads/mytopic", - "Target": "refs/heads/master", + "Source": "mytopic", + "Target": "master", "Fork": "", "Link": "https://dev.azure.com/fabrikam/DefaultCollection/_apis/repos/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/pullRequests/1", "Diff": "", @@ -39,7 +39,7 @@ "Sha": "" }, "Author": { - "Login": "54d125f7-69f7-4191-904f-c5b96b6261c8", + "Login": "Jamal Hartnett", "Name": "Jamal Hartnett", "Email": "fabrikamfiber4@hotmail.com", "Avatar": "https://dev.azure.com/fabrikam/DefaultCollection/_api/_common/identityImage?id=54d125f7-69f7-4191-904f-c5b96b6261c8", diff --git a/scm/driver/azure/testdata/webhooks/pr_merged.json b/scm/driver/azure/testdata/webhooks/pr_merged.json index 2cdd4a359..15537ac3e 100644 --- a/scm/driver/azure/testdata/webhooks/pr_merged.json +++ b/scm/driver/azure/testdata/webhooks/pr_merged.json @@ -24,7 +24,8 @@ "url": "https://dev.azure.com/fabrikam/DefaultCollection/_apis/projects/6ce954b1-ce1f-45d1-b94d-e6bf2464ba2c", "state": "wellFormed" }, - "defaultBranch": "refs/heads/master", + "sshUrl": "git@ssh.dev.azure.com:v3/fabrikam/DefaultCollection/Fabrikam", + "webUrl": "https://dev.azure.com/fabrikam/DefaultCollection/_git/Fabrikam", "remoteUrl": "https://dev.azure.com/fabrikam/DefaultCollection/_git/Fabrikam" }, "pullRequestId": 1, diff --git a/scm/driver/azure/testdata/webhooks/pr_merged.json.golden b/scm/driver/azure/testdata/webhooks/pr_merged.json.golden index 0b9fcf117..844d14542 100644 --- a/scm/driver/azure/testdata/webhooks/pr_merged.json.golden +++ b/scm/driver/azure/testdata/webhooks/pr_merged.json.golden @@ -3,15 +3,15 @@ "Repo": { "ID": "4bc14d40-c903-45e2-872e-0462c7748079", "Namespace": "Fabrikam", - "Name": "4bc14d40-c903-45e2-872e-0462c7748079", + "Name": "Fabrikam", "Perm": null, "Branch": "", "Archived": false, "Private": false, "Visibility": 0, - "Clone": "", - "CloneSSH": "", - "Link": "https://dev.azure.com/fabrikam/DefaultCollection/_apis/repos/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079", + "Clone": "https://dev.azure.com/fabrikam/DefaultCollection/_git/Fabrikam", + "CloneSSH": "git@ssh.dev.azure.com:v3/fabrikam/DefaultCollection/Fabrikam", + "Link": "https://dev.azure.com/fabrikam/DefaultCollection/_git/Fabrikam", "Created": "0001-01-01T00:00:00Z", "Updated": "0001-01-01T00:00:00Z" }, @@ -19,15 +19,15 @@ "Number": 1, "Title": "my first pull request", "Body": " - test2\r\n", - "Sha": "a10bb228-6ba6-4362-abd7-49ea21333dbd", + "Sha": "53d54ac915144006c2c9e90d2c7d3880920db49c", "Ref": "refs/heads/mytopic", - "Source": "refs/heads/mytopic", - "Target": "refs/heads/master", + "Source": "mytopic", + "Target": "master", "Fork": "", "Link": "https://dev.azure.com/fabrikam/DefaultCollection/_apis/repos/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/pullRequests/1", "Diff": "", "Closed": false, - "Merged": false, + "Merged": true, "Base": { "Name": "", "Path": "", @@ -39,7 +39,7 @@ "Sha": "" }, "Author": { - "Login": "54d125f7-69f7-4191-904f-c5b96b6261c8", + "Login": "Jamal Hartnett", "Name": "Jamal Hartnett", "Email": "fabrikamfiber4@hotmail.com", "Avatar": "https://dev.azure.com/fabrikam/DefaultCollection/_api/_common/identityImage?id=54d125f7-69f7-4191-904f-c5b96b6261c8", diff --git a/scm/driver/azure/testdata/webhooks/pr_updated.json b/scm/driver/azure/testdata/webhooks/pr_updated.json index 25115a743..ac0f7f1ac 100644 --- a/scm/driver/azure/testdata/webhooks/pr_updated.json +++ b/scm/driver/azure/testdata/webhooks/pr_updated.json @@ -24,7 +24,8 @@ "url": "https://dev.azure.com/fabrikam/DefaultCollection/_apis/projects/6ce954b1-ce1f-45d1-b94d-e6bf2464ba2c", "state": "wellFormed" }, - "defaultBranch": "refs/heads/master", + "sshUrl": "git@ssh.dev.azure.com:v3/fabrikam/DefaultCollection/Fabrikam", + "webUrl": "https://dev.azure.com/fabrikam/DefaultCollection/_git/Fabrikam", "remoteUrl": "https://dev.azure.com/fabrikam/DefaultCollection/_git/Fabrikam" }, "pullRequestId": 1, diff --git a/scm/driver/azure/testdata/webhooks/pr_updated.json.golden b/scm/driver/azure/testdata/webhooks/pr_updated.json.golden index aed341d44..ae36b5d5b 100644 --- a/scm/driver/azure/testdata/webhooks/pr_updated.json.golden +++ b/scm/driver/azure/testdata/webhooks/pr_updated.json.golden @@ -3,15 +3,15 @@ "Repo": { "ID": "4bc14d40-c903-45e2-872e-0462c7748079", "Namespace": "Fabrikam", - "Name": "4bc14d40-c903-45e2-872e-0462c7748079", + "Name": "Fabrikam", "Perm": null, "Branch": "", "Archived": false, "Private": false, "Visibility": 0, - "Clone": "", - "CloneSSH": "", - "Link": "https://dev.azure.com/fabrikam/DefaultCollection/_apis/repos/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079", + "Clone": "https://dev.azure.com/fabrikam/DefaultCollection/_git/Fabrikam", + "CloneSSH": "git@ssh.dev.azure.com:v3/fabrikam/DefaultCollection/Fabrikam", + "Link": "https://dev.azure.com/fabrikam/DefaultCollection/_git/Fabrikam", "Created": "0001-01-01T00:00:00Z", "Updated": "0001-01-01T00:00:00Z" }, @@ -19,14 +19,14 @@ "Number": 1, "Title": "my first pull request", "Body": " - test2\r\n", - "Sha": "a10bb228-6ba6-4362-abd7-49ea21333dbd", + "Sha": "53d54ac915144006c2c9e90d2c7d3880920db49c", "Ref": "refs/heads/mytopic", - "Source": "refs/heads/mytopic", - "Target": "refs/heads/master", + "Source": "mytopic", + "Target": "master", "Fork": "", "Link": "https://dev.azure.com/fabrikam/DefaultCollection/_apis/repos/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/pullRequests/1", "Diff": "", - "Closed": false, + "Closed": true, "Merged": false, "Base": { "Name": "", @@ -39,7 +39,7 @@ "Sha": "" }, "Author": { - "Login": "54d125f7-69f7-4191-904f-c5b96b6261c8", + "Login": "Jamal Hartnett", "Name": "Jamal Hartnett", "Email": "fabrikamfiber4@hotmail.com", "Avatar": "https://dev.azure.com/fabrikam/DefaultCollection/_api/_common/identityImage?id=54d125f7-69f7-4191-904f-c5b96b6261c8", diff --git a/scm/driver/azure/testdata/webhooks/push.json.golden b/scm/driver/azure/testdata/webhooks/push.json.golden index 76073d237..59fae065b 100644 --- a/scm/driver/azure/testdata/webhooks/push.json.golden +++ b/scm/driver/azure/testdata/webhooks/push.json.golden @@ -4,14 +4,14 @@ "After": "33b55f7cb7e7e245323987634f960cf4a6e6bc74", "Repo": { "ID": "278d5cd2-584d-4b63-824a-2ba458937249", - "Namespace": "", + "Namespace": "Fabrikam-Fiber-Git", "Name": "Fabrikam-Fiber-Git", "Perm": null, - "Branch": "", + "Branch": "master", "Private": false, - "Clone": "https://dev.azure.com/fabrikam-fiber-inc/DefaultCollection/_apis/repos/git/repositories/278d5cd2-584d-4b63-824a-2ba458937249", + "Clone": "https://dev.azure.com/fabrikam-fiber-inc/DefaultCollection/_git/Fabrikam-Fiber-Git", "CloneSSH": "", - "Link": "", + "Link": "https://dev.azure.com/fabrikam-fiber-inc/DefaultCollection/_git/Fabrikam-Fiber-Git", "Created": "0001-01-01T00:00:00Z", "Updated": "0001-01-01T00:00:00Z" }, @@ -37,9 +37,26 @@ } ], "Sender": { - "Login": "", - "Name": "", - "Email": "", + "Login": "00067FFED5C7AF52@Live.com", + "Name": "Jamal Hartnett", + "Email": "Windows Live ID\\fabrikamfiber4@hotmail.com", "Avatar": "" + }, + "Commit": { + "Sha": "33b55f7cb7e7e245323987634f960cf4a6e6bc74", + "Message": "", + "Author": { + "Login": "00067FFED5C7AF52@Live.com", + "Name": "Jamal Hartnett", + "Email": "Windows Live ID\\fabrikamfiber4@hotmail.com", + "Avatar": "" + }, + "Committer": { + "Login": "00067FFED5C7AF52@Live.com", + "Name": "Jamal Hartnett", + "Email": "Windows Live ID\\fabrikamfiber4@hotmail.com", + "Avatar": "" + }, + "Link": "" } } \ No newline at end of file diff --git a/scm/driver/azure/webhook.go b/scm/driver/azure/webhook.go index 94bafe10d..ff73ab99c 100644 --- a/scm/driver/azure/webhook.go +++ b/scm/driver/azure/webhook.go @@ -13,6 +13,7 @@ import ( "time" "github.com/drone/go-scm/scm" + "github.com/drone/go-scm/scm/driver/internal/null" ) type webhookService struct { @@ -52,7 +53,7 @@ func (s *webhookService) Parse(req *http.Request, fn scm.SecretFunc) (scm.Webhoo return nil, err } dst := convertCreatePullRequestHook(src) - dst.Action = scm.ActionOpen + dst.Action = scm.ActionCreate return dst, nil case "git.pullrequest.updated": // https://docs.microsoft.com/en-us/azure/devops/service-hooks/events?view=azure-devops#git.pullrequest.updated @@ -102,13 +103,39 @@ func convertPushHook(src *pushHook) *scm.PushHook { }) } dst := &scm.PushHook{ + Commit: scm.Commit{ + Sha: src.Resource.RefUpdates[0].NewObjectID, + Message: "", + Author: scm.Signature{ + Login: src.Resource.PushedBy.ID, + Name: src.Resource.PushedBy.DisplayName, + Email: src.Resource.PushedBy.UniqueName, + Avatar: src.Resource.PushedBy.ImageURL, + }, + Committer: scm.Signature{ + Login: src.Resource.PushedBy.ID, + Name: src.Resource.PushedBy.DisplayName, + Email: src.Resource.PushedBy.UniqueName, + Avatar: src.Resource.PushedBy.ImageURL, + }, + Link: "", + }, Ref: src.Resource.RefUpdates[0].Name, Before: src.Resource.RefUpdates[0].OldObjectID, After: src.Resource.RefUpdates[0].NewObjectID, + Sender: scm.User{ + Login: src.Resource.PushedBy.ID, + Name: src.Resource.PushedBy.DisplayName, + Email: src.Resource.PushedBy.UniqueName, + Avatar: src.Resource.PushedBy.ImageURL, + }, Repo: scm.Repository{ - ID: src.Resource.Repository.ID, - Name: src.Resource.Repository.Name, - Clone: src.Resource.Repository.URL, + ID: src.Resource.Repository.ID, + Branch: scm.TrimRef(src.Resource.Repository.DefaultBranch), + Name: src.Resource.Repository.Name, + Namespace: src.Resource.Repository.Project.Name, + Clone: src.Resource.Repository.RemoteURL, + Link: src.Resource.Repository.RemoteURL, }, Commits: commits, } @@ -121,13 +148,15 @@ func convertCreatePullRequestHook(src *createPullRequestHook) (returnVal *scm.Pu Number: src.Resource.PullRequestID, Title: src.Resource.Title, Body: src.Resource.Description, - Sha: src.Resource.MergeID, + Sha: src.Resource.LastMergeSourceCommit.CommitID, Ref: src.Resource.SourceRefName, - Source: src.Resource.SourceRefName, - Target: src.Resource.TargetRefName, + Source: scm.TrimRef(src.Resource.SourceRefName), + Target: scm.TrimRef(src.Resource.TargetRefName), Link: src.Resource.URL, + Closed: false, + Merged: false, Author: scm.User{ - Login: src.Resource.CreatedBy.ID, + Login: src.Resource.CreatedBy.DisplayName, Name: src.Resource.CreatedBy.DisplayName, Email: src.Resource.CreatedBy.UniqueName, Avatar: src.Resource.CreatedBy.ImageURL, @@ -136,9 +165,11 @@ func convertCreatePullRequestHook(src *createPullRequestHook) (returnVal *scm.Pu }, Repo: scm.Repository{ ID: src.Resource.Repository.ID, - Name: src.Resource.Repository.ID, - Namespace: src.Resource.Repository.Name, - Link: src.Resource.Repository.URL, + Name: src.Resource.Repository.Name, + Namespace: src.Resource.Repository.Project.Name, + Link: src.Resource.Repository.WebURL, + Clone: src.Resource.Repository.WebURL, + CloneSSH: src.Resource.Repository.SSHURL, }, Sender: scm.User{ Login: src.Resource.CreatedBy.ID, @@ -156,13 +187,15 @@ func convertUpdatePullRequestHook(src *updatePullRequestHook) (returnVal *scm.Pu Number: src.Resource.PullRequestID, Title: src.Resource.Title, Body: src.Resource.Description, - Sha: src.Resource.MergeID, + Sha: src.Resource.LastMergeSourceCommit.CommitID, Ref: src.Resource.SourceRefName, - Source: src.Resource.SourceRefName, - Target: src.Resource.TargetRefName, + Source: scm.TrimRef(src.Resource.SourceRefName), + Target: scm.TrimRef(src.Resource.TargetRefName), Link: src.Resource.URL, + Closed: src.Resource.ClosedDate.Valid, + Merged: false, Author: scm.User{ - Login: src.Resource.CreatedBy.ID, + Login: src.Resource.CreatedBy.DisplayName, Name: src.Resource.CreatedBy.DisplayName, Email: src.Resource.CreatedBy.UniqueName, Avatar: src.Resource.CreatedBy.ImageURL, @@ -171,9 +204,11 @@ func convertUpdatePullRequestHook(src *updatePullRequestHook) (returnVal *scm.Pu }, Repo: scm.Repository{ ID: src.Resource.Repository.ID, - Name: src.Resource.Repository.ID, - Namespace: src.Resource.Repository.Name, - Link: src.Resource.Repository.URL, + Name: src.Resource.Repository.Name, + Namespace: src.Resource.Repository.Project.Name, + Link: src.Resource.Repository.WebURL, + Clone: src.Resource.Repository.WebURL, + CloneSSH: src.Resource.Repository.SSHURL, }, Sender: scm.User{ Login: src.Resource.CreatedBy.ID, @@ -191,13 +226,15 @@ func convertMergePullRequestHook(src *mergePullRequestHook) (returnVal *scm.Pull Number: src.Resource.PullRequestID, Title: src.Resource.Title, Body: src.Resource.Description, - Sha: src.Resource.MergeID, + Sha: src.Resource.LastMergeSourceCommit.CommitID, Ref: src.Resource.SourceRefName, - Source: src.Resource.SourceRefName, - Target: src.Resource.TargetRefName, + Source: scm.TrimRef(src.Resource.SourceRefName), + Target: scm.TrimRef(src.Resource.TargetRefName), Link: src.Resource.URL, + Closed: false, + Merged: true, Author: scm.User{ - Login: src.Resource.CreatedBy.ID, + Login: src.Resource.CreatedBy.DisplayName, Name: src.Resource.CreatedBy.DisplayName, Email: src.Resource.CreatedBy.UniqueName, Avatar: src.Resource.CreatedBy.ImageURL, @@ -206,9 +243,11 @@ func convertMergePullRequestHook(src *mergePullRequestHook) (returnVal *scm.Pull }, Repo: scm.Repository{ ID: src.Resource.Repository.ID, - Name: src.Resource.Repository.ID, - Namespace: src.Resource.Repository.Name, - Link: src.Resource.Repository.URL, + Name: src.Resource.Repository.Name, + Namespace: src.Resource.Repository.Project.Name, + Link: src.Resource.Repository.WebURL, + Clone: src.Resource.Repository.WebURL, + CloneSSH: src.Resource.Repository.SSHURL, }, Sender: scm.User{ Login: src.Resource.CreatedBy.ID, @@ -257,6 +296,7 @@ type pushHook struct { DisplayName string `json:"displayName"` ID string `json:"id"` UniqueName string `json:"uniqueName"` + ImageURL string `json:"imageUrl"` } `json:"pushedBy"` RefUpdates []struct { Name string `json:"name"` @@ -313,6 +353,8 @@ type createPullRequestHook struct { ID string `json:"id"` Name string `json:"name"` URL string `json:"url"` + WebURL string `json:"webUrl"` + SSHURL string `json:"sshUrl"` Project struct { ID string `json:"id"` Name string `json:"name"` @@ -393,7 +435,7 @@ type updatePullRequestHook struct { } `json:"message"` PublisherID string `json:"publisherId"` Resource struct { - ClosedDate string `json:"closedDate"` + ClosedDate null.String `json:"closedDate"` Commits []struct { CommitID string `json:"commitId"` URL string `json:"url"` @@ -434,6 +476,8 @@ type updatePullRequestHook struct { } `json:"project"` RemoteURL string `json:"remoteUrl"` URL string `json:"url"` + WebURL string `json:"webUrl"` + SSHURL string `json:"sshUrl"` } `json:"repository"` Reviewers []struct { DisplayName string `json:"displayName"` @@ -519,6 +563,8 @@ type mergePullRequestHook struct { } `json:"project"` RemoteURL string `json:"remoteUrl"` URL string `json:"url"` + WebURL string `json:"webUrl"` + SSHURL string `json:"sshUrl"` } `json:"repository"` Reviewers []struct { DisplayName string `json:"displayName"` From cc265c122bc0edfd118dab4ef6a6b8e0bba5a736 Mon Sep 17 00:00:00 2001 From: Hemanth Mantri Date: Mon, 20 Jun 2022 11:39:23 -0700 Subject: [PATCH 014/195] Fixed formatting in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7ada651d4..a95de0461 100644 --- a/README.md +++ b/README.md @@ -163,7 +163,7 @@ comment, _, err := client.Issues.CreateComment(ctx, "octocat/Hello-World", 1, in Here are some useful links to providers API documentation: -- [Azure DevOps](https://docs.microsoft.com/en-us/rest/api/azure/devops/git/?view=azure-devops-rest-6.0)) +- [Azure DevOps](https://docs.microsoft.com/en-us/rest/api/azure/devops/git/?view=azure-devops-rest-6.0) - [Bitbucket cloud API](https://developer.atlassian.com/cloud/bitbucket/rest/intro/) - [Bitbucket server/Stash API](https://docs.atlassian.com/bitbucket-server/rest/5.16.0/bitbucket-rest.html) - [Gitea API](https://gitea.com/api/swagger/#/) From 71ecc3b1545f257f51207ad6c8d7f373bbf05636 Mon Sep 17 00:00:00 2001 From: Raghav Date: Tue, 28 Jun 2022 16:12:00 +0530 Subject: [PATCH 015/195] added issue comment hook support for Azure (#200) * added issue comment hook support for Azure * added supported actions --- scm/const.go | 4 + .../testdata/webhooks/issue_comment.json | 132 ++++++++++++ .../webhooks/issue_comment.json.golden | 88 ++++++++ .../webhooks/issue_comment_delete.json | 133 ++++++++++++ .../webhooks/issue_comment_delete.json.golden | 88 ++++++++ .../testdata/webhooks/issue_comment_edit.json | 132 ++++++++++++ .../webhooks/issue_comment_edit.json.golden | 88 ++++++++ scm/driver/azure/webhook.go | 192 ++++++++++++++++++ scm/driver/azure/webhook_test.go | 18 ++ 9 files changed, 875 insertions(+) create mode 100644 scm/driver/azure/testdata/webhooks/issue_comment.json create mode 100644 scm/driver/azure/testdata/webhooks/issue_comment.json.golden create mode 100644 scm/driver/azure/testdata/webhooks/issue_comment_delete.json create mode 100644 scm/driver/azure/testdata/webhooks/issue_comment_delete.json.golden create mode 100644 scm/driver/azure/testdata/webhooks/issue_comment_edit.json create mode 100644 scm/driver/azure/testdata/webhooks/issue_comment_edit.json.golden diff --git a/scm/const.go b/scm/const.go index 576290e70..690202cb5 100644 --- a/scm/const.go +++ b/scm/const.go @@ -67,6 +67,8 @@ func (a Action) String() (s string) { return "synchronized" case ActionMerge: return "merged" + case ActionEdit: + return "edited" default: return } @@ -104,6 +106,8 @@ func (a *Action) UnmarshalJSON(data []byte) error { *a = ActionSync case "merged": *a = ActionMerge + case "edited": + *a = ActionEdit } return nil } diff --git a/scm/driver/azure/testdata/webhooks/issue_comment.json b/scm/driver/azure/testdata/webhooks/issue_comment.json new file mode 100644 index 000000000..33cd10cad --- /dev/null +++ b/scm/driver/azure/testdata/webhooks/issue_comment.json @@ -0,0 +1,132 @@ +{ + "subscriptionId": "00000000-0000-0000-0000-000000000000", + "notificationId": 2, + "id": "af07be1b-f3ad-44c8-a7f1-c4835f2df06b", + "eventType": "ms.vss-code.git-pullrequest-comment-event", + "publisherId": "tfs", + "message": { + "text": "Jamal Hartnett has edited a pull request comment", + "html": "Jamal Hartnett has edited a pull request comment", + "markdown": "Jamal Hartnett has [edited](https://fabrikam.visualstudio.com/DefaultCollection/_git/Fabrikam/pullrequest/1?discussionId=5) a pull request comment" + }, + "detailedMessage": { + "text": "Jamal Hartnett has edited a pull request comment\r\nThis is my comment.\r\n", + "html": "Jamal Hartnett has edited a pull request comment

This is my comment.

", + "markdown": "Jamal Hartnett has [edited](https://fabrikam.visualstudio.com/DefaultCollection/_git/Fabrikam/pullrequest/1?discussionId=5) a pull request comment\r\nThis is my comment.\r\n" + }, + "resource": { + "comment": { + "id": 2, + "parentCommentId": 1, + "author": { + "displayName": "Jamal Hartnett", + "url": "https://fabrikam.vssps.visualstudio.com/_apis/Identities/54d125f7-69f7-4191-904f-c5b96b6261c8", + "id": "54d125f7-69f7-4191-904f-c5b96b6261c8", + "uniqueName": "fabrikamfiber4@hotmail.com", + "imageUrl": "https://fabrikam.visualstudio.com/DefaultCollection/_api/_common/identityImage?id=54d125f7-69f7-4191-904f-c5b96b6261c8" + }, + "content": "This is my comment.", + "publishedDate": "2014-06-17T16:55:46.589889Z", + "lastUpdatedDate": "2014-06-17T16:55:46.589889Z", + "lastContentUpdatedDate": "2014-06-17T16:58:33.123889Z", + "commentType": "text", + "_links": { + "self": { + "href": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/pullRequests/1/threads/5/comments/2" + }, + "repository": { + "href": "http://joscol2/DefaultCollection/ebed510c-62eb-474b-965f-fd151ebb82e4/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079" + }, + "threads": { + "href": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/pullRequests/1/threads/5" + } + } + }, + "pullRequest": { + "repository": { + "id": "4bc14d40-c903-45e2-872e-0462c7748079", + "name": "Fabrikam", + "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079", + "project": { + "id": "6ce954b1-ce1f-45d1-b94d-e6bf2464ba2c", + "name": "Fabrikam", + "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/projects/6ce954b1-ce1f-45d1-b94d-e6bf2464ba2c", + "state": "wellFormed", + "visibility": "unchanged", + "lastUpdateTime": "0001-01-01T00:00:00" + }, + "sshUrl": "git@ssh.dev.azure.com:v3/fabrikam/DefaultCollection/Fabrikam", + "webUrl": "https://dev.azure.com/fabrikam/DefaultCollection/_git/Fabrikam", + "remoteUrl": "https://fabrikam.visualstudio.com/DefaultCollection/_git/Fabrikam" + }, + "pullRequestId": 1, + "status": "active", + "createdBy": { + "displayName": "Jamal Hartnett", + "url": "https://fabrikam.vssps.visualstudio.com/_apis/Identities/54d125f7-69f7-4191-904f-c5b96b6261c8", + "id": "54d125f7-69f7-4191-904f-c5b96b6261c8", + "uniqueName": "fabrikamfiber4@hotmail.com", + "imageUrl": "https://fabrikam.visualstudio.com/DefaultCollection/_api/_common/identityImage?id=54d125f7-69f7-4191-904f-c5b96b6261c8" + }, + "creationDate": "2014-06-17T16:55:46.589889Z", + "title": "my first pull request", + "description": " - test2\r\n", + "sourceRefName": "refs/heads/mytopic", + "targetRefName": "refs/heads/master", + "mergeStatus": "succeeded", + "mergeId": "a10bb228-6ba6-4362-abd7-49ea21333dbd", + "lastMergeSourceCommit": { + "commitId": "53d54ac915144006c2c9e90d2c7d3880920db49c", + "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/commits/53d54ac915144006c2c9e90d2c7d3880920db49c" + }, + "lastMergeTargetCommit": { + "commitId": "a511f535b1ea495ee0c903badb68fbc83772c882", + "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/commits/a511f535b1ea495ee0c903badb68fbc83772c882" + }, + "lastMergeCommit": { + "commitId": "eef717f69257a6333f221566c1c987dc94cc0d72", + "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/commits/eef717f69257a6333f221566c1c987dc94cc0d72" + }, + "reviewers": [ + { + "reviewerUrl": null, + "vote": 0, + "displayName": "[Mobile]\\Mobile Team", + "url": "https://fabrikam.vssps.visualstudio.com/_apis/Identities/2ea2d095-48f9-4cd6-9966-62f6f574096c", + "id": "2ea2d095-48f9-4cd6-9966-62f6f574096c", + "uniqueName": "vstfs:///Classification/TeamProject/f0811a3b-8c8a-4e43-a3bf-9a049b4835bd\\Mobile Team", + "imageUrl": "https://fabrikam.visualstudio.com/DefaultCollection/_api/_common/identityImage?id=2ea2d095-48f9-4cd6-9966-62f6f574096c", + "isContainer": true + } + ], + "commits": [ + { + "commitId": "53d54ac915144006c2c9e90d2c7d3880920db49c", + "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/commits/53d54ac915144006c2c9e90d2c7d3880920db49c" + } + ], + "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/pullRequests/1", + "_links": { + "web": { + "href": "https://fabrikam.visualstudio.com/DefaultCollection/_git/Fabrikam/pullrequest/1#view=discussion" + }, + "statuses": { + "href": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/pullRequests/1/statuses" + } + } + } + }, + "resourceVersion": "2.0", + "resourceContainers": { + "collection": { + "id": "c12d0eb8-e382-443b-9f9c-c52cba5014c2" + }, + "account": { + "id": "f844ec47-a9db-4511-8281-8b63f4eaf94e" + }, + "project": { + "id": "be9b3917-87e6-42a4-a549-2bc06a7a878f" + } + }, + "createdDate": "2022-06-21T13:03:20.480894Z" + } \ No newline at end of file diff --git a/scm/driver/azure/testdata/webhooks/issue_comment.json.golden b/scm/driver/azure/testdata/webhooks/issue_comment.json.golden new file mode 100644 index 000000000..70b4da243 --- /dev/null +++ b/scm/driver/azure/testdata/webhooks/issue_comment.json.golden @@ -0,0 +1,88 @@ +{ + "Action": "created", + "Repo": { + "ID": "4bc14d40-c903-45e2-872e-0462c7748079", + "Namespace": "Fabrikam", + "Name": "Fabrikam", + "Perm": null, + "Branch": "mytopic", + "Archived": false, + "Private": false, + "Visibility": 0, + "Clone": "https://dev.azure.com/fabrikam/DefaultCollection/_git/Fabrikam", + "CloneSSH": "git@ssh.dev.azure.com:v3/fabrikam/DefaultCollection/Fabrikam", + "Link": "https://dev.azure.com/fabrikam/DefaultCollection/_git/Fabrikam", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Issue": { + "Number": 1, + "Title": "my first pull request", + "Body": " - test2\r\n", + "Link": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/pullRequests/1", + "Author": { + "Login": "Jamal Hartnett", + "Name": "Jamal Hartnett", + "Email": "fabrikamfiber4@hotmail.com", + "Avatar": "https://fabrikam.visualstudio.com/DefaultCollection/_api/_common/identityImage?id=54d125f7-69f7-4191-904f-c5b96b6261c8", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "PullRequest": { + "Number": 1, + "Title": "my first pull request", + "Body": " - test2\r\n", + "Sha": "53d54ac915144006c2c9e90d2c7d3880920db49c", + "Ref": "refs/heads/mytopic", + "Source": "mytopic", + "Target": "master", + "Fork": "", + "Link": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/pullRequests/1", + "Diff": "", + "Closed": false, + "Merged": false, + "Base": { + "Name": "", + "Path": "", + "Sha": "" + }, + "Head": { + "Name": "", + "Path": "", + "Sha": "" + }, + "Author": { + "Login": "Jamal Hartnett", + "Name": "Jamal Hartnett", + "Email": "fabrikamfiber4@hotmail.com", + "Avatar": "https://fabrikam.visualstudio.com/DefaultCollection/_api/_common/identityImage?id=54d125f7-69f7-4191-904f-c5b96b6261c8", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Created": "2014-06-17T16:55:46.589889Z", + "Updated": "0001-01-01T00:00:00Z", + "Labels": null + }, + "Created": "2014-06-17T16:55:46.589889Z" + }, + "Comment": { + "ID": 2, + "Body": "This is my comment.", + "Author": { + "Login": "54d125f7-69f7-4191-904f-c5b96b6261c8", + "Name": "Jamal Hartnett", + "Email": "fabrikamfiber4@hotmail.com", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Created": "2014-06-17T16:55:46.589889Z", + "Updated": "2014-06-17T16:55:46.589889Z" + }, + "Sender": { + "Login": "54d125f7-69f7-4191-904f-c5b96b6261c8", + "Name": "Jamal Hartnett", + "Email": "fabrikamfiber4@hotmail.com", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + } +} \ No newline at end of file diff --git a/scm/driver/azure/testdata/webhooks/issue_comment_delete.json b/scm/driver/azure/testdata/webhooks/issue_comment_delete.json new file mode 100644 index 000000000..5b154f7b3 --- /dev/null +++ b/scm/driver/azure/testdata/webhooks/issue_comment_delete.json @@ -0,0 +1,133 @@ +{ + "subscriptionId": "00000000-0000-0000-0000-000000000000", + "notificationId": 2, + "id": "af07be1b-f3ad-44c8-a7f1-c4835f2df06b", + "eventType": "ms.vss-code.git-pullrequest-comment-event", + "publisherId": "tfs", + "message": { + "text": "Jamal Hartnett has edited a pull request comment", + "html": "Jamal Hartnett has edited a pull request comment", + "markdown": "Jamal Hartnett has [edited](https://fabrikam.visualstudio.com/DefaultCollection/_git/Fabrikam/pullrequest/1?discussionId=5) a pull request comment" + }, + "detailedMessage": { + "text": "Jamal Hartnett has edited a pull request comment\r\nThis is my comment.\r\n", + "html": "Jamal Hartnett has edited a pull request comment

This is my comment.

", + "markdown": "Jamal Hartnett has [edited](https://fabrikam.visualstudio.com/DefaultCollection/_git/Fabrikam/pullrequest/1?discussionId=5) a pull request comment\r\nThis is my comment.\r\n" + }, + "resource": { + "comment": { + "id": 2, + "parentCommentId": 1, + "author": { + "displayName": "Jamal Hartnett", + "url": "https://fabrikam.vssps.visualstudio.com/_apis/Identities/54d125f7-69f7-4191-904f-c5b96b6261c8", + "id": "54d125f7-69f7-4191-904f-c5b96b6261c8", + "uniqueName": "fabrikamfiber4@hotmail.com", + "imageUrl": "https://fabrikam.visualstudio.com/DefaultCollection/_api/_common/identityImage?id=54d125f7-69f7-4191-904f-c5b96b6261c8" + }, + "content": "This is my comment.", + "publishedDate": "2014-06-17T16:55:46.589889Z", + "lastUpdatedDate": "2014-06-17T16:58:33.123889Z", + "lastContentUpdatedDate": "2014-06-17T16:58:33.123889Z", + "commentType": "text", + "isDeleted": true, + "_links": { + "self": { + "href": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/pullRequests/1/threads/5/comments/2" + }, + "repository": { + "href": "http://joscol2/DefaultCollection/ebed510c-62eb-474b-965f-fd151ebb82e4/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079" + }, + "threads": { + "href": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/pullRequests/1/threads/5" + } + } + }, + "pullRequest": { + "repository": { + "id": "4bc14d40-c903-45e2-872e-0462c7748079", + "name": "Fabrikam", + "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079", + "project": { + "id": "6ce954b1-ce1f-45d1-b94d-e6bf2464ba2c", + "name": "Fabrikam", + "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/projects/6ce954b1-ce1f-45d1-b94d-e6bf2464ba2c", + "state": "wellFormed", + "visibility": "unchanged", + "lastUpdateTime": "0001-01-01T00:00:00" + }, + "sshUrl": "git@ssh.dev.azure.com:v3/fabrikam/DefaultCollection/Fabrikam", + "webUrl": "https://dev.azure.com/fabrikam/DefaultCollection/_git/Fabrikam", + "remoteUrl": "https://fabrikam.visualstudio.com/DefaultCollection/_git/Fabrikam" + }, + "pullRequestId": 1, + "status": "active", + "createdBy": { + "displayName": "Jamal Hartnett", + "url": "https://fabrikam.vssps.visualstudio.com/_apis/Identities/54d125f7-69f7-4191-904f-c5b96b6261c8", + "id": "54d125f7-69f7-4191-904f-c5b96b6261c8", + "uniqueName": "fabrikamfiber4@hotmail.com", + "imageUrl": "https://fabrikam.visualstudio.com/DefaultCollection/_api/_common/identityImage?id=54d125f7-69f7-4191-904f-c5b96b6261c8" + }, + "creationDate": "2014-06-17T16:55:46.589889Z", + "title": "my first pull request", + "description": " - test2\r\n", + "sourceRefName": "refs/heads/mytopic", + "targetRefName": "refs/heads/master", + "mergeStatus": "succeeded", + "mergeId": "a10bb228-6ba6-4362-abd7-49ea21333dbd", + "lastMergeSourceCommit": { + "commitId": "53d54ac915144006c2c9e90d2c7d3880920db49c", + "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/commits/53d54ac915144006c2c9e90d2c7d3880920db49c" + }, + "lastMergeTargetCommit": { + "commitId": "a511f535b1ea495ee0c903badb68fbc83772c882", + "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/commits/a511f535b1ea495ee0c903badb68fbc83772c882" + }, + "lastMergeCommit": { + "commitId": "eef717f69257a6333f221566c1c987dc94cc0d72", + "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/commits/eef717f69257a6333f221566c1c987dc94cc0d72" + }, + "reviewers": [ + { + "reviewerUrl": null, + "vote": 0, + "displayName": "[Mobile]\\Mobile Team", + "url": "https://fabrikam.vssps.visualstudio.com/_apis/Identities/2ea2d095-48f9-4cd6-9966-62f6f574096c", + "id": "2ea2d095-48f9-4cd6-9966-62f6f574096c", + "uniqueName": "vstfs:///Classification/TeamProject/f0811a3b-8c8a-4e43-a3bf-9a049b4835bd\\Mobile Team", + "imageUrl": "https://fabrikam.visualstudio.com/DefaultCollection/_api/_common/identityImage?id=2ea2d095-48f9-4cd6-9966-62f6f574096c", + "isContainer": true + } + ], + "commits": [ + { + "commitId": "53d54ac915144006c2c9e90d2c7d3880920db49c", + "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/commits/53d54ac915144006c2c9e90d2c7d3880920db49c" + } + ], + "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/pullRequests/1", + "_links": { + "web": { + "href": "https://fabrikam.visualstudio.com/DefaultCollection/_git/Fabrikam/pullrequest/1#view=discussion" + }, + "statuses": { + "href": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/pullRequests/1/statuses" + } + } + } + }, + "resourceVersion": "2.0", + "resourceContainers": { + "collection": { + "id": "c12d0eb8-e382-443b-9f9c-c52cba5014c2" + }, + "account": { + "id": "f844ec47-a9db-4511-8281-8b63f4eaf94e" + }, + "project": { + "id": "be9b3917-87e6-42a4-a549-2bc06a7a878f" + } + }, + "createdDate": "2022-06-21T13:03:20.480894Z" + } \ No newline at end of file diff --git a/scm/driver/azure/testdata/webhooks/issue_comment_delete.json.golden b/scm/driver/azure/testdata/webhooks/issue_comment_delete.json.golden new file mode 100644 index 000000000..cd1e33741 --- /dev/null +++ b/scm/driver/azure/testdata/webhooks/issue_comment_delete.json.golden @@ -0,0 +1,88 @@ +{ + "Action": "deleted", + "Repo": { + "ID": "4bc14d40-c903-45e2-872e-0462c7748079", + "Namespace": "Fabrikam", + "Name": "Fabrikam", + "Perm": null, + "Branch": "mytopic", + "Archived": false, + "Private": false, + "Visibility": 0, + "Clone": "https://dev.azure.com/fabrikam/DefaultCollection/_git/Fabrikam", + "CloneSSH": "git@ssh.dev.azure.com:v3/fabrikam/DefaultCollection/Fabrikam", + "Link": "https://dev.azure.com/fabrikam/DefaultCollection/_git/Fabrikam", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Issue": { + "Number": 1, + "Title": "my first pull request", + "Body": " - test2\r\n", + "Link": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/pullRequests/1", + "Author": { + "Login": "Jamal Hartnett", + "Name": "Jamal Hartnett", + "Email": "fabrikamfiber4@hotmail.com", + "Avatar": "https://fabrikam.visualstudio.com/DefaultCollection/_api/_common/identityImage?id=54d125f7-69f7-4191-904f-c5b96b6261c8", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "PullRequest": { + "Number": 1, + "Title": "my first pull request", + "Body": " - test2\r\n", + "Sha": "53d54ac915144006c2c9e90d2c7d3880920db49c", + "Ref": "refs/heads/mytopic", + "Source": "mytopic", + "Target": "master", + "Fork": "", + "Link": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/pullRequests/1", + "Diff": "", + "Closed": false, + "Merged": false, + "Base": { + "Name": "", + "Path": "", + "Sha": "" + }, + "Head": { + "Name": "", + "Path": "", + "Sha": "" + }, + "Author": { + "Login": "Jamal Hartnett", + "Name": "Jamal Hartnett", + "Email": "fabrikamfiber4@hotmail.com", + "Avatar": "https://fabrikam.visualstudio.com/DefaultCollection/_api/_common/identityImage?id=54d125f7-69f7-4191-904f-c5b96b6261c8", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Created": "2014-06-17T16:55:46.589889Z", + "Updated": "0001-01-01T00:00:00Z", + "Labels": null + }, + "Created": "2014-06-17T16:55:46.589889Z" + }, + "Comment": { + "ID": 2, + "Body": "This is my comment.", + "Author": { + "Login": "54d125f7-69f7-4191-904f-c5b96b6261c8", + "Name": "Jamal Hartnett", + "Email": "fabrikamfiber4@hotmail.com", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Created": "2014-06-17T16:55:46.589889Z", + "Updated": "2014-06-17T16:58:33.123889Z" + }, + "Sender": { + "Login": "54d125f7-69f7-4191-904f-c5b96b6261c8", + "Name": "Jamal Hartnett", + "Email": "fabrikamfiber4@hotmail.com", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + } +} \ No newline at end of file diff --git a/scm/driver/azure/testdata/webhooks/issue_comment_edit.json b/scm/driver/azure/testdata/webhooks/issue_comment_edit.json new file mode 100644 index 000000000..971daae0d --- /dev/null +++ b/scm/driver/azure/testdata/webhooks/issue_comment_edit.json @@ -0,0 +1,132 @@ +{ + "subscriptionId": "00000000-0000-0000-0000-000000000000", + "notificationId": 2, + "id": "af07be1b-f3ad-44c8-a7f1-c4835f2df06b", + "eventType": "ms.vss-code.git-pullrequest-comment-event", + "publisherId": "tfs", + "message": { + "text": "Jamal Hartnett has edited a pull request comment", + "html": "Jamal Hartnett has edited a pull request comment", + "markdown": "Jamal Hartnett has [edited](https://fabrikam.visualstudio.com/DefaultCollection/_git/Fabrikam/pullrequest/1?discussionId=5) a pull request comment" + }, + "detailedMessage": { + "text": "Jamal Hartnett has edited a pull request comment\r\nThis is my comment.\r\n", + "html": "Jamal Hartnett has edited a pull request comment

This is my comment.

", + "markdown": "Jamal Hartnett has [edited](https://fabrikam.visualstudio.com/DefaultCollection/_git/Fabrikam/pullrequest/1?discussionId=5) a pull request comment\r\nThis is my comment.\r\n" + }, + "resource": { + "comment": { + "id": 2, + "parentCommentId": 1, + "author": { + "displayName": "Jamal Hartnett", + "url": "https://fabrikam.vssps.visualstudio.com/_apis/Identities/54d125f7-69f7-4191-904f-c5b96b6261c8", + "id": "54d125f7-69f7-4191-904f-c5b96b6261c8", + "uniqueName": "fabrikamfiber4@hotmail.com", + "imageUrl": "https://fabrikam.visualstudio.com/DefaultCollection/_api/_common/identityImage?id=54d125f7-69f7-4191-904f-c5b96b6261c8" + }, + "content": "This is my comment.", + "publishedDate": "2014-06-17T16:55:46.589889Z", + "lastUpdatedDate": "2014-06-17T16:58:33.123889Z", + "lastContentUpdatedDate": "2014-06-17T16:58:33.123889Z", + "commentType": "text", + "_links": { + "self": { + "href": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/pullRequests/1/threads/5/comments/2" + }, + "repository": { + "href": "http://joscol2/DefaultCollection/ebed510c-62eb-474b-965f-fd151ebb82e4/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079" + }, + "threads": { + "href": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/pullRequests/1/threads/5" + } + } + }, + "pullRequest": { + "repository": { + "id": "4bc14d40-c903-45e2-872e-0462c7748079", + "name": "Fabrikam", + "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079", + "project": { + "id": "6ce954b1-ce1f-45d1-b94d-e6bf2464ba2c", + "name": "Fabrikam", + "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/projects/6ce954b1-ce1f-45d1-b94d-e6bf2464ba2c", + "state": "wellFormed", + "visibility": "unchanged", + "lastUpdateTime": "0001-01-01T00:00:00" + }, + "sshUrl": "git@ssh.dev.azure.com:v3/fabrikam/DefaultCollection/Fabrikam", + "webUrl": "https://dev.azure.com/fabrikam/DefaultCollection/_git/Fabrikam", + "remoteUrl": "https://fabrikam.visualstudio.com/DefaultCollection/_git/Fabrikam" + }, + "pullRequestId": 1, + "status": "active", + "createdBy": { + "displayName": "Jamal Hartnett", + "url": "https://fabrikam.vssps.visualstudio.com/_apis/Identities/54d125f7-69f7-4191-904f-c5b96b6261c8", + "id": "54d125f7-69f7-4191-904f-c5b96b6261c8", + "uniqueName": "fabrikamfiber4@hotmail.com", + "imageUrl": "https://fabrikam.visualstudio.com/DefaultCollection/_api/_common/identityImage?id=54d125f7-69f7-4191-904f-c5b96b6261c8" + }, + "creationDate": "2014-06-17T16:55:46.589889Z", + "title": "my first pull request", + "description": " - test2\r\n", + "sourceRefName": "refs/heads/mytopic", + "targetRefName": "refs/heads/master", + "mergeStatus": "succeeded", + "mergeId": "a10bb228-6ba6-4362-abd7-49ea21333dbd", + "lastMergeSourceCommit": { + "commitId": "53d54ac915144006c2c9e90d2c7d3880920db49c", + "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/commits/53d54ac915144006c2c9e90d2c7d3880920db49c" + }, + "lastMergeTargetCommit": { + "commitId": "a511f535b1ea495ee0c903badb68fbc83772c882", + "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/commits/a511f535b1ea495ee0c903badb68fbc83772c882" + }, + "lastMergeCommit": { + "commitId": "eef717f69257a6333f221566c1c987dc94cc0d72", + "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/commits/eef717f69257a6333f221566c1c987dc94cc0d72" + }, + "reviewers": [ + { + "reviewerUrl": null, + "vote": 0, + "displayName": "[Mobile]\\Mobile Team", + "url": "https://fabrikam.vssps.visualstudio.com/_apis/Identities/2ea2d095-48f9-4cd6-9966-62f6f574096c", + "id": "2ea2d095-48f9-4cd6-9966-62f6f574096c", + "uniqueName": "vstfs:///Classification/TeamProject/f0811a3b-8c8a-4e43-a3bf-9a049b4835bd\\Mobile Team", + "imageUrl": "https://fabrikam.visualstudio.com/DefaultCollection/_api/_common/identityImage?id=2ea2d095-48f9-4cd6-9966-62f6f574096c", + "isContainer": true + } + ], + "commits": [ + { + "commitId": "53d54ac915144006c2c9e90d2c7d3880920db49c", + "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/commits/53d54ac915144006c2c9e90d2c7d3880920db49c" + } + ], + "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/pullRequests/1", + "_links": { + "web": { + "href": "https://fabrikam.visualstudio.com/DefaultCollection/_git/Fabrikam/pullrequest/1#view=discussion" + }, + "statuses": { + "href": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/pullRequests/1/statuses" + } + } + } + }, + "resourceVersion": "2.0", + "resourceContainers": { + "collection": { + "id": "c12d0eb8-e382-443b-9f9c-c52cba5014c2" + }, + "account": { + "id": "f844ec47-a9db-4511-8281-8b63f4eaf94e" + }, + "project": { + "id": "be9b3917-87e6-42a4-a549-2bc06a7a878f" + } + }, + "createdDate": "2022-06-21T13:03:20.480894Z" + } \ No newline at end of file diff --git a/scm/driver/azure/testdata/webhooks/issue_comment_edit.json.golden b/scm/driver/azure/testdata/webhooks/issue_comment_edit.json.golden new file mode 100644 index 000000000..4ae2669fb --- /dev/null +++ b/scm/driver/azure/testdata/webhooks/issue_comment_edit.json.golden @@ -0,0 +1,88 @@ +{ + "Action": "edited", + "Repo": { + "ID": "4bc14d40-c903-45e2-872e-0462c7748079", + "Namespace": "Fabrikam", + "Name": "Fabrikam", + "Perm": null, + "Branch": "mytopic", + "Archived": false, + "Private": false, + "Visibility": 0, + "Clone": "https://dev.azure.com/fabrikam/DefaultCollection/_git/Fabrikam", + "CloneSSH": "git@ssh.dev.azure.com:v3/fabrikam/DefaultCollection/Fabrikam", + "Link": "https://dev.azure.com/fabrikam/DefaultCollection/_git/Fabrikam", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Issue": { + "Number": 1, + "Title": "my first pull request", + "Body": " - test2\r\n", + "Link": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/pullRequests/1", + "Author": { + "Login": "Jamal Hartnett", + "Name": "Jamal Hartnett", + "Email": "fabrikamfiber4@hotmail.com", + "Avatar": "https://fabrikam.visualstudio.com/DefaultCollection/_api/_common/identityImage?id=54d125f7-69f7-4191-904f-c5b96b6261c8", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "PullRequest": { + "Number": 1, + "Title": "my first pull request", + "Body": " - test2\r\n", + "Sha": "53d54ac915144006c2c9e90d2c7d3880920db49c", + "Ref": "refs/heads/mytopic", + "Source": "mytopic", + "Target": "master", + "Fork": "", + "Link": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/pullRequests/1", + "Diff": "", + "Closed": false, + "Merged": false, + "Base": { + "Name": "", + "Path": "", + "Sha": "" + }, + "Head": { + "Name": "", + "Path": "", + "Sha": "" + }, + "Author": { + "Login": "Jamal Hartnett", + "Name": "Jamal Hartnett", + "Email": "fabrikamfiber4@hotmail.com", + "Avatar": "https://fabrikam.visualstudio.com/DefaultCollection/_api/_common/identityImage?id=54d125f7-69f7-4191-904f-c5b96b6261c8", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Created": "2014-06-17T16:55:46.589889Z", + "Updated": "0001-01-01T00:00:00Z", + "Labels": null + }, + "Created": "2014-06-17T16:55:46.589889Z" + }, + "Comment": { + "ID": 2, + "Body": "This is my comment.", + "Author": { + "Login": "54d125f7-69f7-4191-904f-c5b96b6261c8", + "Name": "Jamal Hartnett", + "Email": "fabrikamfiber4@hotmail.com", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Created": "2014-06-17T16:55:46.589889Z", + "Updated": "2014-06-17T16:58:33.123889Z" + }, + "Sender": { + "Login": "54d125f7-69f7-4191-904f-c5b96b6261c8", + "Name": "Jamal Hartnett", + "Email": "fabrikamfiber4@hotmail.com", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + } +} \ No newline at end of file diff --git a/scm/driver/azure/webhook.go b/scm/driver/azure/webhook.go index ff73ab99c..9e17da18f 100644 --- a/scm/driver/azure/webhook.go +++ b/scm/driver/azure/webhook.go @@ -75,11 +75,30 @@ func (s *webhookService) Parse(req *http.Request, fn scm.SecretFunc) (scm.Webhoo dst := convertMergePullRequestHook(src) dst.Action = scm.ActionMerge return dst, nil + case "ms.vss-code.git-pullrequest-comment-event": + src := new(issueCommentPullRequestHook) + err := json.Unmarshal(data, src) + if err != nil { + return nil, err + } + dst := convertIssueCommentHook(src) + dst.Action = getIssueCommentAction(src) + return dst, nil default: return nil, scm.ErrUnknownEvent } } +func getIssueCommentAction(src *issueCommentPullRequestHook) scm.Action { + if src.Resource.Comment.IsDeleted { + return scm.ActionDelete + } else if src.Resource.Comment.PublishedDate.Equal(src.Resource.Comment.LastUpdatedDate) { + return scm.ActionCreate + } else { + return scm.ActionEdit + } +} + func convertPushHook(src *pushHook) *scm.PushHook { var commits []scm.Commit for _, c := range src.Resource.Commits { @@ -259,6 +278,70 @@ func convertMergePullRequestHook(src *mergePullRequestHook) (returnVal *scm.Pull return returnVal } +func convertIssueCommentHook(src *issueCommentPullRequestHook) *scm.IssueCommentHook { + dst := &scm.IssueCommentHook{ + Repo: scm.Repository{ + ID: src.Resource.PullRequest.Repository.ID, + Namespace: src.Resource.PullRequest.Repository.Project.Name, + Name: src.Resource.PullRequest.Repository.Name, + Branch: scm.TrimRef(src.Resource.PullRequest.SourceRefName), + Private: false, + Clone: src.Resource.PullRequest.Repository.WebURL, + CloneSSH: src.Resource.PullRequest.Repository.SSHURL, + Link: src.Resource.PullRequest.Repository.WebURL, + }, + Issue: scm.Issue{ + Number: src.Resource.PullRequest.PullRequestID, + Title: src.Resource.PullRequest.Title, + Body: src.Resource.PullRequest.Description, + Link: src.Resource.PullRequest.URL, + Author: scm.User{ + Login: src.Resource.PullRequest.CreatedBy.DisplayName, + Name: src.Resource.PullRequest.CreatedBy.DisplayName, + Email: src.Resource.PullRequest.CreatedBy.UniqueName, + Avatar: src.Resource.PullRequest.CreatedBy.ImageURL, + }, + PullRequest: scm.PullRequest{ + Number: src.Resource.PullRequest.PullRequestID, + Title: src.Resource.PullRequest.Title, + Body: src.Resource.PullRequest.Description, + Sha: src.Resource.PullRequest.LastMergeSourceCommit.CommitID, + Ref: src.Resource.PullRequest.SourceRefName, + Source: scm.TrimRef(src.Resource.PullRequest.SourceRefName), + Target: scm.TrimRef(src.Resource.PullRequest.TargetRefName), + Link: src.Resource.PullRequest.URL, + Closed: false, + Merged: false, + Author: scm.User{ + Login: src.Resource.PullRequest.CreatedBy.DisplayName, + Name: src.Resource.PullRequest.CreatedBy.DisplayName, + Email: src.Resource.PullRequest.CreatedBy.UniqueName, + Avatar: src.Resource.PullRequest.CreatedBy.ImageURL, + }, + Created: src.Resource.PullRequest.CreationDate, + }, + Created: src.Resource.PullRequest.CreationDate, + }, + Comment: scm.Comment{ + ID: src.Resource.Comment.ID, + Body: src.Resource.Comment.Content, + Author: scm.User{ + Email: src.Resource.Comment.Author.UniqueName, + Login: src.Resource.Comment.Author.ID, + Name: src.Resource.Comment.Author.DisplayName, + }, + Created: src.Resource.Comment.PublishedDate, + Updated: src.Resource.Comment.LastUpdatedDate, + }, + Sender: scm.User{ + Email: src.Resource.Comment.Author.UniqueName, + Login: src.Resource.Comment.Author.ID, + Name: src.Resource.Comment.Author.DisplayName, + }, + } + return dst +} + type pushHook struct { CreatedDate string `json:"createdDate"` DetailedMessage struct { @@ -596,3 +679,112 @@ type mergePullRequestHook struct { ResourceVersion string `json:"resourceVersion"` Scope string `json:"scope"` } + +type issueCommentPullRequestHook struct { + CreatedDate string `json:"createdDate"` + DetailedMessage struct { + HTML string `json:"html"` + Markdown string `json:"markdown"` + Text string `json:"text"` + } `json:"detailedMessage"` + EventType string `json:"eventType"` + ID string `json:"id"` + Message struct { + HTML string `json:"html"` + Markdown string `json:"markdown"` + Text string `json:"text"` + } `json:"message"` + PublisherID string `json:"publisherId"` + Resource struct { + PullRequest struct { + CreatedBy struct { + DisplayName string `json:"displayName"` + ID string `json:"id"` + ImageURL string `json:"imageUrl"` + UniqueName string `json:"uniqueName"` + URL string `json:"url"` + } `json:"createdBy"` + CreationDate time.Time `json:"creationDate"` + Description string `json:"description"` + LastMergeCommit struct { + CommitID string `json:"commitId"` + Author struct { + Date time.Time `json:"date"` + Email string `json:"email"` + Name string `json:"name"` + } `json:"author"` + URL string `json:"url"` + } `json:"lastMergeCommit"` + LastMergeSourceCommit struct { + CommitID string `json:"commitId"` + URL string `json:"url"` + } `json:"lastMergeSourceCommit"` + LastMergeTargetCommit struct { + CommitID string `json:"commitId"` + URL string `json:"url"` + } `json:"lastMergeTargetCommit"` + MergeID string `json:"mergeId"` + MergeStatus string `json:"mergeStatus"` + PullRequestID int `json:"pullRequestId"` + Repository struct { + ID string `json:"id"` + Name string `json:"name"` + Project struct { + ID string `json:"id"` + Name string `json:"name"` + State string `json:"state"` + URL string `json:"url"` + } `json:"project"` + RemoteURL string `json:"remoteUrl"` + URL string `json:"url"` + WebURL string `json:"webUrl"` + SSHURL string `json:"sshUrl"` + } `json:"repository"` + Reviewers []struct { + DisplayName string `json:"displayName"` + ID string `json:"id"` + ImageURL string `json:"imageUrl"` + IsContainer bool `json:"isContainer"` + ReviewerURL interface{} `json:"reviewerUrl"` + UniqueName string `json:"uniqueName"` + URL string `json:"url"` + Vote int64 `json:"vote"` + } `json:"reviewers"` + SourceRefName string `json:"sourceRefName"` + Status string `json:"status"` + TargetRefName string `json:"targetRefName"` + Title string `json:"title"` + URL string `json:"url"` + } `json:"pullRequest"` + Comment struct { + ID int `json:"id"` + ParentCommentId int `json:"parentCommentId"` + Content string `json:"content"` + PublishedDate time.Time `json:"publishedDate"` + LastUpdatedDate time.Time `json:"lastUpdatedDate"` + LastContentUpdatedDate time.Time `json:"lastContentUpdatedDate"` + CommentType string `json:"commentType"` + IsDeleted bool `json:"isDeleted"` + Author struct { + DisplayName string `json:"displayName"` + ID string `json:"id"` + ImageURL string `json:"imageUrl"` + UniqueName string `json:"uniqueName"` + URL string `json:"url"` + } `json:"author"` + } `json:"comment"` + } `json:"resource"` + ResourceContainers struct { + Account struct { + ID string `json:"id"` + } `json:"account"` + Collection struct { + ID string `json:"id"` + } `json:"collection"` + Project struct { + ID string `json:"id"` + } `json:"project"` + } `json:"resourceContainers"` + ResourceVersion string `json:"resourceVersion"` + Scope string `json:"scope"` +} \ No newline at end of file diff --git a/scm/driver/azure/webhook_test.go b/scm/driver/azure/webhook_test.go index 7ea03870e..d4024c2f8 100644 --- a/scm/driver/azure/webhook_test.go +++ b/scm/driver/azure/webhook_test.go @@ -47,6 +47,24 @@ func TestWebhooks(t *testing.T) { after: "testdata/webhooks/pr_merged.json.golden", obj: new(scm.PullRequestHook), }, + // issue comment create + { + before: "testdata/webhooks/issue_comment.json", + after: "testdata/webhooks/issue_comment.json.golden", + obj: new(scm.IssueCommentHook), + }, + // issue comment edit + { + before: "testdata/webhooks/issue_comment_edit.json", + after: "testdata/webhooks/issue_comment_edit.json.golden", + obj: new(scm.IssueCommentHook), + }, + // issue comment delete + { + before: "testdata/webhooks/issue_comment_delete.json", + after: "testdata/webhooks/issue_comment_delete.json.golden", + obj: new(scm.IssueCommentHook), + }, } for _, test := range tests { From 152fbb89839c65c859b065ec7e40156521651ed4 Mon Sep 17 00:00:00 2001 From: Rutvij Mehta Date: Thu, 23 Jun 2022 18:50:48 -0700 Subject: [PATCH 016/195] Support parsing PR comment events for Bitbucket Cloud --- .../testdata/webhooks/pr_comment_created.json | 331 ++++++++++++++++++ .../webhooks/pr_comment_created.json.golden | 96 +++++ .../testdata/webhooks/pr_comment_deleted.json | 305 ++++++++++++++++ .../webhooks/pr_comment_deleted.json.golden | 96 +++++ scm/driver/bitbucket/webhook.go | 279 +++++++++++++++ scm/driver/bitbucket/webhook_test.go | 14 + scm/user.go | 1 + 7 files changed, 1122 insertions(+) create mode 100644 scm/driver/bitbucket/testdata/webhooks/pr_comment_created.json create mode 100644 scm/driver/bitbucket/testdata/webhooks/pr_comment_created.json.golden create mode 100644 scm/driver/bitbucket/testdata/webhooks/pr_comment_deleted.json create mode 100644 scm/driver/bitbucket/testdata/webhooks/pr_comment_deleted.json.golden diff --git a/scm/driver/bitbucket/testdata/webhooks/pr_comment_created.json b/scm/driver/bitbucket/testdata/webhooks/pr_comment_created.json new file mode 100644 index 000000000..b13056f91 --- /dev/null +++ b/scm/driver/bitbucket/testdata/webhooks/pr_comment_created.json @@ -0,0 +1,331 @@ +{ + "comment": { + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba/pullrequests/1/comments/311512047" + }, + "html": { + "href": "https://bitbucket.org/rutvijmehta-harness/spring-cloud-alibaba/pull-requests/1/_/diff#comment-311512047" + } + }, + "deleted": false, + "pullrequest": { + "type": "pullrequest", + "id": 1, + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba/pullrequests/1" + }, + "html": { + "href": "https://bitbucket.org/rutvijmehta-harness/spring-cloud-alibaba/pull-requests/1" + } + }, + "title": "Update pom.xml" + }, + "content": { + "raw": "test comment", + "markup": "markdown", + "html": "

test comment

", + "type": "rendered" + }, + "created_on": "2022-06-23T22:10:09.939925+00:00", + "user": { + "display_name": "Rutvij Mehta", + "uuid": "{145a94da-035e-42d6-bf85-296cea8005ba}", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/users/%7B145a94da-035e-42d6-bf85-296cea8005ba%7D" + }, + "html": { + "href": "https://bitbucket.org/%7B145a94da-035e-42d6-bf85-296cea8005ba%7D/" + }, + "avatar": { + "href": "https://secure.gravatar.com/avatar/1bf4d1258f18330b314d2737db430cb0?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FRM-5.png" + } + }, + "type": "user", + "nickname": "Rutvij Mehta", + "account_id": "624de6f6fd5e450070486936" + }, + "updated_on": "2022-06-23T22:10:09.939978+00:00", + "type": "pullrequest_comment", + "id": 311512047 + }, + "pullrequest": { + "rendered": { + "description": { + "raw": "Test", + "markup": "markdown", + "html": "

Test

", + "type": "rendered" + }, + "title": { + "raw": "Update pom.xml", + "markup": "markdown", + "html": "

Update pom.xml

", + "type": "rendered" + } + }, + "type": "pullrequest", + "description": "Test", + "links": { + "decline": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba/pullrequests/1/decline" + }, + "diffstat": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba/diffstat/rutvijmehta-harness/spring-cloud-alibaba:b9437f32dddd%0Dcfd2d864e389?from_pullrequest_id=1&topic=true" + }, + "commits": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba/pullrequests/1/commits" + }, + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba/pullrequests/1" + }, + "comments": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba/pullrequests/1/comments" + }, + "merge": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba/pullrequests/1/merge" + }, + "html": { + "href": "https://bitbucket.org/rutvijmehta-harness/spring-cloud-alibaba/pull-requests/1" + }, + "activity": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba/pullrequests/1/activity" + }, + "request-changes": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba/pullrequests/1/request-changes" + }, + "diff": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba/diff/rutvijmehta-harness/spring-cloud-alibaba:b9437f32dddd%0Dcfd2d864e389?from_pullrequest_id=1&topic=true" + }, + "approve": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba/pullrequests/1/approve" + }, + "statuses": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba/pullrequests/1/statuses" + } + }, + "title": "Update pom.xml", + "close_source_branch": false, + "reviewers": [], + "id": 1, + "destination": { + "commit": { + "hash": "cfd2d864e389", + "type": "commit", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba/commit/cfd2d864e389" + }, + "html": { + "href": "https://bitbucket.org/rutvijmehta-harness/spring-cloud-alibaba/commits/cfd2d864e389" + } + } + }, + "repository": { + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba" + }, + "html": { + "href": "https://bitbucket.org/rutvijmehta-harness/spring-cloud-alibaba" + }, + "avatar": { + "href": "https://bytebucket.org/ravatar/%7B4402cbae-7790-453a-b29e-5fcab61a84df%7D?ts=default" + } + }, + "type": "repository", + "name": "spring-cloud-alibaba", + "full_name": "rutvijmehta-harness/spring-cloud-alibaba", + "uuid": "{4402cbae-7790-453a-b29e-5fcab61a84df}" + }, + "branch": { + "name": "2021.x" + } + }, + "created_on": "2022-06-23T19:27:25.443049+00:00", + "summary": { + "raw": "Test", + "markup": "markdown", + "html": "

Test

", + "type": "rendered" + }, + "source": { + "commit": { + "hash": "b9437f32dddd", + "type": "commit", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba/commit/b9437f32dddd" + }, + "html": { + "href": "https://bitbucket.org/rutvijmehta-harness/spring-cloud-alibaba/commits/b9437f32dddd" + } + } + }, + "repository": { + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba" + }, + "html": { + "href": "https://bitbucket.org/rutvijmehta-harness/spring-cloud-alibaba" + }, + "avatar": { + "href": "https://bytebucket.org/ravatar/%7B4402cbae-7790-453a-b29e-5fcab61a84df%7D?ts=default" + } + }, + "type": "repository", + "name": "spring-cloud-alibaba", + "full_name": "rutvijmehta-harness/spring-cloud-alibaba", + "uuid": "{4402cbae-7790-453a-b29e-5fcab61a84df}" + }, + "branch": { + "name": "tiwhitepaper-rutvij" + } + }, + "comment_count": 1, + "state": "OPEN", + "task_count": 0, + "participants": [ + { + "participated_on": "2022-06-23T22:10:09.939978+00:00", + "state": null, + "role": "PARTICIPANT", + "user": { + "display_name": "Rutvij Mehta", + "uuid": "{145a94da-035e-42d6-bf85-296cea8005ba}", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/users/%7B145a94da-035e-42d6-bf85-296cea8005ba%7D" + }, + "html": { + "href": "https://bitbucket.org/%7B145a94da-035e-42d6-bf85-296cea8005ba%7D/" + }, + "avatar": { + "href": "https://secure.gravatar.com/avatar/1bf4d1258f18330b314d2737db430cb0?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FRM-5.png" + } + }, + "type": "user", + "nickname": "Rutvij Mehta", + "account_id": "624de6f6fd5e450070486936" + }, + "type": "participant", + "approved": false + } + ], + "reason": "", + "updated_on": "2022-06-23T22:10:09.939978+00:00", + "author": { + "display_name": "Rutvij Mehta", + "uuid": "{145a94da-035e-42d6-bf85-296cea8005ba}", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/users/%7B145a94da-035e-42d6-bf85-296cea8005ba%7D" + }, + "html": { + "href": "https://bitbucket.org/%7B145a94da-035e-42d6-bf85-296cea8005ba%7D/" + }, + "avatar": { + "href": "https://secure.gravatar.com/avatar/1bf4d1258f18330b314d2737db430cb0?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FRM-5.png" + } + }, + "type": "user", + "nickname": "Rutvij Mehta", + "account_id": "624de6f6fd5e450070486936" + }, + "merge_commit": null, + "closed_by": null + }, + "repository": { + "scm": "git", + "website": null, + "uuid": "{4402cbae-7790-453a-b29e-5fcab61a84df}", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba" + }, + "html": { + "href": "https://bitbucket.org/rutvijmehta-harness/spring-cloud-alibaba" + }, + "avatar": { + "href": "https://bytebucket.org/ravatar/%7B4402cbae-7790-453a-b29e-5fcab61a84df%7D?ts=default" + } + }, + "project": { + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/workspaces/rutvijmehta-harness/projects/TEST" + }, + "html": { + "href": "https://bitbucket.org/rutvijmehta-harness/workspace/projects/TEST" + }, + "avatar": { + "href": "https://bitbucket.org/account/user/rutvijmehta-harness/projects/TEST/avatar/32?ts=1655023274" + } + }, + "type": "project", + "name": "Test", + "key": "TEST", + "uuid": "{aa857cae-daad-4fbd-93ef-503cc3d6c3d6}" + }, + "full_name": "rutvijmehta-harness/spring-cloud-alibaba", + "owner": { + "display_name": "Rutvij Mehta", + "uuid": "{145a94da-035e-42d6-bf85-296cea8005ba}", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/users/%7B145a94da-035e-42d6-bf85-296cea8005ba%7D" + }, + "html": { + "href": "https://bitbucket.org/%7B145a94da-035e-42d6-bf85-296cea8005ba%7D/" + }, + "avatar": { + "href": "https://secure.gravatar.com/avatar/1bf4d1258f18330b314d2737db430cb0?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FRM-5.png" + } + }, + "type": "user", + "nickname": "Rutvij Mehta", + "account_id": "624de6f6fd5e450070486936" + }, + "workspace": { + "slug": "rutvijmehta-harness", + "type": "workspace", + "name": "Rutvij Mehta", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/workspaces/rutvijmehta-harness" + }, + "html": { + "href": "https://bitbucket.org/rutvijmehta-harness/" + }, + "avatar": { + "href": "https://bitbucket.org/workspaces/rutvijmehta-harness/avatar/?ts=1655023237" + } + }, + "uuid": "{145a94da-035e-42d6-bf85-296cea8005ba}" + }, + "type": "repository", + "is_private": false, + "name": "spring-cloud-alibaba" + }, + "actor": { + "display_name": "Rutvij Mehta", + "uuid": "{145a94da-035e-42d6-bf85-296cea8005ba}", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/users/%7B145a94da-035e-42d6-bf85-296cea8005ba%7D" + }, + "html": { + "href": "https://bitbucket.org/%7B145a94da-035e-42d6-bf85-296cea8005ba%7D/" + }, + "avatar": { + "href": "https://secure.gravatar.com/avatar/1bf4d1258f18330b314d2737db430cb0?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FRM-5.png" + } + }, + "type": "user", + "nickname": "Rutvij Mehta", + "account_id": "624de6f6fd5e450070486936" + } +} \ No newline at end of file diff --git a/scm/driver/bitbucket/testdata/webhooks/pr_comment_created.json.golden b/scm/driver/bitbucket/testdata/webhooks/pr_comment_created.json.golden new file mode 100644 index 000000000..f4b06fb9d --- /dev/null +++ b/scm/driver/bitbucket/testdata/webhooks/pr_comment_created.json.golden @@ -0,0 +1,96 @@ +{ + "Action": "created", + "Repo": { + "ID": "{4402cbae-7790-453a-b29e-5fcab61a84df}", + "Namespace": "rutvijmehta-harness", + "Name": "spring-cloud-alibaba", + "Perm": null, + "Branch": "", + "Archived": false, + "Private": false, + "Visibility": 0, + "Clone": "https://bitbucket.org/rutvijmehta-harness/spring-cloud-alibaba.git", + "CloneSSH": "git@bitbucket.org:rutvijmehta-harness/spring-cloud-alibaba.git", + "Link": "https://bitbucket.org/rutvijmehta-harness/spring-cloud-alibaba", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Issue": { + "Number": 1, + "Title": "Update pom.xml", + "Body": "Test", + "Link": "https://bitbucket.org/rutvijmehta-harness/spring-cloud-alibaba/pull-requests/1", + "Labels": null, + "Closed": false, + "Locked": false, + "Author": { + "Login": "", + "Name": "Rutvij Mehta", + "Email": "", + "Avatar": "https://secure.gravatar.com/avatar/1bf4d1258f18330b314d2737db430cb0?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FRM-5.png", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "PullRequest": { + "Number": 1, + "Title": "Update pom.xml", + "Body": "Test", + "Sha": "b9437f32dddd", + "Ref": "refs/pull-requests/1/from", + "Source": "tiwhitepaper-rutvij", + "Target": "2021.x", + "Fork": "rutvijmehta-harness/spring-cloud-alibaba", + "Link": "https://bitbucket.org/rutvijmehta-harness/spring-cloud-alibaba/pull-requests/1", + "Diff": "", + "Closed": false, + "Merged": false, + "Base": { + "Name": "", + "Path": "", + "Sha": "" + }, + "Head": { + "Name": "", + "Path": "", + "Sha": "" + }, + "Author": { + "Login": "", + "Name": "Rutvij Mehta", + "Email": "", + "Avatar": "https://secure.gravatar.com/avatar/1bf4d1258f18330b314d2737db430cb0?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FRM-5.png", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Created": "2022-06-23T19:27:25.443049Z", + "Updated": "2022-06-23T22:10:09.939978Z", + "Labels": null + }, + "Created": "2022-06-23T19:27:25.443049Z", + "Updated": "2022-06-23T22:10:09.939978Z" + }, + "Comment": { + "ID": 311512047, + "Body": "test comment", + "Author": { + "ID": "{145a94da-035e-42d6-bf85-296cea8005ba}", + "Login": "", + "Name": "Rutvij Mehta", + "Email": "", + "Avatar": "https://secure.gravatar.com/avatar/1bf4d1258f18330b314d2737db430cb0?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FRM-5.png", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Created": "2022-06-23T22:10:09.939925Z", + "Updated": "2022-06-23T22:10:09.939978Z" + }, + "Sender": { + "ID": "{145a94da-035e-42d6-bf85-296cea8005ba}", + "Login": "", + "Name": "Rutvij Mehta", + "Email": "", + "Avatar": "https://secure.gravatar.com/avatar/1bf4d1258f18330b314d2737db430cb0?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FRM-5.png", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + } +} \ No newline at end of file diff --git a/scm/driver/bitbucket/testdata/webhooks/pr_comment_deleted.json b/scm/driver/bitbucket/testdata/webhooks/pr_comment_deleted.json new file mode 100644 index 000000000..23b3f0e3b --- /dev/null +++ b/scm/driver/bitbucket/testdata/webhooks/pr_comment_deleted.json @@ -0,0 +1,305 @@ +{ + "comment": { + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba/pullrequests/1/comments/311512047" + }, + "html": { + "href": "https://bitbucket.org/rutvijmehta-harness/spring-cloud-alibaba/pull-requests/1/_/diff#comment-311512047" + } + }, + "deleted": true, + "pullrequest": { + "type": "pullrequest", + "id": 1, + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba/pullrequests/1" + }, + "html": { + "href": "https://bitbucket.org/rutvijmehta-harness/spring-cloud-alibaba/pull-requests/1" + } + }, + "title": "Update pom.xml" + }, + "content": { + "raw": "", + "markup": "markdown", + "html": "", + "type": "rendered" + }, + "created_on": "2022-06-23T22:10:09.939925+00:00", + "user": { + "display_name": "Rutvij Mehta", + "uuid": "{145a94da-035e-42d6-bf85-296cea8005ba}", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/users/%7B145a94da-035e-42d6-bf85-296cea8005ba%7D" + }, + "html": { + "href": "https://bitbucket.org/%7B145a94da-035e-42d6-bf85-296cea8005ba%7D/" + }, + "avatar": { + "href": "https://secure.gravatar.com/avatar/1bf4d1258f18330b314d2737db430cb0?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FRM-5.png" + } + }, + "type": "user", + "nickname": "Rutvij Mehta", + "account_id": "624de6f6fd5e450070486936" + }, + "updated_on": "2022-06-24T01:38:47.831843+00:00", + "type": "pullrequest_comment", + "id": 311512047 + }, + "pullrequest": { + "rendered": { + "description": { + "raw": "Test", + "markup": "markdown", + "html": "

Test

", + "type": "rendered" + }, + "title": { + "raw": "Update pom.xml", + "markup": "markdown", + "html": "

Update pom.xml

", + "type": "rendered" + } + }, + "type": "pullrequest", + "description": "Test", + "links": { + "decline": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba/pullrequests/1/decline" + }, + "diffstat": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba/diffstat/rutvijmehta-harness/spring-cloud-alibaba:b9437f32dddd%0Dcfd2d864e389?from_pullrequest_id=1&topic=true" + }, + "commits": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba/pullrequests/1/commits" + }, + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba/pullrequests/1" + }, + "comments": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba/pullrequests/1/comments" + }, + "merge": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba/pullrequests/1/merge" + }, + "html": { + "href": "https://bitbucket.org/rutvijmehta-harness/spring-cloud-alibaba/pull-requests/1" + }, + "activity": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba/pullrequests/1/activity" + }, + "request-changes": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba/pullrequests/1/request-changes" + }, + "diff": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba/diff/rutvijmehta-harness/spring-cloud-alibaba:b9437f32dddd%0Dcfd2d864e389?from_pullrequest_id=1&topic=true" + }, + "approve": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba/pullrequests/1/approve" + }, + "statuses": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba/pullrequests/1/statuses" + } + }, + "title": "Update pom.xml", + "close_source_branch": false, + "reviewers": [], + "id": 1, + "destination": { + "commit": { + "hash": "cfd2d864e389", + "type": "commit", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba/commit/cfd2d864e389" + }, + "html": { + "href": "https://bitbucket.org/rutvijmehta-harness/spring-cloud-alibaba/commits/cfd2d864e389" + } + } + }, + "repository": { + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba" + }, + "html": { + "href": "https://bitbucket.org/rutvijmehta-harness/spring-cloud-alibaba" + }, + "avatar": { + "href": "https://bytebucket.org/ravatar/%7B4402cbae-7790-453a-b29e-5fcab61a84df%7D?ts=default" + } + }, + "type": "repository", + "name": "spring-cloud-alibaba", + "full_name": "rutvijmehta-harness/spring-cloud-alibaba", + "uuid": "{4402cbae-7790-453a-b29e-5fcab61a84df}" + }, + "branch": { + "name": "2021.x" + } + }, + "created_on": "2022-06-23T19:27:25.443049+00:00", + "summary": { + "raw": "Test", + "markup": "markdown", + "html": "

Test

", + "type": "rendered" + }, + "source": { + "commit": { + "hash": "b9437f32dddd", + "type": "commit", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba/commit/b9437f32dddd" + }, + "html": { + "href": "https://bitbucket.org/rutvijmehta-harness/spring-cloud-alibaba/commits/b9437f32dddd" + } + } + }, + "repository": { + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba" + }, + "html": { + "href": "https://bitbucket.org/rutvijmehta-harness/spring-cloud-alibaba" + }, + "avatar": { + "href": "https://bytebucket.org/ravatar/%7B4402cbae-7790-453a-b29e-5fcab61a84df%7D?ts=default" + } + }, + "type": "repository", + "name": "spring-cloud-alibaba", + "full_name": "rutvijmehta-harness/spring-cloud-alibaba", + "uuid": "{4402cbae-7790-453a-b29e-5fcab61a84df}" + }, + "branch": { + "name": "tiwhitepaper-rutvij" + } + }, + "comment_count": 0, + "state": "OPEN", + "task_count": 0, + "participants": [], + "reason": "", + "updated_on": "2022-06-24T01:40:18.667126+00:00", + "author": { + "display_name": "Rutvij Mehta", + "uuid": "{145a94da-035e-42d6-bf85-296cea8005ba}", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/users/%7B145a94da-035e-42d6-bf85-296cea8005ba%7D" + }, + "html": { + "href": "https://bitbucket.org/%7B145a94da-035e-42d6-bf85-296cea8005ba%7D/" + }, + "avatar": { + "href": "https://secure.gravatar.com/avatar/1bf4d1258f18330b314d2737db430cb0?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FRM-5.png" + } + }, + "type": "user", + "nickname": "Rutvij Mehta", + "account_id": "624de6f6fd5e450070486936" + }, + "merge_commit": null, + "closed_by": null + }, + "repository": { + "scm": "git", + "website": null, + "uuid": "{4402cbae-7790-453a-b29e-5fcab61a84df}", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/rutvijmehta-harness/spring-cloud-alibaba" + }, + "html": { + "href": "https://bitbucket.org/rutvijmehta-harness/spring-cloud-alibaba" + }, + "avatar": { + "href": "https://bytebucket.org/ravatar/%7B4402cbae-7790-453a-b29e-5fcab61a84df%7D?ts=default" + } + }, + "project": { + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/workspaces/rutvijmehta-harness/projects/TEST" + }, + "html": { + "href": "https://bitbucket.org/rutvijmehta-harness/workspace/projects/TEST" + }, + "avatar": { + "href": "https://bitbucket.org/account/user/rutvijmehta-harness/projects/TEST/avatar/32?ts=1655023274" + } + }, + "type": "project", + "name": "Test", + "key": "TEST", + "uuid": "{aa857cae-daad-4fbd-93ef-503cc3d6c3d6}" + }, + "full_name": "rutvijmehta-harness/spring-cloud-alibaba", + "owner": { + "display_name": "Rutvij Mehta", + "uuid": "{145a94da-035e-42d6-bf85-296cea8005ba}", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/users/%7B145a94da-035e-42d6-bf85-296cea8005ba%7D" + }, + "html": { + "href": "https://bitbucket.org/%7B145a94da-035e-42d6-bf85-296cea8005ba%7D/" + }, + "avatar": { + "href": "https://secure.gravatar.com/avatar/1bf4d1258f18330b314d2737db430cb0?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FRM-5.png" + } + }, + "type": "user", + "nickname": "Rutvij Mehta", + "account_id": "624de6f6fd5e450070486936" + }, + "workspace": { + "slug": "rutvijmehta-harness", + "type": "workspace", + "name": "Rutvij Mehta", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/workspaces/rutvijmehta-harness" + }, + "html": { + "href": "https://bitbucket.org/rutvijmehta-harness/" + }, + "avatar": { + "href": "https://bitbucket.org/workspaces/rutvijmehta-harness/avatar/?ts=1655023237" + } + }, + "uuid": "{145a94da-035e-42d6-bf85-296cea8005ba}" + }, + "type": "repository", + "is_private": false, + "name": "spring-cloud-alibaba" + }, + "actor": { + "display_name": "Rutvij Mehta", + "uuid": "{145a94da-035e-42d6-bf85-296cea8005ba}", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/users/%7B145a94da-035e-42d6-bf85-296cea8005ba%7D" + }, + "html": { + "href": "https://bitbucket.org/%7B145a94da-035e-42d6-bf85-296cea8005ba%7D/" + }, + "avatar": { + "href": "https://secure.gravatar.com/avatar/1bf4d1258f18330b314d2737db430cb0?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FRM-5.png" + } + }, + "type": "user", + "nickname": "Rutvij Mehta", + "account_id": "624de6f6fd5e450070486936" + } +} \ No newline at end of file diff --git a/scm/driver/bitbucket/testdata/webhooks/pr_comment_deleted.json.golden b/scm/driver/bitbucket/testdata/webhooks/pr_comment_deleted.json.golden new file mode 100644 index 000000000..7190b1ff7 --- /dev/null +++ b/scm/driver/bitbucket/testdata/webhooks/pr_comment_deleted.json.golden @@ -0,0 +1,96 @@ +{ + "Action": "deleted", + "Repo": { + "ID": "{4402cbae-7790-453a-b29e-5fcab61a84df}", + "Namespace": "rutvijmehta-harness", + "Name": "spring-cloud-alibaba", + "Perm": null, + "Branch": "", + "Archived": false, + "Private": false, + "Visibility": 0, + "Clone": "https://bitbucket.org/rutvijmehta-harness/spring-cloud-alibaba.git", + "CloneSSH": "git@bitbucket.org:rutvijmehta-harness/spring-cloud-alibaba.git", + "Link": "https://bitbucket.org/rutvijmehta-harness/spring-cloud-alibaba", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Issue": { + "Number": 1, + "Title": "Update pom.xml", + "Body": "Test", + "Link": "https://bitbucket.org/rutvijmehta-harness/spring-cloud-alibaba/pull-requests/1", + "Labels": null, + "Closed": false, + "Locked": false, + "Author": { + "Login": "", + "Name": "Rutvij Mehta", + "Email": "", + "Avatar": "https://secure.gravatar.com/avatar/1bf4d1258f18330b314d2737db430cb0?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FRM-5.png", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "PullRequest": { + "Number": 1, + "Title": "Update pom.xml", + "Body": "Test", + "Sha": "b9437f32dddd", + "Ref": "refs/pull-requests/1/from", + "Source": "tiwhitepaper-rutvij", + "Target": "2021.x", + "Fork": "rutvijmehta-harness/spring-cloud-alibaba", + "Link": "https://bitbucket.org/rutvijmehta-harness/spring-cloud-alibaba/pull-requests/1", + "Diff": "", + "Closed": false, + "Merged": false, + "Base": { + "Name": "", + "Path": "", + "Sha": "" + }, + "Head": { + "Name": "", + "Path": "", + "Sha": "" + }, + "Author": { + "Login": "", + "Name": "Rutvij Mehta", + "Email": "", + "Avatar": "https://secure.gravatar.com/avatar/1bf4d1258f18330b314d2737db430cb0?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FRM-5.png", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Created": "2022-06-23T19:27:25.443049Z", + "Updated": "2022-06-24T01:40:18.667126Z", + "Labels": null + }, + "Created": "2022-06-23T19:27:25.443049Z", + "Updated": "2022-06-24T01:40:18.667126Z" + }, + "Comment": { + "ID": 311512047, + "Body": "", + "Author": { + "ID": "{145a94da-035e-42d6-bf85-296cea8005ba}", + "Login": "", + "Name": "Rutvij Mehta", + "Email": "", + "Avatar": "https://secure.gravatar.com/avatar/1bf4d1258f18330b314d2737db430cb0?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FRM-5.png", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Created": "2022-06-23T22:10:09.939925Z", + "Updated": "2022-06-24T01:38:47.831843Z" + }, + "Sender": { + "ID": "{145a94da-035e-42d6-bf85-296cea8005ba}", + "Login": "", + "Name": "Rutvij Mehta", + "Email": "", + "Avatar": "https://secure.gravatar.com/avatar/1bf4d1258f18330b314d2737db430cb0?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FRM-5.png", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + } +} \ No newline at end of file diff --git a/scm/driver/bitbucket/webhook.go b/scm/driver/bitbucket/webhook.go index da62ba876..c567e565f 100644 --- a/scm/driver/bitbucket/webhook.go +++ b/scm/driver/bitbucket/webhook.go @@ -53,6 +53,23 @@ func (s *webhookService) Parse(req *http.Request, fn scm.SecretFunc) (scm.Webhoo if hook != nil { hook.(*scm.PullRequestHook).Action = scm.ActionClose } + case "pullrequest:comment_created": + hook, err = s.parsePullRequestCommentHook(data) + if hook != nil { + hook.(*scm.IssueCommentHook).Action = scm.ActionCreate + } + case "pullrequest:comment_updated": + // Bitbucket PR Comment Update is unreliable and does not send events + // most of the time https://github.com/iterative/cml/issues/817 + hook, err = s.parsePullRequestCommentHook(data) + if hook != nil { + hook.(*scm.IssueCommentHook).Action = scm.ActionEdit + } + case "pullrequest:comment_deleted": + hook, err = s.parsePullRequestCommentHook(data) + if hook != nil { + hook.(*scm.IssueCommentHook).Action = scm.ActionDelete + } } if err != nil { return nil, err @@ -78,6 +95,12 @@ func (s *webhookService) Parse(req *http.Request, fn scm.SecretFunc) (scm.Webhoo return hook, nil } +func (s *webhookService) parsePullRequestCommentHook(data []byte) (scm.Webhook, error) { + dst := new(prCommentHook) + err := json.Unmarshal(data, dst) + return convertPrCommentHook(dst), err +} + func (s *webhookService) parsePushHook(data []byte) (scm.Webhook, error) { dst := new(pushHook) err := json.Unmarshal(data, dst) @@ -381,6 +404,194 @@ type ( } `json:"links"` UUID string `json:"uuid"` } + + prComment struct { + Links struct { + Self link `json:"self"` + HTML link `json:"html"` + } `json:"links"` + Deleted bool `json:"deleted"` + PullRequest struct { + Type string `json:"type"` + ID int `json:"id"` + Links struct { + Self link `json:"self"` + HTML link `json:"html"` + } `json:"links"` + Title string `json:"title"` + } + Content struct { + Raw string `json:"raw"` + Markup string `json:"markup"` + Html string `json:"html"` + Type string `json:"type"` + } + CreatedOn time.Time `json:"created_on"` + User prCommentHookUser `json:"user"` + UpdatedOn time.Time `json:"updated_on"` + Type string `json:"type"` + ID int `json:"id"` + } + + prCommentHookRepo struct { + Scm string `json:"scm"` + Website string `json:"website"` + UUID string `json:"uuid"` + Links struct { + Self link `json:"self"` + HTML link `json:"html"` + Avatar link `json:"avatar"` + } `json:"links"` + Project struct { + Links struct { + Self link `json:"self"` + HTML link `json:"html"` + Avatar link `json:"avatar"` + } `json:"links"` + Type string `json:"type"` + Name string `json:"name"` + Key string `json:"key"` + UUID string `json:"uuid"` + } `json:"project"` + FullName string `json:"full_name"` + Owner prCommentHookUser `json:"owner"` + Workspace struct { + Slug string `json:"slugg"` + Type string `json:"type"` + Name string `json:"name"` + Links struct { + Self link `json:"self"` + HTML link `json:"html"` + Avatar link `json:"avatar"` + } `json:"links"` + UUID string `json:"uuid"` + } `json:"workspace"` + Type string `json:"type"` + IsPrivate bool `json:"is_private"` + Name string `json:"name"` + } + + prCommentHookUser struct { + Username string `json:"username"` + DisplayName string `json:"display_name"` + UUID string `json:"uuid"` + Links struct { + Self link `json:"self"` + HTML link `json:"html"` + Avatar link `json:"avatar"` + } `json:"links"` + Type string `json:"type"` + Nickname string `json:"nickname"` + AccountID string `json:"account_id"` + } + + prCommentHookPullRequest struct { + Rendered struct { + Description struct { + Raw string `json:"raw"` + Markup string `json:"markup"` + Html string `json:"html"` + Type string `json:"type"` + } `json:"description"` + Title struct { + Raw string `json:"raw"` + Markup string `json:"markup"` + Html string `json:"html"` + Type string `json:"type"` + } `json:"title"` + } `json:"rendered"` + Type string `json:"type"` + Description string `json:"description"` + Links struct { + Decline link `json:"decline"` + Diffstat link `json:"diffstat"` + Commits link `json:"commits"` + Self link `json:"self"` + Comments link `json:"comments"` + Merge link `json:"merge"` + Html link `json:"html"` + Activity link `json:"activity"` + RequestChanges link `json:"request-changes"` + Diff link `json:"diff"` + Approve link `json:"approve"` + Statuses link `json:"statuses"` + } `json:"links"` + Title string `json:"title"` + CloseSourceBranch bool `json:"close_source_branch"` + Reviewers []interface{} `json:"reviewers"` + ID int `json:"id"` + Destination struct { + Commit struct { + Hash string `json:"hash"` + Type string `json:"type"` + Links struct { + Self link `json:"self"` + HTML link `json:"html"` + } `json:"links"` + } + Repository struct { + Links struct { + Self link `json:"self"` + HTML link `json:"html"` + Avatar link `json:"avatar"` + } `json:"links"` + Type string `json:"type"` + Name string `json:"name"` + FullName string `json:"full_name"` + UUID string `json:"uuid"` + } `json:"repository"` + Branch struct { + Name string `json:"name"` + } `json:"branch"` + } `json:"destination"` + CreatedOn time.Time `json:"created_on"` + Summary struct { + Raw string `json:"raw"` + Markup string `json:"markup"` + Html string `json:"html"` + Type string `json:"type"` + } `json:"summary"` + Source struct { + Commit struct { + Hash string `json:"hash"` + Type string `json:"type"` + Links struct { + Self link `json:"self"` + HTML link `json:"html"` + } `json:"links"` + } + Repository struct { + Links struct { + Self link `json:"self"` + HTML link `json:"html"` + Avatar link `json:"avatar"` + } `json:"links"` + Type string `json:"type"` + Name string `json:"name"` + FullName string `json:"full_name"` + UUID string `json:"uuid"` + } `json:"repository"` + Branch struct { + Name string `json:"name"` + } `json:"branch"` + } `json:"source"` + CommentCount int `json:"comment_count"` + State string `json:"state"` + TaskCount int `json:"task_count"` + Participants []interface{} `json:"participants"` + Reason string `json:"reason"` + UpdatedOn time.Time `json:"updated_on"` + Author prCommentHookUser `json:"author"` + MergeCommit interface{} `json:"merge_commit"` + ClosedBy interface{} `json:"closed_by"` + } + + prCommentHook struct { + Comment prComment `json:"comment"` + PullRequest prCommentHookPullRequest `json:"pullRequest"` + Repository prCommentHookRepo `json:"repository"` + Actor prCommentHookUser `json:"actor"` + } ) // @@ -610,3 +821,71 @@ func convertPullRequestHook(src *webhook) *scm.PullRequestHook { }, } } + +func convertPrCommentHook(src *prCommentHook) *scm.IssueCommentHook { + namespace, _ := scm.Split(src.Repository.FullName) + dst := scm.IssueCommentHook{ + Repo: scm.Repository{ + ID: src.Repository.UUID, + Namespace: namespace, + Name: src.Repository.Name, + Clone: fmt.Sprintf("https://bitbucket.org/%s.git", src.Repository.FullName), + CloneSSH: fmt.Sprintf("git@bitbucket.org:%s.git", src.Repository.FullName), + Link: src.Repository.Links.HTML.Href, + Private: src.Repository.IsPrivate, + }, + Issue: scm.Issue{ + Number: src.PullRequest.ID, + Title: src.PullRequest.Title, + Body: src.PullRequest.Description, + Link: src.PullRequest.Links.Html.Href, + Author: scm.User{ + Login: src.PullRequest.Author.Username, + Name: src.PullRequest.Author.DisplayName, + Avatar: src.PullRequest.Author.Links.Avatar.Href, + }, + PullRequest: scm.PullRequest{ + Number: src.PullRequest.ID, + Title: src.PullRequest.Title, + Body: src.PullRequest.Description, + Sha: src.PullRequest.Source.Commit.Hash, + // Bitbucket does not support PR Refs: https://jira.atlassian.com/browse/BCLOUD-5814 + Ref: fmt.Sprintf("refs/pull-requests/%d/from", src.PullRequest.ID), + Source: src.PullRequest.Source.Branch.Name, + Target: src.PullRequest.Destination.Branch.Name, + Fork: src.PullRequest.Source.Repository.FullName, + Link: src.PullRequest.Links.Html.Href, + Closed: src.PullRequest.State != "OPEN", + Merged: src.PullRequest.State == "MERGED", + Author: scm.User{ + Login: src.PullRequest.Author.Username, + Name: src.PullRequest.Author.DisplayName, + Avatar: src.PullRequest.Author.Links.Avatar.Href, + }, + Created: src.PullRequest.CreatedOn, + Updated: src.PullRequest.UpdatedOn, + }, + Created: src.PullRequest.CreatedOn, + Updated: src.PullRequest.UpdatedOn, + }, + Comment: scm.Comment{ + ID: src.Comment.ID, + Body: src.Comment.Content.Raw, + Author: scm.User{ + ID: src.Comment.User.UUID, + Login: src.Comment.User.Username, + Name: src.Comment.User.DisplayName, + Avatar: src.Comment.User.Links.Avatar.Href, + }, + Created: src.Comment.CreatedOn, + Updated: src.Comment.UpdatedOn, + }, + Sender: scm.User{ + ID: src.Actor.UUID, + Login: src.Actor.Username, + Name: src.Actor.DisplayName, + Avatar: src.Actor.Links.Avatar.Href, + }, + } + return &dst +} diff --git a/scm/driver/bitbucket/webhook_test.go b/scm/driver/bitbucket/webhook_test.go index 9e633ed23..e72e096ff 100644 --- a/scm/driver/bitbucket/webhook_test.go +++ b/scm/driver/bitbucket/webhook_test.go @@ -132,6 +132,20 @@ func TestWebhooks(t *testing.T) { // after: "samples/pr_unlabeled.json.golden", // obj: new(scm.PullRequestHook), // }, + { + sig: "71295b197fa25f4356d2fb9965df3f2379d903d7", + event: "pullrequest:comment_created", + before: "testdata/webhooks/pr_comment_created.json", + after: "testdata/webhooks/pr_comment_created.json.golden", + obj: new(scm.IssueCommentHook), + }, + { + sig: "71295b197fa25f4356d2fb9965df3f2379d903d7", + event: "pullrequest:comment_deleted", + before: "testdata/webhooks/pr_comment_deleted.json", + after: "testdata/webhooks/pr_comment_deleted.json.golden", + obj: new(scm.IssueCommentHook), + }, } for _, test := range tests { diff --git a/scm/user.go b/scm/user.go index e1ea08fa5..fd448770a 100644 --- a/scm/user.go +++ b/scm/user.go @@ -12,6 +12,7 @@ import ( type ( // User represents a user account. User struct { + ID string Login string Name string Email string From 5f245ea841e985bef2cc34c456e73328cd95451c Mon Sep 17 00:00:00 2001 From: Rutvij Mehta Date: Thu, 30 Jun 2022 02:20:00 -0700 Subject: [PATCH 017/195] Update scm version 1.26.0 (#203) --- CHANGELOG.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 642d37d15..8bc4f787f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,23 @@ # Changelog +## [v1.26.0](https://github.com/drone/go-scm/tree/v1.26.0) (2022-07-01) + +[Full Changelog](https://github.com/drone/go-scm/compare/v1.25.0...v1.26.0) + +**Implemented enhancements:** + +- Support parsing PR comment events for Bitbucket Cloud [\#202](https://github.com/drone/go-scm/pull/202) ([rutvijmehta-harness](https://github.com/rutvijmehta-harness)) +- added issue comment hook support for Azure [\#200](https://github.com/drone/go-scm/pull/200) ([raghavharness](https://github.com/raghavharness)) + +**Fixed bugs:** + +- \[CI-4623\] - Azure webhook parseAPI changes [\#198](https://github.com/drone/go-scm/pull/198) ([raghavharness](https://github.com/raghavharness)) + +**Merged pull requests:** + +- Update scm version 1.26.0 [\#203](https://github.com/drone/go-scm/pull/203) ([rutvijmehta-harness](https://github.com/rutvijmehta-harness)) +- Fixed formatting in README.md [\#199](https://github.com/drone/go-scm/pull/199) ([hemanthmantri](https://github.com/hemanthmantri)) + ## [v1.25.0](https://github.com/drone/go-scm/tree/v1.25.0) (2022-06-16) [Full Changelog](https://github.com/drone/go-scm/compare/v1.24.0...v1.25.0) @@ -13,6 +31,10 @@ - \[PL-25889\]: fix list branches Azure API [\#195](https://github.com/drone/go-scm/pull/195) ([bhavya181](https://github.com/bhavya181)) - Return project specific hooks only in ListHooks API for Azure. [\#192](https://github.com/drone/go-scm/pull/192) ([raghavharness](https://github.com/raghavharness)) +**Merged pull requests:** + +- Update scm version 1.25.0 [\#197](https://github.com/drone/go-scm/pull/197) ([rutvijmehta-harness](https://github.com/rutvijmehta-harness)) + ## [v1.24.0](https://github.com/drone/go-scm/tree/v1.24.0) (2022-06-07) [Full Changelog](https://github.com/drone/go-scm/compare/v1.23.0...v1.24.0) From 9b81b04a4df2d9aa7ad8dd5d7127fe0a862c8899 Mon Sep 17 00:00:00 2001 From: raghavharness Date: Thu, 14 Jul 2022 19:13:11 +0530 Subject: [PATCH 018/195] using resource version 2.0 for Azure --- scm/driver/azure/repo.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scm/driver/azure/repo.go b/scm/driver/azure/repo.go index a590bffee..f46ede285 100644 --- a/scm/driver/azure/repo.go +++ b/scm/driver/azure/repo.go @@ -109,6 +109,10 @@ func (s *RepositoryService) CreateHook(ctx context.Context, repo string, input * if input.SkipVerify { in.ConsumerInputs.AcceptUntrustedCerts = "enabled" } + // with version 1.0, azure provides incomplete data for issue-comment + if in.EventType == "ms.vss-code.git-pullrequest-comment-event" { + in.ResourceVersion = "2.0" + } out := new(subscription) res, err := s.client.do(ctx, "POST", endpoint, in, out) return convertHook(out), res, err From 65018053d4317c83058a483ff815d2137092da09 Mon Sep 17 00:00:00 2001 From: Raghav Date: Tue, 19 Jul 2022 14:34:34 +0530 Subject: [PATCH 019/195] Update scm version 1.27.0 (#206) --- CHANGELOG.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8bc4f787f..2ccb06957 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [v1.27.0](https://github.com/drone/go-scm/tree/v1.27.0) (2022-07-18) + +[Full Changelog](https://github.com/drone/go-scm/compare/v1.26.0...v1.27.0) + +**Merged pull requests:** + +- Using resource version 2.0 for Azure [\#205](https://github.com/drone/go-scm/pull/205) ([raghavharness](https://github.com/raghavharness)) + ## [v1.26.0](https://github.com/drone/go-scm/tree/v1.26.0) (2022-07-01) [Full Changelog](https://github.com/drone/go-scm/compare/v1.25.0...v1.26.0) @@ -15,7 +23,6 @@ **Merged pull requests:** -- Update scm version 1.26.0 [\#203](https://github.com/drone/go-scm/pull/203) ([rutvijmehta-harness](https://github.com/rutvijmehta-harness)) - Fixed formatting in README.md [\#199](https://github.com/drone/go-scm/pull/199) ([hemanthmantri](https://github.com/hemanthmantri)) ## [v1.25.0](https://github.com/drone/go-scm/tree/v1.25.0) (2022-06-16) From 07b069c7f79af40bf6cdb2bd91022591477be0a6 Mon Sep 17 00:00:00 2001 From: Brad Rydzewski Date: Sun, 24 Jul 2022 17:36:52 -0400 Subject: [PATCH 020/195] gogs find commit for branch --- scm/driver/gogs/git.go | 9 +++++++++ scm/driver/gogs/git_test.go | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/scm/driver/gogs/git.go b/scm/driver/gogs/git.go index 2cb3c687e..1ab6dd8a2 100644 --- a/scm/driver/gogs/git.go +++ b/scm/driver/gogs/git.go @@ -28,6 +28,15 @@ func (s *gitService) FindBranch(ctx context.Context, repo, name string) (*scm.Re } func (s *gitService) FindCommit(ctx context.Context, repo, ref string) (*scm.Commit, *scm.Response, error) { + // github and gitlab permit fetching a commit by sha + // or branch. This code emulates the github and gitlab + // behavior for gogs by fetching the commit sha for the + // branch and using in the subsequent API call. + if scm.IsHash(ref) == false { + if branch, _, err := s.FindBranch(ctx, repo, scm.TrimRef(ref)); err == nil { + ref = branch.Sha // replace ref with sha + } + } path := fmt.Sprintf("api/v1/repos/%s/commits/%s", repo, ref) out := new(commitDetail) res, err := s.client.do(ctx, "GET", path, nil, out) diff --git a/scm/driver/gogs/git_test.go b/scm/driver/gogs/git_test.go index 5b226e1db..9fe8d1322 100644 --- a/scm/driver/gogs/git_test.go +++ b/scm/driver/gogs/git_test.go @@ -44,6 +44,40 @@ func TestCommitFind(t *testing.T) { } } +func TestCommitFindBranch(t *testing.T) { + defer gock.Off() + + gock.New("https://try.gogs.io"). + Get("/api/v1/repos/gogits/gogs/branches/master"). + Reply(200). + Type("application/json"). + File("testdata/branch.json") + + gock.New("https://try.gogs.io"). + Get("/api/v1/repos/gogits/gogs/commits/f05f642b892d59a0a9ef6a31f6c905a24b5db13a"). + Reply(200). + Type("application/json"). + File("testdata/commits.json") + + client, _ := New("https://try.gogs.io") + got, _, err := client.Git.FindCommit( + context.Background(), + "gogits/gogs", + "master", + ) + if err != nil { + t.Error(err) + } + want := new(scm.Commit) + raw, _ := ioutil.ReadFile("testdata/commits.json.golden") + json.Unmarshal(raw, &want) + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } +} + func TestCommitList(t *testing.T) { client, _ := New("https://try.gogs.io") _, _, err := client.Git.ListCommits(context.Background(), "gogits/gogs", scm.CommitListOptions{}) From c29b3f1156cd6fb200364177aa6accc631e74082 Mon Sep 17 00:00:00 2001 From: Brad Rydzewski Date: Sun, 24 Jul 2022 17:45:05 -0400 Subject: [PATCH 021/195] escape forward slashes in gitlab branch name --- scm/driver/gitlab/git.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/scm/driver/gitlab/git.go b/scm/driver/gitlab/git.go index e9a1cffef..739621288 100644 --- a/scm/driver/gitlab/git.go +++ b/scm/driver/gitlab/git.go @@ -7,6 +7,8 @@ package gitlab import ( "context" "fmt" + "net/url" + "strings" "time" "github.com/drone/go-scm/scm" @@ -33,6 +35,11 @@ func (s *gitService) FindBranch(ctx context.Context, repo, name string) (*scm.Re } func (s *gitService) FindCommit(ctx context.Context, repo, ref string) (*scm.Commit, *scm.Response, error) { + // if the reference is a branch, ensure forward slashes + // in the branch name are escaped. + if strings.Contains("ref", "/") { + ref = url.PathEscape(ref) + } path := fmt.Sprintf("api/v4/projects/%s/repository/commits/%s", encode(repo), scm.TrimRef(ref)) out := new(commit) res, err := s.client.do(ctx, "GET", path, nil, out) From 99b9843dc4d6ad9a033a3c160f4e143a90637b98 Mon Sep 17 00:00:00 2001 From: TP Honey Date: Tue, 26 Jul 2022 11:00:18 +0100 Subject: [PATCH 022/195] (maint) fixing naming and add more go best practice --- .drone.yml | 33 ++++- .golangci.yml | 130 ++++++++++++++++++ .../{testSettings.go => integration.go} | 0 .../{testSettings.go => integration.go} | 0 4 files changed, 159 insertions(+), 4 deletions(-) create mode 100644 .golangci.yml rename scm/driver/azure/integration/{testSettings.go => integration.go} (100%) rename scm/driver/stash/integration/{testSettings.go => integration.go} (100%) diff --git a/.drone.yml b/.drone.yml index 6636d8200..2c3b73492 100644 --- a/.drone.yml +++ b/.drone.yml @@ -1,11 +1,10 @@ --- kind: pipeline -type: docker +type: vm name: default -platform: - os: linux - arch: amd64 +pool: + use: ubuntu steps: - name: vet @@ -15,6 +14,8 @@ steps: volumes: - name: gopath path: /go + depends_on: + - clone - name: test image: golang:1.15 @@ -23,6 +24,30 @@ steps: volumes: - name: gopath path: /go + depends_on: + - vet + +- name: check go.mod is up to date + image: golang:1.15 + commands: + - cp go.mod go.mod.bak + - go mod tidy + - diff go.mod go.mod.bak || (echo "go.mod is not up to date" && exit 1) + volumes: + - name: gopath + path: /go + depends_on: + - vet + +- name: golangci-lint + image: golangci/golangci-lint + commands: + - golangci-lint run --timeout 500s --new-from-rev=HEAD~ + volumes: + - name: gopath + path: /go + depends_on: + - clone volumes: - name: gopath diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 000000000..1ca20e4a8 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,130 @@ +linters-settings: + dupl: + threshold: 100 + funlen: + lines: 400 + statements: 100 + gci: + local-prefixes: github.com/golangci/golangci-lint + goconst: + min-len: 3 + min-occurrences: 3 + gocritic: + enabled-tags: + - diagnostic + - experimental + - opinionated + - performance + - style + disabled-checks: + - dupImport # https://github.com/go-critic/go-critic/issues/845 + - ifElseChain + - octalLiteral + - whyNoLint + - wrapperFunc + gocyclo: + min-complexity: 25 + goimports: + local-prefixes: github.com/golangci/golangci-lint + gomnd: + settings: + mnd: + # don't include the "operation" and "assign" + checks: argument,case,condition,return + govet: + check-shadowing: true + settings: + printf: + funcs: + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf + lll: + line-length: 200 + maligned: + suggest-new: true + misspell: + locale: US + nolintlint: + allow-leading-space: true # don't require machine-readable nolint directives (i.e. with no leading space) + allow-unused: false # report any unused nolint directives + require-explanation: false # don't require an explanation for nolint directives + require-specific: false # don't require nolint directives to be specific about which linter is being skipped + nakedret: + max-func-lines: 100 + +linters: + # please, do not use `enable-all`: it's deprecated and will be removed soon. + # inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint + disable-all: true + enable: + - bodyclose + - deadcode + - depguard + - dogsled + - errcheck + - exportloopref + - exhaustive + - funlen + - gochecknoinits + - goconst + - gocritic + - gocyclo + - gofmt + - goimports + - gomnd + - goprintffuncname + - gosec + - gosimple + - govet + - ineffassign + - lll + - misspell + - nakedret + - noctx + - nolintlint + - revive + - rowserrcheck + - staticcheck + - structcheck + - stylecheck + - typecheck + - unconvert + - unparam + - unused + - varcheck + - whitespace + + # don't enable: + # - asciicheck + # - dupl + # - scopelint + # - gochecknoglobals + # - gocognit + # - godot + # - godox + # - goerr113 + # - interfacer + # - maligned + # - nestif + # - prealloc + # - testpackage + # - revive + # - wsl + +issues: + # Excluding configuration per-path, per-linter, per-text and per-source + exclude-rules: + - path: _test\.go + linters: + - gomnd + + # https://github.com/go-critic/go-critic/issues/926 + - linters: + - gocritic + text: "unnecessaryDefer:" + +run: + skip-files: + - _gen\.go diff --git a/scm/driver/azure/integration/testSettings.go b/scm/driver/azure/integration/integration.go similarity index 100% rename from scm/driver/azure/integration/testSettings.go rename to scm/driver/azure/integration/integration.go diff --git a/scm/driver/stash/integration/testSettings.go b/scm/driver/stash/integration/integration.go similarity index 100% rename from scm/driver/stash/integration/testSettings.go rename to scm/driver/stash/integration/integration.go From 6024f33534850c0a9c6f03a90d8d8139aa18f480 Mon Sep 17 00:00:00 2001 From: Bhavya Agrawal Date: Thu, 4 Aug 2022 19:44:57 +0530 Subject: [PATCH 023/195] [PL-26239]: added api to list installation for github app --- scm/driver/github/repo.go | 8 ++++++++ scm/driver/github/repo_test.go | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/scm/driver/github/repo.go b/scm/driver/github/repo.go index f5a9c5140..9a38e9071 100644 --- a/scm/driver/github/repo.go +++ b/scm/driver/github/repo.go @@ -105,6 +105,14 @@ func (s *RepositoryService) List(ctx context.Context, opts scm.ListOptions) ([]* return convertRepositoryList(out), res, err } +// List returns the githubapp installation list. +func (s *RepositoryService) ListAppInstallations(ctx context.Context, opts scm.ListOptions) ([]*scm.Repository, *scm.Response, error) { + path := fmt.Sprintf("installation/repositories?%s", encodeListOptions(opts)) + out := []*repository{} + res, err := s.client.do(ctx, "GET", path, nil, &out) + return convertRepositoryList(out), res, err +} + // ListHooks returns a list or repository hooks. func (s *RepositoryService) ListHooks(ctx context.Context, repo string, opts scm.ListOptions) ([]*scm.Hook, *scm.Response, error) { path := fmt.Sprintf("repos/%s/hooks?%s", repo, encodeListOptions(opts)) diff --git a/scm/driver/github/repo_test.go b/scm/driver/github/repo_test.go index caa93b45f..0131e89f9 100644 --- a/scm/driver/github/repo_test.go +++ b/scm/driver/github/repo_test.go @@ -131,6 +131,40 @@ func TestRepositoryList(t *testing.T) { t.Run("Page", testPage(res)) } +func TestGithubAppInstallationList(t *testing.T) { + defer gock.Off() + + gock.New("https://api.github.com"). + Get("/installation/repositories"). + MatchParam("page", "1"). + MatchParam("per_page", "30"). + Reply(200). + Type("application/json"). + SetHeaders(mockHeaders). + SetHeaders(mockPageHeaders). + File("testdata/repos.json") + + client := NewDefault() + got, res, err := client.Repositories.(*RepositoryService).ListAppInstallations(context.Background(), scm.ListOptions{Page: 1, Size: 30}) + if err != nil { + t.Error(err) + return + } + + want := []*scm.Repository{} + raw, _ := ioutil.ReadFile("testdata/repos.json.golden") + _ = json.Unmarshal(raw, &want) + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } + + t.Run("Request", testRequest(res)) + t.Run("Rate", testRate(res)) + t.Run("Page", testPage(res)) +} + func TestStatusList(t *testing.T) { defer gock.Off() From f481597b5e2a727112c912b58c94bf4e70801aa8 Mon Sep 17 00:00:00 2001 From: Brad Rydzewski Date: Sun, 7 Aug 2022 13:00:21 -0400 Subject: [PATCH 024/195] adopt golangci config from Rancher project --- .golangci.json | 51 +++++++++++++++++++ .golangci.yml | 130 ------------------------------------------------- 2 files changed, 51 insertions(+), 130 deletions(-) create mode 100644 .golangci.json delete mode 100644 .golangci.yml diff --git a/.golangci.json b/.golangci.json new file mode 100644 index 000000000..dc836dacc --- /dev/null +++ b/.golangci.json @@ -0,0 +1,51 @@ +{ + "linters": { + "disable-all": true, + "enable": [ + "govet", + "revive", + "goimports", + "misspell", + "ineffassign", + "gofmt" + ] + }, + "linters-settings": { + "govet": { + "check-shadowing": false + }, + "gofmt": { + "simplify": false + } + }, + "run": { + "skip-dirs": [ + "vendor", + "tests", + "pkg/client", + "pkg/generated" + ], + "tests": false, + "timeout": "10m" + }, + "issues": { + "exclude-rules": [ + { + "linters": "govet", + "text": "^(nilness|structtag)" + }, + { + "linters": "revive", + "text": "should have comment" + }, + { + "linters": "revive", + "text": "should be of the form" + }, + { + "linters": "typecheck", + "text": "imported but not used as apierrors" + } + ] + } +} diff --git a/.golangci.yml b/.golangci.yml deleted file mode 100644 index 1ca20e4a8..000000000 --- a/.golangci.yml +++ /dev/null @@ -1,130 +0,0 @@ -linters-settings: - dupl: - threshold: 100 - funlen: - lines: 400 - statements: 100 - gci: - local-prefixes: github.com/golangci/golangci-lint - goconst: - min-len: 3 - min-occurrences: 3 - gocritic: - enabled-tags: - - diagnostic - - experimental - - opinionated - - performance - - style - disabled-checks: - - dupImport # https://github.com/go-critic/go-critic/issues/845 - - ifElseChain - - octalLiteral - - whyNoLint - - wrapperFunc - gocyclo: - min-complexity: 25 - goimports: - local-prefixes: github.com/golangci/golangci-lint - gomnd: - settings: - mnd: - # don't include the "operation" and "assign" - checks: argument,case,condition,return - govet: - check-shadowing: true - settings: - printf: - funcs: - - (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof - - (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf - - (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf - - (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf - lll: - line-length: 200 - maligned: - suggest-new: true - misspell: - locale: US - nolintlint: - allow-leading-space: true # don't require machine-readable nolint directives (i.e. with no leading space) - allow-unused: false # report any unused nolint directives - require-explanation: false # don't require an explanation for nolint directives - require-specific: false # don't require nolint directives to be specific about which linter is being skipped - nakedret: - max-func-lines: 100 - -linters: - # please, do not use `enable-all`: it's deprecated and will be removed soon. - # inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint - disable-all: true - enable: - - bodyclose - - deadcode - - depguard - - dogsled - - errcheck - - exportloopref - - exhaustive - - funlen - - gochecknoinits - - goconst - - gocritic - - gocyclo - - gofmt - - goimports - - gomnd - - goprintffuncname - - gosec - - gosimple - - govet - - ineffassign - - lll - - misspell - - nakedret - - noctx - - nolintlint - - revive - - rowserrcheck - - staticcheck - - structcheck - - stylecheck - - typecheck - - unconvert - - unparam - - unused - - varcheck - - whitespace - - # don't enable: - # - asciicheck - # - dupl - # - scopelint - # - gochecknoglobals - # - gocognit - # - godot - # - godox - # - goerr113 - # - interfacer - # - maligned - # - nestif - # - prealloc - # - testpackage - # - revive - # - wsl - -issues: - # Excluding configuration per-path, per-linter, per-text and per-source - exclude-rules: - - path: _test\.go - linters: - - gomnd - - # https://github.com/go-critic/go-critic/issues/926 - - linters: - - gocritic - text: "unnecessaryDefer:" - -run: - skip-files: - - _gen\.go From b9de5f548dc9d9d644f6bd9dc8fb279859150355 Mon Sep 17 00:00:00 2001 From: Brad Rydzewski Date: Sun, 7 Aug 2022 13:06:30 -0400 Subject: [PATCH 025/195] pin golangci version to use image from docker cache --- .drone.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.drone.yml b/.drone.yml index 2c3b73492..74ace6a27 100644 --- a/.drone.yml +++ b/.drone.yml @@ -40,7 +40,7 @@ steps: - vet - name: golangci-lint - image: golangci/golangci-lint + image: golangci/golangci-lint:v1.48-alpine commands: - golangci-lint run --timeout 500s --new-from-rev=HEAD~ volumes: From 3edbe5560fdc172e093e6214196ee37ce516152d Mon Sep 17 00:00:00 2001 From: Brad Rydzewski Date: Sun, 7 Aug 2022 13:12:09 -0400 Subject: [PATCH 026/195] upate function to match convention List[By] where By is singular --- scm/driver/github/repo.go | 4 ++-- scm/driver/github/repo_test.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scm/driver/github/repo.go b/scm/driver/github/repo.go index 9a38e9071..965b91253 100644 --- a/scm/driver/github/repo.go +++ b/scm/driver/github/repo.go @@ -105,8 +105,8 @@ func (s *RepositoryService) List(ctx context.Context, opts scm.ListOptions) ([]* return convertRepositoryList(out), res, err } -// List returns the githubapp installation list. -func (s *RepositoryService) ListAppInstallations(ctx context.Context, opts scm.ListOptions) ([]*scm.Repository, *scm.Response, error) { +// List returns the github app installation repository list. +func (s *RepositoryService) ListInstallation(ctx context.Context, opts scm.ListOptions) ([]*scm.Repository, *scm.Response, error) { path := fmt.Sprintf("installation/repositories?%s", encodeListOptions(opts)) out := []*repository{} res, err := s.client.do(ctx, "GET", path, nil, &out) diff --git a/scm/driver/github/repo_test.go b/scm/driver/github/repo_test.go index 0131e89f9..439a8797f 100644 --- a/scm/driver/github/repo_test.go +++ b/scm/driver/github/repo_test.go @@ -145,7 +145,7 @@ func TestGithubAppInstallationList(t *testing.T) { File("testdata/repos.json") client := NewDefault() - got, res, err := client.Repositories.(*RepositoryService).ListAppInstallations(context.Background(), scm.ListOptions{Page: 1, Size: 30}) + got, res, err := client.Repositories.(*RepositoryService).ListInstallation(context.Background(), scm.ListOptions{Page: 1, Size: 30}) if err != nil { t.Error(err) return From 43b3e0a4fc1adf61ff946c8790cc11451d521871 Mon Sep 17 00:00:00 2001 From: Brad Rydzewski Date: Sun, 7 Aug 2022 23:49:16 -0400 Subject: [PATCH 027/195] update list (by) installation name --- scm/driver/github/repo.go | 2 +- scm/driver/github/repo_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scm/driver/github/repo.go b/scm/driver/github/repo.go index 965b91253..b1cdc7290 100644 --- a/scm/driver/github/repo.go +++ b/scm/driver/github/repo.go @@ -106,7 +106,7 @@ func (s *RepositoryService) List(ctx context.Context, opts scm.ListOptions) ([]* } // List returns the github app installation repository list. -func (s *RepositoryService) ListInstallation(ctx context.Context, opts scm.ListOptions) ([]*scm.Repository, *scm.Response, error) { +func (s *RepositoryService) ListByInstallation(ctx context.Context, opts scm.ListOptions) ([]*scm.Repository, *scm.Response, error) { path := fmt.Sprintf("installation/repositories?%s", encodeListOptions(opts)) out := []*repository{} res, err := s.client.do(ctx, "GET", path, nil, &out) diff --git a/scm/driver/github/repo_test.go b/scm/driver/github/repo_test.go index 439a8797f..67cbec69a 100644 --- a/scm/driver/github/repo_test.go +++ b/scm/driver/github/repo_test.go @@ -145,7 +145,7 @@ func TestGithubAppInstallationList(t *testing.T) { File("testdata/repos.json") client := NewDefault() - got, res, err := client.Repositories.(*RepositoryService).ListInstallation(context.Background(), scm.ListOptions{Page: 1, Size: 30}) + got, res, err := client.Repositories.(*RepositoryService).ListByInstallation(context.Background(), scm.ListOptions{Page: 1, Size: 30}) if err != nil { t.Error(err) return From 09a4fde5917cd635f693534d742ea605fcc5de56 Mon Sep 17 00:00:00 2001 From: Mohit Garg Date: Wed, 17 Aug 2022 21:32:04 +0530 Subject: [PATCH 028/195] Added support for branch in list commits bb onprem API (#215) * added support for branch in list commits bb onprem API --- scm/driver/stash/git.go | 4 +- scm/driver/stash/git_test.go | 1 + scm/driver/stash/integration/git_test.go | 54 ++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/scm/driver/stash/git.go b/scm/driver/stash/git.go index 2c38c4cd4..c3576c1f0 100644 --- a/scm/driver/stash/git.go +++ b/scm/driver/stash/git.go @@ -83,9 +83,9 @@ func (s *gitService) ListCommits(ctx context.Context, repo string, opts scm.Comm namespace, name := scm.Split(repo) var requestPath string if opts.Path != "" { - requestPath = fmt.Sprintf("rest/api/1.0/projects/%s/repos/%s/commits?path=%s", namespace, name, opts.Path) + requestPath = fmt.Sprintf("rest/api/1.0/projects/%s/repos/%s/commits?until=%s&path=%s", namespace, name, opts.Ref, opts.Path) } else { - requestPath = fmt.Sprintf("rest/api/1.0/projects/%s/repos/%s/commits", namespace, name) + requestPath = fmt.Sprintf("rest/api/1.0/projects/%s/repos/%s/commits?until=%s", namespace, name, opts.Ref) } out := new(commits) res, err := s.client.do(ctx, "GET", requestPath, nil, out) diff --git a/scm/driver/stash/git_test.go b/scm/driver/stash/git_test.go index dfa37bfba..bf4d8e990 100644 --- a/scm/driver/stash/git_test.go +++ b/scm/driver/stash/git_test.go @@ -98,6 +98,7 @@ func TestGitListCommits(t *testing.T) { gock.New("http://example.com:7990"). Get("/rest/api/1.0/projects/PRJ/repos/my-repo/commits"). + MatchParam("until", ""). Reply(200). Type("application/json"). File("testdata/commits.json") diff --git a/scm/driver/stash/integration/git_test.go b/scm/driver/stash/integration/git_test.go index bd5933f25..6b4c18b82 100644 --- a/scm/driver/stash/integration/git_test.go +++ b/scm/driver/stash/integration/git_test.go @@ -62,3 +62,57 @@ func TestGetLatestCommitOfBranch(t *testing.T) { } } } + +func TestGetLatestCommitOfNonDefaultBranch(t *testing.T) { + if token == "" { + t.Skip("Skipping, Acceptance test") + } + client, _ = stash.New(endpoint) + client.Client = &http.Client{ + Transport: &transport.BasicAuth{ + Username: username, + Password: token, + }, + } + + commits, response, err := client.Git.ListCommits(context.Background(), repoID, scm.CommitListOptions{Ref: "main", Path: "do-not-touch.txt"}) + + if err != nil { + t.Errorf("GetLatestCommitOfFile got an error %v", err) + } else { + if response.Status != http.StatusOK { + t.Errorf("GetLatestCommitOfFile did not get a 200 back %v", response.Status) + } + + if commits[0].Sha != "76fb1762048a277596d3fa330b3da140cd12d361" { + t.Errorf("Got the commitId %s instead of the top commit of the file", commits[0].Sha) + } + } +} + +func TestGetLatestCommitOfBranchWhenNoRefPassed(t *testing.T) { + if token == "" { + t.Skip("Skipping, Acceptance test") + } + client, _ = stash.New(endpoint) + client.Client = &http.Client{ + Transport: &transport.BasicAuth{ + Username: username, + Password: token, + }, + } + + commits, response, err := client.Git.ListCommits(context.Background(), repoID, scm.CommitListOptions{Path: "README"}) + + if err != nil { + t.Errorf("GetLatestCommitOfFile got an error %v", err) + } else { + if response.Status != http.StatusOK { + t.Errorf("GetLatestCommitOfFile did not get a 200 back %v", response.Status) + } + + if commits[0].Sha != "2cc4dbe084f0d66761318b305c408cb0ea300c9a" { + t.Errorf("Got the commitId %s instead of the top commit of the file", commits[0].Sha) + } + } +} \ No newline at end of file From b83308fa5a3bb9ab72da898661d57cf7b55c9694 Mon Sep 17 00:00:00 2001 From: Brad Rydzewski Date: Tue, 23 Aug 2022 11:49:39 -0400 Subject: [PATCH 029/195] fix naming convention for CreateBranch Input --- scm/driver/azure/git.go | 2 +- scm/driver/azure/git_test.go | 2 +- scm/driver/azure/integration/git_test.go | 2 +- scm/driver/bitbucket/git.go | 2 +- scm/driver/bitbucket/git_test.go | 2 +- scm/driver/gitea/git.go | 2 +- scm/driver/gitee/git.go | 2 +- scm/driver/gitee/git_test.go | 2 +- scm/driver/github/git.go | 2 +- scm/driver/github/git_test.go | 2 +- scm/driver/gitlab/git.go | 2 +- scm/driver/gitlab/git_test.go | 2 +- scm/driver/gogs/git.go | 2 +- scm/driver/stash/git.go | 2 +- scm/driver/stash/git_test.go | 2 +- scm/driver/stash/integration/git_test.go | 4 ++-- scm/git.go | 16 ++++++++++------ 17 files changed, 27 insertions(+), 23 deletions(-) diff --git a/scm/driver/azure/git.go b/scm/driver/azure/git.go index 5aa41b07f..b23a0f7d7 100644 --- a/scm/driver/azure/git.go +++ b/scm/driver/azure/git.go @@ -16,7 +16,7 @@ type gitService struct { client *wrapper } -func (s *gitService) CreateBranch(ctx context.Context, repo string, params *scm.CreateBranch) (*scm.Response, error) { +func (s *gitService) CreateBranch(ctx context.Context, repo string, params *scm.ReferenceInput) (*scm.Response, error) { // https://docs.microsoft.com/en-us/rest/api/azure/devops/git/refs/update-refs?view=azure-devops-rest-6.0 if s.client.project == "" { return nil, ProjectRequiredError() diff --git a/scm/driver/azure/git_test.go b/scm/driver/azure/git_test.go index 0e652eca2..d5faf0ef7 100644 --- a/scm/driver/azure/git_test.go +++ b/scm/driver/azure/git_test.go @@ -53,7 +53,7 @@ func TestGitCreateBranch(t *testing.T) { Type("application/json"). File("testdata/branch_create.json") - params := &scm.CreateBranch{ + params := &scm.ReferenceInput{ Name: "test_branch", Sha: "312797ba52425353dec56871a255e2a36fc96344", } diff --git a/scm/driver/azure/integration/git_test.go b/scm/driver/azure/integration/git_test.go index ce9eefca6..aeb9f41b8 100644 --- a/scm/driver/azure/integration/git_test.go +++ b/scm/driver/azure/integration/git_test.go @@ -54,7 +54,7 @@ func TestCreateBranch(t *testing.T) { if commitErr != nil { t.Errorf("we got an error %v", commitErr) } - input := &scm.CreateBranch{ + input := &scm.ReferenceInput{ Name: "test_branch", Sha: currentCommit, } diff --git a/scm/driver/bitbucket/git.go b/scm/driver/bitbucket/git.go index 03093c5bc..4a2298d59 100644 --- a/scm/driver/bitbucket/git.go +++ b/scm/driver/bitbucket/git.go @@ -16,7 +16,7 @@ type gitService struct { client *wrapper } -func (s *gitService) CreateBranch(ctx context.Context, repo string, params *scm.CreateBranch) (*scm.Response, error) { +func (s *gitService) CreateBranch(ctx context.Context, repo string, params *scm.ReferenceInput) (*scm.Response, error) { path := fmt.Sprintf("2.0/repositories/%s/refs/branches", repo) in := &createBranch{ Name: params.Name, diff --git a/scm/driver/bitbucket/git_test.go b/scm/driver/bitbucket/git_test.go index 7e666772c..ec3b49f43 100644 --- a/scm/driver/bitbucket/git_test.go +++ b/scm/driver/bitbucket/git_test.go @@ -81,7 +81,7 @@ func TestGitCreateBranch(t *testing.T) { Type("application/json"). File("testdata/branch_create.json") - params := &scm.CreateBranch{ + params := &scm.ReferenceInput{ Name: "yooo", Sha: "2e684d13a43afd86cb48ea36d9f40f43e791fae9", } diff --git a/scm/driver/gitea/git.go b/scm/driver/gitea/git.go index 8382b8cad..60de87bec 100644 --- a/scm/driver/gitea/git.go +++ b/scm/driver/gitea/git.go @@ -17,7 +17,7 @@ type gitService struct { client *wrapper } -func (s *gitService) CreateBranch(ctx context.Context, repo string, params *scm.CreateBranch) (*scm.Response, error) { +func (s *gitService) CreateBranch(ctx context.Context, repo string, params *scm.ReferenceInput) (*scm.Response, error) { return nil, scm.ErrNotSupported } diff --git a/scm/driver/gitee/git.go b/scm/driver/gitee/git.go index 6b2933b67..ffbd5c0e2 100644 --- a/scm/driver/gitee/git.go +++ b/scm/driver/gitee/git.go @@ -16,7 +16,7 @@ type gitService struct { client *wrapper } -func (s *gitService) CreateBranch(ctx context.Context, repo string, params *scm.CreateBranch) (*scm.Response, error) { +func (s *gitService) CreateBranch(ctx context.Context, repo string, params *scm.ReferenceInput) (*scm.Response, error) { path := fmt.Sprintf("repos/%s/branches", repo) in := &branchCreate{ Refs: params.Sha, diff --git a/scm/driver/gitee/git_test.go b/scm/driver/gitee/git_test.go index b62cd951c..bdceb7634 100644 --- a/scm/driver/gitee/git_test.go +++ b/scm/driver/gitee/git_test.go @@ -26,7 +26,7 @@ func TestGitCreateBranch(t *testing.T) { SetHeaders(mockHeaders) client := NewDefault() - input := scm.CreateBranch{ + input := scm.ReferenceInput{ Name: "create-by-api", Sha: "b72a4c4a2d838d96a545a42d41d7776ae5566f4a", } diff --git a/scm/driver/github/git.go b/scm/driver/github/git.go index 0ef94db44..5a5829f4d 100644 --- a/scm/driver/github/git.go +++ b/scm/driver/github/git.go @@ -16,7 +16,7 @@ type gitService struct { client *wrapper } -func (s *gitService) CreateBranch(ctx context.Context, repo string, params *scm.CreateBranch) (*scm.Response, error) { +func (s *gitService) CreateBranch(ctx context.Context, repo string, params *scm.ReferenceInput) (*scm.Response, error) { path := fmt.Sprintf("repos/%s/git/refs", repo) in := &createBranch{ Ref: scm.ExpandRef(params.Name, "refs/heads"), diff --git a/scm/driver/github/git_test.go b/scm/driver/github/git_test.go index 65c2562c9..36e18e77f 100644 --- a/scm/driver/github/git_test.go +++ b/scm/driver/github/git_test.go @@ -116,7 +116,7 @@ func TestGitCreateBranch(t *testing.T) { SetHeaders(mockHeaders). File("testdata/branch_create.json") - params := &scm.CreateBranch{ + params := &scm.ReferenceInput{ Name: "Hello", Sha: "312797ba52425353dec56871a255e2a36fc96344", } diff --git a/scm/driver/gitlab/git.go b/scm/driver/gitlab/git.go index 739621288..ebada6c99 100644 --- a/scm/driver/gitlab/git.go +++ b/scm/driver/gitlab/git.go @@ -18,7 +18,7 @@ type gitService struct { client *wrapper } -func (s *gitService) CreateBranch(ctx context.Context, repo string, params *scm.CreateBranch) (*scm.Response, error) { +func (s *gitService) CreateBranch(ctx context.Context, repo string, params *scm.ReferenceInput) (*scm.Response, error) { path := fmt.Sprintf("api/v4/projects/%s/repository/branches", encode(repo)) in := &createBranch{ Branch: params.Name, diff --git a/scm/driver/gitlab/git_test.go b/scm/driver/gitlab/git_test.go index 6315b85b9..32d58f6f2 100644 --- a/scm/driver/gitlab/git_test.go +++ b/scm/driver/gitlab/git_test.go @@ -90,7 +90,7 @@ func TestGitCreateBranch(t *testing.T) { SetHeaders(mockHeaders). File("testdata/branch_create.json") - params := &scm.CreateBranch{ + params := &scm.ReferenceInput{ Name: "yooo", Sha: "0efb1bed7c6a4871cb4ddb862ecc2111e11f31ee", } diff --git a/scm/driver/gogs/git.go b/scm/driver/gogs/git.go index 1ab6dd8a2..aaf6a0616 100644 --- a/scm/driver/gogs/git.go +++ b/scm/driver/gogs/git.go @@ -16,7 +16,7 @@ type gitService struct { client *wrapper } -func (s *gitService) CreateBranch(ctx context.Context, repo string, params *scm.CreateBranch) (*scm.Response, error) { +func (s *gitService) CreateBranch(ctx context.Context, repo string, params *scm.ReferenceInput) (*scm.Response, error) { return nil, scm.ErrNotSupported } diff --git a/scm/driver/stash/git.go b/scm/driver/stash/git.go index c3576c1f0..dece5d940 100644 --- a/scm/driver/stash/git.go +++ b/scm/driver/stash/git.go @@ -19,7 +19,7 @@ type gitService struct { client *wrapper } -func (s *gitService) CreateBranch(ctx context.Context, repo string, params *scm.CreateBranch) (*scm.Response, error) { +func (s *gitService) CreateBranch(ctx context.Context, repo string, params *scm.ReferenceInput) (*scm.Response, error) { namespace, repoName := scm.Split(repo) path := fmt.Sprintf("rest/api/1.0/projects/%s/repos/%s/branches", namespace, repoName) in := &createBranch{ diff --git a/scm/driver/stash/git_test.go b/scm/driver/stash/git_test.go index bf4d8e990..4d92fec4e 100644 --- a/scm/driver/stash/git_test.go +++ b/scm/driver/stash/git_test.go @@ -239,7 +239,7 @@ func TestCreateBranch(t *testing.T) { File("testdata/branch_create.json") client, _ := New("http://example.com:7990") - params := &scm.CreateBranch{ + params := &scm.ReferenceInput{ Name: "Hello", Sha: "312797ba52425353dec56871a255e2a36fc96344", } diff --git a/scm/driver/stash/integration/git_test.go b/scm/driver/stash/integration/git_test.go index 6b4c18b82..6ef33fee7 100644 --- a/scm/driver/stash/integration/git_test.go +++ b/scm/driver/stash/integration/git_test.go @@ -23,7 +23,7 @@ func TestCreateBranch(t *testing.T) { } commitId, _ := GetCurrentCommitOfBranch(client, "master") - input := &scm.CreateBranch{ + input := &scm.ReferenceInput{ Name: "test_branch", Sha: commitId, } @@ -115,4 +115,4 @@ func TestGetLatestCommitOfBranchWhenNoRefPassed(t *testing.T) { t.Errorf("Got the commitId %s instead of the top commit of the file", commits[0].Sha) } } -} \ No newline at end of file +} diff --git a/scm/git.go b/scm/git.go index 07811b1fc..eff476038 100644 --- a/scm/git.go +++ b/scm/git.go @@ -13,16 +13,16 @@ import ( const EmptyCommit = "0000000000000000000000000000000000000000" type ( - // CreateBranch provides a SHA for creating a branch. - CreateBranch struct { + // Reference represents a git reference. + Reference struct { Name string + Path string Sha string } - // Reference represents a git reference. - Reference struct { + // ReferenceInput provides a SHA for creating a reference. + ReferenceInput struct { Name string - Path string Sha string } @@ -59,7 +59,7 @@ type ( // GitService provides access to git resources. GitService interface { // CreateBranch creates a git branch by name given a sha. - CreateBranch(ctx context.Context, repo string, params *CreateBranch) (*Response, error) + CreateBranch(ctx context.Context, repo string, params *ReferenceInput) (*Response, error) // FindBranch finds a git branch by name. FindBranch(ctx context.Context, repo, name string) (*Reference, *Response, error) @@ -88,4 +88,8 @@ type ( // return a 2-way or 3-way diff changeset. CompareChanges(ctx context.Context, repo, source, target string, opts ListOptions) ([]*Change, *Response, error) } + + // CreateBranch is a type alias for upstream projects + // that use the previous CreateBranch type name. + CreateBranch = ReferenceInput ) From f4a311024d4ece31370f2bd1bf90d0248852e57a Mon Sep 17 00:00:00 2001 From: Bhavya Agrawal Date: Fri, 26 Aug 2022 16:12:21 +0530 Subject: [PATCH 030/195] [PL-26239]: fix for list response (#218) * [PL-26239]: fix for list response --- scm/driver/github/repo.go | 11 +- scm/driver/github/repo_test.go | 2 +- .../github/testdata/github_app_repos.json | 115 ++++++++++++++++++ 3 files changed, 124 insertions(+), 4 deletions(-) create mode 100644 scm/driver/github/testdata/github_app_repos.json diff --git a/scm/driver/github/repo.go b/scm/driver/github/repo.go index b1cdc7290..cc781cb92 100644 --- a/scm/driver/github/repo.go +++ b/scm/driver/github/repo.go @@ -53,6 +53,11 @@ type hook struct { } `json:"config"` } +type repositoryList struct { + TotalCount int `json:"total_count"` + Repositories []*repository `json:"repositories"` +} + // RepositoryService implements the repository service for // the GitHub driver. type RepositoryService struct { @@ -108,9 +113,9 @@ func (s *RepositoryService) List(ctx context.Context, opts scm.ListOptions) ([]* // List returns the github app installation repository list. func (s *RepositoryService) ListByInstallation(ctx context.Context, opts scm.ListOptions) ([]*scm.Repository, *scm.Response, error) { path := fmt.Sprintf("installation/repositories?%s", encodeListOptions(opts)) - out := []*repository{} - res, err := s.client.do(ctx, "GET", path, nil, &out) - return convertRepositoryList(out), res, err + out := new(repositoryList) + res, err := s.client.do(ctx, "GET", path, nil, out) + return convertRepositoryList(out.Repositories), res, err } // ListHooks returns a list or repository hooks. diff --git a/scm/driver/github/repo_test.go b/scm/driver/github/repo_test.go index 67cbec69a..cd1d7f8b3 100644 --- a/scm/driver/github/repo_test.go +++ b/scm/driver/github/repo_test.go @@ -142,7 +142,7 @@ func TestGithubAppInstallationList(t *testing.T) { Type("application/json"). SetHeaders(mockHeaders). SetHeaders(mockPageHeaders). - File("testdata/repos.json") + File("testdata/github_app_repos.json") client := NewDefault() got, res, err := client.Repositories.(*RepositoryService).ListByInstallation(context.Background(), scm.ListOptions{Page: 1, Size: 30}) diff --git a/scm/driver/github/testdata/github_app_repos.json b/scm/driver/github/testdata/github_app_repos.json new file mode 100644 index 000000000..2526a4000 --- /dev/null +++ b/scm/driver/github/testdata/github_app_repos.json @@ -0,0 +1,115 @@ +{ + "total_count": 1, + "repositories": [ + { + "id": 1296269, + "owner": { + "login": "octocat", + "id": 1, + "avatar_url": "https://github.com/images/error/octocat_happy.gif", + "gravatar_id": "", + "url": "https://api.github.com/users/octocat", + "html_url": "https://github.com/octocat", + "followers_url": "https://api.github.com/users/octocat/followers", + "following_url": "https://api.github.com/users/octocat/following{/other_user}", + "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", + "organizations_url": "https://api.github.com/users/octocat/orgs", + "repos_url": "https://api.github.com/users/octocat/repos", + "events_url": "https://api.github.com/users/octocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/octocat/received_events", + "type": "User", + "site_admin": false + }, + "name": "Hello-World", + "full_name": "octocat/Hello-World", + "description": "This your first repo!", + "private": true, + "fork": true, + "visibility": "public", + "url": "https://api.github.com/repos/octocat/Hello-World", + "html_url": "https://github.com/octocat/Hello-World", + "archive_url": "http://api.github.com/repos/octocat/Hello-World/{archive_format}{/ref}", + "assignees_url": "http://api.github.com/repos/octocat/Hello-World/assignees{/user}", + "blobs_url": "http://api.github.com/repos/octocat/Hello-World/git/blobs{/sha}", + "branches_url": "http://api.github.com/repos/octocat/Hello-World/branches{/branch}", + "clone_url": "https://github.com/octocat/Hello-World.git", + "collaborators_url": "http://api.github.com/repos/octocat/Hello-World/collaborators{/collaborator}", + "comments_url": "http://api.github.com/repos/octocat/Hello-World/comments{/number}", + "commits_url": "http://api.github.com/repos/octocat/Hello-World/commits{/sha}", + "compare_url": "http://api.github.com/repos/octocat/Hello-World/compare/{base}...{head}", + "contents_url": "http://api.github.com/repos/octocat/Hello-World/contents/{+path}", + "contributors_url": "http://api.github.com/repos/octocat/Hello-World/contributors", + "deployments_url": "http://api.github.com/repos/octocat/Hello-World/deployments", + "downloads_url": "http://api.github.com/repos/octocat/Hello-World/downloads", + "events_url": "http://api.github.com/repos/octocat/Hello-World/events", + "forks_url": "http://api.github.com/repos/octocat/Hello-World/forks", + "git_commits_url": "http://api.github.com/repos/octocat/Hello-World/git/commits{/sha}", + "git_refs_url": "http://api.github.com/repos/octocat/Hello-World/git/refs{/sha}", + "git_tags_url": "http://api.github.com/repos/octocat/Hello-World/git/tags{/sha}", + "git_url": "git:github.com/octocat/Hello-World.git", + "hooks_url": "http://api.github.com/repos/octocat/Hello-World/hooks", + "issue_comment_url": "http://api.github.com/repos/octocat/Hello-World/issues/comments{/number}", + "issue_events_url": "http://api.github.com/repos/octocat/Hello-World/issues/events{/number}", + "issues_url": "http://api.github.com/repos/octocat/Hello-World/issues{/number}", + "keys_url": "http://api.github.com/repos/octocat/Hello-World/keys{/key_id}", + "labels_url": "http://api.github.com/repos/octocat/Hello-World/labels{/name}", + "languages_url": "http://api.github.com/repos/octocat/Hello-World/languages", + "merges_url": "http://api.github.com/repos/octocat/Hello-World/merges", + "milestones_url": "http://api.github.com/repos/octocat/Hello-World/milestones{/number}", + "mirror_url": "git:git.example.com/octocat/Hello-World", + "notifications_url": "http://api.github.com/repos/octocat/Hello-World/notifications{?since, all, participating}", + "pulls_url": "http://api.github.com/repos/octocat/Hello-World/pulls{/number}", + "releases_url": "http://api.github.com/repos/octocat/Hello-World/releases{/id}", + "ssh_url": "git@github.com:octocat/Hello-World.git", + "stargazers_url": "http://api.github.com/repos/octocat/Hello-World/stargazers", + "statuses_url": "http://api.github.com/repos/octocat/Hello-World/statuses/{sha}", + "subscribers_url": "http://api.github.com/repos/octocat/Hello-World/subscribers", + "subscription_url": "http://api.github.com/repos/octocat/Hello-World/subscription", + "svn_url": "https://svn.github.com/octocat/Hello-World", + "tags_url": "http://api.github.com/repos/octocat/Hello-World/tags", + "teams_url": "http://api.github.com/repos/octocat/Hello-World/teams", + "trees_url": "http://api.github.com/repos/octocat/Hello-World/git/trees{/sha}", + "homepage": "https://github.com", + "language": null, + "forks_count": 9, + "stargazers_count": 80, + "watchers_count": 80, + "size": 108, + "default_branch": "master", + "open_issues_count": 0, + "topics": [ + "octocat", + "atom", + "electron", + "API" + ], + "has_issues": true, + "has_wiki": true, + "has_pages": false, + "has_downloads": true, + "archived": false, + "pushed_at": "2011-01-26T19:06:43Z", + "created_at": "2011-01-26T19:01:12Z", + "updated_at": "2011-01-26T19:14:43Z", + "permissions": { + "admin": true, + "push": true, + "pull": true + }, + "allow_rebase_merge": true, + "allow_squash_merge": true, + "allow_merge_commit": true, + "subscribers_count": 42, + "network_count": 0, + "license": { + "key": "mit", + "name": "MIT License", + "spdx_id": "MIT", + "url": "https://api.github.com/licenses/mit", + "html_url": "http://choosealicense.com/licenses/mit/" + } + } + ] +} \ No newline at end of file From c43e9f0b54ad9b669a7b36283efc9a53dcd35767 Mon Sep 17 00:00:00 2001 From: Raghav Date: Mon, 5 Sep 2022 15:59:42 +0530 Subject: [PATCH 031/195] added date info for commits in push hook (#223) * added date info for commits in push hook --- .../testdata/webhooks/branch_create.json | 2 +- .../webhooks/branch_create.json.golden | 4 +- scm/driver/gitlab/testdata/webhooks/push.json | 2 +- .../gitlab/testdata/webhooks/push.json.golden | 4 +- .../gitlab/testdata/webhooks/tag_create.json | 2 +- .../testdata/webhooks/tag_create.json.golden | 4 +- scm/driver/gitlab/webhook.go | 52 ++++++++++--------- 7 files changed, 36 insertions(+), 34 deletions(-) diff --git a/scm/driver/gitlab/testdata/webhooks/branch_create.json b/scm/driver/gitlab/testdata/webhooks/branch_create.json index 9abeda061..9c99d83b2 100644 --- a/scm/driver/gitlab/testdata/webhooks/branch_create.json +++ b/scm/driver/gitlab/testdata/webhooks/branch_create.json @@ -34,7 +34,7 @@ { "id": "c4c79227ed610f1151f05bbc5be33b4f340d39c8", "message": "update readme\n", - "timestamp": "2017-12-10T08:28:36-08:00", + "timestamp": "2017-12-10T08:28:36+00:00", "url": "https://gitlab.com/gitlab-org/hello-world/commit/c4c79227ed610f1151f05bbc5be33b4f340d39c8", "author": { "name": "Sid Sijbrandij", diff --git a/scm/driver/gitlab/testdata/webhooks/branch_create.json.golden b/scm/driver/gitlab/testdata/webhooks/branch_create.json.golden index 010c28001..1a618b2a9 100644 --- a/scm/driver/gitlab/testdata/webhooks/branch_create.json.golden +++ b/scm/driver/gitlab/testdata/webhooks/branch_create.json.golden @@ -41,14 +41,14 @@ "Author": { "Name": "Sid Sijbrandij", "Email": "noreply@gitlab.com", - "Date": "0001-01-01T00:00:00Z", + "Date": "2017-12-10T08:28:36Z", "Login": "", "Avatar": "" }, "Committer": { "Name": "Sid Sijbrandij", "Email": "noreply@gitlab.com", - "Date": "0001-01-01T00:00:00Z", + "Date": "2017-12-10T08:28:36Z", "Login": "", "Avatar": "" }, diff --git a/scm/driver/gitlab/testdata/webhooks/push.json b/scm/driver/gitlab/testdata/webhooks/push.json index dde1a9a84..40801e1d4 100644 --- a/scm/driver/gitlab/testdata/webhooks/push.json +++ b/scm/driver/gitlab/testdata/webhooks/push.json @@ -34,7 +34,7 @@ { "id": "2adc9465c4edfc33834e173fe89436a7cb899a1d", "message": "added readme\n", - "timestamp": "2017-12-10T08:26:38-08:00", + "timestamp": "2017-12-10T08:26:38+00:00", "url": "https://gitlab.com/gitlab-org/hello-world/commit/2adc9465c4edfc33834e173fe89436a7cb899a1d", "author": { "name": "Sid Sijbrandij", diff --git a/scm/driver/gitlab/testdata/webhooks/push.json.golden b/scm/driver/gitlab/testdata/webhooks/push.json.golden index 2b6863cbb..8c8bbf9e8 100644 --- a/scm/driver/gitlab/testdata/webhooks/push.json.golden +++ b/scm/driver/gitlab/testdata/webhooks/push.json.golden @@ -41,14 +41,14 @@ "Author": { "Name": "Sid Sijbrandij", "Email": "noreply@gitlab.com", - "Date": "0001-01-01T00:00:00Z", + "Date": "2017-12-10T08:26:38Z", "Login": "", "Avatar": "" }, "Committer": { "Name": "Sid Sijbrandij", "Email": "noreply@gitlab.com", - "Date": "0001-01-01T00:00:00Z", + "Date": "2017-12-10T08:26:38Z", "Login": "", "Avatar": "" }, diff --git a/scm/driver/gitlab/testdata/webhooks/tag_create.json b/scm/driver/gitlab/testdata/webhooks/tag_create.json index f28bdc160..4544eec7c 100644 --- a/scm/driver/gitlab/testdata/webhooks/tag_create.json +++ b/scm/driver/gitlab/testdata/webhooks/tag_create.json @@ -34,7 +34,7 @@ { "id": "2adc9465c4edfc33834e173fe89436a7cb899a1d", "message": "added readme\n", - "timestamp": "2017-12-10T08:26:38-08:00", + "timestamp": "2017-12-10T08:26:38+00:00", "url": "https://gitlab.com/gitlab-org/hello-world/commit/2adc9465c4edfc33834e173fe89436a7cb899a1d", "author": { "name": "Sid Sijbrandij", diff --git a/scm/driver/gitlab/testdata/webhooks/tag_create.json.golden b/scm/driver/gitlab/testdata/webhooks/tag_create.json.golden index b96828528..963085c35 100644 --- a/scm/driver/gitlab/testdata/webhooks/tag_create.json.golden +++ b/scm/driver/gitlab/testdata/webhooks/tag_create.json.golden @@ -41,14 +41,14 @@ "Author": { "Name": "Sid Sijbrandij", "Email": "noreply@gitlab.com", - "Date": "0001-01-01T00:00:00Z", + "Date": "2017-12-10T08:26:38Z", "Login": "", "Avatar": "" }, "Committer": { "Name": "Sid Sijbrandij", "Email": "noreply@gitlab.com", - "Date": "0001-01-01T00:00:00Z", + "Date": "2017-12-10T08:26:38Z", "Login": "", "Avatar": "" }, diff --git a/scm/driver/gitlab/webhook.go b/scm/driver/gitlab/webhook.go index b50f8d904..b0a519739 100644 --- a/scm/driver/gitlab/webhook.go +++ b/scm/driver/gitlab/webhook.go @@ -14,6 +14,7 @@ import ( "time" "github.com/drone/go-scm/scm" + "github.com/drone/go-scm/scm/driver/internal/null" ) type webhookService struct { @@ -130,10 +131,12 @@ func convertPushHook(src *pushHook) *scm.PushHook { Author: scm.Signature{ Name: c.Author.Name, Email: c.Author.Email, + Date: c.Timestamp.ValueOrZero(), }, Committer: scm.Signature{ Name: c.Author.Name, Email: c.Author.Email, + Date: c.Timestamp.ValueOrZero(), }, }) } @@ -219,8 +222,8 @@ func converBranchHook(src *pushHook) *scm.BranchHook { } func convertCommentHook(src *commentHook) (*scm.IssueCommentHook, error) { - var issue scm.Issue - var comment scm.Comment + var issue scm.Issue + var comment scm.Comment switch src.ObjectAttributes.NoteableType { case "Commit", "Issue", "Snippet": @@ -242,7 +245,7 @@ func convertCommentHook(src *commentHook) (*scm.IssueCommentHook, error) { Updated: parseTimeString(src.MergeRequest.UpdatedAt), } for _, l := range src.MergeRequest.Labels { - label := scm.Label { + label := scm.Label{ Name: l.Title, Color: l.Color, } @@ -271,16 +274,16 @@ func convertCommentHook(src *commentHook) (*scm.IssueCommentHook, error) { namespace, _ := scm.Split(src.Project.PathWithNamespace) dst := scm.IssueCommentHook{ - Action: scm.ActionCreate, - Repo: scm.Repository{ - ID: strconv.Itoa(src.Project.ID), - Namespace: namespace, - Name: src.Repository.Name, - Clone: src.Project.GitHTTPURL, - CloneSSH: src.Project.GitSSHURL, - Link: src.Project.WebURL, - Branch: src.Project.DefaultBranch, - Private: false, // TODO how do we correctly set Private vs Public? + Action: scm.ActionCreate, + Repo: scm.Repository{ + ID: strconv.Itoa(src.Project.ID), + Namespace: namespace, + Name: src.Repository.Name, + Clone: src.Project.GitHTTPURL, + CloneSSH: src.Project.GitSSHURL, + Link: src.Project.WebURL, + Branch: src.Project.DefaultBranch, + Private: false, // TODO how do we correctly set Private vs Public? }, Issue: issue, Comment: comment, @@ -383,7 +386,7 @@ func convertPullRequestHook(src *pullRequestHook) *scm.PullRequestHook { } } -func parseTimeString(timeString string) (time.Time) { +func parseTimeString(timeString string) time.Time { layout := "2006-01-02 15:04:05 UTC" // Returns zero value of time in case of an error 0001-01-01 00:00:00 +0000 UTC t, _ := time.Parse(layout, timeString) @@ -424,10 +427,10 @@ type ( HTTPURL string `json:"http_url"` } `json:"project"` Commits []struct { - ID string `json:"id"` - Message string `json:"message"` - Timestamp string `json:"timestamp"` - URL string `json:"url"` + ID string `json:"id"` + Message string `json:"message"` + Timestamp null.Time `json:"timestamp"` + URL string `json:"url"` Author struct { Name string `json:"name"` Email string `json:"email"` @@ -471,7 +474,7 @@ type ( SSHURL string `json:"ssh_url"` HTTPURL string `json:"http_url"` } `json:"project"` - ObjectAttributes struct { + ObjectAttributes struct { ID int `json:"id"` Note string `json:"note"` NoteableType string `json:"noteable_type"` @@ -496,13 +499,13 @@ type ( Type interface{} `json:"type"` Description string `json:"description"` } `json:"object_attributes"` - Repository struct { + Repository struct { Name string `json:"name"` URL string `json:"url"` Description string `json:"description"` Homepage string `json:"homepage"` } `json:"repository"` - MergeRequest struct { + MergeRequest struct { AssigneeID interface{} `json:"assignee_id"` AuthorID int `json:"author_id"` CreatedAt string `json:"created_at"` @@ -558,7 +561,7 @@ type ( SSHURL string `json:"ssh_url"` HTTPURL string `json:"http_url"` } `json:"source"` - Target struct { + Target struct { ID int `json:"id"` Name string `json:"name"` Description string `json:"description"` @@ -576,7 +579,7 @@ type ( SSHURL string `json:"ssh_url"` HTTPURL string `json:"http_url"` } `json:"target"` - LastCommit struct { + LastCommit struct { ID string `json:"id"` Message string `json:"message"` Timestamp string `json:"timestamp"` @@ -586,7 +589,7 @@ type ( Email string `json:"email"` } `json:"author"` } `json:"last_commit"` - Labels []struct { + Labels []struct { ID int `json:"id"` Title string `json:"title"` Color string `json:"color"` @@ -598,7 +601,6 @@ type ( Type string `json:"type"` GroupID interface{} `json:"group_id"` } `json:"labels"` - } `json:"merge_request"` } From 531cb95bd122b8e23b4e43e99e3399bbeb53a612 Mon Sep 17 00:00:00 2001 From: Raghav Date: Mon, 5 Sep 2022 16:01:06 +0530 Subject: [PATCH 032/195] added omitempty annotation for secret (#221) --- scm/driver/stash/repo.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm/driver/stash/repo.go b/scm/driver/stash/repo.go index c44fd661f..70f4c01de 100644 --- a/scm/driver/stash/repo.go +++ b/scm/driver/stash/repo.go @@ -81,7 +81,7 @@ type hookInput struct { URL string `json:"url"` Active bool `json:"active"` Config struct { - Secret string `json:"secret"` + Secret string `json:"secret,omitempty"` } `json:"configuration"` } From 7ee0aa5806a55868aeb7573f1de4478b1e15ee1f Mon Sep 17 00:00:00 2001 From: Raghav Date: Thu, 8 Sep 2022 14:35:41 +0530 Subject: [PATCH 033/195] decoding projectName for azure repo (#224) --- scm/driver/azure/repo.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scm/driver/azure/repo.go b/scm/driver/azure/repo.go index f46ede285..5d0427fa4 100644 --- a/scm/driver/azure/repo.go +++ b/scm/driver/azure/repo.go @@ -7,6 +7,7 @@ package azure import ( "context" "fmt" + "net/url" "github.com/drone/go-scm/scm" ) @@ -146,6 +147,11 @@ func (s *RepositoryService) DeleteHook(ctx context.Context, repo, id string) (*s // helper function to return the projectID from the project name func (s *RepositoryService) getProjectIDFromProjectName(ctx context.Context, projectName string) (string, error) { // https://docs.microsoft.com/en-us/rest/api/azure/devops/core/projects/list?view=azure-devops-rest-6.0 + projectName, err := url.PathUnescape(projectName) + if err != nil { + return "", fmt.Errorf("unable to unscape project: %s", projectName) + } + endpoint := fmt.Sprintf("%s/_apis/projects?api-version=6.0", s.client.owner) type projects struct { Count int64 `json:"count"` From 32e680098bb1e96ae0d2a5d05378bc54db37d575 Mon Sep 17 00:00:00 2001 From: raghavharness Date: Tue, 13 Sep 2022 17:27:33 +0530 Subject: [PATCH 034/195] use merge commit sha if pull request is merged for bitbucket --- scm/driver/bitbucket/pr.go | 11 ++++++++++- .../testdata/webhooks/pr_fulfilled.json.golden | 2 +- scm/driver/bitbucket/webhook.go | 7 ++++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/scm/driver/bitbucket/pr.go b/scm/driver/bitbucket/pr.go index 20dc31441..033860f85 100644 --- a/scm/driver/bitbucket/pr.go +++ b/scm/driver/bitbucket/pr.go @@ -108,6 +108,10 @@ type pr struct { HTML string `json:"html"` Type string `json:"type"` } `json:"summary"` + MergeCommit struct { + Type string `json:"type"` + Hash string `json:"hash"` + } `json:"merge_commit"` Source reference `json:"source"` State string `json:"state"` Author user `json:"author"` @@ -144,11 +148,16 @@ func convertPullRequests(from *prs) []*scm.PullRequest { } func convertPullRequest(from *pr) *scm.PullRequest { + sha := from.Source.Commit.Hash + // if pr is merged, use the merge commit + if from.MergeCommit.Hash != "" { + sha = from.MergeCommit.Hash + } return &scm.PullRequest{ Number: from.ID, Title: from.Title, Body: from.Description, - Sha: from.Source.Commit.Hash, + Sha: sha, Source: from.Source.Branch.Name, Target: from.Destination.Branch.Name, Fork: from.Source.Repository.FullName, diff --git a/scm/driver/bitbucket/testdata/webhooks/pr_fulfilled.json.golden b/scm/driver/bitbucket/testdata/webhooks/pr_fulfilled.json.golden index 1cc60a2f0..6b03b80fd 100644 --- a/scm/driver/bitbucket/testdata/webhooks/pr_fulfilled.json.golden +++ b/scm/driver/bitbucket/testdata/webhooks/pr_fulfilled.json.golden @@ -17,7 +17,7 @@ "Number": 1, "Title": "Awesome new feature", "Body": "made some changes", - "Sha": "0704fc5beccc", + "Sha": "4f8f6de9d0ff", "Ref": "refs/pull-requests/1/from", "Source": "develop", "Target": "master", diff --git a/scm/driver/bitbucket/webhook.go b/scm/driver/bitbucket/webhook.go index c567e565f..51f2c3f48 100644 --- a/scm/driver/bitbucket/webhook.go +++ b/scm/driver/bitbucket/webhook.go @@ -782,6 +782,11 @@ func convertTagDeleteHook(src *pushHook) *scm.TagHook { // func convertPullRequestHook(src *webhook) *scm.PullRequestHook { + sha := src.PullRequest.Source.Commit.Hash + // if pr is merged, use the merge commit + if src.PullRequest.MergeCommit.Hash != "" { + sha = src.PullRequest.MergeCommit.Hash + } namespace, name := scm.Split(src.Repository.FullName) return &scm.PullRequestHook{ Action: scm.ActionOpen, @@ -789,7 +794,7 @@ func convertPullRequestHook(src *webhook) *scm.PullRequestHook { Number: src.PullRequest.ID, Title: src.PullRequest.Title, Body: src.PullRequest.Description, - Sha: src.PullRequest.Source.Commit.Hash, + Sha: sha, Ref: fmt.Sprintf("refs/pull-requests/%d/from", src.PullRequest.ID), Source: src.PullRequest.Source.Branch.Name, Target: src.PullRequest.Destination.Branch.Name, From cfb5ca9937b25722f9a35832b66e463731a6f66d Mon Sep 17 00:00:00 2001 From: raghavharness Date: Wed, 14 Sep 2022 13:42:38 +0530 Subject: [PATCH 035/195] changes for stash --- scm/driver/stash/pr.go | 14 +++++++++++++- .../stash/testdata/webhooks/pr_merged.json.golden | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/scm/driver/stash/pr.go b/scm/driver/stash/pr.go index 836c5392b..e7607b859 100644 --- a/scm/driver/stash/pr.go +++ b/scm/driver/stash/pr.go @@ -173,6 +173,12 @@ type pr struct { Links struct { Self []link `json:"self"` } `json:"links"` + Properties struct { + MergeCommit struct { + ID string `json:"id"` + DisplayID string `json:"displayId"` + } `json:"mergeCommit"` + } `json:"properties"` } type prs struct { @@ -212,6 +218,12 @@ func convertPullRequests(from *prs) []*scm.PullRequest { } func convertPullRequest(from *pr) *scm.PullRequest { + sha := from.FromRef.LatestCommit + // if pr is merged, use the merge commit + if from.Properties.MergeCommit.ID != "" { + sha = from.Properties.MergeCommit.ID + } + fork := scm.Join( from.FromRef.Repository.Project.Key, from.FromRef.Repository.Slug, @@ -220,7 +232,7 @@ func convertPullRequest(from *pr) *scm.PullRequest { Number: from.ID, Title: from.Title, Body: from.Description, - Sha: from.FromRef.LatestCommit, + Sha: sha, Ref: fmt.Sprintf("refs/pull-requests/%d/from", from.ID), Source: from.FromRef.DisplayID, Target: from.ToRef.DisplayID, diff --git a/scm/driver/stash/testdata/webhooks/pr_merged.json.golden b/scm/driver/stash/testdata/webhooks/pr_merged.json.golden index 344032d2c..f4ab41c57 100644 --- a/scm/driver/stash/testdata/webhooks/pr_merged.json.golden +++ b/scm/driver/stash/testdata/webhooks/pr_merged.json.golden @@ -17,7 +17,7 @@ "Number": 3, "Title": "Develop", "Body": "* added LICENSE\r\n* add COPYING file", - "Sha": "b9eaed50a03c073b20dfa82e5e753d295e7f0e56", + "Sha": "83f836ca538dc4f43d29fda46a5b85ea49f1b8e7", "Ref": "refs/pull-requests/3/from", "Source": "develop", "Target": "master", From e073dbfa2bde20ab73068b47dfb9af69129b22be Mon Sep 17 00:00:00 2001 From: Brad Rydzewski Date: Wed, 14 Sep 2022 08:42:14 -0400 Subject: [PATCH 036/195] Add field to capture merge sha --- scm/pr.go | 1 + 1 file changed, 1 insertion(+) diff --git a/scm/pr.go b/scm/pr.go index b36254a34..1fd2e5a5b 100644 --- a/scm/pr.go +++ b/scm/pr.go @@ -24,6 +24,7 @@ type ( Diff string Closed bool Merged bool + Merge string Base Reference Head Reference Author User From c7c7db684a217ff0514650a9d3562c6e64f3cfd4 Mon Sep 17 00:00:00 2001 From: raghavharness Date: Wed, 14 Sep 2022 18:39:13 +0530 Subject: [PATCH 037/195] use new merge field instead of exisiting sha field --- scm/driver/bitbucket/pr.go | 8 ++------ .../bitbucket/testdata/webhooks/pr_fulfilled.json.golden | 3 ++- scm/driver/bitbucket/webhook.go | 8 ++------ scm/driver/stash/pr.go | 9 ++------- scm/driver/stash/testdata/webhooks/pr_merged.json.golden | 3 ++- 5 files changed, 10 insertions(+), 21 deletions(-) diff --git a/scm/driver/bitbucket/pr.go b/scm/driver/bitbucket/pr.go index 033860f85..5cc3e5ba9 100644 --- a/scm/driver/bitbucket/pr.go +++ b/scm/driver/bitbucket/pr.go @@ -148,16 +148,12 @@ func convertPullRequests(from *prs) []*scm.PullRequest { } func convertPullRequest(from *pr) *scm.PullRequest { - sha := from.Source.Commit.Hash - // if pr is merged, use the merge commit - if from.MergeCommit.Hash != "" { - sha = from.MergeCommit.Hash - } return &scm.PullRequest{ Number: from.ID, Title: from.Title, Body: from.Description, - Sha: sha, + Sha: from.Source.Commit.Hash, + Merge: from.MergeCommit.Hash, Source: from.Source.Branch.Name, Target: from.Destination.Branch.Name, Fork: from.Source.Repository.FullName, diff --git a/scm/driver/bitbucket/testdata/webhooks/pr_fulfilled.json.golden b/scm/driver/bitbucket/testdata/webhooks/pr_fulfilled.json.golden index 6b03b80fd..b76c354af 100644 --- a/scm/driver/bitbucket/testdata/webhooks/pr_fulfilled.json.golden +++ b/scm/driver/bitbucket/testdata/webhooks/pr_fulfilled.json.golden @@ -17,7 +17,8 @@ "Number": 1, "Title": "Awesome new feature", "Body": "made some changes", - "Sha": "4f8f6de9d0ff", + "Sha": "0704fc5beccc", + "Merge": "4f8f6de9d0ff", "Ref": "refs/pull-requests/1/from", "Source": "develop", "Target": "master", diff --git a/scm/driver/bitbucket/webhook.go b/scm/driver/bitbucket/webhook.go index 51f2c3f48..b47675e6d 100644 --- a/scm/driver/bitbucket/webhook.go +++ b/scm/driver/bitbucket/webhook.go @@ -782,11 +782,6 @@ func convertTagDeleteHook(src *pushHook) *scm.TagHook { // func convertPullRequestHook(src *webhook) *scm.PullRequestHook { - sha := src.PullRequest.Source.Commit.Hash - // if pr is merged, use the merge commit - if src.PullRequest.MergeCommit.Hash != "" { - sha = src.PullRequest.MergeCommit.Hash - } namespace, name := scm.Split(src.Repository.FullName) return &scm.PullRequestHook{ Action: scm.ActionOpen, @@ -794,7 +789,8 @@ func convertPullRequestHook(src *webhook) *scm.PullRequestHook { Number: src.PullRequest.ID, Title: src.PullRequest.Title, Body: src.PullRequest.Description, - Sha: sha, + Sha: src.PullRequest.Source.Commit.Hash, + Merge: src.PullRequest.MergeCommit.Hash, Ref: fmt.Sprintf("refs/pull-requests/%d/from", src.PullRequest.ID), Source: src.PullRequest.Source.Branch.Name, Target: src.PullRequest.Destination.Branch.Name, diff --git a/scm/driver/stash/pr.go b/scm/driver/stash/pr.go index e7607b859..87cdb8fda 100644 --- a/scm/driver/stash/pr.go +++ b/scm/driver/stash/pr.go @@ -218,12 +218,6 @@ func convertPullRequests(from *prs) []*scm.PullRequest { } func convertPullRequest(from *pr) *scm.PullRequest { - sha := from.FromRef.LatestCommit - // if pr is merged, use the merge commit - if from.Properties.MergeCommit.ID != "" { - sha = from.Properties.MergeCommit.ID - } - fork := scm.Join( from.FromRef.Repository.Project.Key, from.FromRef.Repository.Slug, @@ -232,7 +226,8 @@ func convertPullRequest(from *pr) *scm.PullRequest { Number: from.ID, Title: from.Title, Body: from.Description, - Sha: sha, + Sha: from.FromRef.LatestCommit, + Merge: from.Properties.MergeCommit.ID, Ref: fmt.Sprintf("refs/pull-requests/%d/from", from.ID), Source: from.FromRef.DisplayID, Target: from.ToRef.DisplayID, diff --git a/scm/driver/stash/testdata/webhooks/pr_merged.json.golden b/scm/driver/stash/testdata/webhooks/pr_merged.json.golden index f4ab41c57..2b3367535 100644 --- a/scm/driver/stash/testdata/webhooks/pr_merged.json.golden +++ b/scm/driver/stash/testdata/webhooks/pr_merged.json.golden @@ -17,7 +17,8 @@ "Number": 3, "Title": "Develop", "Body": "* added LICENSE\r\n* add COPYING file", - "Sha": "83f836ca538dc4f43d29fda46a5b85ea49f1b8e7", + "Sha": "b9eaed50a03c073b20dfa82e5e753d295e7f0e56", + "Merge": "83f836ca538dc4f43d29fda46a5b85ea49f1b8e7", "Ref": "refs/pull-requests/3/from", "Source": "develop", "Target": "master", From a6796f5d93e6c43ac7879bb4d2515514b8c01a1b Mon Sep 17 00:00:00 2001 From: Rutvij Mehta Date: Fri, 23 Sep 2022 14:43:02 -0700 Subject: [PATCH 038/195] Add Actor UUID to Sender for all webhooks responses for Bitbucket --- scm/driver/bitbucket/testdata/webhooks/pr_created.json.golden | 1 + .../bitbucket/testdata/webhooks/pr_declined.json.golden | 1 + .../bitbucket/testdata/webhooks/pr_fulfilled.json.golden | 1 + scm/driver/bitbucket/testdata/webhooks/pr_updated.json.golden | 1 + .../testdata/webhooks/push_branch_delete.json.golden | 1 + .../bitbucket/testdata/webhooks/push_tag_delete.json.golden | 1 + scm/driver/bitbucket/webhook.go | 4 ++++ 7 files changed, 10 insertions(+) diff --git a/scm/driver/bitbucket/testdata/webhooks/pr_created.json.golden b/scm/driver/bitbucket/testdata/webhooks/pr_created.json.golden index 00825c69a..f1901d6d9 100644 --- a/scm/driver/bitbucket/testdata/webhooks/pr_created.json.golden +++ b/scm/driver/bitbucket/testdata/webhooks/pr_created.json.golden @@ -35,6 +35,7 @@ "Updated": "2018-07-02T21:51:39.532546Z" }, "Sender": { + "ID": "{87bb15eb-47c1-49b3-9f16-ca824a2979a4}", "Login": "brydzewski", "Name": "Brad Rydzewski", "Email": "", diff --git a/scm/driver/bitbucket/testdata/webhooks/pr_declined.json.golden b/scm/driver/bitbucket/testdata/webhooks/pr_declined.json.golden index 395a0bc80..081cf4aff 100644 --- a/scm/driver/bitbucket/testdata/webhooks/pr_declined.json.golden +++ b/scm/driver/bitbucket/testdata/webhooks/pr_declined.json.golden @@ -35,6 +35,7 @@ "Updated": "2018-07-03T01:44:00.030575Z" }, "Sender": { + "ID": "{87bb15eb-47c1-49b3-9f16-ca824a2979a4}", "Login": "brydzewski", "Name": "Brad Rydzewski", "Email": "", diff --git a/scm/driver/bitbucket/testdata/webhooks/pr_fulfilled.json.golden b/scm/driver/bitbucket/testdata/webhooks/pr_fulfilled.json.golden index b76c354af..642fe2a9f 100644 --- a/scm/driver/bitbucket/testdata/webhooks/pr_fulfilled.json.golden +++ b/scm/driver/bitbucket/testdata/webhooks/pr_fulfilled.json.golden @@ -36,6 +36,7 @@ "Updated": "2018-07-03T01:28:05.903251Z" }, "Sender": { + "ID": "{87bb15eb-47c1-49b3-9f16-ca824a2979a4}", "Login": "brydzewski", "Name": "Brad Rydzewski", "Email": "", diff --git a/scm/driver/bitbucket/testdata/webhooks/pr_updated.json.golden b/scm/driver/bitbucket/testdata/webhooks/pr_updated.json.golden index b5a933fbb..3c4a45ea4 100644 --- a/scm/driver/bitbucket/testdata/webhooks/pr_updated.json.golden +++ b/scm/driver/bitbucket/testdata/webhooks/pr_updated.json.golden @@ -35,6 +35,7 @@ "Updated": "2018-07-02T21:54:34.210775Z" }, "Sender": { + "ID": "{87bb15eb-47c1-49b3-9f16-ca824a2979a4}", "Login": "brydzewski", "Name": "Brad Rydzewski", "Email": "", diff --git a/scm/driver/bitbucket/testdata/webhooks/push_branch_delete.json.golden b/scm/driver/bitbucket/testdata/webhooks/push_branch_delete.json.golden index 34a12d028..9c5ed6dce 100644 --- a/scm/driver/bitbucket/testdata/webhooks/push_branch_delete.json.golden +++ b/scm/driver/bitbucket/testdata/webhooks/push_branch_delete.json.golden @@ -18,6 +18,7 @@ }, "Action": "deleted", "Sender": { + "ID": "{87bb15eb-47c1-49b3-9f16-ca824a2979a4}", "Login": "brydzewski", "Name": "Brad Rydzewski", "Email": "", diff --git a/scm/driver/bitbucket/testdata/webhooks/push_tag_delete.json.golden b/scm/driver/bitbucket/testdata/webhooks/push_tag_delete.json.golden index 5fe074bcb..479ffec02 100644 --- a/scm/driver/bitbucket/testdata/webhooks/push_tag_delete.json.golden +++ b/scm/driver/bitbucket/testdata/webhooks/push_tag_delete.json.golden @@ -18,6 +18,7 @@ }, "Action": "deleted", "Sender": { + "ID": "{87bb15eb-47c1-49b3-9f16-ca824a2979a4}", "Login": "brydzewski", "Name": "Brad Rydzewski", "Email": "", diff --git a/scm/driver/bitbucket/webhook.go b/scm/driver/bitbucket/webhook.go index b47675e6d..7ba3783a1 100644 --- a/scm/driver/bitbucket/webhook.go +++ b/scm/driver/bitbucket/webhook.go @@ -716,6 +716,7 @@ func convertBranchDeleteHook(src *pushHook) *scm.BranchHook { Link: src.Repository.Links.HTML.Href, }, Sender: scm.User{ + ID: src.Actor.UUID, Login: src.Actor.Username, Name: src.Actor.DisplayName, Avatar: src.Actor.Links.Avatar.Href, @@ -743,6 +744,7 @@ func convertTagCreateHook(src *pushHook) *scm.TagHook { Link: src.Repository.Links.HTML.Href, }, Sender: scm.User{ + ID: src.Actor.UUID, Login: src.Actor.Username, Name: src.Actor.DisplayName, Avatar: src.Actor.Links.Avatar.Href, @@ -770,6 +772,7 @@ func convertTagDeleteHook(src *pushHook) *scm.TagHook { Link: src.Repository.Links.HTML.Href, }, Sender: scm.User{ + ID: src.Actor.UUID, Login: src.Actor.Username, Name: src.Actor.DisplayName, Avatar: src.Actor.Links.Avatar.Href, @@ -816,6 +819,7 @@ func convertPullRequestHook(src *webhook) *scm.PullRequestHook { Link: src.Repository.Links.HTML.Href, }, Sender: scm.User{ + ID: src.Actor.UUID, Login: src.Actor.Username, Name: src.Actor.DisplayName, Avatar: src.Actor.Links.Avatar.Href, From 81afb0fa48d4d083518f98f6eeaf95107e44cf48 Mon Sep 17 00:00:00 2001 From: kit101 Date: Tue, 27 Sep 2022 17:11:35 +0800 Subject: [PATCH 039/195] fixbug: gitee convert repository (#226) --- scm/driver/gitee/repo.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm/driver/gitee/repo.go b/scm/driver/gitee/repo.go index 2628c5df7..fa14ab8ea 100644 --- a/scm/driver/gitee/repo.go +++ b/scm/driver/gitee/repo.go @@ -159,7 +159,7 @@ func convertRepositoryList(from []*repository) []*scm.Repository { func convertRepository(from *repository) *scm.Repository { return &scm.Repository{ ID: strconv.Itoa(from.ID), - Name: from.Name, + Name: from.Path, Namespace: from.Namespace.Path, Perm: &scm.Perm{ Push: from.Permission.Push, From 692aa9a8d2888daa7237e5cdee1037f42e317af6 Mon Sep 17 00:00:00 2001 From: Rutvij Mehta Date: Thu, 10 Nov 2022 09:50:32 +0530 Subject: [PATCH 040/195] Add Actor UUID to push and branch create events for Bitbucket --- scm/driver/bitbucket/testdata/webhooks/push.json.golden | 1 + .../bitbucket/testdata/webhooks/push_branch_create.json.golden | 1 + .../bitbucket/testdata/webhooks/push_tag_create.json.golden | 1 + scm/driver/bitbucket/webhook.go | 2 ++ 4 files changed, 5 insertions(+) diff --git a/scm/driver/bitbucket/testdata/webhooks/push.json.golden b/scm/driver/bitbucket/testdata/webhooks/push.json.golden index 5c76ff577..7d6e576b5 100644 --- a/scm/driver/bitbucket/testdata/webhooks/push.json.golden +++ b/scm/driver/bitbucket/testdata/webhooks/push.json.golden @@ -56,6 +56,7 @@ } ], "Sender": { + "ID": "{87bb15eb-47c1-49b3-9f16-ca824a2979a4}", "Login": "brydzewski", "Name": "Brad Rydzewski", "Email": "", diff --git a/scm/driver/bitbucket/testdata/webhooks/push_branch_create.json.golden b/scm/driver/bitbucket/testdata/webhooks/push_branch_create.json.golden index 0797aae42..d8986b55a 100644 --- a/scm/driver/bitbucket/testdata/webhooks/push_branch_create.json.golden +++ b/scm/driver/bitbucket/testdata/webhooks/push_branch_create.json.golden @@ -74,6 +74,7 @@ } ], "Sender": { + "ID": "{87bb15eb-47c1-49b3-9f16-ca824a2979a4}", "Login": "brydzewski", "Name": "Brad Rydzewski", "Email": "", diff --git a/scm/driver/bitbucket/testdata/webhooks/push_tag_create.json.golden b/scm/driver/bitbucket/testdata/webhooks/push_tag_create.json.golden index 322223a56..688fff348 100644 --- a/scm/driver/bitbucket/testdata/webhooks/push_tag_create.json.golden +++ b/scm/driver/bitbucket/testdata/webhooks/push_tag_create.json.golden @@ -34,6 +34,7 @@ "Link": "https://bitbucket.org/brydzewski/foo/commits/141977fedf5cf35aa290ac87d4b5177ac4cd9de1" }, "Sender": { + "ID": "{87bb15eb-47c1-49b3-9f16-ca824a2979a4}", "Login": "brydzewski", "Name": "Brad Rydzewski", "Email": "", diff --git a/scm/driver/bitbucket/webhook.go b/scm/driver/bitbucket/webhook.go index 7ba3783a1..6d88690ec 100644 --- a/scm/driver/bitbucket/webhook.go +++ b/scm/driver/bitbucket/webhook.go @@ -657,6 +657,7 @@ func convertPushHook(src *pushHook) *scm.PushHook { Link: src.Repository.Links.HTML.Href, }, Sender: scm.User{ + ID: src.Actor.UUID, Login: src.Actor.Username, Name: src.Actor.DisplayName, Avatar: src.Actor.Links.Avatar.Href, @@ -689,6 +690,7 @@ func convertBranchCreateHook(src *pushHook) *scm.BranchHook { Link: src.Repository.Links.HTML.Href, }, Sender: scm.User{ + ID: src.Actor.UUID, Login: src.Actor.Username, Name: src.Actor.DisplayName, Avatar: src.Actor.Links.Avatar.Href, From 1949a8eb740777e552841264c9913ab9af11e99e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Calasans?= Date: Wed, 16 Nov 2022 10:20:08 -0300 Subject: [PATCH 041/195] Add support for Github release webhook (#229) * Add support for Github release webhook --- scm/const.go | 23 ++- .../testdata/webhooks/release_created.json | 164 ++++++++++++++++++ .../webhooks/release_created.json.golden | 34 ++++ .../testdata/webhooks/release_deleted.json | 164 ++++++++++++++++++ .../webhooks/release_deleted.json.golden | 34 ++++ .../testdata/webhooks/release_edited.json | 164 ++++++++++++++++++ .../webhooks/release_edited.json.golden | 34 ++++ .../webhooks/release_prereleased.json | 164 ++++++++++++++++++ .../webhooks/release_prereleased.json.golden | 34 ++++ .../testdata/webhooks/release_published.json | 164 ++++++++++++++++++ .../webhooks/release_published.json.golden | 34 ++++ .../testdata/webhooks/release_released.json | 164 ++++++++++++++++++ .../webhooks/release_released.json.golden | 34 ++++ .../webhooks/release_unpublished.json | 164 ++++++++++++++++++ .../webhooks/release_unpublished.json.golden | 34 ++++ scm/driver/github/webhook.go | 79 +++++++++ scm/driver/github/webhook_test.go | 45 +++++ scm/webhook.go | 10 ++ 18 files changed, 1541 insertions(+), 2 deletions(-) create mode 100644 scm/driver/github/testdata/webhooks/release_created.json create mode 100644 scm/driver/github/testdata/webhooks/release_created.json.golden create mode 100644 scm/driver/github/testdata/webhooks/release_deleted.json create mode 100644 scm/driver/github/testdata/webhooks/release_deleted.json.golden create mode 100644 scm/driver/github/testdata/webhooks/release_edited.json create mode 100644 scm/driver/github/testdata/webhooks/release_edited.json.golden create mode 100644 scm/driver/github/testdata/webhooks/release_prereleased.json create mode 100644 scm/driver/github/testdata/webhooks/release_prereleased.json.golden create mode 100644 scm/driver/github/testdata/webhooks/release_published.json create mode 100644 scm/driver/github/testdata/webhooks/release_published.json.golden create mode 100644 scm/driver/github/testdata/webhooks/release_released.json create mode 100644 scm/driver/github/testdata/webhooks/release_released.json.golden create mode 100644 scm/driver/github/testdata/webhooks/release_unpublished.json create mode 100644 scm/driver/github/testdata/webhooks/release_unpublished.json.golden diff --git a/scm/const.go b/scm/const.go index 690202cb5..84fb47151 100644 --- a/scm/const.go +++ b/scm/const.go @@ -42,6 +42,11 @@ const ( ActionMerge // issue comment ActionEdit + // release + ActionPublish + ActionUnpublish + ActionPrerelease + ActionRelease ) // String returns the string representation of Action. @@ -67,8 +72,14 @@ func (a Action) String() (s string) { return "synchronized" case ActionMerge: return "merged" - case ActionEdit: - return "edited" + case ActionPublish: + return "published" + case ActionUnpublish: + return "unpublished" + case ActionPrerelease: + return "prereleased" + case ActionRelease: + return "released" default: return } @@ -108,6 +119,14 @@ func (a *Action) UnmarshalJSON(data []byte) error { *a = ActionMerge case "edited": *a = ActionEdit + case "published": + *a = ActionPublish + case "unpublished": + *a = ActionUnpublish + case "prereleased": + *a = ActionPrerelease + case "released": + *a = ActionRelease } return nil } diff --git a/scm/driver/github/testdata/webhooks/release_created.json b/scm/driver/github/testdata/webhooks/release_created.json new file mode 100644 index 000000000..39a6d8d78 --- /dev/null +++ b/scm/driver/github/testdata/webhooks/release_created.json @@ -0,0 +1,164 @@ +{ + "action": "created", + "release": { + "url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/releases/81372309", + "assets_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/releases/81372309/assets", + "upload_url": "https://uploads.github.com/repos/vcalasansh/harness-ngtriggers-test/releases/81372309/assets{?name,label}", + "html_url": "https://github.com/vcalasansh/harness-ngtriggers-test/releases/tag/v1.0.0", + "id": 81372309, + "author": { + "login": "vcalasansh", + "id": 109106581, + "node_id": "U_kgDOBoDVlQ", + "avatar_url": "https://avatars.githubusercontent.com/u/109106581?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/vcalasansh", + "html_url": "https://github.com/vcalasansh", + "followers_url": "https://api.github.com/users/vcalasansh/followers", + "following_url": "https://api.github.com/users/vcalasansh/following{/other_user}", + "gists_url": "https://api.github.com/users/vcalasansh/gists{/gist_id}", + "starred_url": "https://api.github.com/users/vcalasansh/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/vcalasansh/subscriptions", + "organizations_url": "https://api.github.com/users/vcalasansh/orgs", + "repos_url": "https://api.github.com/users/vcalasansh/repos", + "events_url": "https://api.github.com/users/vcalasansh/events{/privacy}", + "received_events_url": "https://api.github.com/users/vcalasansh/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOH5utuc4E2aSV", + "tag_name": "v1.0.0", + "target_commitish": "test-branch", + "name": "New release!", + "draft": false, + "prerelease": false, + "created_at": "2022-10-28T13:03:11Z", + "published_at": "2022-10-28T16:36:52Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/tarball/v1.0.0", + "zipball_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/zipball/v1.0.0", + "body": "New release!" + }, + "repository": { + "id": 530296249, + "node_id": "R_kgDOH5utuQ", + "name": "harness-ngtriggers-test", + "full_name": "vcalasansh/harness-ngtriggers-test", + "private": true, + "owner": { + "login": "vcalasansh", + "id": 109106581, + "node_id": "U_kgDOBoDVlQ", + "avatar_url": "https://avatars.githubusercontent.com/u/109106581?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/vcalasansh", + "html_url": "https://github.com/vcalasansh", + "followers_url": "https://api.github.com/users/vcalasansh/followers", + "following_url": "https://api.github.com/users/vcalasansh/following{/other_user}", + "gists_url": "https://api.github.com/users/vcalasansh/gists{/gist_id}", + "starred_url": "https://api.github.com/users/vcalasansh/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/vcalasansh/subscriptions", + "organizations_url": "https://api.github.com/users/vcalasansh/orgs", + "repos_url": "https://api.github.com/users/vcalasansh/repos", + "events_url": "https://api.github.com/users/vcalasansh/events{/privacy}", + "received_events_url": "https://api.github.com/users/vcalasansh/received_events", + "type": "User", + "site_admin": false + }, + "html_url": "https://github.com/vcalasansh/harness-ngtriggers-test", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test", + "forks_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/forks", + "keys_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/teams", + "hooks_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/hooks", + "issue_events_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/issues/events{/number}", + "events_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/events", + "assignees_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/assignees{/user}", + "branches_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/branches{/branch}", + "tags_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/tags", + "blobs_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/statuses/{sha}", + "languages_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/languages", + "stargazers_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/stargazers", + "contributors_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/contributors", + "subscribers_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/subscribers", + "subscription_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/subscription", + "commits_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/contents/{+path}", + "compare_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/merges", + "archive_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/downloads", + "issues_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/issues{/number}", + "pulls_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/pulls{/number}", + "milestones_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/milestones{/number}", + "notifications_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/labels{/name}", + "releases_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/releases{/id}", + "deployments_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/deployments", + "created_at": "2022-08-29T16:12:07Z", + "updated_at": "2022-08-29T16:12:07Z", + "pushed_at": "2022-10-28T16:36:27Z", + "git_url": "git://github.com/vcalasansh/harness-ngtriggers-test.git", + "ssh_url": "git@github.com:vcalasansh/harness-ngtriggers-test.git", + "clone_url": "https://github.com/vcalasansh/harness-ngtriggers-test.git", + "svn_url": "https://github.com/vcalasansh/harness-ngtriggers-test", + "homepage": null, + "size": 11, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 0, + "license": null, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [ + + ], + "forks": 0, + "open_issues": 0, + "watchers": 0, + "default_branch": "test-branch" + }, + "sender": { + "login": "vcalasansh", + "id": 109106581, + "node_id": "U_kgDOBoDVlQ", + "avatar_url": "https://avatars.githubusercontent.com/u/109106581?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/vcalasansh", + "html_url": "https://github.com/vcalasansh", + "followers_url": "https://api.github.com/users/vcalasansh/followers", + "following_url": "https://api.github.com/users/vcalasansh/following{/other_user}", + "gists_url": "https://api.github.com/users/vcalasansh/gists{/gist_id}", + "starred_url": "https://api.github.com/users/vcalasansh/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/vcalasansh/subscriptions", + "organizations_url": "https://api.github.com/users/vcalasansh/orgs", + "repos_url": "https://api.github.com/users/vcalasansh/repos", + "events_url": "https://api.github.com/users/vcalasansh/events{/privacy}", + "received_events_url": "https://api.github.com/users/vcalasansh/received_events", + "type": "User", + "site_admin": false + } +} diff --git a/scm/driver/github/testdata/webhooks/release_created.json.golden b/scm/driver/github/testdata/webhooks/release_created.json.golden new file mode 100644 index 000000000..b7935c46d --- /dev/null +++ b/scm/driver/github/testdata/webhooks/release_created.json.golden @@ -0,0 +1,34 @@ +{ + "Action": "created", + "Release": { + "ID": 81372309, + "Title": "New release!", + "Description": "New release!", + "Link": "https://github.com/vcalasansh/harness-ngtriggers-test/releases/tag/v1.0.0", + "Tag": "v1.0.0", + "Commitish": "test-branch", + "Draft": false, + "Prerelease": false, + "Created": "2022-10-28T13:03:11Z", + "Published": "2022-10-28T16:36:52Z" + }, + "Repo": { + "ID": "530296249", + "Namespace": "vcalasansh", + "Name": "harness-ngtriggers-test", + "Perm": null, + "Branch": "test-branch", + "Private": true, + "Clone": "https://github.com/vcalasansh/harness-ngtriggers-test.git", + "CloneSSH": "git@github.com:vcalasansh/harness-ngtriggers-test.git", + "Link": "https://github.com/vcalasansh/harness-ngtriggers-test", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Sender": { + "Login": "vcalasansh", + "Name": "", + "Email": "", + "Avatar": "https://avatars.githubusercontent.com/u/109106581?v=4" + } +} diff --git a/scm/driver/github/testdata/webhooks/release_deleted.json b/scm/driver/github/testdata/webhooks/release_deleted.json new file mode 100644 index 000000000..a5ba0fef2 --- /dev/null +++ b/scm/driver/github/testdata/webhooks/release_deleted.json @@ -0,0 +1,164 @@ +{ + "action": "deleted", + "release": { + "url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/releases/81372309", + "assets_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/releases/81372309/assets", + "upload_url": "https://uploads.github.com/repos/vcalasansh/harness-ngtriggers-test/releases/81372309/assets{?name,label}", + "html_url": "https://github.com/vcalasansh/harness-ngtriggers-test/releases/tag/v1.0.0", + "id": 81372309, + "author": { + "login": "vcalasansh", + "id": 109106581, + "node_id": "U_kgDOBoDVlQ", + "avatar_url": "https://avatars.githubusercontent.com/u/109106581?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/vcalasansh", + "html_url": "https://github.com/vcalasansh", + "followers_url": "https://api.github.com/users/vcalasansh/followers", + "following_url": "https://api.github.com/users/vcalasansh/following{/other_user}", + "gists_url": "https://api.github.com/users/vcalasansh/gists{/gist_id}", + "starred_url": "https://api.github.com/users/vcalasansh/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/vcalasansh/subscriptions", + "organizations_url": "https://api.github.com/users/vcalasansh/orgs", + "repos_url": "https://api.github.com/users/vcalasansh/repos", + "events_url": "https://api.github.com/users/vcalasansh/events{/privacy}", + "received_events_url": "https://api.github.com/users/vcalasansh/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOH5utuc4E2aSV", + "tag_name": "v1.0.0", + "target_commitish": "test-branch", + "name": "New release!", + "draft": false, + "prerelease": false, + "created_at": "2022-10-28T13:03:11Z", + "published_at": "2022-10-28T16:36:52Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/tarball/v1.0.0", + "zipball_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/zipball/v1.0.0", + "body": "New release!" + }, + "repository": { + "id": 530296249, + "node_id": "R_kgDOH5utuQ", + "name": "harness-ngtriggers-test", + "full_name": "vcalasansh/harness-ngtriggers-test", + "private": true, + "owner": { + "login": "vcalasansh", + "id": 109106581, + "node_id": "U_kgDOBoDVlQ", + "avatar_url": "https://avatars.githubusercontent.com/u/109106581?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/vcalasansh", + "html_url": "https://github.com/vcalasansh", + "followers_url": "https://api.github.com/users/vcalasansh/followers", + "following_url": "https://api.github.com/users/vcalasansh/following{/other_user}", + "gists_url": "https://api.github.com/users/vcalasansh/gists{/gist_id}", + "starred_url": "https://api.github.com/users/vcalasansh/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/vcalasansh/subscriptions", + "organizations_url": "https://api.github.com/users/vcalasansh/orgs", + "repos_url": "https://api.github.com/users/vcalasansh/repos", + "events_url": "https://api.github.com/users/vcalasansh/events{/privacy}", + "received_events_url": "https://api.github.com/users/vcalasansh/received_events", + "type": "User", + "site_admin": false + }, + "html_url": "https://github.com/vcalasansh/harness-ngtriggers-test", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test", + "forks_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/forks", + "keys_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/teams", + "hooks_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/hooks", + "issue_events_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/issues/events{/number}", + "events_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/events", + "assignees_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/assignees{/user}", + "branches_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/branches{/branch}", + "tags_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/tags", + "blobs_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/statuses/{sha}", + "languages_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/languages", + "stargazers_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/stargazers", + "contributors_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/contributors", + "subscribers_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/subscribers", + "subscription_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/subscription", + "commits_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/contents/{+path}", + "compare_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/merges", + "archive_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/downloads", + "issues_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/issues{/number}", + "pulls_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/pulls{/number}", + "milestones_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/milestones{/number}", + "notifications_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/labels{/name}", + "releases_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/releases{/id}", + "deployments_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/deployments", + "created_at": "2022-08-29T16:12:07Z", + "updated_at": "2022-08-29T16:12:07Z", + "pushed_at": "2022-10-28T16:36:27Z", + "git_url": "git://github.com/vcalasansh/harness-ngtriggers-test.git", + "ssh_url": "git@github.com:vcalasansh/harness-ngtriggers-test.git", + "clone_url": "https://github.com/vcalasansh/harness-ngtriggers-test.git", + "svn_url": "https://github.com/vcalasansh/harness-ngtriggers-test", + "homepage": null, + "size": 11, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 0, + "license": null, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [ + + ], + "forks": 0, + "open_issues": 0, + "watchers": 0, + "default_branch": "test-branch" + }, + "sender": { + "login": "vcalasansh", + "id": 109106581, + "node_id": "U_kgDOBoDVlQ", + "avatar_url": "https://avatars.githubusercontent.com/u/109106581?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/vcalasansh", + "html_url": "https://github.com/vcalasansh", + "followers_url": "https://api.github.com/users/vcalasansh/followers", + "following_url": "https://api.github.com/users/vcalasansh/following{/other_user}", + "gists_url": "https://api.github.com/users/vcalasansh/gists{/gist_id}", + "starred_url": "https://api.github.com/users/vcalasansh/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/vcalasansh/subscriptions", + "organizations_url": "https://api.github.com/users/vcalasansh/orgs", + "repos_url": "https://api.github.com/users/vcalasansh/repos", + "events_url": "https://api.github.com/users/vcalasansh/events{/privacy}", + "received_events_url": "https://api.github.com/users/vcalasansh/received_events", + "type": "User", + "site_admin": false + } +} diff --git a/scm/driver/github/testdata/webhooks/release_deleted.json.golden b/scm/driver/github/testdata/webhooks/release_deleted.json.golden new file mode 100644 index 000000000..30dee53c1 --- /dev/null +++ b/scm/driver/github/testdata/webhooks/release_deleted.json.golden @@ -0,0 +1,34 @@ +{ + "Action": "deleted", + "Release": { + "ID": 81372309, + "Title": "New release!", + "Description": "New release!", + "Link": "https://github.com/vcalasansh/harness-ngtriggers-test/releases/tag/v1.0.0", + "Tag": "v1.0.0", + "Commitish": "test-branch", + "Draft": false, + "Prerelease": false, + "Created": "2022-10-28T13:03:11Z", + "Published": "2022-10-28T16:36:52Z" + }, + "Repo": { + "ID": "530296249", + "Namespace": "vcalasansh", + "Name": "harness-ngtriggers-test", + "Perm": null, + "Branch": "test-branch", + "Private": true, + "Clone": "https://github.com/vcalasansh/harness-ngtriggers-test.git", + "CloneSSH": "git@github.com:vcalasansh/harness-ngtriggers-test.git", + "Link": "https://github.com/vcalasansh/harness-ngtriggers-test", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Sender": { + "Login": "vcalasansh", + "Name": "", + "Email": "", + "Avatar": "https://avatars.githubusercontent.com/u/109106581?v=4" + } +} diff --git a/scm/driver/github/testdata/webhooks/release_edited.json b/scm/driver/github/testdata/webhooks/release_edited.json new file mode 100644 index 000000000..45f7511b4 --- /dev/null +++ b/scm/driver/github/testdata/webhooks/release_edited.json @@ -0,0 +1,164 @@ +{ + "action": "edited", + "release": { + "url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/releases/81372309", + "assets_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/releases/81372309/assets", + "upload_url": "https://uploads.github.com/repos/vcalasansh/harness-ngtriggers-test/releases/81372309/assets{?name,label}", + "html_url": "https://github.com/vcalasansh/harness-ngtriggers-test/releases/tag/v1.0.0", + "id": 81372309, + "author": { + "login": "vcalasansh", + "id": 109106581, + "node_id": "U_kgDOBoDVlQ", + "avatar_url": "https://avatars.githubusercontent.com/u/109106581?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/vcalasansh", + "html_url": "https://github.com/vcalasansh", + "followers_url": "https://api.github.com/users/vcalasansh/followers", + "following_url": "https://api.github.com/users/vcalasansh/following{/other_user}", + "gists_url": "https://api.github.com/users/vcalasansh/gists{/gist_id}", + "starred_url": "https://api.github.com/users/vcalasansh/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/vcalasansh/subscriptions", + "organizations_url": "https://api.github.com/users/vcalasansh/orgs", + "repos_url": "https://api.github.com/users/vcalasansh/repos", + "events_url": "https://api.github.com/users/vcalasansh/events{/privacy}", + "received_events_url": "https://api.github.com/users/vcalasansh/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOH5utuc4E2aSV", + "tag_name": "v1.0.0", + "target_commitish": "test-branch", + "name": "New release!", + "draft": false, + "prerelease": false, + "created_at": "2022-10-28T13:03:11Z", + "published_at": "2022-10-28T16:36:52Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/tarball/v1.0.0", + "zipball_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/zipball/v1.0.0", + "body": "New release!" + }, + "repository": { + "id": 530296249, + "node_id": "R_kgDOH5utuQ", + "name": "harness-ngtriggers-test", + "full_name": "vcalasansh/harness-ngtriggers-test", + "private": true, + "owner": { + "login": "vcalasansh", + "id": 109106581, + "node_id": "U_kgDOBoDVlQ", + "avatar_url": "https://avatars.githubusercontent.com/u/109106581?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/vcalasansh", + "html_url": "https://github.com/vcalasansh", + "followers_url": "https://api.github.com/users/vcalasansh/followers", + "following_url": "https://api.github.com/users/vcalasansh/following{/other_user}", + "gists_url": "https://api.github.com/users/vcalasansh/gists{/gist_id}", + "starred_url": "https://api.github.com/users/vcalasansh/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/vcalasansh/subscriptions", + "organizations_url": "https://api.github.com/users/vcalasansh/orgs", + "repos_url": "https://api.github.com/users/vcalasansh/repos", + "events_url": "https://api.github.com/users/vcalasansh/events{/privacy}", + "received_events_url": "https://api.github.com/users/vcalasansh/received_events", + "type": "User", + "site_admin": false + }, + "html_url": "https://github.com/vcalasansh/harness-ngtriggers-test", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test", + "forks_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/forks", + "keys_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/teams", + "hooks_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/hooks", + "issue_events_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/issues/events{/number}", + "events_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/events", + "assignees_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/assignees{/user}", + "branches_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/branches{/branch}", + "tags_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/tags", + "blobs_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/statuses/{sha}", + "languages_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/languages", + "stargazers_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/stargazers", + "contributors_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/contributors", + "subscribers_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/subscribers", + "subscription_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/subscription", + "commits_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/contents/{+path}", + "compare_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/merges", + "archive_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/downloads", + "issues_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/issues{/number}", + "pulls_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/pulls{/number}", + "milestones_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/milestones{/number}", + "notifications_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/labels{/name}", + "releases_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/releases{/id}", + "deployments_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/deployments", + "created_at": "2022-08-29T16:12:07Z", + "updated_at": "2022-08-29T16:12:07Z", + "pushed_at": "2022-10-28T16:36:27Z", + "git_url": "git://github.com/vcalasansh/harness-ngtriggers-test.git", + "ssh_url": "git@github.com:vcalasansh/harness-ngtriggers-test.git", + "clone_url": "https://github.com/vcalasansh/harness-ngtriggers-test.git", + "svn_url": "https://github.com/vcalasansh/harness-ngtriggers-test", + "homepage": null, + "size": 11, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 0, + "license": null, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [ + + ], + "forks": 0, + "open_issues": 0, + "watchers": 0, + "default_branch": "test-branch" + }, + "sender": { + "login": "vcalasansh", + "id": 109106581, + "node_id": "U_kgDOBoDVlQ", + "avatar_url": "https://avatars.githubusercontent.com/u/109106581?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/vcalasansh", + "html_url": "https://github.com/vcalasansh", + "followers_url": "https://api.github.com/users/vcalasansh/followers", + "following_url": "https://api.github.com/users/vcalasansh/following{/other_user}", + "gists_url": "https://api.github.com/users/vcalasansh/gists{/gist_id}", + "starred_url": "https://api.github.com/users/vcalasansh/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/vcalasansh/subscriptions", + "organizations_url": "https://api.github.com/users/vcalasansh/orgs", + "repos_url": "https://api.github.com/users/vcalasansh/repos", + "events_url": "https://api.github.com/users/vcalasansh/events{/privacy}", + "received_events_url": "https://api.github.com/users/vcalasansh/received_events", + "type": "User", + "site_admin": false + } +} diff --git a/scm/driver/github/testdata/webhooks/release_edited.json.golden b/scm/driver/github/testdata/webhooks/release_edited.json.golden new file mode 100644 index 000000000..0b1e387ad --- /dev/null +++ b/scm/driver/github/testdata/webhooks/release_edited.json.golden @@ -0,0 +1,34 @@ +{ + "Action": "edited", + "Release": { + "ID": 81372309, + "Title": "New release!", + "Description": "New release!", + "Link": "https://github.com/vcalasansh/harness-ngtriggers-test/releases/tag/v1.0.0", + "Tag": "v1.0.0", + "Commitish": "test-branch", + "Draft": false, + "Prerelease": false, + "Created": "2022-10-28T13:03:11Z", + "Published": "2022-10-28T16:36:52Z" + }, + "Repo": { + "ID": "530296249", + "Namespace": "vcalasansh", + "Name": "harness-ngtriggers-test", + "Perm": null, + "Branch": "test-branch", + "Private": true, + "Clone": "https://github.com/vcalasansh/harness-ngtriggers-test.git", + "CloneSSH": "git@github.com:vcalasansh/harness-ngtriggers-test.git", + "Link": "https://github.com/vcalasansh/harness-ngtriggers-test", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Sender": { + "Login": "vcalasansh", + "Name": "", + "Email": "", + "Avatar": "https://avatars.githubusercontent.com/u/109106581?v=4" + } +} diff --git a/scm/driver/github/testdata/webhooks/release_prereleased.json b/scm/driver/github/testdata/webhooks/release_prereleased.json new file mode 100644 index 000000000..94ab938c8 --- /dev/null +++ b/scm/driver/github/testdata/webhooks/release_prereleased.json @@ -0,0 +1,164 @@ +{ + "action": "prereleased", + "release": { + "url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/releases/81372309", + "assets_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/releases/81372309/assets", + "upload_url": "https://uploads.github.com/repos/vcalasansh/harness-ngtriggers-test/releases/81372309/assets{?name,label}", + "html_url": "https://github.com/vcalasansh/harness-ngtriggers-test/releases/tag/v1.0.0", + "id": 81372309, + "author": { + "login": "vcalasansh", + "id": 109106581, + "node_id": "U_kgDOBoDVlQ", + "avatar_url": "https://avatars.githubusercontent.com/u/109106581?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/vcalasansh", + "html_url": "https://github.com/vcalasansh", + "followers_url": "https://api.github.com/users/vcalasansh/followers", + "following_url": "https://api.github.com/users/vcalasansh/following{/other_user}", + "gists_url": "https://api.github.com/users/vcalasansh/gists{/gist_id}", + "starred_url": "https://api.github.com/users/vcalasansh/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/vcalasansh/subscriptions", + "organizations_url": "https://api.github.com/users/vcalasansh/orgs", + "repos_url": "https://api.github.com/users/vcalasansh/repos", + "events_url": "https://api.github.com/users/vcalasansh/events{/privacy}", + "received_events_url": "https://api.github.com/users/vcalasansh/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOH5utuc4E2aSV", + "tag_name": "v1.0.0", + "target_commitish": "test-branch", + "name": "New release!", + "draft": false, + "prerelease": false, + "created_at": "2022-10-28T13:03:11Z", + "published_at": "2022-10-28T16:36:52Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/tarball/v1.0.0", + "zipball_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/zipball/v1.0.0", + "body": "New release!" + }, + "repository": { + "id": 530296249, + "node_id": "R_kgDOH5utuQ", + "name": "harness-ngtriggers-test", + "full_name": "vcalasansh/harness-ngtriggers-test", + "private": true, + "owner": { + "login": "vcalasansh", + "id": 109106581, + "node_id": "U_kgDOBoDVlQ", + "avatar_url": "https://avatars.githubusercontent.com/u/109106581?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/vcalasansh", + "html_url": "https://github.com/vcalasansh", + "followers_url": "https://api.github.com/users/vcalasansh/followers", + "following_url": "https://api.github.com/users/vcalasansh/following{/other_user}", + "gists_url": "https://api.github.com/users/vcalasansh/gists{/gist_id}", + "starred_url": "https://api.github.com/users/vcalasansh/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/vcalasansh/subscriptions", + "organizations_url": "https://api.github.com/users/vcalasansh/orgs", + "repos_url": "https://api.github.com/users/vcalasansh/repos", + "events_url": "https://api.github.com/users/vcalasansh/events{/privacy}", + "received_events_url": "https://api.github.com/users/vcalasansh/received_events", + "type": "User", + "site_admin": false + }, + "html_url": "https://github.com/vcalasansh/harness-ngtriggers-test", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test", + "forks_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/forks", + "keys_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/teams", + "hooks_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/hooks", + "issue_events_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/issues/events{/number}", + "events_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/events", + "assignees_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/assignees{/user}", + "branches_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/branches{/branch}", + "tags_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/tags", + "blobs_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/statuses/{sha}", + "languages_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/languages", + "stargazers_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/stargazers", + "contributors_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/contributors", + "subscribers_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/subscribers", + "subscription_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/subscription", + "commits_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/contents/{+path}", + "compare_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/merges", + "archive_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/downloads", + "issues_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/issues{/number}", + "pulls_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/pulls{/number}", + "milestones_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/milestones{/number}", + "notifications_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/labels{/name}", + "releases_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/releases{/id}", + "deployments_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/deployments", + "created_at": "2022-08-29T16:12:07Z", + "updated_at": "2022-08-29T16:12:07Z", + "pushed_at": "2022-10-28T16:36:27Z", + "git_url": "git://github.com/vcalasansh/harness-ngtriggers-test.git", + "ssh_url": "git@github.com:vcalasansh/harness-ngtriggers-test.git", + "clone_url": "https://github.com/vcalasansh/harness-ngtriggers-test.git", + "svn_url": "https://github.com/vcalasansh/harness-ngtriggers-test", + "homepage": null, + "size": 11, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 0, + "license": null, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [ + + ], + "forks": 0, + "open_issues": 0, + "watchers": 0, + "default_branch": "test-branch" + }, + "sender": { + "login": "vcalasansh", + "id": 109106581, + "node_id": "U_kgDOBoDVlQ", + "avatar_url": "https://avatars.githubusercontent.com/u/109106581?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/vcalasansh", + "html_url": "https://github.com/vcalasansh", + "followers_url": "https://api.github.com/users/vcalasansh/followers", + "following_url": "https://api.github.com/users/vcalasansh/following{/other_user}", + "gists_url": "https://api.github.com/users/vcalasansh/gists{/gist_id}", + "starred_url": "https://api.github.com/users/vcalasansh/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/vcalasansh/subscriptions", + "organizations_url": "https://api.github.com/users/vcalasansh/orgs", + "repos_url": "https://api.github.com/users/vcalasansh/repos", + "events_url": "https://api.github.com/users/vcalasansh/events{/privacy}", + "received_events_url": "https://api.github.com/users/vcalasansh/received_events", + "type": "User", + "site_admin": false + } +} diff --git a/scm/driver/github/testdata/webhooks/release_prereleased.json.golden b/scm/driver/github/testdata/webhooks/release_prereleased.json.golden new file mode 100644 index 000000000..996beb3a6 --- /dev/null +++ b/scm/driver/github/testdata/webhooks/release_prereleased.json.golden @@ -0,0 +1,34 @@ +{ + "Action": "prereleased", + "Release": { + "ID": 81372309, + "Title": "New release!", + "Description": "New release!", + "Link": "https://github.com/vcalasansh/harness-ngtriggers-test/releases/tag/v1.0.0", + "Tag": "v1.0.0", + "Commitish": "test-branch", + "Draft": false, + "Prerelease": false, + "Created": "2022-10-28T13:03:11Z", + "Published": "2022-10-28T16:36:52Z" + }, + "Repo": { + "ID": "530296249", + "Namespace": "vcalasansh", + "Name": "harness-ngtriggers-test", + "Perm": null, + "Branch": "test-branch", + "Private": true, + "Clone": "https://github.com/vcalasansh/harness-ngtriggers-test.git", + "CloneSSH": "git@github.com:vcalasansh/harness-ngtriggers-test.git", + "Link": "https://github.com/vcalasansh/harness-ngtriggers-test", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Sender": { + "Login": "vcalasansh", + "Name": "", + "Email": "", + "Avatar": "https://avatars.githubusercontent.com/u/109106581?v=4" + } +} diff --git a/scm/driver/github/testdata/webhooks/release_published.json b/scm/driver/github/testdata/webhooks/release_published.json new file mode 100644 index 000000000..23b9bad66 --- /dev/null +++ b/scm/driver/github/testdata/webhooks/release_published.json @@ -0,0 +1,164 @@ +{ + "action": "published", + "release": { + "url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/releases/81372309", + "assets_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/releases/81372309/assets", + "upload_url": "https://uploads.github.com/repos/vcalasansh/harness-ngtriggers-test/releases/81372309/assets{?name,label}", + "html_url": "https://github.com/vcalasansh/harness-ngtriggers-test/releases/tag/v1.0.0", + "id": 81372309, + "author": { + "login": "vcalasansh", + "id": 109106581, + "node_id": "U_kgDOBoDVlQ", + "avatar_url": "https://avatars.githubusercontent.com/u/109106581?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/vcalasansh", + "html_url": "https://github.com/vcalasansh", + "followers_url": "https://api.github.com/users/vcalasansh/followers", + "following_url": "https://api.github.com/users/vcalasansh/following{/other_user}", + "gists_url": "https://api.github.com/users/vcalasansh/gists{/gist_id}", + "starred_url": "https://api.github.com/users/vcalasansh/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/vcalasansh/subscriptions", + "organizations_url": "https://api.github.com/users/vcalasansh/orgs", + "repos_url": "https://api.github.com/users/vcalasansh/repos", + "events_url": "https://api.github.com/users/vcalasansh/events{/privacy}", + "received_events_url": "https://api.github.com/users/vcalasansh/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOH5utuc4E2aSV", + "tag_name": "v1.0.0", + "target_commitish": "test-branch", + "name": "New release!", + "draft": false, + "prerelease": false, + "created_at": "2022-10-28T13:03:11Z", + "published_at": "2022-10-28T16:36:52Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/tarball/v1.0.0", + "zipball_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/zipball/v1.0.0", + "body": "New release!" + }, + "repository": { + "id": 530296249, + "node_id": "R_kgDOH5utuQ", + "name": "harness-ngtriggers-test", + "full_name": "vcalasansh/harness-ngtriggers-test", + "private": true, + "owner": { + "login": "vcalasansh", + "id": 109106581, + "node_id": "U_kgDOBoDVlQ", + "avatar_url": "https://avatars.githubusercontent.com/u/109106581?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/vcalasansh", + "html_url": "https://github.com/vcalasansh", + "followers_url": "https://api.github.com/users/vcalasansh/followers", + "following_url": "https://api.github.com/users/vcalasansh/following{/other_user}", + "gists_url": "https://api.github.com/users/vcalasansh/gists{/gist_id}", + "starred_url": "https://api.github.com/users/vcalasansh/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/vcalasansh/subscriptions", + "organizations_url": "https://api.github.com/users/vcalasansh/orgs", + "repos_url": "https://api.github.com/users/vcalasansh/repos", + "events_url": "https://api.github.com/users/vcalasansh/events{/privacy}", + "received_events_url": "https://api.github.com/users/vcalasansh/received_events", + "type": "User", + "site_admin": false + }, + "html_url": "https://github.com/vcalasansh/harness-ngtriggers-test", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test", + "forks_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/forks", + "keys_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/teams", + "hooks_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/hooks", + "issue_events_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/issues/events{/number}", + "events_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/events", + "assignees_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/assignees{/user}", + "branches_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/branches{/branch}", + "tags_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/tags", + "blobs_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/statuses/{sha}", + "languages_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/languages", + "stargazers_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/stargazers", + "contributors_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/contributors", + "subscribers_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/subscribers", + "subscription_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/subscription", + "commits_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/contents/{+path}", + "compare_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/merges", + "archive_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/downloads", + "issues_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/issues{/number}", + "pulls_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/pulls{/number}", + "milestones_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/milestones{/number}", + "notifications_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/labels{/name}", + "releases_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/releases{/id}", + "deployments_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/deployments", + "created_at": "2022-08-29T16:12:07Z", + "updated_at": "2022-08-29T16:12:07Z", + "pushed_at": "2022-10-28T16:36:27Z", + "git_url": "git://github.com/vcalasansh/harness-ngtriggers-test.git", + "ssh_url": "git@github.com:vcalasansh/harness-ngtriggers-test.git", + "clone_url": "https://github.com/vcalasansh/harness-ngtriggers-test.git", + "svn_url": "https://github.com/vcalasansh/harness-ngtriggers-test", + "homepage": null, + "size": 11, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 0, + "license": null, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [ + + ], + "forks": 0, + "open_issues": 0, + "watchers": 0, + "default_branch": "test-branch" + }, + "sender": { + "login": "vcalasansh", + "id": 109106581, + "node_id": "U_kgDOBoDVlQ", + "avatar_url": "https://avatars.githubusercontent.com/u/109106581?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/vcalasansh", + "html_url": "https://github.com/vcalasansh", + "followers_url": "https://api.github.com/users/vcalasansh/followers", + "following_url": "https://api.github.com/users/vcalasansh/following{/other_user}", + "gists_url": "https://api.github.com/users/vcalasansh/gists{/gist_id}", + "starred_url": "https://api.github.com/users/vcalasansh/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/vcalasansh/subscriptions", + "organizations_url": "https://api.github.com/users/vcalasansh/orgs", + "repos_url": "https://api.github.com/users/vcalasansh/repos", + "events_url": "https://api.github.com/users/vcalasansh/events{/privacy}", + "received_events_url": "https://api.github.com/users/vcalasansh/received_events", + "type": "User", + "site_admin": false + } +} diff --git a/scm/driver/github/testdata/webhooks/release_published.json.golden b/scm/driver/github/testdata/webhooks/release_published.json.golden new file mode 100644 index 000000000..a1f070b04 --- /dev/null +++ b/scm/driver/github/testdata/webhooks/release_published.json.golden @@ -0,0 +1,34 @@ +{ + "Action": "published", + "Release": { + "ID": 81372309, + "Title": "New release!", + "Description": "New release!", + "Link": "https://github.com/vcalasansh/harness-ngtriggers-test/releases/tag/v1.0.0", + "Tag": "v1.0.0", + "Commitish": "test-branch", + "Draft": false, + "Prerelease": false, + "Created": "2022-10-28T13:03:11Z", + "Published": "2022-10-28T16:36:52Z" + }, + "Repo": { + "ID": "530296249", + "Namespace": "vcalasansh", + "Name": "harness-ngtriggers-test", + "Perm": null, + "Branch": "test-branch", + "Private": true, + "Clone": "https://github.com/vcalasansh/harness-ngtriggers-test.git", + "CloneSSH": "git@github.com:vcalasansh/harness-ngtriggers-test.git", + "Link": "https://github.com/vcalasansh/harness-ngtriggers-test", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Sender": { + "Login": "vcalasansh", + "Name": "", + "Email": "", + "Avatar": "https://avatars.githubusercontent.com/u/109106581?v=4" + } +} diff --git a/scm/driver/github/testdata/webhooks/release_released.json b/scm/driver/github/testdata/webhooks/release_released.json new file mode 100644 index 000000000..b4af3b457 --- /dev/null +++ b/scm/driver/github/testdata/webhooks/release_released.json @@ -0,0 +1,164 @@ +{ + "action": "released", + "release": { + "url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/releases/81372309", + "assets_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/releases/81372309/assets", + "upload_url": "https://uploads.github.com/repos/vcalasansh/harness-ngtriggers-test/releases/81372309/assets{?name,label}", + "html_url": "https://github.com/vcalasansh/harness-ngtriggers-test/releases/tag/v1.0.0", + "id": 81372309, + "author": { + "login": "vcalasansh", + "id": 109106581, + "node_id": "U_kgDOBoDVlQ", + "avatar_url": "https://avatars.githubusercontent.com/u/109106581?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/vcalasansh", + "html_url": "https://github.com/vcalasansh", + "followers_url": "https://api.github.com/users/vcalasansh/followers", + "following_url": "https://api.github.com/users/vcalasansh/following{/other_user}", + "gists_url": "https://api.github.com/users/vcalasansh/gists{/gist_id}", + "starred_url": "https://api.github.com/users/vcalasansh/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/vcalasansh/subscriptions", + "organizations_url": "https://api.github.com/users/vcalasansh/orgs", + "repos_url": "https://api.github.com/users/vcalasansh/repos", + "events_url": "https://api.github.com/users/vcalasansh/events{/privacy}", + "received_events_url": "https://api.github.com/users/vcalasansh/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOH5utuc4E2aSV", + "tag_name": "v1.0.0", + "target_commitish": "test-branch", + "name": "New release!", + "draft": false, + "prerelease": false, + "created_at": "2022-10-28T13:03:11Z", + "published_at": "2022-10-28T16:36:52Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/tarball/v1.0.0", + "zipball_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/zipball/v1.0.0", + "body": "New release!" + }, + "repository": { + "id": 530296249, + "node_id": "R_kgDOH5utuQ", + "name": "harness-ngtriggers-test", + "full_name": "vcalasansh/harness-ngtriggers-test", + "private": true, + "owner": { + "login": "vcalasansh", + "id": 109106581, + "node_id": "U_kgDOBoDVlQ", + "avatar_url": "https://avatars.githubusercontent.com/u/109106581?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/vcalasansh", + "html_url": "https://github.com/vcalasansh", + "followers_url": "https://api.github.com/users/vcalasansh/followers", + "following_url": "https://api.github.com/users/vcalasansh/following{/other_user}", + "gists_url": "https://api.github.com/users/vcalasansh/gists{/gist_id}", + "starred_url": "https://api.github.com/users/vcalasansh/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/vcalasansh/subscriptions", + "organizations_url": "https://api.github.com/users/vcalasansh/orgs", + "repos_url": "https://api.github.com/users/vcalasansh/repos", + "events_url": "https://api.github.com/users/vcalasansh/events{/privacy}", + "received_events_url": "https://api.github.com/users/vcalasansh/received_events", + "type": "User", + "site_admin": false + }, + "html_url": "https://github.com/vcalasansh/harness-ngtriggers-test", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test", + "forks_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/forks", + "keys_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/teams", + "hooks_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/hooks", + "issue_events_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/issues/events{/number}", + "events_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/events", + "assignees_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/assignees{/user}", + "branches_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/branches{/branch}", + "tags_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/tags", + "blobs_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/statuses/{sha}", + "languages_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/languages", + "stargazers_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/stargazers", + "contributors_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/contributors", + "subscribers_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/subscribers", + "subscription_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/subscription", + "commits_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/contents/{+path}", + "compare_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/merges", + "archive_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/downloads", + "issues_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/issues{/number}", + "pulls_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/pulls{/number}", + "milestones_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/milestones{/number}", + "notifications_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/labels{/name}", + "releases_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/releases{/id}", + "deployments_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/deployments", + "created_at": "2022-08-29T16:12:07Z", + "updated_at": "2022-08-29T16:12:07Z", + "pushed_at": "2022-10-28T16:36:27Z", + "git_url": "git://github.com/vcalasansh/harness-ngtriggers-test.git", + "ssh_url": "git@github.com:vcalasansh/harness-ngtriggers-test.git", + "clone_url": "https://github.com/vcalasansh/harness-ngtriggers-test.git", + "svn_url": "https://github.com/vcalasansh/harness-ngtriggers-test", + "homepage": null, + "size": 11, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 0, + "license": null, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [ + + ], + "forks": 0, + "open_issues": 0, + "watchers": 0, + "default_branch": "test-branch" + }, + "sender": { + "login": "vcalasansh", + "id": 109106581, + "node_id": "U_kgDOBoDVlQ", + "avatar_url": "https://avatars.githubusercontent.com/u/109106581?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/vcalasansh", + "html_url": "https://github.com/vcalasansh", + "followers_url": "https://api.github.com/users/vcalasansh/followers", + "following_url": "https://api.github.com/users/vcalasansh/following{/other_user}", + "gists_url": "https://api.github.com/users/vcalasansh/gists{/gist_id}", + "starred_url": "https://api.github.com/users/vcalasansh/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/vcalasansh/subscriptions", + "organizations_url": "https://api.github.com/users/vcalasansh/orgs", + "repos_url": "https://api.github.com/users/vcalasansh/repos", + "events_url": "https://api.github.com/users/vcalasansh/events{/privacy}", + "received_events_url": "https://api.github.com/users/vcalasansh/received_events", + "type": "User", + "site_admin": false + } +} diff --git a/scm/driver/github/testdata/webhooks/release_released.json.golden b/scm/driver/github/testdata/webhooks/release_released.json.golden new file mode 100644 index 000000000..3e93aa08e --- /dev/null +++ b/scm/driver/github/testdata/webhooks/release_released.json.golden @@ -0,0 +1,34 @@ +{ + "Action": "released", + "Release": { + "ID": 81372309, + "Title": "New release!", + "Description": "New release!", + "Link": "https://github.com/vcalasansh/harness-ngtriggers-test/releases/tag/v1.0.0", + "Tag": "v1.0.0", + "Commitish": "test-branch", + "Draft": false, + "Prerelease": false, + "Created": "2022-10-28T13:03:11Z", + "Published": "2022-10-28T16:36:52Z" + }, + "Repo": { + "ID": "530296249", + "Namespace": "vcalasansh", + "Name": "harness-ngtriggers-test", + "Perm": null, + "Branch": "test-branch", + "Private": true, + "Clone": "https://github.com/vcalasansh/harness-ngtriggers-test.git", + "CloneSSH": "git@github.com:vcalasansh/harness-ngtriggers-test.git", + "Link": "https://github.com/vcalasansh/harness-ngtriggers-test", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Sender": { + "Login": "vcalasansh", + "Name": "", + "Email": "", + "Avatar": "https://avatars.githubusercontent.com/u/109106581?v=4" + } +} diff --git a/scm/driver/github/testdata/webhooks/release_unpublished.json b/scm/driver/github/testdata/webhooks/release_unpublished.json new file mode 100644 index 000000000..6ee38d4e2 --- /dev/null +++ b/scm/driver/github/testdata/webhooks/release_unpublished.json @@ -0,0 +1,164 @@ +{ + "action": "unpublished", + "release": { + "url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/releases/81372309", + "assets_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/releases/81372309/assets", + "upload_url": "https://uploads.github.com/repos/vcalasansh/harness-ngtriggers-test/releases/81372309/assets{?name,label}", + "html_url": "https://github.com/vcalasansh/harness-ngtriggers-test/releases/tag/v1.0.0", + "id": 81372309, + "author": { + "login": "vcalasansh", + "id": 109106581, + "node_id": "U_kgDOBoDVlQ", + "avatar_url": "https://avatars.githubusercontent.com/u/109106581?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/vcalasansh", + "html_url": "https://github.com/vcalasansh", + "followers_url": "https://api.github.com/users/vcalasansh/followers", + "following_url": "https://api.github.com/users/vcalasansh/following{/other_user}", + "gists_url": "https://api.github.com/users/vcalasansh/gists{/gist_id}", + "starred_url": "https://api.github.com/users/vcalasansh/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/vcalasansh/subscriptions", + "organizations_url": "https://api.github.com/users/vcalasansh/orgs", + "repos_url": "https://api.github.com/users/vcalasansh/repos", + "events_url": "https://api.github.com/users/vcalasansh/events{/privacy}", + "received_events_url": "https://api.github.com/users/vcalasansh/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOH5utuc4E2aSV", + "tag_name": "v1.0.0", + "target_commitish": "test-branch", + "name": "New release!", + "draft": false, + "prerelease": false, + "created_at": "2022-10-28T13:03:11Z", + "published_at": "2022-10-28T16:36:52Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/tarball/v1.0.0", + "zipball_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/zipball/v1.0.0", + "body": "New release!" + }, + "repository": { + "id": 530296249, + "node_id": "R_kgDOH5utuQ", + "name": "harness-ngtriggers-test", + "full_name": "vcalasansh/harness-ngtriggers-test", + "private": true, + "owner": { + "login": "vcalasansh", + "id": 109106581, + "node_id": "U_kgDOBoDVlQ", + "avatar_url": "https://avatars.githubusercontent.com/u/109106581?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/vcalasansh", + "html_url": "https://github.com/vcalasansh", + "followers_url": "https://api.github.com/users/vcalasansh/followers", + "following_url": "https://api.github.com/users/vcalasansh/following{/other_user}", + "gists_url": "https://api.github.com/users/vcalasansh/gists{/gist_id}", + "starred_url": "https://api.github.com/users/vcalasansh/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/vcalasansh/subscriptions", + "organizations_url": "https://api.github.com/users/vcalasansh/orgs", + "repos_url": "https://api.github.com/users/vcalasansh/repos", + "events_url": "https://api.github.com/users/vcalasansh/events{/privacy}", + "received_events_url": "https://api.github.com/users/vcalasansh/received_events", + "type": "User", + "site_admin": false + }, + "html_url": "https://github.com/vcalasansh/harness-ngtriggers-test", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test", + "forks_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/forks", + "keys_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/teams", + "hooks_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/hooks", + "issue_events_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/issues/events{/number}", + "events_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/events", + "assignees_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/assignees{/user}", + "branches_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/branches{/branch}", + "tags_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/tags", + "blobs_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/statuses/{sha}", + "languages_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/languages", + "stargazers_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/stargazers", + "contributors_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/contributors", + "subscribers_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/subscribers", + "subscription_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/subscription", + "commits_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/contents/{+path}", + "compare_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/merges", + "archive_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/downloads", + "issues_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/issues{/number}", + "pulls_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/pulls{/number}", + "milestones_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/milestones{/number}", + "notifications_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/labels{/name}", + "releases_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/releases{/id}", + "deployments_url": "https://api.github.com/repos/vcalasansh/harness-ngtriggers-test/deployments", + "created_at": "2022-08-29T16:12:07Z", + "updated_at": "2022-08-29T16:12:07Z", + "pushed_at": "2022-10-28T16:36:27Z", + "git_url": "git://github.com/vcalasansh/harness-ngtriggers-test.git", + "ssh_url": "git@github.com:vcalasansh/harness-ngtriggers-test.git", + "clone_url": "https://github.com/vcalasansh/harness-ngtriggers-test.git", + "svn_url": "https://github.com/vcalasansh/harness-ngtriggers-test", + "homepage": null, + "size": 11, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 0, + "license": null, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [ + + ], + "forks": 0, + "open_issues": 0, + "watchers": 0, + "default_branch": "test-branch" + }, + "sender": { + "login": "vcalasansh", + "id": 109106581, + "node_id": "U_kgDOBoDVlQ", + "avatar_url": "https://avatars.githubusercontent.com/u/109106581?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/vcalasansh", + "html_url": "https://github.com/vcalasansh", + "followers_url": "https://api.github.com/users/vcalasansh/followers", + "following_url": "https://api.github.com/users/vcalasansh/following{/other_user}", + "gists_url": "https://api.github.com/users/vcalasansh/gists{/gist_id}", + "starred_url": "https://api.github.com/users/vcalasansh/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/vcalasansh/subscriptions", + "organizations_url": "https://api.github.com/users/vcalasansh/orgs", + "repos_url": "https://api.github.com/users/vcalasansh/repos", + "events_url": "https://api.github.com/users/vcalasansh/events{/privacy}", + "received_events_url": "https://api.github.com/users/vcalasansh/received_events", + "type": "User", + "site_admin": false + } +} diff --git a/scm/driver/github/testdata/webhooks/release_unpublished.json.golden b/scm/driver/github/testdata/webhooks/release_unpublished.json.golden new file mode 100644 index 000000000..21ea08eea --- /dev/null +++ b/scm/driver/github/testdata/webhooks/release_unpublished.json.golden @@ -0,0 +1,34 @@ +{ + "Action": "unpublished", + "Release": { + "ID": 81372309, + "Title": "New release!", + "Description": "New release!", + "Link": "https://github.com/vcalasansh/harness-ngtriggers-test/releases/tag/v1.0.0", + "Tag": "v1.0.0", + "Commitish": "test-branch", + "Draft": false, + "Prerelease": false, + "Created": "2022-10-28T13:03:11Z", + "Published": "2022-10-28T16:36:52Z" + }, + "Repo": { + "ID": "530296249", + "Namespace": "vcalasansh", + "Name": "harness-ngtriggers-test", + "Perm": null, + "Branch": "test-branch", + "Private": true, + "Clone": "https://github.com/vcalasansh/harness-ngtriggers-test.git", + "CloneSSH": "git@github.com:vcalasansh/harness-ngtriggers-test.git", + "Link": "https://github.com/vcalasansh/harness-ngtriggers-test", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Sender": { + "Login": "vcalasansh", + "Name": "", + "Email": "", + "Avatar": "https://avatars.githubusercontent.com/u/109106581?v=4" + } +} diff --git a/scm/driver/github/webhook.go b/scm/driver/github/webhook.go index e0f6ae77a..57d3ed9ed 100644 --- a/scm/driver/github/webhook.go +++ b/scm/driver/github/webhook.go @@ -46,6 +46,8 @@ func (s *webhookService) Parse(req *http.Request, fn scm.SecretFunc) (scm.Webhoo // case "issues": case "issue_comment": hook, err = s.parseIssueCommentHook(data) + case "release": + hook, err = s.parseReleaseHook(data) default: return nil, scm.ErrUnknownEvent } @@ -178,6 +180,34 @@ func (s *webhookService) parsePullRequestHook(data []byte) (scm.Webhook, error) return dst, nil } +func (s *webhookService) parseReleaseHook(data []byte) (scm.Webhook, error) { + src := new(releaseHook) + err := json.Unmarshal(data, src) + if err != nil { + return nil, err + } + dst := convertReleaseHook(src) + switch src.Action { + case "created": + dst.Action = scm.ActionCreate + case "edited": + dst.Action = scm.ActionEdit + case "deleted": + dst.Action = scm.ActionDelete + case "published": + dst.Action = scm.ActionPublish + case "unpublished": + dst.Action = scm.ActionUnpublish + case "prereleased": + dst.Action = scm.ActionPrerelease + case "released": + dst.Action = scm.ActionRelease + default: + dst.Action = scm.ActionUnknown + } + return dst, nil +} + // // native data structures // @@ -301,6 +331,25 @@ type ( Updated time.Time `json:"updated_at"` } `json:"comment"` } + + // github release webhook payload + releaseHook struct { + Action string `json:"action"` + Release struct { + ID int `json:"id"` + Title string `json:"name"` + Description string `json:"body"` + Link string `json:"html_url,omitempty"` + Tag string `json:"tag_name,omitempty"` + Commitish string `json:"target_commitish,omitempty"` + Draft bool `json:"draft"` + Prerelease bool `json:"prerelease"` + Created time.Time `json:"created_at"` + Published time.Time `json:"published_at"` + } `json:"release"` + Repository repository `json:"repository"` + Sender user `json:"sender"` + } ) // @@ -500,6 +549,36 @@ func convertIssueCommentHook(src *issueCommentHook) *scm.IssueCommentHook { return dst } +func convertReleaseHook(src *releaseHook) *scm.ReleaseHook { + dst := &scm.ReleaseHook{ + Release: scm.Release{ + ID: src.Release.ID, + Title: src.Release.Title, + Description: src.Release.Description, + Link: src.Release.Link, + Tag: src.Release.Tag, + Commitish: src.Release.Commitish, + Draft: src.Release.Draft, + Prerelease: src.Release.Prerelease, + Created: src.Release.Created, + Published: src.Release.Published, + }, + Repo: scm.Repository{ + ID: fmt.Sprint(src.Repository.ID), + Namespace: src.Repository.Owner.Login, + Name: src.Repository.Name, + Branch: src.Repository.DefaultBranch, + Private: src.Repository.Private, + Visibility: convertVisibility(src.Repository.Visibility), + Clone: src.Repository.CloneURL, + CloneSSH: src.Repository.SSHURL, + Link: src.Repository.HTMLURL, + }, + Sender: *convertUser(&src.Sender), + } + return dst +} + // regexp help determine if the named git object is a tag. // this is not meant to be 100% accurate. var tagRE = regexp.MustCompile("^v?(\\d+).(.+)") diff --git a/scm/driver/github/webhook_test.go b/scm/driver/github/webhook_test.go index e54970f0d..7d3621c94 100644 --- a/scm/driver/github/webhook_test.go +++ b/scm/driver/github/webhook_test.go @@ -185,6 +185,51 @@ func TestWebhooks(t *testing.T) { after: "testdata/webhooks/deployment_commit.json.golden", obj: new(scm.DeployHook), }, + // + // release + // + { + event: "release", + before: "testdata/webhooks/release_published.json", + after: "testdata/webhooks/release_published.json.golden", + obj: new(scm.ReleaseHook), + }, + { + event: "release", + before: "testdata/webhooks/release_unpublished.json", + after: "testdata/webhooks/release_unpublished.json.golden", + obj: new(scm.ReleaseHook), + }, + { + event: "release", + before: "testdata/webhooks/release_created.json", + after: "testdata/webhooks/release_created.json.golden", + obj: new(scm.ReleaseHook), + }, + { + event: "release", + before: "testdata/webhooks/release_edited.json", + after: "testdata/webhooks/release_edited.json.golden", + obj: new(scm.ReleaseHook), + }, + { + event: "release", + before: "testdata/webhooks/release_deleted.json", + after: "testdata/webhooks/release_deleted.json.golden", + obj: new(scm.ReleaseHook), + }, + { + event: "release", + before: "testdata/webhooks/release_prereleased.json", + after: "testdata/webhooks/release_prereleased.json.golden", + obj: new(scm.ReleaseHook), + }, + { + event: "release", + before: "testdata/webhooks/release_released.json", + after: "testdata/webhooks/release_released.json.golden", + obj: new(scm.ReleaseHook), + }, } for _, test := range tests { diff --git a/scm/webhook.go b/scm/webhook.go index b36c25feb..f6875f6f2 100644 --- a/scm/webhook.go +++ b/scm/webhook.go @@ -115,6 +115,15 @@ type ( Task string } + // ReleaseHook represents a release event. This is + // currently a GitHub-specific event type. + ReleaseHook struct { + Action Action + Release Release + Repo Repository + Sender User + } + // SecretFunc provides the Webhook parser with the // secret key used to validate webhook authenticity. SecretFunc func(webhook Webhook) (string, error) @@ -140,3 +149,4 @@ func (h *IssueCommentHook) Repository() Repository { return h.Repo } func (h *PullRequestHook) Repository() Repository { return h.Repo } func (h *PullRequestCommentHook) Repository() Repository { return h.Repo } func (h *ReviewCommentHook) Repository() Repository { return h.Repo } +func (h *ReleaseHook) Repository() Repository { return h.Repo } From 5f3c26274ccaf748b36ee9a29bf1363f37b7ee87 Mon Sep 17 00:00:00 2001 From: TP Honey Date: Tue, 22 Nov 2022 15:57:05 +0000 Subject: [PATCH 042/195] (maint) release prep for 1.28.0 (#232) --- CHANGELOG.md | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ccb06957..0d74e8c58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,44 @@ # Changelog -## [v1.27.0](https://github.com/drone/go-scm/tree/v1.27.0) (2022-07-18) +## [1.28.0](https://github.com/drone/go-scm/tree/1.28.0) (2022-11-22) + +[Full Changelog](https://github.com/drone/go-scm/compare/v1.27.0...1.28.0) + +**Implemented enhancements:** + +- Add Actor UUID to push and branch create events for Bitbucket [\#230](https://github.com/drone/go-scm/pull/230) ([rutvijmehta-harness](https://github.com/rutvijmehta-harness)) +- Add support for Github release webhook [\#229](https://github.com/drone/go-scm/pull/229) ([vcalasansh](https://github.com/vcalasansh)) +- Add Actor UUID to Sender for all webhooks responses for Bitbucket [\#227](https://github.com/drone/go-scm/pull/227) ([rutvijmehta-harness](https://github.com/rutvijmehta-harness)) +- added date info for commits in push hook [\#223](https://github.com/drone/go-scm/pull/223) ([raghavharness](https://github.com/raghavharness)) +- Added support for branch in list commits bb onprem API [\#215](https://github.com/drone/go-scm/pull/215) ([mohitg0795](https://github.com/mohitg0795)) +- \[PL-26239\]: added api to list installation for github app [\#213](https://github.com/drone/go-scm/pull/213) ([bhavya181](https://github.com/bhavya181)) + +**Fixed bugs:** + +- fixbug: gitee convert repository [\#226](https://github.com/drone/go-scm/pull/226) ([kit101](https://github.com/kit101)) +- Bitbucket sha fix for merged pr [\#225](https://github.com/drone/go-scm/pull/225) ([raghavharness](https://github.com/raghavharness)) +- decoding projectName for azure repo [\#224](https://github.com/drone/go-scm/pull/224) ([raghavharness](https://github.com/raghavharness)) +- added omitempty annotation for secret [\#221](https://github.com/drone/go-scm/pull/221) ([raghavharness](https://github.com/raghavharness)) +- \[PL-26239\]: fix for list response [\#218](https://github.com/drone/go-scm/pull/218) ([bhavya181](https://github.com/bhavya181)) + +**Closed issues:** + +- gitlab: force\_remove\_source\_branch type is inconsistent [\#228](https://github.com/drone/go-scm/issues/228) +- gitee: When the name and path are inconsistent, got 404 error [\#217](https://github.com/drone/go-scm/issues/217) +- file naming conventions [\#208](https://github.com/drone/go-scm/issues/208) +- Support for Azure Devops git repos? [\#53](https://github.com/drone/go-scm/issues/53) + +**Merged pull requests:** + +- \(maint\) fixing naming and add more go best practice [\#211](https://github.com/drone/go-scm/pull/211) ([tphoney](https://github.com/tphoney)) + +## [v1.27.0](https://github.com/drone/go-scm/tree/v1.27.0) (2022-07-19) [Full Changelog](https://github.com/drone/go-scm/compare/v1.26.0...v1.27.0) **Merged pull requests:** +- Update scm version 1.27.0 [\#206](https://github.com/drone/go-scm/pull/206) ([raghavharness](https://github.com/raghavharness)) - Using resource version 2.0 for Azure [\#205](https://github.com/drone/go-scm/pull/205) ([raghavharness](https://github.com/raghavharness)) ## [v1.26.0](https://github.com/drone/go-scm/tree/v1.26.0) (2022-07-01) From ef3c3cc4886311ff6617e78f9e8537633a53b241 Mon Sep 17 00:00:00 2001 From: Mohit Garg Date: Fri, 27 Jan 2023 15:39:44 +0530 Subject: [PATCH 043/195] feat: [PIE-7927]: added header to avoid/bypass csrf check (#234) --- scm/driver/stash/stash.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scm/driver/stash/stash.go b/scm/driver/stash/stash.go index 440cf3844..60511ed7d 100644 --- a/scm/driver/stash/stash.go +++ b/scm/driver/stash/stash.go @@ -69,7 +69,8 @@ func (c *wrapper) do(ctx context.Context, method, path string, in, out interface Method: method, Path: path, Header: map[string][]string{ - "Accept": {"application/json"}, + "Accept": {"application/json"}, + "x-atlassian-token": {"no-token"}, }, } // if we are posting or putting data, we need to From 4121e2cc0f3d9a2f8c39aa5886ae8768e181c0b5 Mon Sep 17 00:00:00 2001 From: TP Honey Date: Fri, 27 Jan 2023 10:25:10 +0000 Subject: [PATCH 044/195] (maint) prep 1.28.1 release (#235) --- CHANGELOG.md | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d74e8c58..5f8653ef1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,20 @@ # Changelog -## [1.28.0](https://github.com/drone/go-scm/tree/1.28.0) (2022-11-22) +## [1.28.1](https://github.com/drone/go-scm/tree/1.28.1) (2023-01-27) -[Full Changelog](https://github.com/drone/go-scm/compare/v1.27.0...1.28.0) +[Full Changelog](https://github.com/drone/go-scm/compare/v1.28.0...1.28.1) + +**Fixed bugs:** + +- feat: \[PIE-7927\]: added header to avoid/bypass csrf check [\#234](https://github.com/drone/go-scm/pull/234) ([mohitg0795](https://github.com/mohitg0795)) + +**Closed issues:** + +- Gogs commit fails to deserialize commitDetails in some cases [\#231](https://github.com/drone/go-scm/issues/231) + +## [v1.28.0](https://github.com/drone/go-scm/tree/v1.28.0) (2022-11-22) + +[Full Changelog](https://github.com/drone/go-scm/compare/v1.27.0...v1.28.0) **Implemented enhancements:** @@ -30,6 +42,7 @@ **Merged pull requests:** +- \(maint\) release prep for 1.28.0 [\#232](https://github.com/drone/go-scm/pull/232) ([tphoney](https://github.com/tphoney)) - \(maint\) fixing naming and add more go best practice [\#211](https://github.com/drone/go-scm/pull/211) ([tphoney](https://github.com/tphoney)) ## [v1.27.0](https://github.com/drone/go-scm/tree/v1.27.0) (2022-07-19) From 4428a9bf64df846195cf80ba133a5be2f3f5091a Mon Sep 17 00:00:00 2001 From: Mohit Garg Date: Mon, 30 Jan 2023 16:52:42 +0530 Subject: [PATCH 045/195] fix: [PIE-7927]: Fix header value typo issue for BB OnPrem CSRF header (#236) --- scm/driver/stash/stash.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm/driver/stash/stash.go b/scm/driver/stash/stash.go index 60511ed7d..33f3d5711 100644 --- a/scm/driver/stash/stash.go +++ b/scm/driver/stash/stash.go @@ -70,7 +70,7 @@ func (c *wrapper) do(ctx context.Context, method, path string, in, out interface Path: path, Header: map[string][]string{ "Accept": {"application/json"}, - "x-atlassian-token": {"no-token"}, + "x-atlassian-token": {"no-check"}, }, } // if we are posting or putting data, we need to From ca3776c0f0b280b28bd7a8d0298fb207a4d8072b Mon Sep 17 00:00:00 2001 From: TP Honey Date: Mon, 6 Feb 2023 16:36:56 +0000 Subject: [PATCH 046/195] Harness move (#237) * (feat) initial commit for harness code * (feat) harness, add update delete create file --- scm/const.go | 3 + scm/driver/harness/content.go | 234 ++++++++++++ scm/driver/harness/content_test.go | 208 ++++++++++ scm/driver/harness/git.go | 187 +++++++++ scm/driver/harness/git_test.go | 5 + scm/driver/harness/harness.go | 108 ++++++ scm/driver/harness/harness_test.go | 47 +++ scm/driver/harness/issue.go | 147 +++++++ scm/driver/harness/issue_test.go | 5 + scm/driver/harness/linker.go | 27 ++ scm/driver/harness/linker_test.go | 5 + scm/driver/harness/milestone.go | 90 +++++ scm/driver/harness/milestone_test.go | 1 + scm/driver/harness/org.go | 57 +++ scm/driver/harness/org_test.go | 5 + scm/driver/harness/pr.go | 157 ++++++++ scm/driver/harness/pr_test.go | 5 + scm/driver/harness/release.go | 112 ++++++ scm/driver/harness/release_test.go | 1 + scm/driver/harness/repo.go | 273 +++++++++++++ scm/driver/harness/repo_test.go | 9 + scm/driver/harness/review.go | 31 ++ scm/driver/harness/review_test.go | 5 + scm/driver/harness/testdata/content.json | 30 ++ scm/driver/harness/testdata/content_list.json | 79 ++++ .../harness/testdata/content_list.json.golden | 14 + .../webhooks/pull_request_opened.json | 172 +++++++++ .../webhooks/pull_request_opened.json.golden | 47 +++ scm/driver/harness/user.go | 66 ++++ scm/driver/harness/user_test.go | 5 + scm/driver/harness/util.go | 103 +++++ scm/driver/harness/util_test.go | 81 ++++ scm/driver/harness/webhook.go | 361 ++++++++++++++++++ scm/driver/harness/webhook_test.go | 5 + 34 files changed, 2685 insertions(+) create mode 100644 scm/driver/harness/content.go create mode 100644 scm/driver/harness/content_test.go create mode 100644 scm/driver/harness/git.go create mode 100644 scm/driver/harness/git_test.go create mode 100644 scm/driver/harness/harness.go create mode 100644 scm/driver/harness/harness_test.go create mode 100644 scm/driver/harness/issue.go create mode 100644 scm/driver/harness/issue_test.go create mode 100644 scm/driver/harness/linker.go create mode 100644 scm/driver/harness/linker_test.go create mode 100644 scm/driver/harness/milestone.go create mode 100644 scm/driver/harness/milestone_test.go create mode 100644 scm/driver/harness/org.go create mode 100644 scm/driver/harness/org_test.go create mode 100644 scm/driver/harness/pr.go create mode 100644 scm/driver/harness/pr_test.go create mode 100644 scm/driver/harness/release.go create mode 100644 scm/driver/harness/release_test.go create mode 100644 scm/driver/harness/repo.go create mode 100644 scm/driver/harness/repo_test.go create mode 100644 scm/driver/harness/review.go create mode 100644 scm/driver/harness/review_test.go create mode 100644 scm/driver/harness/testdata/content.json create mode 100644 scm/driver/harness/testdata/content_list.json create mode 100644 scm/driver/harness/testdata/content_list.json.golden create mode 100644 scm/driver/harness/testdata/webhooks/pull_request_opened.json create mode 100644 scm/driver/harness/testdata/webhooks/pull_request_opened.json.golden create mode 100644 scm/driver/harness/user.go create mode 100644 scm/driver/harness/user_test.go create mode 100644 scm/driver/harness/util.go create mode 100644 scm/driver/harness/util_test.go create mode 100644 scm/driver/harness/webhook.go create mode 100644 scm/driver/harness/webhook_test.go diff --git a/scm/const.go b/scm/const.go index 84fb47151..dca74b699 100644 --- a/scm/const.go +++ b/scm/const.go @@ -146,6 +146,7 @@ const ( DriverCoding DriverGitee DriverAzure + DriverHarness ) // String returns the string representation of Driver. @@ -169,6 +170,8 @@ func (d Driver) String() (s string) { return "gitee" case DriverAzure: return "azure" + case DriverHarness: + return "harness" default: return "unknown" } diff --git a/scm/driver/harness/content.go b/scm/driver/harness/content.go new file mode 100644 index 000000000..e5e7724b3 --- /dev/null +++ b/scm/driver/harness/content.go @@ -0,0 +1,234 @@ +// Copyright 2017 Drone.IO Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package harness + +import ( + "context" + "encoding/base64" + "fmt" + "time" + + "github.com/drone/go-scm/scm" +) + +type contentService struct { + client *wrapper +} + +func (s *contentService) Find(ctx context.Context, repo, path, ref string) (*scm.Content, *scm.Response, error) { + repo = buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + endpoint := fmt.Sprintf("api/v1/repos/%s/content/%s?%s&include_commit=true", repo, path, ref) + out := new(fileContent) + res, err := s.client.do(ctx, "GET", endpoint, nil, out) + // decode raw output content + raw, _ := base64.StdEncoding.DecodeString(out.Content.Data) + return &scm.Content{ + Path: path, + Sha: out.LatestCommit.Sha, + BlobID: out.Sha, + Data: raw, + }, res, err +} + +func (s *contentService) Create(ctx context.Context, repo, path string, params *scm.ContentParams) (*scm.Response, error) { + repo = buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + endpoint := fmt.Sprintf("api/v1/repos/%s/commits", repo) + a := action{ + Action: "CREATE", + Path: path, + Payload: string(params.Data), + Encoding: "string", + } + in := editFile{ + Branch: params.Branch, + Message: params.Message, + Title: params.Message, + Actions: []action{a}, + } + + res, err := s.client.do(ctx, "POST", endpoint, in, nil) + return res, err +} + +func (s *contentService) Update(ctx context.Context, repo, path string, params *scm.ContentParams) (*scm.Response, error) { + repo = buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + endpoint := fmt.Sprintf("api/v1/repos/%s/commits", repo) + a := action{ + Action: "UPDATE", + Path: path, + Payload: string(params.Data), + Encoding: "string", + } + in := editFile{ + Branch: params.Branch, + Message: params.Message, + Title: params.Message, + Actions: []action{a}, + } + + res, err := s.client.do(ctx, "POST", endpoint, in, nil) + return res, err +} + +func (s *contentService) Delete(ctx context.Context, repo, path string, params *scm.ContentParams) (*scm.Response, error) { + repo = buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + endpoint := fmt.Sprintf("api/v1/repos/%s/commits", repo) + a := action{ + Action: "DELETE", + Path: path, + Encoding: "string", + } + in := editFile{ + Branch: params.Branch, + Message: params.Message, + Title: params.Message, + Actions: []action{a}, + } + + res, err := s.client.do(ctx, "POST", endpoint, in, nil) + return res, err +} + +func buildHarnessURI(account, organization, project, repo string) (uri string) { + if account != "" { + return fmt.Sprintf("%s/%s/%s/%s/+", account, organization, project, repo) + } + return repo +} + +func (s *contentService) List(ctx context.Context, repo, path, ref string, _ scm.ListOptions) ([]*scm.ContentInfo, *scm.Response, error) { + repo = buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + endpoint := fmt.Sprintf("api/v1/repos/%s/content/%s?%s&include_commit=true", repo, path, ref) + out := new(contentList) + res, err := s.client.do(ctx, "GET", endpoint, nil, &out) + return convertContentInfoList(out.Content.Entries), res, err +} + +type editFile struct { + Actions []action `json:"actions"` + Branch string `json:"branch"` + Message string `json:"message"` + NewBranch string `json:"new_branch"` + Title string `json:"title"` +} + +type action struct { + Action string `json:"action"` + Encoding string `json:"encoding"` + Path string `json:"path"` + Payload string `json:"payload"` + Sha string `json:"sha"` +} + +type fileContent struct { + Type string `json:"type"` + Sha string `json:"sha"` + Name string `json:"name"` + Path string `json:"path"` + LatestCommit struct { + Sha string `json:"sha"` + Title string `json:"title"` + Message string `json:"message"` + Author struct { + Identity struct { + Name string `json:"name"` + Email string `json:"email"` + } `json:"identity"` + When time.Time `json:"when"` + } `json:"author"` + Committer struct { + Identity struct { + Name string `json:"name"` + Email string `json:"email"` + } `json:"identity"` + When time.Time `json:"when"` + } `json:"committer"` + } `json:"latest_commit"` + Content struct { + Encoding string `json:"encoding"` + Data string `json:"data"` + Size int `json:"size"` + } `json:"content"` +} + +type contentList struct { + Type string `json:"type"` + Sha string `json:"sha"` + Name string `json:"name"` + Path string `json:"path"` + LatestCommit struct { + Sha string `json:"sha"` + Title string `json:"title"` + Message string `json:"message"` + Author struct { + Identity struct { + Name string `json:"name"` + Email string `json:"email"` + } `json:"identity"` + When time.Time `json:"when"` + } `json:"author"` + Committer struct { + Identity struct { + Name string `json:"name"` + Email string `json:"email"` + } `json:"identity"` + When time.Time `json:"when"` + } `json:"committer"` + } `json:"latest_commit"` + Content struct { + Entries []fileEntry `json:"entries"` + } `json:"content"` +} + +type fileEntry struct { + Type string `json:"type"` + Sha string `json:"sha"` + Name string `json:"name"` + Path string `json:"path"` + LatestCommit struct { + Sha string `json:"sha"` + Title string `json:"title"` + Message string `json:"message"` + Author struct { + Identity struct { + Name string `json:"name"` + Email string `json:"email"` + } `json:"identity"` + When time.Time `json:"when"` + } `json:"author"` + Committer struct { + Identity struct { + Name string `json:"name"` + Email string `json:"email"` + } `json:"identity"` + When time.Time `json:"when"` + } `json:"committer"` + } `json:"latest_commit"` +} + +func convertContentInfoList(from []fileEntry) []*scm.ContentInfo { + to := []*scm.ContentInfo{} + for _, v := range from { + to = append(to, convertContentInfo(v)) + } + return to +} + +func convertContentInfo(from fileEntry) *scm.ContentInfo { + to := &scm.ContentInfo{ + Path: from.Path, + Sha: from.LatestCommit.Sha, + BlobID: from.Sha, + } + switch from.Type { + case "file": + to.Kind = scm.ContentKindFile + case "dir": + to.Kind = scm.ContentKindDirectory + default: + to.Kind = scm.ContentKindUnsupported + } + return to +} diff --git a/scm/driver/harness/content_test.go b/scm/driver/harness/content_test.go new file mode 100644 index 000000000..feba75672 --- /dev/null +++ b/scm/driver/harness/content_test.go @@ -0,0 +1,208 @@ +// Copyright 2017 Drone.IO Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package harness + +import ( + "context" + "encoding/json" + "io/ioutil" + "net/http" + "strings" + "testing" + + "github.com/drone/go-scm/scm" + "github.com/drone/go-scm/scm/transport" + "github.com/google/go-cmp/cmp" + "github.com/h2non/gock" +) + +const ( + gockOrigin = "https://qa.harness.io/gateway/code" + harnessOrg = "px7xd_BFRCi-pfWPYXVjvw" + harnessAccount = "default" + harnessProject = "codeciintegration" + harnessRepo = "demo" + harnessPAT = "" +) + +func TestContentFind(t *testing.T) { + defer gock.Off() + + gock.New(gockOrigin). + Get("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/demo/+/content/README.md"). + Reply(200). + Type("plain/text"). + File("testdata/content.json") + + client, _ := New(gockOrigin, harnessOrg, harnessAccount, harnessProject) + client.Client = &http.Client{ + Transport: &transport.Custom{ + Before: func(r *http.Request) { + r.Header.Set("x-api-key", harnessPAT) + }, + }, + } + result, _, err := client.Contents.Find( + context.Background(), + harnessRepo, + "README.md", + "98189d5cf2a751a6246c24a72945ba70839f1b20", + ) + if err != nil { + t.Error(err) + } + + if got, want := result.Path, "README.md"; got != want { + t.Errorf("Want file Path %q, got %q", want, got) + } + if !strings.Contains(string(result.Data), "demo") { + t.Errorf("Want file Data %q, must contain 'demo'", result.Data) + } +} + +func TestContentCreate(t *testing.T) { + defer gock.Off() + + gock.New(gockOrigin). + Post("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/demo/+/commits"). + Reply(200). + Type("plain/text"). + BodyString("{\"commit_id\":\"20ecde1f8c277da0e91750bef9f3b88f228d86db\"}") + + client, _ := New(gockOrigin, harnessOrg, harnessAccount, harnessProject) + client.Client = &http.Client{ + Transport: &transport.Custom{ + Before: func(r *http.Request) { + r.Header.Set("x-api-key", harnessPAT) + }, + }, + } + result, err := client.Contents.Create( + context.Background(), + harnessRepo, + "README.2", + &scm.ContentParams{ + Data: []byte("hello world"), + Message: "create README.2", + Branch: "main", + }, + ) + if err != nil { + t.Error(err) + } + + if result.Status != 200 { + t.Errorf("Unexpected Results") + } +} + +func TestContentUpdate(t *testing.T) { + defer gock.Off() + + gock.New(gockOrigin). + Post("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/demo/+/commits"). + Reply(200). + Type("plain/text"). + BodyString("{\"commit_id\":\"20ecde1f8c277da0e91750bef9f3b88f228d86db\"}") + + client, _ := New(gockOrigin, harnessOrg, harnessAccount, harnessProject) + client.Client = &http.Client{ + Transport: &transport.Custom{ + Before: func(r *http.Request) { + r.Header.Set("x-api-key", harnessPAT) + }, + }, + } + result, err := client.Contents.Update( + context.Background(), + harnessRepo, + "README.2", + &scm.ContentParams{ + Data: []byte("hello world 2"), + Message: "update README.2", + Branch: "main", + }, + ) + if err != nil { + t.Error(err) + } + + if result.Status != 200 { + t.Errorf("Unexpected Results") + } +} + +func TestContentDelete(t *testing.T) { + defer gock.Off() + + gock.New(gockOrigin). + Post("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/demo/+/commits"). + Reply(200). + Type("plain/text"). + BodyString("{\"commit_id\":\"20ecde1f8c277da0e91750bef9f3b88f228d86db\"}") + + client, _ := New(gockOrigin, harnessOrg, harnessAccount, harnessProject) + client.Client = &http.Client{ + Transport: &transport.Custom{ + Before: func(r *http.Request) { + r.Header.Set("x-api-key", harnessPAT) + }, + }, + } + result, err := client.Contents.Delete( + context.Background(), + harnessRepo, + "README.2", + &scm.ContentParams{ + Message: "delete README.2", + Branch: "main", + }, + ) + if err != nil { + t.Error(err) + } + + if result.Status != 200 { + t.Errorf("Unexpected Results") + } +} + +func TestContentList(t *testing.T) { + defer gock.Off() + + gock.New(gockOrigin). + Get("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/demo/+/content/docker"). + Reply(200). + Type("application/json"). + File("testdata/content_list.json") + + client, _ := New(gockOrigin, harnessOrg, harnessAccount, harnessProject) + client.Client = &http.Client{ + Transport: &transport.Custom{ + Before: func(r *http.Request) { + r.Header.Set("x-api-key", harnessPAT) + }, + }, + } + got, _, err := client.Contents.List( + context.Background(), + harnessRepo, + "docker", + "", + scm.ListOptions{}, + ) + if err != nil { + t.Error(err) + } + + want := []*scm.ContentInfo{} + raw, _ := ioutil.ReadFile("testdata/content_list.json.golden") + json.Unmarshal(raw, &want) + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } +} diff --git a/scm/driver/harness/git.go b/scm/driver/harness/git.go new file mode 100644 index 000000000..47b228021 --- /dev/null +++ b/scm/driver/harness/git.go @@ -0,0 +1,187 @@ +// Copyright 2017 Drone.IO Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package harness + +import ( + "context" + "fmt" + "net/url" + "time" + + "github.com/drone/go-scm/scm" +) + +type gitService struct { + client *wrapper +} + +func (s *gitService) CreateBranch(ctx context.Context, repo string, params *scm.ReferenceInput) (*scm.Response, error) { + return nil, scm.ErrNotSupported +} + +func (s *gitService) FindBranch(ctx context.Context, repo, name string) (*scm.Reference, *scm.Response, error) { + path := fmt.Sprintf("api/v1/repos/%s/branches/%s", repo, name) + out := new(branch) + res, err := s.client.do(ctx, "GET", path, nil, out) + return convertBranch(out), res, err +} + +func (s *gitService) FindCommit(ctx context.Context, repo, ref string) (*scm.Commit, *scm.Response, error) { + ref = scm.TrimRef(ref) + path := fmt.Sprintf("api/v1/repos/%s/git/commits/%s", repo, url.PathEscape(ref)) + out := new(commitInfo) + res, err := s.client.do(ctx, "GET", path, nil, out) + return convertCommitInfo(out), res, err +} + +func (s *gitService) FindTag(ctx context.Context, repo, name string) (*scm.Reference, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *gitService) ListBranches(ctx context.Context, repo string, opts scm.ListOptions) ([]*scm.Reference, *scm.Response, error) { + path := fmt.Sprintf("api/v1/repos/%s/branches?%s", repo, encodeListOptions(opts)) + out := []*branch{} + res, err := s.client.do(ctx, "GET", path, nil, &out) + return convertBranchList(out), res, err +} + +func (s *gitService) ListCommits(ctx context.Context, repo string, _ scm.CommitListOptions) ([]*scm.Commit, *scm.Response, error) { + path := fmt.Sprintf("api/v1/repos/%s/commits", repo) + out := []*commitInfo{} + res, err := s.client.do(ctx, "GET", path, nil, &out) + return convertCommitList(out), res, err +} + +func (s *gitService) ListTags(ctx context.Context, repo string, _ scm.ListOptions) ([]*scm.Reference, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *gitService) ListChanges(ctx context.Context, repo, ref string, _ scm.ListOptions) ([]*scm.Change, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *gitService) CompareChanges(ctx context.Context, repo, source, target string, _ scm.ListOptions) ([]*scm.Change, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +// +// native data structures +// + +type ( + // gitea branch object. + branch struct { + Name string `json:"name"` + Commit commit `json:"commit"` + } + + // gitea commit object. + commit struct { + ID string `json:"id"` + Sha string `json:"sha"` + Message string `json:"message"` + URL string `json:"url"` + Author signature `json:"author"` + Committer signature `json:"committer"` + Timestamp time.Time `json:"timestamp"` + } + + // gitea commit info object. + commitInfo struct { + Sha string `json:"sha"` + Commit commit `json:"commit"` + Author user `json:"author"` + Committer user `json:"committer"` + } + + // gitea signature object. + signature struct { + Name string `json:"name"` + Email string `json:"email"` + Username string `json:"username"` + } + + // gitea tag object + tag struct { + Ref string `json:"ref"` + URL string `json:"url"` + Object struct { + Type string `json:"type"` + Sha string `json:"sha"` + URL string `json:"url"` + } `json:"object"` + } +) + +// +// native data structure conversion +// + +func convertBranchList(src []*branch) []*scm.Reference { + dst := []*scm.Reference{} + for _, v := range src { + dst = append(dst, convertBranch(v)) + } + return dst +} + +func convertBranch(src *branch) *scm.Reference { + return &scm.Reference{ + Name: scm.TrimRef(src.Name), + Path: scm.ExpandRef(src.Name, "refs/heads/"), + Sha: src.Commit.ID, + } +} + +func convertCommitList(src []*commitInfo) []*scm.Commit { + dst := []*scm.Commit{} + for _, v := range src { + dst = append(dst, convertCommitInfo(v)) + } + return dst +} + +func convertCommitInfo(src *commitInfo) *scm.Commit { + return &scm.Commit{ + Sha: src.Sha, + Link: src.Commit.URL, + Message: src.Commit.Message, + Author: convertUserSignature(src.Author), + Committer: convertUserSignature(src.Committer), + } +} + +func convertSignature(src signature) scm.Signature { + return scm.Signature{ + Login: src.Username, + Email: src.Email, + Name: src.Name, + } +} + +func convertUserSignature(src user) scm.Signature { + return scm.Signature{ + Login: userLogin(&src), + Email: src.Email, + Name: src.Fullname, + Avatar: src.Avatar, + } +} + +func convertTagList(src []*tag) []*scm.Reference { + var dst []*scm.Reference + for _, v := range src { + dst = append(dst, convertTag(v)) + } + return dst +} + +func convertTag(src *tag) *scm.Reference { + return &scm.Reference{ + Name: scm.TrimRef(src.Ref), + Path: src.Ref, + Sha: src.Object.Sha, + } +} diff --git a/scm/driver/harness/git_test.go b/scm/driver/harness/git_test.go new file mode 100644 index 000000000..5d232e2ff --- /dev/null +++ b/scm/driver/harness/git_test.go @@ -0,0 +1,5 @@ +// Copyright 2017 Drone.IO Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package harness diff --git a/scm/driver/harness/harness.go b/scm/driver/harness/harness.go new file mode 100644 index 000000000..d26835374 --- /dev/null +++ b/scm/driver/harness/harness.go @@ -0,0 +1,108 @@ +// Copyright 2017 Drone.IO Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package harness + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "strings" + + "github.com/drone/go-scm/scm" +) + +// New returns a new gitness API client. +func New(uri, account, organization, project string) (*scm.Client, error) { + if !((organization == "" && account == "" && project == "") || (organization != "" && account != "" && project != "")) { + return nil, fmt.Errorf("harness account, organization and project are required") + } + base, err := url.Parse(uri) + if err != nil { + return nil, err + } + if !strings.HasSuffix(base.Path, "/") { + base.Path = base.Path + "/" + } + client := &wrapper{new(scm.Client), account, organization, project} + client.BaseURL = base + // initialize services + client.Driver = scm.DriverGitea + client.Linker = &linker{base.String()} + client.Contents = &contentService{client} + client.Git = &gitService{client} + client.Issues = &issueService{client} + client.Milestones = &milestoneService{client} + client.Organizations = &organizationService{client} + client.PullRequests = &pullService{client} + client.Repositories = &repositoryService{client} + client.Releases = &releaseService{client} + client.Reviews = &reviewService{client} + client.Users = &userService{client} + client.Webhooks = &webhookService{client} + return client.Client, nil +} + +// wraper wraps the Client to provide high level helper functions +// for making http requests and unmarshaling the response. +type wrapper struct { + *scm.Client + account string + organization string + project string +} + +// do wraps the Client.Do function by creating the Request and +// unmarshalling the response. +func (c *wrapper) do(ctx context.Context, method, path string, in, out interface{}) (*scm.Response, error) { + req := &scm.Request{ + Method: method, + Path: path, + } + // if we are posting or putting data, we need to + // write it to the body of the request. + if in != nil { + buf := new(bytes.Buffer) + json.NewEncoder(buf).Encode(in) + req.Header = map[string][]string{ + "Content-Type": {"application/json"}, + } + req.Body = buf + } + + // execute the http request + res, err := c.Client.Do(ctx, req) + if err != nil { + return nil, err + } + defer res.Body.Close() + + // if an error is encountered, unmarshal and return the + // error response. + if res.Status > 300 { + return res, errors.New( + http.StatusText(res.Status), + ) + } + + if out == nil { + return res, nil + } + + // if raw output is expected, copy to the provided + // buffer and exit. + if w, ok := out.(io.Writer); ok { + io.Copy(w, res.Body) + return res, nil + } + + // if a json response is expected, parse and return + // the json response. + return res, json.NewDecoder(res.Body).Decode(out) +} diff --git a/scm/driver/harness/harness_test.go b/scm/driver/harness/harness_test.go new file mode 100644 index 000000000..a1ccc6f90 --- /dev/null +++ b/scm/driver/harness/harness_test.go @@ -0,0 +1,47 @@ +// Copyright 2017 Drone.IO Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// package gitea implements a Gogs client. +package harness + +import ( + "fmt" + "testing" + + "github.com/drone/go-scm/scm" +) + +func TestClient(t *testing.T) { + client, err := New(gockOrigin, "", "", "") + if err != nil { + t.Error(err) + } + if got, want := client.BaseURL.String(), fmt.Sprintf("%s/", gockOrigin); got != want { + t.Errorf("Want Client URL %q, got %q", want, got) + } +} + +func TestClient_Error(t *testing.T) { + _, err := New("http://a b.com/", "", "", "") + if err == nil { + t.Errorf("Expect error when invalid URL") + } +} + +func testPage(res *scm.Response) func(t *testing.T) { + return func(t *testing.T) { + if got, want := res.Page.Next, 2; got != want { + t.Errorf("Want next page %d, got %d", want, got) + } + if got, want := res.Page.Prev, 1; got != want { + t.Errorf("Want prev page %d, got %d", want, got) + } + if got, want := res.Page.First, 1; got != want { + t.Errorf("Want first page %d, got %d", want, got) + } + if got, want := res.Page.Last, 5; got != want { + t.Errorf("Want last page %d, got %d", want, got) + } + } +} diff --git a/scm/driver/harness/issue.go b/scm/driver/harness/issue.go new file mode 100644 index 000000000..6eab881c5 --- /dev/null +++ b/scm/driver/harness/issue.go @@ -0,0 +1,147 @@ +// Copyright 2017 Drone.IO Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package harness + +import ( + "context" + "time" + + "github.com/drone/go-scm/scm" +) + +type issueService struct { + client *wrapper +} + +func (s *issueService) Find(ctx context.Context, repo string, number int) (*scm.Issue, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *issueService) FindComment(ctx context.Context, repo string, index, id int) (*scm.Comment, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *issueService) List(ctx context.Context, repo string, opts scm.IssueListOptions) ([]*scm.Issue, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported + +} + +func (s *issueService) ListComments(ctx context.Context, repo string, index int, opts scm.ListOptions) ([]*scm.Comment, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported + +} + +func (s *issueService) Create(ctx context.Context, repo string, input *scm.IssueInput) (*scm.Issue, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported + +} + +func (s *issueService) CreateComment(ctx context.Context, repo string, index int, input *scm.CommentInput) (*scm.Comment, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *issueService) DeleteComment(ctx context.Context, repo string, index, id int) (*scm.Response, error) { + return nil, scm.ErrNotSupported +} + +func (s *issueService) Close(ctx context.Context, repo string, number int) (*scm.Response, error) { + return nil, scm.ErrNotSupported +} + +func (s *issueService) Lock(ctx context.Context, repo string, number int) (*scm.Response, error) { + return nil, scm.ErrNotSupported +} + +func (s *issueService) Unlock(ctx context.Context, repo string, number int) (*scm.Response, error) { + return nil, scm.ErrNotSupported +} + +// +// native data structures +// + +type ( + // gitea issue response object. + issue struct { + ID int `json:"id"` + Number int `json:"number"` + User user `json:"user"` + Title string `json:"title"` + Body string `json:"body"` + State string `json:"state"` + Labels []string `json:"labels"` + Comments int `json:"comments"` + Created time.Time `json:"created_at"` + Updated time.Time `json:"updated_at"` + PullRequest *struct { + Merged bool `json:"merged"` + MergedAt interface{} `json:"merged_at"` + } `json:"pull_request"` + } + + // gitea issue request object. + issueInput struct { + Title string `json:"title"` + Body string `json:"body"` + } + + // gitea issue comment response object. + issueComment struct { + ID int `json:"id"` + HTMLURL string `json:"html_url"` + User user `json:"user"` + Body string `json:"body"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + } + + // gitea issue comment request object. + issueCommentInput struct { + Body string `json:"body"` + } +) + +// +// native data structure conversion +// + +func convertIssueList(from []*issue) []*scm.Issue { + to := []*scm.Issue{} + for _, v := range from { + to = append(to, convertIssue(v)) + } + return to +} + +func convertIssue(from *issue) *scm.Issue { + return &scm.Issue{ + Number: from.Number, + Title: from.Title, + Body: from.Body, + Link: "", // TODO construct the link to the issue. + Closed: from.State == "closed", + Author: *convertUser(&from.User), + Created: from.Created, + Updated: from.Updated, + } +} + +func convertIssueCommentList(from []*issueComment) []*scm.Comment { + to := []*scm.Comment{} + for _, v := range from { + to = append(to, convertIssueComment(v)) + } + return to +} + +func convertIssueComment(from *issueComment) *scm.Comment { + return &scm.Comment{ + ID: from.ID, + Body: from.Body, + Author: *convertUser(&from.User), + Created: from.CreatedAt, + Updated: from.UpdatedAt, + } +} diff --git a/scm/driver/harness/issue_test.go b/scm/driver/harness/issue_test.go new file mode 100644 index 000000000..5d232e2ff --- /dev/null +++ b/scm/driver/harness/issue_test.go @@ -0,0 +1,5 @@ +// Copyright 2017 Drone.IO Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package harness diff --git a/scm/driver/harness/linker.go b/scm/driver/harness/linker.go new file mode 100644 index 000000000..e0c01d820 --- /dev/null +++ b/scm/driver/harness/linker.go @@ -0,0 +1,27 @@ +// Copyright 2017 Drone.IO Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package harness + +import ( + "context" + + "github.com/drone/go-scm/scm" +) + +type linker struct { + base string +} + +// Resource returns a link to the resource. +func (l *linker) Resource(ctx context.Context, repo string, ref scm.Reference) (string, error) { + return "", scm.ErrNotSupported + +} + +// Diff returns a link to the diff. +func (l *linker) Diff(ctx context.Context, repo string, source, target scm.Reference) (string, error) { + return "", scm.ErrNotSupported + +} diff --git a/scm/driver/harness/linker_test.go b/scm/driver/harness/linker_test.go new file mode 100644 index 000000000..5d232e2ff --- /dev/null +++ b/scm/driver/harness/linker_test.go @@ -0,0 +1,5 @@ +// Copyright 2017 Drone.IO Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package harness diff --git a/scm/driver/harness/milestone.go b/scm/driver/harness/milestone.go new file mode 100644 index 000000000..34784287a --- /dev/null +++ b/scm/driver/harness/milestone.go @@ -0,0 +1,90 @@ +package harness + +import ( + "context" + + "github.com/drone/go-scm/scm" + "github.com/drone/go-scm/scm/driver/internal/null" +) + +type milestoneService struct { + client *wrapper +} + +func (s *milestoneService) Find(ctx context.Context, repo string, id int) (*scm.Milestone, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported + +} + +func (s *milestoneService) List(ctx context.Context, repo string, opts scm.MilestoneListOptions) ([]*scm.Milestone, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported + +} + +func (s *milestoneService) Create(ctx context.Context, repo string, input *scm.MilestoneInput) (*scm.Milestone, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported + +} + +func (s *milestoneService) Delete(ctx context.Context, repo string, id int) (*scm.Response, error) { + return nil, scm.ErrNotSupported + +} + +func (s *milestoneService) Update(ctx context.Context, repo string, id int, input *scm.MilestoneInput) (*scm.Milestone, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +// stateType issue state type +type stateType string + +const ( + // stateOpen pr/issue is open + stateOpen stateType = "open" + // stateClosed pr/issue is closed + stateClosed stateType = "closed" + // stateAll is all + stateAll stateType = "all" +) + +type milestone struct { + ID int64 `json:"id"` + Title string `json:"title"` + Description string `json:"description"` + State stateType `json:"state"` + OpenIssues int `json:"open_issues"` + ClosedIssues int `json:"closed_issues"` + Created null.Time `json:"created_at"` + Updated null.Time `json:"updated_at"` + Closed null.Time `json:"closed_at"` + Deadline null.Time `json:"due_on"` +} + +type milestoneInput struct { + Title string `json:"title"` + Description string `json:"description"` + State stateType `json:"state"` + Deadline null.Time `json:"due_on"` +} + +func convertMilestoneList(src []*milestone) []*scm.Milestone { + var dst []*scm.Milestone + for _, v := range src { + dst = append(dst, convertMilestone(v)) + } + return dst +} + +func convertMilestone(src *milestone) *scm.Milestone { + if src == nil || src.Deadline.IsZero() { + return nil + } + return &scm.Milestone{ + Number: int(src.ID), + ID: int(src.ID), + Title: src.Title, + Description: src.Description, + State: string(src.State), + DueDate: src.Deadline.ValueOrZero(), + } +} diff --git a/scm/driver/harness/milestone_test.go b/scm/driver/harness/milestone_test.go new file mode 100644 index 000000000..1815bffed --- /dev/null +++ b/scm/driver/harness/milestone_test.go @@ -0,0 +1 @@ +package harness diff --git a/scm/driver/harness/org.go b/scm/driver/harness/org.go new file mode 100644 index 000000000..28239d8d6 --- /dev/null +++ b/scm/driver/harness/org.go @@ -0,0 +1,57 @@ +// Copyright 2017 Drone.IO Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package harness + +import ( + "context" + + "github.com/drone/go-scm/scm" +) + +type organizationService struct { + client *wrapper +} + +func (s *organizationService) Find(ctx context.Context, name string) (*scm.Organization, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported + +} + +func (s *organizationService) FindMembership(ctx context.Context, name, username string) (*scm.Membership, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *organizationService) List(ctx context.Context, opts scm.ListOptions) ([]*scm.Organization, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported + +} + +// +// native data structures +// + +type org struct { + Name string `json:"username"` + Avatar string `json:"avatar_url"` +} + +// +// native data structure conversion +// + +func convertOrgList(from []*org) []*scm.Organization { + to := []*scm.Organization{} + for _, v := range from { + to = append(to, convertOrg(v)) + } + return to +} + +func convertOrg(from *org) *scm.Organization { + return &scm.Organization{ + Name: from.Name, + Avatar: from.Avatar, + } +} diff --git a/scm/driver/harness/org_test.go b/scm/driver/harness/org_test.go new file mode 100644 index 000000000..5d232e2ff --- /dev/null +++ b/scm/driver/harness/org_test.go @@ -0,0 +1,5 @@ +// Copyright 2017 Drone.IO Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package harness diff --git a/scm/driver/harness/pr.go b/scm/driver/harness/pr.go new file mode 100644 index 000000000..46f64367b --- /dev/null +++ b/scm/driver/harness/pr.go @@ -0,0 +1,157 @@ +// Copyright 2017 Drone.IO Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package harness + +import ( + "context" + "fmt" + "time" + + "github.com/drone/go-scm/scm" +) + +type pullService struct { + client *wrapper +} + +func (s *pullService) Find(ctx context.Context, repo string, index int) (*scm.PullRequest, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported + +} + +func (s *pullService) FindComment(context.Context, string, int, int) (*scm.Comment, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *pullService) List(ctx context.Context, repo string, opts scm.PullRequestListOptions) ([]*scm.PullRequest, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *pullService) ListComments(context.Context, string, int, scm.ListOptions) ([]*scm.Comment, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *pullService) ListCommits(context.Context, string, int, scm.ListOptions) ([]*scm.Commit, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *pullService) ListChanges(context.Context, string, int, scm.ListOptions) ([]*scm.Change, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *pullService) Create(ctx context.Context, repo string, input *scm.PullRequestInput) (*scm.PullRequest, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *pullService) CreateComment(context.Context, string, int, *scm.CommentInput) (*scm.Comment, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *pullService) DeleteComment(context.Context, string, int, int) (*scm.Response, error) { + return nil, scm.ErrNotSupported +} + +func (s *pullService) Merge(ctx context.Context, repo string, index int) (*scm.Response, error) { + return nil, scm.ErrNotSupported +} + +func (s *pullService) Close(context.Context, string, int) (*scm.Response, error) { + return nil, scm.ErrNotSupported +} + +// +// native data structures +// + +type pr struct { + ID int `json:"id"` + Number int `json:"number"` + User user `json:"user"` + Title string `json:"title"` + Body string `json:"body"` + State string `json:"state"` + HeadBranch string `json:"head_branch"` + HeadRepo repository `json:"head_repo"` + Head reference `json:"head"` + BaseBranch string `json:"base_branch"` + BaseRepo repository `json:"base_repo"` + Base reference `json:"base"` + HTMLURL string `json:"html_url"` + DiffURL string `json:"diff_url"` + Mergeable bool `json:"mergeable"` + Merged bool `json:"merged"` + Created time.Time `json:"created_at"` + Updated time.Time `json:"updated_at"` + Labels []struct { + Name string `json:"name"` + Color string `json:"color"` + } `json:"labels"` +} + +type reference struct { + Repo repository `json:"repo"` + Name string `json:"ref"` + Sha string `json:"sha"` +} + +type prInput struct { + Title string `json:"title"` + Body string `json:"body"` + Head string `json:"head"` + Base string `json:"base"` +} + +// +// native data structure conversion +// + +func convertPullRequests(src []*pr) []*scm.PullRequest { + dst := []*scm.PullRequest{} + for _, v := range src { + dst = append(dst, convertPullRequest(v)) + } + return dst +} + +func convertPullRequest(src *pr) *scm.PullRequest { + var labels []scm.Label + for _, label := range src.Labels { + labels = append(labels, scm.Label{ + Name: label.Name, + Color: label.Color, + }) + } + return &scm.PullRequest{ + Number: src.Number, + Title: src.Title, + Body: src.Body, + Sha: src.Head.Sha, + Source: src.Head.Name, + Target: src.Base.Name, + Link: src.HTMLURL, + Diff: src.DiffURL, + Fork: src.Base.Repo.FullName, + Ref: fmt.Sprintf("refs/pull/%d/head", src.Number), + Closed: src.State == "closed", + Author: *convertUser(&src.User), + Merged: src.Merged, + Created: src.Created, + Updated: src.Updated, + Labels: labels, + } +} + +func convertPullRequestFromIssue(src *issue) *scm.PullRequest { + return &scm.PullRequest{ + Number: src.Number, + Title: src.Title, + Body: src.Body, + Closed: src.State == "closed", + Author: *convertUser(&src.User), + Merged: src.PullRequest.Merged, + Created: src.Created, + Updated: src.Updated, + } +} diff --git a/scm/driver/harness/pr_test.go b/scm/driver/harness/pr_test.go new file mode 100644 index 000000000..5d232e2ff --- /dev/null +++ b/scm/driver/harness/pr_test.go @@ -0,0 +1,5 @@ +// Copyright 2017 Drone.IO Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package harness diff --git a/scm/driver/harness/release.go b/scm/driver/harness/release.go new file mode 100644 index 000000000..45e10704a --- /dev/null +++ b/scm/driver/harness/release.go @@ -0,0 +1,112 @@ +package harness + +import ( + "context" + + "github.com/drone/go-scm/scm" + "github.com/drone/go-scm/scm/driver/internal/null" +) + +type releaseService struct { + client *wrapper +} + +func (s *releaseService) Find(ctx context.Context, repo string, id int) (*scm.Release, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *releaseService) FindByTag(ctx context.Context, repo string, tag string) (*scm.Release, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *releaseService) List(ctx context.Context, repo string, opts scm.ReleaseListOptions) ([]*scm.Release, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *releaseService) Create(ctx context.Context, repo string, input *scm.ReleaseInput) (*scm.Release, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *releaseService) Delete(ctx context.Context, repo string, id int) (*scm.Response, error) { + return nil, scm.ErrNotSupported +} + +func (s *releaseService) DeleteByTag(ctx context.Context, repo string, tag string) (*scm.Response, error) { + return nil, scm.ErrNotSupported +} + +func (s *releaseService) Update(ctx context.Context, repo string, id int, input *scm.ReleaseInput) (*scm.Release, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *releaseService) UpdateByTag(ctx context.Context, repo string, tag string, input *scm.ReleaseInput) (*scm.Release, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +type ReleaseInput struct { + TagName string `json:"tag_name"` + Target string `json:"target_commitish"` + Title string `json:"name"` + Note string `json:"body"` + IsDraft bool `json:"draft"` + IsPrerelease bool `json:"prerelease"` +} + +// release represents a repository release +type release struct { + ID int64 `json:"id"` + TagName string `json:"tag_name"` + Target string `json:"target_commitish"` + Title string `json:"name"` + Note string `json:"body"` + URL string `json:"url"` + HTMLURL string `json:"html_url"` + TarURL string `json:"tarball_url"` + ZipURL string `json:"zipball_url"` + IsDraft bool `json:"draft"` + IsPrerelease bool `json:"prerelease"` + CreatedAt null.Time `json:"created_at"` + PublishedAt null.Time `json:"published_at"` + Publisher *user `json:"author"` + Attachments []*Attachment `json:"assets"` +} + +type Attachment struct { + ID int64 `json:"id"` + Name string `json:"name"` + Size int64 `json:"size"` + DownloadCount int64 `json:"download_count"` + Created null.Time `json:"created_at"` + UUID string `json:"uuid"` + DownloadURL string `json:"browser_download_url"` +} + +func convertRelease(src *release) *scm.Release { + return &scm.Release{ + ID: int(src.ID), + Title: src.Title, + Description: src.Note, + Link: convertAPIURLToHTMLURL(src.URL, src.TagName), + Tag: src.TagName, + Commitish: src.Target, + Draft: src.IsDraft, + Prerelease: src.IsPrerelease, + Created: src.CreatedAt.ValueOrZero(), + Published: src.PublishedAt.ValueOrZero(), + } +} + +func convertReleaseList(src []*release) []*scm.Release { + var dst []*scm.Release + for _, v := range src { + dst = append(dst, convertRelease(v)) + } + return dst +} + +func releaseListOptionsToGiteaListOptions(in scm.ReleaseListOptions) ListOptions { + return ListOptions{ + Page: in.Page, + PageSize: in.Size, + } +} diff --git a/scm/driver/harness/release_test.go b/scm/driver/harness/release_test.go new file mode 100644 index 000000000..1815bffed --- /dev/null +++ b/scm/driver/harness/release_test.go @@ -0,0 +1 @@ +package harness diff --git a/scm/driver/harness/repo.go b/scm/driver/harness/repo.go new file mode 100644 index 000000000..d21017154 --- /dev/null +++ b/scm/driver/harness/repo.go @@ -0,0 +1,273 @@ +// Copyright 2017 Drone.IO Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package harness + +import ( + "context" + "fmt" + "net/url" + "strconv" + "time" + + "github.com/drone/go-scm/scm" +) + +type repositoryService struct { + client *wrapper +} + +func (s *repositoryService) Find(ctx context.Context, repo string) (*scm.Repository, *scm.Response, error) { + path := fmt.Sprintf("api/v1/repos/%s", repo) + out := new(repository) + res, err := s.client.do(ctx, "GET", path, nil, out) + return convertRepository(out), res, err +} + +func (s *repositoryService) FindHook(ctx context.Context, repo string, id string) (*scm.Hook, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *repositoryService) FindPerms(ctx context.Context, repo string) (*scm.Perm, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *repositoryService) List(ctx context.Context, opts scm.ListOptions) ([]*scm.Repository, *scm.Response, error) { + path := fmt.Sprintf("api/v1/user/repos?%s", encodeListOptions(opts)) + out := []*repository{} + res, err := s.client.do(ctx, "GET", path, nil, &out) + return convertRepositoryList(out), res, err +} + +func (s *repositoryService) ListHooks(ctx context.Context, repo string, opts scm.ListOptions) ([]*scm.Hook, *scm.Response, error) { + path := fmt.Sprintf("api/v1/repos/%s/hooks?%s", repo, encodeListOptions(opts)) + out := []*hook{} + res, err := s.client.do(ctx, "GET", path, nil, &out) + return convertHookList(out), res, err +} + +func (s *repositoryService) ListStatus(ctx context.Context, repo string, ref string, opts scm.ListOptions) ([]*scm.Status, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *repositoryService) CreateHook(ctx context.Context, repo string, input *scm.HookInput) (*scm.Hook, *scm.Response, error) { + target, err := url.Parse(input.Target) + if err != nil { + return nil, nil, err + } + params := target.Query() + params.Set("secret", input.Secret) + target.RawQuery = params.Encode() + + path := fmt.Sprintf("api/v1/repos/%s/hooks", repo) + in := new(hook) + in.Type = "gitea" + in.Active = true + in.Config.Secret = input.Secret + in.Config.ContentType = "json" + in.Config.URL = target.String() + in.Events = append( + input.NativeEvents, + convertHookEvent(input.Events)..., + ) + out := new(hook) + res, err := s.client.do(ctx, "POST", path, in, out) + return convertHook(out), res, err +} + +func (s *repositoryService) CreateStatus(ctx context.Context, repo string, ref string, input *scm.StatusInput) (*scm.Status, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *repositoryService) UpdateHook(ctx context.Context, repo, id string, input *scm.HookInput) (*scm.Hook, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *repositoryService) DeleteHook(ctx context.Context, repo string, id string) (*scm.Response, error) { + path := fmt.Sprintf("api/v1/repos/%s/hooks/%s", repo, id) + return s.client.do(ctx, "DELETE", path, nil, nil) +} + +// +// native data structures +// + +type ( + // gitea repository resource. + repository struct { + ID int `json:"id"` + Owner user `json:"owner"` + Name string `json:"name"` + FullName string `json:"full_name"` + Private bool `json:"private"` + Fork bool `json:"fork"` + HTMLURL string `json:"html_url"` + SSHURL string `json:"ssh_url"` + CloneURL string `json:"clone_url"` + DefaultBranch string `json:"default_branch"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + Permissions perm `json:"permissions"` + Archived bool `json:"archived"` + } + + // gitea permissions details. + perm struct { + Admin bool `json:"admin"` + Push bool `json:"push"` + Pull bool `json:"pull"` + } + + // gitea hook resource. + hook struct { + ID int `json:"id"` + Type string `json:"type"` + Events []string `json:"events"` + Active bool `json:"active"` + Config hookConfig `json:"config"` + } + + // gitea hook configuration details. + hookConfig struct { + URL string `json:"url"` + ContentType string `json:"content_type"` + Secret string `json:"secret"` + } + + // gitea status resource. + status struct { + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + State string `json:"status"` + TargetURL string `json:"target_url"` + Description string `json:"description"` + Context string `json:"context"` + } + + // gitea status creation request. + statusInput struct { + State string `json:"state"` + TargetURL string `json:"target_url"` + Description string `json:"description"` + Context string `json:"context"` + } +) + +// +// native data structure conversion +// + +func convertRepositoryList(src []*repository) []*scm.Repository { + var dst []*scm.Repository + for _, v := range src { + dst = append(dst, convertRepository(v)) + } + return dst +} + +func convertRepository(src *repository) *scm.Repository { + return &scm.Repository{ + ID: strconv.Itoa(src.ID), + Namespace: userLogin(&src.Owner), + Name: src.Name, + Perm: convertPerm(src.Permissions), + Branch: src.DefaultBranch, + Private: src.Private, + Clone: src.CloneURL, + CloneSSH: src.SSHURL, + Link: src.HTMLURL, + Archived: src.Archived, + } +} + +func convertPerm(src perm) *scm.Perm { + return &scm.Perm{ + Push: src.Push, + Pull: src.Pull, + Admin: src.Admin, + } +} + +func convertHookList(src []*hook) []*scm.Hook { + var dst []*scm.Hook + for _, v := range src { + dst = append(dst, convertHook(v)) + } + return dst +} + +func convertHook(from *hook) *scm.Hook { + return &scm.Hook{ + ID: strconv.Itoa(from.ID), + Active: from.Active, + Target: from.Config.URL, + Events: from.Events, + } +} + +func convertHookEvent(from scm.HookEvents) []string { + var events []string + if from.PullRequest { + events = append(events, "pull_request") + } + if from.Issue { + events = append(events, "issues") + } + if from.IssueComment || from.PullRequestComment { + events = append(events, "issue_comment") + } + if from.Branch || from.Tag { + events = append(events, "create") + events = append(events, "delete") + } + if from.Push { + events = append(events, "push") + } + return events +} + +func convertStatusList(src []*status) []*scm.Status { + var dst []*scm.Status + for _, v := range src { + dst = append(dst, convertStatus(v)) + } + return dst +} + +func convertStatus(from *status) *scm.Status { + return &scm.Status{ + State: convertState(from.State), + Label: from.Context, + Desc: from.Description, + Target: from.TargetURL, + } +} + +func convertState(from string) scm.State { + switch from { + case "error": + return scm.StateError + case "failure": + return scm.StateFailure + case "pending": + return scm.StatePending + case "success": + return scm.StateSuccess + default: + return scm.StateUnknown + } +} + +func convertFromState(from scm.State) string { + switch from { + case scm.StatePending, scm.StateRunning: + return "pending" + case scm.StateSuccess: + return "success" + case scm.StateFailure: + return "failure" + default: + return "error" + } +} diff --git a/scm/driver/harness/repo_test.go b/scm/driver/harness/repo_test.go new file mode 100644 index 000000000..8bb7df63a --- /dev/null +++ b/scm/driver/harness/repo_test.go @@ -0,0 +1,9 @@ +// Copyright 2017 Drone.IO Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package harness + +// +// repository sub-tests +// diff --git a/scm/driver/harness/review.go b/scm/driver/harness/review.go new file mode 100644 index 000000000..898595bd4 --- /dev/null +++ b/scm/driver/harness/review.go @@ -0,0 +1,31 @@ +// Copyright 2017 Drone.IO Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package harness + +import ( + "context" + + "github.com/drone/go-scm/scm" +) + +type reviewService struct { + client *wrapper +} + +func (s *reviewService) Find(ctx context.Context, repo string, number, id int) (*scm.Review, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *reviewService) List(ctx context.Context, repo string, number int, opts scm.ListOptions) ([]*scm.Review, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *reviewService) Create(ctx context.Context, repo string, number int, input *scm.ReviewInput) (*scm.Review, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *reviewService) Delete(ctx context.Context, repo string, number, id int) (*scm.Response, error) { + return nil, scm.ErrNotSupported +} diff --git a/scm/driver/harness/review_test.go b/scm/driver/harness/review_test.go new file mode 100644 index 000000000..5d232e2ff --- /dev/null +++ b/scm/driver/harness/review_test.go @@ -0,0 +1,5 @@ +// Copyright 2017 Drone.IO Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package harness diff --git a/scm/driver/harness/testdata/content.json b/scm/driver/harness/testdata/content.json new file mode 100644 index 000000000..b7408335a --- /dev/null +++ b/scm/driver/harness/testdata/content.json @@ -0,0 +1,30 @@ +{ + "type": "file", + "sha": "7839122fc2ec4af9d5a6c14c779a82a05c5769b5", + "name": "README.md", + "path": "README.md", + "latest_commit": { + "sha": "98189d5cf2a751a6246c24a72945ba70839f1b20", + "title": "initial commit", + "message": "initial commit", + "author": { + "identity": { + "name": "gitness", + "email": "system@gitness" + }, + "when": "2023-02-02T14:12:13Z" + }, + "committer": { + "identity": { + "name": "gitness", + "email": "system@gitness" + }, + "when": "2023-02-02T14:12:13Z" + } + }, + "content": { + "encoding": "base64", + "data": "ZGVtbw0KdGVzdCBzdHJpbmc=", + "size": 23 + } +} \ No newline at end of file diff --git a/scm/driver/harness/testdata/content_list.json b/scm/driver/harness/testdata/content_list.json new file mode 100644 index 000000000..33575adee --- /dev/null +++ b/scm/driver/harness/testdata/content_list.json @@ -0,0 +1,79 @@ +{ + "type": "dir", + "sha": "4fdc5acb2f9074a6d6ec826f01518fb27fe20a06", + "name": "", + "path": "", + "latest_commit": { + "sha": "4381eecb9dd29c34972087c4185f392c20d9f7c0", + "title": "move to version 1.1.2", + "message": "move to version 1.1.2", + "author": { + "identity": { + "name": "Johannes Batzill", + "email": "johannes.batzill@harness.io" + }, + "when": "2023-02-01T02:27:42Z" + }, + "committer": { + "identity": { + "name": "Johannes Batzill", + "email": "johannes.batzill@harness.io" + }, + "when": "2023-02-01T02:27:42Z" + } + }, + "content": { + "entries": [ + { + "type": "file", + "sha": "41fdf994e79e42bd4136c7e3004367f6d21d800d", + "name": ".gitignore", + "path": ".gitignore", + "latest_commit": { + "sha": "f8de11b6f3e4499889e16b989977c66c84ad02c9", + "title": "add initial version of demo application", + "message": "add initial version of demo application", + "author": { + "identity": { + "name": "Johannes Batzill", + "email": "johannes.batzill@harness.io" + }, + "when": "2023-02-01T00:08:20Z" + }, + "committer": { + "identity": { + "name": "Johannes Batzill", + "email": "johannes.batzill@harness.io" + }, + "when": "2023-02-01T00:08:20Z" + } + } + }, + { + "type": "file", + "sha": "261eeb9e9f8b2b4b0d119366dda99c6fd7d35c64", + "name": "LICENSE", + "path": "LICENSE", + "latest_commit": { + "sha": "a2a1bb3664f096e69f4b15b80f4650cc9f8ae913", + "title": "Initial commit", + "message": "Initial commit", + "author": { + "identity": { + "name": "Johannes Batzill", + "email": "johannes.batzill@harness.io" + }, + "when": "2023-01-31T23:54:24Z" + }, + "committer": { + "identity": { + "name": "GitHub", + "email": "noreply@github.com" + }, + "when": "2023-01-31T23:54:24Z" + } + } + } + ] + } +} \ No newline at end of file diff --git a/scm/driver/harness/testdata/content_list.json.golden b/scm/driver/harness/testdata/content_list.json.golden new file mode 100644 index 000000000..c23fd5007 --- /dev/null +++ b/scm/driver/harness/testdata/content_list.json.golden @@ -0,0 +1,14 @@ +[ + { + "Path": ".gitignore", + "Sha": "f8de11b6f3e4499889e16b989977c66c84ad02c9", + "BlobID": "41fdf994e79e42bd4136c7e3004367f6d21d800d", + "kind": "file" + }, + { + "Path": "LICENSE", + "Sha": "a2a1bb3664f096e69f4b15b80f4650cc9f8ae913", + "BlobID": "261eeb9e9f8b2b4b0d119366dda99c6fd7d35c64", + "kind": "file" + } +] diff --git a/scm/driver/harness/testdata/webhooks/pull_request_opened.json b/scm/driver/harness/testdata/webhooks/pull_request_opened.json new file mode 100644 index 000000000..9244c2035 --- /dev/null +++ b/scm/driver/harness/testdata/webhooks/pull_request_opened.json @@ -0,0 +1,172 @@ +{ + "secret": "12345", + "action": "opened", + "number": 1, + "pull_request": { + "id": 473, + "url": "", + "number": 1, + "user": { + "id": 6641, + "login": "jcitizen", + "full_name": "", + "email": "jane@example.com", + "avatar_url": "https://secure.gravatar.com/avatar/66f07ff48e6a9cb393de7a34e03bb52a?d=identicon", + "language": "en-US", + "username": "jcitizen" + }, + "title": "Add License File", + "body": "Using a BSD License", + "labels": [], + "milestone": null, + "assignee": null, + "assignees": null, + "state": "open", + "comments": 0, + "html_url": "https://try.gitea.io/jcitizen/my-repo/pulls/1", + "diff_url": "https://try.gitea.io/jcitizen/my-repo/pulls/1.diff", + "patch_url": "https://try.gitea.io/jcitizen/my-repo/pulls/1.patch", + "mergeable": true, + "merged": false, + "merged_at": null, + "merge_commit_sha": null, + "merged_by": null, + "base": { + "label": "master", + "ref": "master", + "sha": "39af58f1eff02aa308e16913e887c8d50362b474", + "repo_id": 6589, + "repo": { + "id": 6589, + "owner": { + "id": 6641, + "login": "jcitizen", + "full_name": "", + "email": "jane@example.com", + "avatar_url": "https://secure.gravatar.com/avatar/66f07ff48e6a9cb393de7a34e03bb52a?d=identicon", + "language": "en-US", + "username": "jcitizen" + }, + "name": "my-repo", + "full_name": "jcitizen/my-repo", + "description": "", + "empty": false, + "private": false, + "fork": false, + "parent": null, + "mirror": false, + "size": 64, + "html_url": "https://try.gitea.io/jcitizen/my-repo", + "ssh_url": "git@try.gitea.io:jcitizen/my-repo.git", + "clone_url": "https://try.gitea.io/jcitizen/my-repo.git", + "website": "", + "stars_count": 0, + "forks_count": 0, + "watchers_count": 1, + "open_issues_count": 0, + "default_branch": "master", + "created_at": "2018-07-06T00:08:02Z", + "updated_at": "2018-07-06T01:06:56Z", + "permissions": { + "admin": false, + "push": false, + "pull": false + } + } + }, + "head": { + "label": "feature", + "ref": "feature", + "sha": "2eba238e33607c1fa49253182e9fff42baafa1eb", + "repo_id": 6589, + "repo": { + "id": 6589, + "owner": { + "id": 6641, + "login": "jcitizen", + "full_name": "", + "email": "jane@example.com", + "avatar_url": "https://secure.gravatar.com/avatar/66f07ff48e6a9cb393de7a34e03bb52a?d=identicon", + "language": "en-US", + "username": "jcitizen" + }, + "name": "my-repo", + "full_name": "jcitizen/my-repo", + "description": "", + "empty": false, + "private": false, + "fork": false, + "parent": null, + "mirror": false, + "size": 64, + "html_url": "https://try.gitea.io/jcitizen/my-repo", + "ssh_url": "git@try.gitea.io:jcitizen/my-repo.git", + "clone_url": "https://try.gitea.io/jcitizen/my-repo.git", + "website": "", + "stars_count": 0, + "forks_count": 0, + "watchers_count": 1, + "open_issues_count": 0, + "default_branch": "master", + "created_at": "2018-07-06T00:08:02Z", + "updated_at": "2018-07-06T01:06:56Z", + "permissions": { + "admin": false, + "push": false, + "pull": false + } + } + }, + "merge_base": "39af58f1eff02aa308e16913e887c8d50362b474", + "due_date": null, + "created_at": "2018-07-06T00:37:47Z", + "updated_at": "2018-07-06T00:37:47Z", + "closed_at": null + }, + "repository": { + "id": 6589, + "owner": { + "id": 6641, + "login": "jcitizen", + "full_name": "", + "email": "jane@example.com", + "avatar_url": "https://secure.gravatar.com/avatar/66f07ff48e6a9cb393de7a34e03bb52a?d=identicon", + "language": "en-US", + "username": "jcitizen" + }, + "name": "my-repo", + "full_name": "jcitizen/my-repo", + "description": "", + "empty": false, + "private": false, + "fork": false, + "parent": null, + "mirror": false, + "size": 64, + "html_url": "https://try.gitea.io/jcitizen/my-repo", + "ssh_url": "git@try.gitea.io:jcitizen/my-repo.git", + "clone_url": "https://try.gitea.io/jcitizen/my-repo.git", + "website": "", + "stars_count": 0, + "forks_count": 0, + "watchers_count": 1, + "open_issues_count": 0, + "default_branch": "master", + "created_at": "2018-07-06T00:08:02Z", + "updated_at": "2018-07-06T01:06:56Z", + "permissions": { + "admin": false, + "push": false, + "pull": false + } + }, + "sender": { + "id": 6641, + "login": "jcitizen", + "full_name": "", + "email": "jane@example.com", + "avatar_url": "https://secure.gravatar.com/avatar/66f07ff48e6a9cb393de7a34e03bb52a?d=identicon", + "language": "en-US", + "username": "jcitizen" + } +} \ No newline at end of file diff --git a/scm/driver/harness/testdata/webhooks/pull_request_opened.json.golden b/scm/driver/harness/testdata/webhooks/pull_request_opened.json.golden new file mode 100644 index 000000000..b44944b2d --- /dev/null +++ b/scm/driver/harness/testdata/webhooks/pull_request_opened.json.golden @@ -0,0 +1,47 @@ +{ + "Action": "opened", + "Repo": { + "ID": "6589", + "Namespace": "jcitizen", + "Name": "my-repo", + "Perm": { + "Pull": false, + "Push": false, + "Admin": false + }, + "Branch": "master", + "Private": false, + "Clone": "https://try.gitea.io/jcitizen/my-repo.git", + "CloneSSH": "git@try.gitea.io:jcitizen/my-repo.git", + "Link": "https://try.gitea.io/jcitizen/my-repo", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "PullRequest": { + "Number": 1, + "Title": "Add License File", + "Body": "Using a BSD License", + "Sha": "2eba238e33607c1fa49253182e9fff42baafa1eb", + "Ref": "refs/pull/1/head", + "Source": "feature", + "Target": "master", + "Fork": "jcitizen/my-repo", + "Link": "https://try.gitea.io/jcitizen/my-repo/pulls/1", + "Closed": false, + "Merged": false, + "Author": { + "Login": "jcitizen", + "Name": "", + "Email": "jane@example.com", + "Avatar": "https://secure.gravatar.com/avatar/66f07ff48e6a9cb393de7a34e03bb52a?d=identicon" + }, + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Sender": { + "Login": "jcitizen", + "Name": "", + "Email": "jane@example.com", + "Avatar": "https://secure.gravatar.com/avatar/66f07ff48e6a9cb393de7a34e03bb52a?d=identicon" + } +} \ No newline at end of file diff --git a/scm/driver/harness/user.go b/scm/driver/harness/user.go new file mode 100644 index 000000000..18cba27b4 --- /dev/null +++ b/scm/driver/harness/user.go @@ -0,0 +1,66 @@ +// Copyright 2017 Drone.IO Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package harness + +import ( + "context" + + "github.com/drone/go-scm/scm" +) + +type userService struct { + client *wrapper +} + +func (s *userService) Find(ctx context.Context) (*scm.User, *scm.Response, error) { + out := new(user) + res, err := s.client.do(ctx, "GET", "api/v1/user", nil, out) + return convertUser(out), res, err +} + +func (s *userService) FindLogin(ctx context.Context, login string) (*scm.User, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *userService) FindEmail(ctx context.Context) (string, *scm.Response, error) { + return "", nil, scm.ErrNotSupported +} + +func (s *userService) ListEmail(context.Context, scm.ListOptions) ([]*scm.Email, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +// +// native data structures +// + +type user struct { + ID int `json:"id"` + Login string `json:"login"` + Username string `json:"username"` + Fullname string `json:"full_name"` + Email string `json:"email"` + Avatar string `json:"avatar_url"` +} + +// +// native data structure conversion +// + +func convertUser(src *user) *scm.User { + return &scm.User{ + Login: userLogin(src), + Avatar: src.Avatar, + Email: src.Email, + Name: src.Fullname, + } +} + +func userLogin(src *user) string { + if src.Username != "" { + return src.Username + } + return src.Login +} diff --git a/scm/driver/harness/user_test.go b/scm/driver/harness/user_test.go new file mode 100644 index 000000000..5d232e2ff --- /dev/null +++ b/scm/driver/harness/user_test.go @@ -0,0 +1,5 @@ +// Copyright 2017 Drone.IO Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package harness diff --git a/scm/driver/harness/util.go b/scm/driver/harness/util.go new file mode 100644 index 000000000..5a9cfab18 --- /dev/null +++ b/scm/driver/harness/util.go @@ -0,0 +1,103 @@ +// Copyright 2017 Drone.IO Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package harness + +import ( + "fmt" + "net/url" + "strconv" + "strings" + + "github.com/drone/go-scm/scm" +) + +func encodeListOptions(opts scm.ListOptions) string { + params := url.Values{} + if opts.Page != 0 { + params.Set("page", strconv.Itoa(opts.Page)) + } + if opts.Size != 0 { + params.Set("limit", strconv.Itoa(opts.Size)) + } + return params.Encode() +} + +func encodeIssueListOptions(opts scm.IssueListOptions) string { + params := url.Values{} + if opts.Page != 0 { + params.Set("page", strconv.Itoa(opts.Page)) + } + if opts.Size != 0 { + params.Set("limit", strconv.Itoa(opts.Size)) + } + if opts.Open && opts.Closed { + params.Set("state", "all") + } else if opts.Closed { + params.Set("state", "closed") + } + return params.Encode() +} + +func encodePullRequestListOptions(opts scm.PullRequestListOptions) string { + params := url.Values{} + if opts.Page != 0 { + params.Set("page", strconv.Itoa(opts.Page)) + } + if opts.Size != 0 { + params.Set("limit", strconv.Itoa(opts.Size)) + } + if opts.Open && opts.Closed { + params.Set("state", "all") + } else if opts.Closed { + params.Set("state", "closed") + } + return params.Encode() +} + +// convertAPIURLToHTMLURL converts an release API endpoint into a html endpoint +func convertAPIURLToHTMLURL(apiURL string, tagName string) string { + // "url": "https://try.gitea.com/api/v1/repos/octocat/Hello-World/123", + // "html_url": "https://try.gitea.com/octocat/Hello-World/releases/tag/v1.0.0", + // the url field is the API url, not the html url, so until go-sdk v0.13.3, build it ourselves + link, err := url.Parse(apiURL) + if err != nil { + return "" + } + + pathParts := strings.Split(link.Path, "/") + if len(pathParts) != 7 { + return "" + } + link.Path = fmt.Sprintf("/%s/%s/releases/tag/%s", pathParts[4], pathParts[5], tagName) + return link.String() +} + +func encodeMilestoneListOptions(opts scm.MilestoneListOptions) string { + params := url.Values{} + if opts.Page != 0 { + params.Set("page", strconv.Itoa(opts.Page)) + } + if opts.Size != 0 { + params.Set("per_page", strconv.Itoa(opts.Size)) + } + if opts.Open && opts.Closed { + params.Set("state", "all") + } else if opts.Closed { + params.Set("state", "closed") + } + return params.Encode() +} + +type ListOptions struct { + Page int + PageSize int +} + +func encodeReleaseListOptions(o ListOptions) string { + query := make(url.Values) + query.Add("page", fmt.Sprintf("%d", o.Page)) + query.Add("limit", fmt.Sprintf("%d", o.PageSize)) + return query.Encode() +} diff --git a/scm/driver/harness/util_test.go b/scm/driver/harness/util_test.go new file mode 100644 index 000000000..2264536e0 --- /dev/null +++ b/scm/driver/harness/util_test.go @@ -0,0 +1,81 @@ +// Copyright 2017 Drone.IO Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package harness + +import ( + "testing" + + "github.com/drone/go-scm/scm" +) + +func Test_encodeListOptions(t *testing.T) { + opts := scm.ListOptions{ + Page: 10, + Size: 30, + } + want := "limit=30&page=10" + got := encodeListOptions(opts) + if got != want { + t.Errorf("Want encoded list options %q, got %q", want, got) + } +} + +func Test_encodeIssueListOptions(t *testing.T) { + opts := scm.IssueListOptions{ + Page: 10, + Size: 30, + Open: true, + Closed: true, + } + want := "limit=30&page=10&state=all" + got := encodeIssueListOptions(opts) + if got != want { + t.Errorf("Want encoded issue list options %q, got %q", want, got) + } +} + +func Test_encodeIssueListOptions_Closed(t *testing.T) { + opts := scm.IssueListOptions{ + Page: 10, + Size: 30, + Open: false, + Closed: true, + } + want := "limit=30&page=10&state=closed" + got := encodeIssueListOptions(opts) + if got != want { + t.Errorf("Want encoded issue list options %q, got %q", want, got) + } +} + +func Test_encodePullRequestListOptions(t *testing.T) { + t.Parallel() + opts := scm.PullRequestListOptions{ + Page: 10, + Size: 30, + Open: true, + Closed: true, + } + want := "limit=30&page=10&state=all" + got := encodePullRequestListOptions(opts) + if got != want { + t.Errorf("Want encoded pr list options %q, got %q", want, got) + } +} + +func Test_encodePullRequestListOptions_Closed(t *testing.T) { + t.Parallel() + opts := scm.PullRequestListOptions{ + Page: 10, + Size: 30, + Open: false, + Closed: true, + } + want := "limit=30&page=10&state=closed" + got := encodePullRequestListOptions(opts) + if got != want { + t.Errorf("Want encoded pr list options %q, got %q", want, got) + } +} diff --git a/scm/driver/harness/webhook.go b/scm/driver/harness/webhook.go new file mode 100644 index 000000000..7465668ff --- /dev/null +++ b/scm/driver/harness/webhook.go @@ -0,0 +1,361 @@ +// Copyright 2017 Drone.IO Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package harness + +import ( + "crypto/sha256" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" + + "github.com/drone/go-scm/scm" + "github.com/drone/go-scm/scm/driver/internal/hmac" +) + +type webhookService struct { + client *wrapper +} + +func (s *webhookService) Parse(req *http.Request, fn scm.SecretFunc) (scm.Webhook, error) { + data, err := ioutil.ReadAll( + io.LimitReader(req.Body, 10000000), + ) + if err != nil { + return nil, err + } + + var hook scm.Webhook + switch req.Header.Get("X-Gitea-Event") { + case "push": + hook, err = s.parsePushHook(data) + case "create": + hook, err = s.parseCreateHook(data) + case "delete": + hook, err = s.parseDeleteHook(data) + case "issues": + hook, err = s.parseIssueHook(data) + case "issue_comment": + hook, err = s.parseIssueCommentHook(data) + case "pull_request": + hook, err = s.parsePullRequestHook(data) + default: + return nil, scm.ErrUnknownEvent + } + if err != nil { + return nil, err + } + + // get the gitea signature key to verify the payload + // signature. If no key is provided, no validation + // is performed. + key, err := fn(hook) + if err != nil { + return hook, err + } else if key == "" { + return hook, nil + } + + secret := req.FormValue("secret") + signature := req.Header.Get("X-Gitea-Signature") + + // fail if no signature passed + if signature == "" && secret == "" { + return hook, scm.ErrSignatureInvalid + } + + // test signature if header not set and secret is in payload + if signature == "" && secret != "" && secret != key { + return hook, scm.ErrSignatureInvalid + } + + // test signature using header + if signature != "" && !hmac.Validate(sha256.New, data, []byte(key), signature) { + return hook, scm.ErrSignatureInvalid + } + + return hook, nil +} + +func (s *webhookService) parsePushHook(data []byte) (scm.Webhook, error) { + dst := new(pushHook) + err := json.Unmarshal(data, dst) + return convertPushHook(dst), err +} + +func (s *webhookService) parseCreateHook(data []byte) (scm.Webhook, error) { + dst := new(createHook) + err := json.Unmarshal(data, dst) + switch dst.RefType { + case "tag": + return convertTagHook(dst, scm.ActionCreate), err + case "branch": + return convertBranchHook(dst, scm.ActionCreate), err + default: + return nil, scm.ErrUnknownEvent + } +} + +func (s *webhookService) parseDeleteHook(data []byte) (scm.Webhook, error) { + dst := new(createHook) + err := json.Unmarshal(data, dst) + switch dst.RefType { + case "tag": + return convertTagHook(dst, scm.ActionDelete), err + case "branch": + return convertBranchHook(dst, scm.ActionDelete), err + default: + return nil, scm.ErrUnknownEvent + } +} + +func (s *webhookService) parseIssueHook(data []byte) (scm.Webhook, error) { + dst := new(issueHook) + err := json.Unmarshal(data, dst) + return convertIssueHook(dst), err +} + +func (s *webhookService) parseIssueCommentHook(data []byte) (scm.Webhook, error) { + dst := new(issueHook) + err := json.Unmarshal(data, dst) + if dst.Issue.PullRequest != nil { + return convertPullRequestCommentHook(dst), err + } + return convertIssueCommentHook(dst), err +} + +func (s *webhookService) parsePullRequestHook(data []byte) (scm.Webhook, error) { + dst := new(pullRequestHook) + err := json.Unmarshal(data, dst) + return convertPullRequestHook(dst), err +} + +// +// native data structures +// + +type ( + // gitea push webhook payload + pushHook struct { + Ref string `json:"ref"` + Before string `json:"before"` + After string `json:"after"` + Compare string `json:"compare_url"` + Commits []commit `json:"commits"` + Repository repository `json:"repository"` + Pusher user `json:"pusher"` + Sender user `json:"sender"` + } + + // gitea create webhook payload + createHook struct { + Ref string `json:"ref"` + RefType string `json:"ref_type"` + Sha string `json:"sha"` + DefaultBranch string `json:"default_branch"` + Repository repository `json:"repository"` + Sender user `json:"sender"` + } + + // gitea issue webhook payload + issueHook struct { + Action string `json:"action"` + Issue issue `json:"issue"` + Comment issueComment `json:"comment"` + Repository repository `json:"repository"` + Sender user `json:"sender"` + } + + // gitea pull request webhook payload + pullRequestHook struct { + Action string `json:"action"` + Number int `json:"number"` + PullRequest pr `json:"pull_request"` + Repository repository `json:"repository"` + Sender user `json:"sender"` + } +) + +// +// native data structure conversion +// + +func convertTagHook(dst *createHook, action scm.Action) *scm.TagHook { + return &scm.TagHook{ + Action: action, + Ref: scm.Reference{ + Name: dst.Ref, + Sha: dst.Sha, + }, + Repo: *convertRepository(&dst.Repository), + Sender: *convertUser(&dst.Sender), + } +} + +func convertBranchHook(dst *createHook, action scm.Action) *scm.BranchHook { + return &scm.BranchHook{ + Action: action, + Ref: scm.Reference{ + Name: dst.Ref, + }, + Repo: *convertRepository(&dst.Repository), + Sender: *convertUser(&dst.Sender), + } +} + +func convertPushHook(dst *pushHook) *scm.PushHook { + if len(dst.Commits) > 0 { + var commits []scm.Commit + for _, c := range dst.Commits { + commits = append(commits, + scm.Commit{ + Sha: c.ID, + Message: c.Message, + Link: c.URL, + Author: scm.Signature{ + Login: c.Author.Username, + Email: c.Author.Email, + Name: c.Author.Name, + Date: c.Timestamp, + }, + Committer: scm.Signature{ + Login: c.Committer.Username, + Email: c.Committer.Email, + Name: c.Committer.Name, + Date: c.Timestamp, + }, + }) + } + + return &scm.PushHook{ + Ref: dst.Ref, + Before: dst.Before, + Commit: scm.Commit{ + Sha: dst.After, + Message: dst.Commits[0].Message, + Link: dst.Compare, + Author: scm.Signature{ + Login: dst.Commits[0].Author.Username, + Email: dst.Commits[0].Author.Email, + Name: dst.Commits[0].Author.Name, + Date: dst.Commits[0].Timestamp, + }, + Committer: scm.Signature{ + Login: dst.Commits[0].Committer.Username, + Email: dst.Commits[0].Committer.Email, + Name: dst.Commits[0].Committer.Name, + Date: dst.Commits[0].Timestamp, + }, + }, + Commits: commits, + Repo: *convertRepository(&dst.Repository), + Sender: *convertUser(&dst.Sender), + } + } + return &scm.PushHook{ + Ref: dst.Ref, + Commit: scm.Commit{ + Sha: dst.After, + Link: dst.Compare, + Author: scm.Signature{ + Login: dst.Pusher.Login, + Email: dst.Pusher.Email, + Name: dst.Pusher.Fullname, + }, + Committer: scm.Signature{ + Login: dst.Pusher.Login, + Email: dst.Pusher.Email, + Name: dst.Pusher.Fullname, + }, + }, + Repo: *convertRepository(&dst.Repository), + Sender: *convertUser(&dst.Sender), + } +} + +func convertPullRequestHook(dst *pullRequestHook) *scm.PullRequestHook { + return &scm.PullRequestHook{ + Action: convertAction(dst.Action), + PullRequest: scm.PullRequest{ + Number: dst.PullRequest.Number, + Title: dst.PullRequest.Title, + Body: dst.PullRequest.Body, + Closed: dst.PullRequest.State == "closed", + Author: scm.User{ + Login: dst.PullRequest.User.Login, + Email: dst.PullRequest.User.Email, + Avatar: dst.PullRequest.User.Avatar, + }, + Merged: dst.PullRequest.Merged, + // Created: nil, + // Updated: nil, + Source: dst.PullRequest.Head.Name, + Target: dst.PullRequest.Base.Name, + Fork: dst.PullRequest.Head.Repo.FullName, + Link: dst.PullRequest.HTMLURL, + Ref: fmt.Sprintf("refs/pull/%d/head", dst.PullRequest.Number), + Sha: dst.PullRequest.Head.Sha, + }, + Repo: *convertRepository(&dst.Repository), + Sender: *convertUser(&dst.Sender), + } +} + +func convertPullRequestCommentHook(dst *issueHook) *scm.PullRequestCommentHook { + return &scm.PullRequestCommentHook{ + Action: convertAction(dst.Action), + PullRequest: *convertPullRequestFromIssue(&dst.Issue), + Comment: *convertIssueComment(&dst.Comment), + Repo: *convertRepository(&dst.Repository), + Sender: *convertUser(&dst.Sender), + } +} + +func convertIssueHook(dst *issueHook) *scm.IssueHook { + return &scm.IssueHook{ + Action: convertAction(dst.Action), + Issue: *convertIssue(&dst.Issue), + Repo: *convertRepository(&dst.Repository), + Sender: *convertUser(&dst.Sender), + } +} + +func convertIssueCommentHook(dst *issueHook) *scm.IssueCommentHook { + return &scm.IssueCommentHook{ + Action: convertAction(dst.Action), + Issue: *convertIssue(&dst.Issue), + Comment: *convertIssueComment(&dst.Comment), + Repo: *convertRepository(&dst.Repository), + Sender: *convertUser(&dst.Sender), + } +} + +func convertAction(src string) (action scm.Action) { + switch src { + case "create", "created": + return scm.ActionCreate + case "delete", "deleted": + return scm.ActionDelete + case "update", "updated", "edit", "edited": + return scm.ActionUpdate + case "open", "opened": + return scm.ActionOpen + case "reopen", "reopened": + return scm.ActionReopen + case "close", "closed": + return scm.ActionClose + case "label", "labeled": + return scm.ActionLabel + case "unlabel", "unlabeled": + return scm.ActionUnlabel + case "merge", "merged": + return scm.ActionMerge + case "synchronize", "synchronized": + return scm.ActionSync + default: + return + } +} diff --git a/scm/driver/harness/webhook_test.go b/scm/driver/harness/webhook_test.go new file mode 100644 index 000000000..5d232e2ff --- /dev/null +++ b/scm/driver/harness/webhook_test.go @@ -0,0 +1,5 @@ +// Copyright 2017 Drone.IO Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package harness From 7df18e165adf4e8cd83cdaab9e8ad573d0998097 Mon Sep 17 00:00:00 2001 From: TP Honey Date: Tue, 7 Feb 2023 11:16:06 +0000 Subject: [PATCH 047/195] (feat) harness, add repo list --- scm/driver/harness/content.go | 7 -- scm/driver/harness/pr.go | 2 +- scm/driver/harness/repo.go | 98 ++++++------------- scm/driver/harness/repo_test.go | 52 +++++++++- scm/driver/harness/testdata/repos.json | 40 ++++++++ scm/driver/harness/testdata/repos.json.golden | 22 +++++ scm/driver/harness/util.go | 13 +++ scm/driver/harness/webhook.go | 2 +- 8 files changed, 158 insertions(+), 78 deletions(-) create mode 100644 scm/driver/harness/testdata/repos.json create mode 100644 scm/driver/harness/testdata/repos.json.golden diff --git a/scm/driver/harness/content.go b/scm/driver/harness/content.go index e5e7724b3..310c0e06c 100644 --- a/scm/driver/harness/content.go +++ b/scm/driver/harness/content.go @@ -91,13 +91,6 @@ func (s *contentService) Delete(ctx context.Context, repo, path string, params * return res, err } -func buildHarnessURI(account, organization, project, repo string) (uri string) { - if account != "" { - return fmt.Sprintf("%s/%s/%s/%s/+", account, organization, project, repo) - } - return repo -} - func (s *contentService) List(ctx context.Context, repo, path, ref string, _ scm.ListOptions) ([]*scm.ContentInfo, *scm.Response, error) { repo = buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) endpoint := fmt.Sprintf("api/v1/repos/%s/content/%s?%s&include_commit=true", repo, path, ref) diff --git a/scm/driver/harness/pr.go b/scm/driver/harness/pr.go index 46f64367b..631d994b7 100644 --- a/scm/driver/harness/pr.go +++ b/scm/driver/harness/pr.go @@ -132,7 +132,7 @@ func convertPullRequest(src *pr) *scm.PullRequest { Target: src.Base.Name, Link: src.HTMLURL, Diff: src.DiffURL, - Fork: src.Base.Repo.FullName, + Fork: "fork", Ref: fmt.Sprintf("refs/pull/%d/head", src.Number), Closed: src.State == "closed", Author: *convertUser(&src.User), diff --git a/scm/driver/harness/repo.go b/scm/driver/harness/repo.go index d21017154..eed9ab711 100644 --- a/scm/driver/harness/repo.go +++ b/scm/driver/harness/repo.go @@ -7,7 +7,6 @@ package harness import ( "context" "fmt" - "net/url" "strconv" "time" @@ -19,10 +18,7 @@ type repositoryService struct { } func (s *repositoryService) Find(ctx context.Context, repo string) (*scm.Repository, *scm.Response, error) { - path := fmt.Sprintf("api/v1/repos/%s", repo) - out := new(repository) - res, err := s.client.do(ctx, "GET", path, nil, out) - return convertRepository(out), res, err + return nil, nil, scm.ErrNotSupported } func (s *repositoryService) FindHook(ctx context.Context, repo string, id string) (*scm.Hook, *scm.Response, error) { @@ -34,17 +30,15 @@ func (s *repositoryService) FindPerms(ctx context.Context, repo string) (*scm.Pe } func (s *repositoryService) List(ctx context.Context, opts scm.ListOptions) ([]*scm.Repository, *scm.Response, error) { - path := fmt.Sprintf("api/v1/user/repos?%s", encodeListOptions(opts)) + harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, "") + path := fmt.Sprintf("api/v1/spaces/%s/repos?sort=path&order=asc&%s", harnessURI, encodeListOptions(opts)) out := []*repository{} res, err := s.client.do(ctx, "GET", path, nil, &out) return convertRepositoryList(out), res, err } func (s *repositoryService) ListHooks(ctx context.Context, repo string, opts scm.ListOptions) ([]*scm.Hook, *scm.Response, error) { - path := fmt.Sprintf("api/v1/repos/%s/hooks?%s", repo, encodeListOptions(opts)) - out := []*hook{} - res, err := s.client.do(ctx, "GET", path, nil, &out) - return convertHookList(out), res, err + return nil, nil, scm.ErrNotSupported } func (s *repositoryService) ListStatus(ctx context.Context, repo string, ref string, opts scm.ListOptions) ([]*scm.Status, *scm.Response, error) { @@ -52,28 +46,7 @@ func (s *repositoryService) ListStatus(ctx context.Context, repo string, ref str } func (s *repositoryService) CreateHook(ctx context.Context, repo string, input *scm.HookInput) (*scm.Hook, *scm.Response, error) { - target, err := url.Parse(input.Target) - if err != nil { - return nil, nil, err - } - params := target.Query() - params.Set("secret", input.Secret) - target.RawQuery = params.Encode() - - path := fmt.Sprintf("api/v1/repos/%s/hooks", repo) - in := new(hook) - in.Type = "gitea" - in.Active = true - in.Config.Secret = input.Secret - in.Config.ContentType = "json" - in.Config.URL = target.String() - in.Events = append( - input.NativeEvents, - convertHookEvent(input.Events)..., - ) - out := new(hook) - res, err := s.client.do(ctx, "POST", path, in, out) - return convertHook(out), res, err + return nil, nil, scm.ErrNotSupported } func (s *repositoryService) CreateStatus(ctx context.Context, repo string, ref string, input *scm.StatusInput) (*scm.Status, *scm.Response, error) { @@ -85,8 +58,7 @@ func (s *repositoryService) UpdateHook(ctx context.Context, repo, id string, inp } func (s *repositoryService) DeleteHook(ctx context.Context, repo string, id string) (*scm.Response, error) { - path := fmt.Sprintf("api/v1/repos/%s/hooks/%s", repo, id) - return s.client.do(ctx, "DELETE", path, nil, nil) + return nil, scm.ErrNotSupported } // @@ -94,22 +66,25 @@ func (s *repositoryService) DeleteHook(ctx context.Context, repo string, id stri // type ( - // gitea repository resource. + // harness repository resource. repository struct { - ID int `json:"id"` - Owner user `json:"owner"` - Name string `json:"name"` - FullName string `json:"full_name"` - Private bool `json:"private"` - Fork bool `json:"fork"` - HTMLURL string `json:"html_url"` - SSHURL string `json:"ssh_url"` - CloneURL string `json:"clone_url"` - DefaultBranch string `json:"default_branch"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - Permissions perm `json:"permissions"` - Archived bool `json:"archived"` + ID int `json:"id"` + ParentID int `json:"parent_id"` + UID string `json:"uid"` + Path string `json:"path"` + Description string `json:"description"` + IsPublic bool `json:"is_public"` + CreatedBy int `json:"created_by"` + Created int64 `json:"created"` + Updated int64 `json:"updated"` + DefaultBranch string `json:"default_branch"` + ForkID int `json:"fork_id"` + NumForks int `json:"num_forks"` + NumPulls int `json:"num_pulls"` + NumClosedPulls int `json:"num_closed_pulls"` + NumOpenPulls int `json:"num_open_pulls"` + NumMergedPulls int `json:"num_merged_pulls"` + GitURL string `json:"git_url"` } // gitea permissions details. @@ -169,26 +144,17 @@ func convertRepositoryList(src []*repository) []*scm.Repository { func convertRepository(src *repository) *scm.Repository { return &scm.Repository{ ID: strconv.Itoa(src.ID), - Namespace: userLogin(&src.Owner), - Name: src.Name, - Perm: convertPerm(src.Permissions), + Namespace: src.Path, + Name: src.UID, Branch: src.DefaultBranch, - Private: src.Private, - Clone: src.CloneURL, - CloneSSH: src.SSHURL, - Link: src.HTMLURL, - Archived: src.Archived, + Private: !src.IsPublic, + Clone: src.GitURL, + CloneSSH: src.GitURL, + Link: src.GitURL, + // Created: time.Unix(src.Created, 0), + // Updated: time.Unix(src.Updated, 0), } } - -func convertPerm(src perm) *scm.Perm { - return &scm.Perm{ - Push: src.Push, - Pull: src.Pull, - Admin: src.Admin, - } -} - func convertHookList(src []*hook) []*scm.Hook { var dst []*scm.Hook for _, v := range src { diff --git a/scm/driver/harness/repo_test.go b/scm/driver/harness/repo_test.go index 8bb7df63a..aa689214f 100644 --- a/scm/driver/harness/repo_test.go +++ b/scm/driver/harness/repo_test.go @@ -4,6 +4,52 @@ package harness -// -// repository sub-tests -// +import ( + "context" + "encoding/json" + "io/ioutil" + "net/http" + "testing" + + "github.com/drone/go-scm/scm" + "github.com/drone/go-scm/scm/transport" + "github.com/google/go-cmp/cmp" + "github.com/h2non/gock" +) + +func TestRepositoryList(t *testing.T) { + defer gock.Off() + + gock.New(gockOrigin). + Get("/gateway/code/api/v1/spaces/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/+/repos"). + MatchParam("page", "1"). + MatchParam("limit", "20"). + MatchParam("sort", "path"). + MatchParam("order", "asc"). + Reply(200). + Type("application/json"). + File("testdata/repos.json") + + client, _ := New(gockOrigin, harnessOrg, harnessAccount, harnessProject) + client.Client = &http.Client{ + Transport: &transport.Custom{ + Before: func(r *http.Request) { + r.Header.Set("x-api-key", harnessPAT) + }, + }, + } + got, _, err := client.Repositories.List(context.Background(), scm.ListOptions{Page: 1, Size: 20}) + if err != nil { + t.Error(err) + return + } + + want := []*scm.Repository{} + raw, _ := ioutil.ReadFile("testdata/repos.json.golden") + _ = json.Unmarshal(raw, &want) + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } +} diff --git a/scm/driver/harness/testdata/repos.json b/scm/driver/harness/testdata/repos.json new file mode 100644 index 000000000..77fb6f96e --- /dev/null +++ b/scm/driver/harness/testdata/repos.json @@ -0,0 +1,40 @@ +[ + { + "id": 9, + "parent_id": 16, + "uid": "demo", + "path": "px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/demo", + "description": "", + "is_public": false, + "created_by": 10, + "created": 1675210116158, + "updated": 1675389801066, + "default_branch": "main", + "fork_id": 0, + "num_forks": 0, + "num_pulls": 4, + "num_closed_pulls": 0, + "num_open_pulls": 1, + "num_merged_pulls": 3, + "git_url": "https://qa.harness.io/code/git/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/demo.git" + }, + { + "id": 11, + "parent_id": 16, + "uid": "thomas", + "path": "px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas", + "description": "Playground project for Thomas", + "is_public": true, + "created_by": 10, + "created": 1675458112548, + "updated": 1675458112548, + "default_branch": "main", + "fork_id": 0, + "num_forks": 0, + "num_pulls": 0, + "num_closed_pulls": 0, + "num_open_pulls": 0, + "num_merged_pulls": 0, + "git_url": "https://qa.harness.io/code/git/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas.git" + } +] \ No newline at end of file diff --git a/scm/driver/harness/testdata/repos.json.golden b/scm/driver/harness/testdata/repos.json.golden new file mode 100644 index 000000000..d58eb804b --- /dev/null +++ b/scm/driver/harness/testdata/repos.json.golden @@ -0,0 +1,22 @@ +[ + { + "ID": "9", + "Namespace": "px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/demo", + "Name": "demo", + "Branch": "main", + "Private": true, + "Clone": "https://qa.harness.io/code/git/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/demo.git", + "CloneSSH": "https://qa.harness.io/code/git/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/demo.git", + "Link": "https://qa.harness.io/code/git/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/demo.git" + }, + { + "ID": "11", + "Namespace": "px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas", + "Name": "thomas", + "Branch": "main", + "Private": false, + "Clone": "https://qa.harness.io/code/git/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas.git", + "CloneSSH": "https://qa.harness.io/code/git/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas.git", + "Link": "https://qa.harness.io/code/git/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas.git" + } +] \ No newline at end of file diff --git a/scm/driver/harness/util.go b/scm/driver/harness/util.go index 5a9cfab18..fe7778d9e 100644 --- a/scm/driver/harness/util.go +++ b/scm/driver/harness/util.go @@ -13,6 +13,19 @@ import ( "github.com/drone/go-scm/scm" ) +func buildHarnessURI(account, organization, project, repo string) (uri string) { + if account != "" { + uri = fmt.Sprintf("%s/%s/%s/", account, organization, project) + if repo != "" { + uri += fmt.Sprintf("%s/+", repo) + } else { + uri += "+" + } + return uri + } + return repo +} + func encodeListOptions(opts scm.ListOptions) string { params := url.Values{} if opts.Page != 0 { diff --git a/scm/driver/harness/webhook.go b/scm/driver/harness/webhook.go index 7465668ff..4f7bc187c 100644 --- a/scm/driver/harness/webhook.go +++ b/scm/driver/harness/webhook.go @@ -294,7 +294,7 @@ func convertPullRequestHook(dst *pullRequestHook) *scm.PullRequestHook { // Updated: nil, Source: dst.PullRequest.Head.Name, Target: dst.PullRequest.Base.Name, - Fork: dst.PullRequest.Head.Repo.FullName, + Fork: "fork", Link: dst.PullRequest.HTMLURL, Ref: fmt.Sprintf("refs/pull/%d/head", dst.PullRequest.Number), Sha: dst.PullRequest.Head.Sha, From e62b23f48a7f7909326988e484cc5fa476940459 Mon Sep 17 00:00:00 2001 From: TP Honey Date: Tue, 7 Feb 2023 11:47:07 +0000 Subject: [PATCH 048/195] (feat) harness, add find repo --- scm/driver/harness/repo.go | 138 ++----------------- scm/driver/harness/repo_test.go | 34 +++++ scm/driver/harness/testdata/repo.json | 19 +++ scm/driver/harness/testdata/repo.json.golden | 10 ++ 4 files changed, 76 insertions(+), 125 deletions(-) create mode 100644 scm/driver/harness/testdata/repo.json create mode 100644 scm/driver/harness/testdata/repo.json.golden diff --git a/scm/driver/harness/repo.go b/scm/driver/harness/repo.go index eed9ab711..33fbc832c 100644 --- a/scm/driver/harness/repo.go +++ b/scm/driver/harness/repo.go @@ -6,9 +6,9 @@ package harness import ( "context" + "errors" "fmt" "strconv" - "time" "github.com/drone/go-scm/scm" ) @@ -18,7 +18,18 @@ type repositoryService struct { } func (s *repositoryService) Find(ctx context.Context, repo string) (*scm.Repository, *scm.Response, error) { - return nil, nil, scm.ErrNotSupported + repo = buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + path := fmt.Sprintf("api/v1/repos/%s", repo) + out := new(repository) + res, err := s.client.do(ctx, "GET", path, nil, out) + if err != nil { + return nil, res, err + } + convertedRepo := convertRepository(out) + if convertedRepo == nil { + return nil, res, errors.New("Harness returned an unexpected null repository") + } + return convertedRepo, res, err } func (s *repositoryService) FindHook(ctx context.Context, repo string, id string) (*scm.Hook, *scm.Response, error) { @@ -86,47 +97,6 @@ type ( NumMergedPulls int `json:"num_merged_pulls"` GitURL string `json:"git_url"` } - - // gitea permissions details. - perm struct { - Admin bool `json:"admin"` - Push bool `json:"push"` - Pull bool `json:"pull"` - } - - // gitea hook resource. - hook struct { - ID int `json:"id"` - Type string `json:"type"` - Events []string `json:"events"` - Active bool `json:"active"` - Config hookConfig `json:"config"` - } - - // gitea hook configuration details. - hookConfig struct { - URL string `json:"url"` - ContentType string `json:"content_type"` - Secret string `json:"secret"` - } - - // gitea status resource. - status struct { - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - State string `json:"status"` - TargetURL string `json:"target_url"` - Description string `json:"description"` - Context string `json:"context"` - } - - // gitea status creation request. - statusInput struct { - State string `json:"state"` - TargetURL string `json:"target_url"` - Description string `json:"description"` - Context string `json:"context"` - } ) // @@ -155,85 +125,3 @@ func convertRepository(src *repository) *scm.Repository { // Updated: time.Unix(src.Updated, 0), } } -func convertHookList(src []*hook) []*scm.Hook { - var dst []*scm.Hook - for _, v := range src { - dst = append(dst, convertHook(v)) - } - return dst -} - -func convertHook(from *hook) *scm.Hook { - return &scm.Hook{ - ID: strconv.Itoa(from.ID), - Active: from.Active, - Target: from.Config.URL, - Events: from.Events, - } -} - -func convertHookEvent(from scm.HookEvents) []string { - var events []string - if from.PullRequest { - events = append(events, "pull_request") - } - if from.Issue { - events = append(events, "issues") - } - if from.IssueComment || from.PullRequestComment { - events = append(events, "issue_comment") - } - if from.Branch || from.Tag { - events = append(events, "create") - events = append(events, "delete") - } - if from.Push { - events = append(events, "push") - } - return events -} - -func convertStatusList(src []*status) []*scm.Status { - var dst []*scm.Status - for _, v := range src { - dst = append(dst, convertStatus(v)) - } - return dst -} - -func convertStatus(from *status) *scm.Status { - return &scm.Status{ - State: convertState(from.State), - Label: from.Context, - Desc: from.Description, - Target: from.TargetURL, - } -} - -func convertState(from string) scm.State { - switch from { - case "error": - return scm.StateError - case "failure": - return scm.StateFailure - case "pending": - return scm.StatePending - case "success": - return scm.StateSuccess - default: - return scm.StateUnknown - } -} - -func convertFromState(from scm.State) string { - switch from { - case scm.StatePending, scm.StateRunning: - return "pending" - case scm.StateSuccess: - return "success" - case scm.StateFailure: - return "failure" - default: - return "error" - } -} diff --git a/scm/driver/harness/repo_test.go b/scm/driver/harness/repo_test.go index aa689214f..3136e28cf 100644 --- a/scm/driver/harness/repo_test.go +++ b/scm/driver/harness/repo_test.go @@ -17,6 +17,40 @@ import ( "github.com/h2non/gock" ) +func TestRepositoryFind(t *testing.T) { + defer gock.Off() + + gock.New(gockOrigin). + Get("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/demo/+"). + Reply(200). + Type("application/json"). + File("testdata/repo.json") + + client, _ := New(gockOrigin, harnessOrg, harnessAccount, harnessProject) + client.Client = &http.Client{ + Transport: &transport.Custom{ + Before: func(r *http.Request) { + r.Header.Set("x-api-key", harnessPAT) + }, + }, + } + got, _, err := client.Repositories.Find(context.Background(), "demo") + if err != nil { + t.Error(err) + return + } + + want := new(scm.Repository) + raw, _ := ioutil.ReadFile("testdata/repo.json.golden") + _ = json.Unmarshal(raw, want) + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } + +} + func TestRepositoryList(t *testing.T) { defer gock.Off() diff --git a/scm/driver/harness/testdata/repo.json b/scm/driver/harness/testdata/repo.json new file mode 100644 index 000000000..7e246e625 --- /dev/null +++ b/scm/driver/harness/testdata/repo.json @@ -0,0 +1,19 @@ +{ + "id": 9, + "parent_id": 16, + "uid": "demo", + "path": "px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/demo", + "description": "", + "is_public": false, + "created_by": 10, + "created": 1675210116158, + "updated": 1675389801066, + "default_branch": "main", + "fork_id": 0, + "num_forks": 0, + "num_pulls": 4, + "num_closed_pulls": 0, + "num_open_pulls": 1, + "num_merged_pulls": 3, + "git_url": "https://qa.harness.io/code/git/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/demo.git" +} \ No newline at end of file diff --git a/scm/driver/harness/testdata/repo.json.golden b/scm/driver/harness/testdata/repo.json.golden new file mode 100644 index 000000000..4e187a6d4 --- /dev/null +++ b/scm/driver/harness/testdata/repo.json.golden @@ -0,0 +1,10 @@ +{ + "ID": "9", + "Namespace": "px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/demo", + "Name": "demo", + "Branch": "main", + "Private": true, + "Clone": "https://qa.harness.io/code/git/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/demo.git", + "CloneSSH": "https://qa.harness.io/code/git/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/demo.git", + "Link": "https://qa.harness.io/code/git/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/demo.git" +} \ No newline at end of file From 2066d100540ea807097ca693a68331b8bfe5f52e Mon Sep 17 00:00:00 2001 From: TP Honey Date: Tue, 7 Feb 2023 15:20:04 +0000 Subject: [PATCH 049/195] fix, harness add blobid for update --- scm/driver/harness/content.go | 1 + scm/driver/harness/content_test.go | 69 +++++++++++++----------- scm/driver/harness/repo_test.go | 38 ++++++------- scm/driver/harness/testdata/content.json | 4 +- 4 files changed, 60 insertions(+), 52 deletions(-) diff --git a/scm/driver/harness/content.go b/scm/driver/harness/content.go index 310c0e06c..7eac5b990 100644 --- a/scm/driver/harness/content.go +++ b/scm/driver/harness/content.go @@ -60,6 +60,7 @@ func (s *contentService) Update(ctx context.Context, repo, path string, params * Path: path, Payload: string(params.Data), Encoding: "string", + Sha: params.BlobID, } in := editFile{ Branch: params.Branch, diff --git a/scm/driver/harness/content_test.go b/scm/driver/harness/content_test.go index feba75672..6a84ec797 100644 --- a/scm/driver/harness/content_test.go +++ b/scm/driver/harness/content_test.go @@ -23,19 +23,20 @@ const ( harnessOrg = "px7xd_BFRCi-pfWPYXVjvw" harnessAccount = "default" harnessProject = "codeciintegration" - harnessRepo = "demo" + harnessRepo = "thomas" harnessPAT = "" ) func TestContentFind(t *testing.T) { - defer gock.Off() - - gock.New(gockOrigin). - Get("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/demo/+/content/README.md"). - Reply(200). - Type("plain/text"). - File("testdata/content.json") + if harnessPAT == "" { + defer gock.Off() + gock.New(gockOrigin). + Get("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/content/README.md"). + Reply(200). + Type("plain/text"). + File("testdata/content.json") + } client, _ := New(gockOrigin, harnessOrg, harnessAccount, harnessProject) client.Client = &http.Client{ Transport: &transport.Custom{ @@ -57,20 +58,21 @@ func TestContentFind(t *testing.T) { if got, want := result.Path, "README.md"; got != want { t.Errorf("Want file Path %q, got %q", want, got) } - if !strings.Contains(string(result.Data), "demo") { - t.Errorf("Want file Data %q, must contain 'demo'", result.Data) + if !strings.Contains(string(result.Data), "project") { + t.Errorf("Want file Data %q, must contain 'project'", result.Data) } } func TestContentCreate(t *testing.T) { - defer gock.Off() - - gock.New(gockOrigin). - Post("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/demo/+/commits"). - Reply(200). - Type("plain/text"). - BodyString("{\"commit_id\":\"20ecde1f8c277da0e91750bef9f3b88f228d86db\"}") + if harnessPAT == "" { + defer gock.Off() + gock.New(gockOrigin). + Post("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/commits"). + Reply(200). + Type("plain/text"). + BodyString("{\"commit_id\":\"20ecde1f8c277da0e91750bef9f3b88f228d86db\"}") + } client, _ := New(gockOrigin, harnessOrg, harnessAccount, harnessProject) client.Client = &http.Client{ Transport: &transport.Custom{ @@ -99,14 +101,15 @@ func TestContentCreate(t *testing.T) { } func TestContentUpdate(t *testing.T) { - defer gock.Off() - - gock.New(gockOrigin). - Post("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/demo/+/commits"). - Reply(200). - Type("plain/text"). - BodyString("{\"commit_id\":\"20ecde1f8c277da0e91750bef9f3b88f228d86db\"}") + if harnessPAT == "" { + defer gock.Off() + gock.New(gockOrigin). + Post("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/commits"). + Reply(200). + Type("plain/text"). + BodyString("{\"commit_id\":\"20ecde1f8c277da0e91750bef9f3b88f228d86db\"}") + } client, _ := New(gockOrigin, harnessOrg, harnessAccount, harnessProject) client.Client = &http.Client{ Transport: &transport.Custom{ @@ -123,6 +126,7 @@ func TestContentUpdate(t *testing.T) { Data: []byte("hello world 2"), Message: "update README.2", Branch: "main", + BlobID: "95d09f2b10159347eece71399a7e2e907ea3df4f", }, ) if err != nil { @@ -135,14 +139,15 @@ func TestContentUpdate(t *testing.T) { } func TestContentDelete(t *testing.T) { - defer gock.Off() - - gock.New(gockOrigin). - Post("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/demo/+/commits"). - Reply(200). - Type("plain/text"). - BodyString("{\"commit_id\":\"20ecde1f8c277da0e91750bef9f3b88f228d86db\"}") + if harnessPAT == "" { + defer gock.Off() + gock.New(gockOrigin). + Post("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/commits"). + Reply(200). + Type("plain/text"). + BodyString("{\"commit_id\":\"20ecde1f8c277da0e91750bef9f3b88f228d86db\"}") + } client, _ := New(gockOrigin, harnessOrg, harnessAccount, harnessProject) client.Client = &http.Client{ Transport: &transport.Custom{ @@ -173,7 +178,7 @@ func TestContentList(t *testing.T) { defer gock.Off() gock.New(gockOrigin). - Get("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/demo/+/content/docker"). + Get("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/content/docker"). Reply(200). Type("application/json"). File("testdata/content_list.json") diff --git a/scm/driver/harness/repo_test.go b/scm/driver/harness/repo_test.go index 3136e28cf..812866cba 100644 --- a/scm/driver/harness/repo_test.go +++ b/scm/driver/harness/repo_test.go @@ -18,14 +18,15 @@ import ( ) func TestRepositoryFind(t *testing.T) { - defer gock.Off() - - gock.New(gockOrigin). - Get("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/demo/+"). - Reply(200). - Type("application/json"). - File("testdata/repo.json") + if harnessPAT == "" { + defer gock.Off() + gock.New(gockOrigin). + Get("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/demo/+"). + Reply(200). + Type("application/json"). + File("testdata/repo.json") + } client, _ := New(gockOrigin, harnessOrg, harnessAccount, harnessProject) client.Client = &http.Client{ Transport: &transport.Custom{ @@ -52,18 +53,19 @@ func TestRepositoryFind(t *testing.T) { } func TestRepositoryList(t *testing.T) { - defer gock.Off() - - gock.New(gockOrigin). - Get("/gateway/code/api/v1/spaces/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/+/repos"). - MatchParam("page", "1"). - MatchParam("limit", "20"). - MatchParam("sort", "path"). - MatchParam("order", "asc"). - Reply(200). - Type("application/json"). - File("testdata/repos.json") + if harnessPAT == "" { + defer gock.Off() + gock.New(gockOrigin). + Get("/gateway/code/api/v1/spaces/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/+/repos"). + MatchParam("page", "1"). + MatchParam("limit", "20"). + MatchParam("sort", "path"). + MatchParam("order", "asc"). + Reply(200). + Type("application/json"). + File("testdata/repos.json") + } client, _ := New(gockOrigin, harnessOrg, harnessAccount, harnessProject) client.Client = &http.Client{ Transport: &transport.Custom{ diff --git a/scm/driver/harness/testdata/content.json b/scm/driver/harness/testdata/content.json index b7408335a..fbcda4f5f 100644 --- a/scm/driver/harness/testdata/content.json +++ b/scm/driver/harness/testdata/content.json @@ -24,7 +24,7 @@ }, "content": { "encoding": "base64", - "data": "ZGVtbw0KdGVzdCBzdHJpbmc=", - "size": 23 + "data": "IyB0aG9tYXMKUGxheWdyb3VuZCBwcm9qZWN0IGZvciBUaG9tYXM=", + "size": 38 } } \ No newline at end of file From 16252ffc2540299ba3c8706e1d401d27d2c5b1cf Mon Sep 17 00:00:00 2001 From: TP Honey Date: Wed, 8 Feb 2023 13:08:46 +0000 Subject: [PATCH 050/195] (feat) harness, add webhook parsing --- .../testdata/webhooks/branch_create.json | 50 +++ .../webhooks/branch_create.json.golden | 43 ++ .../webhooks/pull_request_branch_updated.json | 71 ++++ .../pull_request_branch_updated.json.golden | 42 ++ .../webhooks/pull_request_opened.json | 225 +++------- .../webhooks/pull_request_opened.json.golden | 51 ++- .../webhooks/pull_request_reopened.json | 69 ++++ .../pull_request_reopened.json.golden | 42 ++ scm/driver/harness/webhook.go | 384 ++++++------------ scm/driver/harness/webhook_test.go | 113 ++++++ 10 files changed, 648 insertions(+), 442 deletions(-) create mode 100644 scm/driver/harness/testdata/webhooks/branch_create.json create mode 100644 scm/driver/harness/testdata/webhooks/branch_create.json.golden create mode 100644 scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json create mode 100644 scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json.golden create mode 100644 scm/driver/harness/testdata/webhooks/pull_request_reopened.json create mode 100644 scm/driver/harness/testdata/webhooks/pull_request_reopened.json.golden diff --git a/scm/driver/harness/testdata/webhooks/branch_create.json b/scm/driver/harness/testdata/webhooks/branch_create.json new file mode 100644 index 000000000..51ff0b383 --- /dev/null +++ b/scm/driver/harness/testdata/webhooks/branch_create.json @@ -0,0 +1,50 @@ +{ + "trigger": "branch_created", + "repo": { + "id": 13, + "path": "kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba", + "uid": "aba", + "default_branch": "main", + "git_url": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git" + }, + "principal": { + "id": 8, + "uid": "0osgWsTZRsSZ8RWfjLRkEg", + "display_name": "default", + "email": "default@harness.io", + "type": "user", + "created": 1675390885380, + "updated": 1675390885380 + }, + "ref": { + "name": "refs/heads/new2", + "repo": { + "id": 13, + "path": "kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba", + "uid": "aba", + "default_branch": "main", + "git_url": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git" + } + }, + "sha": "aeafa0e2e4ec6909ad75cb8fad57c0b1eb5986e6", + "commit": { + "sha": "aeafa0e2e4ec6909ad75cb8fad57c0b1eb5986e6", + "message": "version 4", + "author": { + "identity": { + "name": "Admin", + "email": "admin@harness.io" + }, + "when": "2023-02-01T13:21:15-08:00" + }, + "committer": { + "identity": { + "name": "Admin", + "email": "admin@harness.io" + }, + "when": "2023-02-01T13:21:15-08:00" + } + }, + "old_sha": "0000000000000000000000000000000000000000", + "forced": false +} \ No newline at end of file diff --git a/scm/driver/harness/testdata/webhooks/branch_create.json.golden b/scm/driver/harness/testdata/webhooks/branch_create.json.golden new file mode 100644 index 000000000..00e4ce11b --- /dev/null +++ b/scm/driver/harness/testdata/webhooks/branch_create.json.golden @@ -0,0 +1,43 @@ +{ + "Ref": "aeafa0e2e4ec6909ad75cb8fad57c0b1eb5986e6", + "Before": "0000000000000000000000000000000000000000", + "After": "aeafa0e2e4ec6909ad75cb8fad57c0b1eb5986e6", + "Repo": { + "ID": "", + "Namespace": "", + "Name": "aba", + "Perm": null, + "Branch": "", + "Private": false, + "Clone": "", + "CloneSSH": "", + "Link": "", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Commit": { + "Sha": "aeafa0e2e4ec6909ad75cb8fad57c0b1eb5986e6", + "Message": "version 4", + "Author": { + "Name": "Admin", + "Email": "admin@harness.io", + "Date": "0001-01-01T00:00:00Z", + "Login": "", + "Avatar": "" + }, + "Committer": { + "Name": "", + "Email": "", + "Date": "0001-01-01T00:00:00Z", + "Login": "", + "Avatar": "" + }, + "Link": "" + }, + "Sender": { + "Login": "", + "Name": "default", + "Email": "", + "Avatar": "" + } +} \ No newline at end of file diff --git a/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json b/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json new file mode 100644 index 000000000..7509798e9 --- /dev/null +++ b/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json @@ -0,0 +1,71 @@ +{ + "trigger": "pullreq_branch_updated", + "repo": { + "id": 13, + "path": "kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba", + "uid": "aba", + "default_branch": "main", + "git_url": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git" + }, + "principal": { + "id": 8, + "uid": "0osgWsTZRsSZ8RWfjLRkEg", + "display_name": "default", + "email": "default@harness.io", + "type": "user", + "created": 1675390885380, + "updated": 1675390885380 + }, + "pull_req": { + "number": 4, + "state": "open", + "is_draft": false, + "title": "aw", + "source_repo_id": 13, + "source_branch": "b", + "target_repo_id": 13, + "target_branch": "main", + "merge_strategy": null + }, + "target_ref": { + "name": "refs/heads/main", + "repo": { + "id": 13, + "path": "kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba", + "uid": "aba", + "default_branch": "main", + "git_url": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git" + } + }, + "ref": { + "name": "refs/heads/b", + "repo": { + "id": 13, + "path": "kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba", + "uid": "aba", + "default_branch": "main", + "git_url": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git" + } + }, + "sha": "f74f3d2a88d1b7cb19ff3bf069aa423763d341ef", + "commit": { + "sha": "f74f3d2a88d1b7cb19ff3bf069aa423763d341ef", + "message": "updated b2", + "author": { + "identity": { + "name": "Admin", + "email": "admin@harness.io" + }, + "when": "2023-02-01T13:28:55-08:00" + }, + "committer": { + "identity": { + "name": "Admin", + "email": "admin@harness.io" + }, + "when": "2023-02-01T13:28:55-08:00" + } + }, + "old_sha": "d74b1ebfe520ac01b209dd9085f005884cc9f4cd", + "forced": false +} \ No newline at end of file diff --git a/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json.golden b/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json.golden new file mode 100644 index 000000000..d978a3b13 --- /dev/null +++ b/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json.golden @@ -0,0 +1,42 @@ +{ + "Action": "updated", + "Repo": { + "ID": "aba", + "Namespace": "", + "Name": "", + "Branch": "main", + "Private": false, + "Clone": "", + "CloneSSH": "", + "Link": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "PullRequest": { + "Number": 4, + "Title": "aw", + "Body": "", + "Sha": "f74f3d2a88d1b7cb19ff3bf069aa423763d341ef", + "Ref": "", + "Source": "13", + "Target": "13", + "Fork": "fork", + "Link": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git", + "Closed": false, + "Merged": false, + "Author": { + "Login": "", + "Name": "", + "Email": "", + "Avatar": "" + }, + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Sender": { + "Login": "", + "Name": "", + "Email": "default@harness.io", + "Avatar": "" + } +} \ No newline at end of file diff --git a/scm/driver/harness/testdata/webhooks/pull_request_opened.json b/scm/driver/harness/testdata/webhooks/pull_request_opened.json index 9244c2035..a7fd7666b 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_opened.json +++ b/scm/driver/harness/testdata/webhooks/pull_request_opened.json @@ -1,172 +1,69 @@ { - "secret": "12345", - "action": "opened", - "number": 1, - "pull_request": { - "id": 473, - "url": "", - "number": 1, - "user": { - "id": 6641, - "login": "jcitizen", - "full_name": "", - "email": "jane@example.com", - "avatar_url": "https://secure.gravatar.com/avatar/66f07ff48e6a9cb393de7a34e03bb52a?d=identicon", - "language": "en-US", - "username": "jcitizen" - }, - "title": "Add License File", - "body": "Using a BSD License", - "labels": [], - "milestone": null, - "assignee": null, - "assignees": null, - "state": "open", - "comments": 0, - "html_url": "https://try.gitea.io/jcitizen/my-repo/pulls/1", - "diff_url": "https://try.gitea.io/jcitizen/my-repo/pulls/1.diff", - "patch_url": "https://try.gitea.io/jcitizen/my-repo/pulls/1.patch", - "mergeable": true, - "merged": false, - "merged_at": null, - "merge_commit_sha": null, - "merged_by": null, - "base": { - "label": "master", - "ref": "master", - "sha": "39af58f1eff02aa308e16913e887c8d50362b474", - "repo_id": 6589, + "trigger": "pullreq_created", + "repo": { + "id": 13, + "path": "kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba", + "uid": "aba", + "default_branch": "main", + "git_url": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git" + }, + "principal": { + "id": 8, + "uid": "0osgWsTZRsSZ8RWfjLRkEg", + "display_name": "default", + "email": "default@harness.io", + "type": "user", + "created": 1675390885380, + "updated": 1675390885380 + }, + "pull_req": { + "number": 4, + "state": "open", + "is_draft": false, + "title": "aw", + "source_repo_id": 13, + "source_branch": "b", + "target_repo_id": 13, + "target_branch": "main", + "merge_strategy": null + }, + "target_ref": { + "name": "refs/heads/main", "repo": { - "id": 6589, - "owner": { - "id": 6641, - "login": "jcitizen", - "full_name": "", - "email": "jane@example.com", - "avatar_url": "https://secure.gravatar.com/avatar/66f07ff48e6a9cb393de7a34e03bb52a?d=identicon", - "language": "en-US", - "username": "jcitizen" - }, - "name": "my-repo", - "full_name": "jcitizen/my-repo", - "description": "", - "empty": false, - "private": false, - "fork": false, - "parent": null, - "mirror": false, - "size": 64, - "html_url": "https://try.gitea.io/jcitizen/my-repo", - "ssh_url": "git@try.gitea.io:jcitizen/my-repo.git", - "clone_url": "https://try.gitea.io/jcitizen/my-repo.git", - "website": "", - "stars_count": 0, - "forks_count": 0, - "watchers_count": 1, - "open_issues_count": 0, - "default_branch": "master", - "created_at": "2018-07-06T00:08:02Z", - "updated_at": "2018-07-06T01:06:56Z", - "permissions": { - "admin": false, - "push": false, - "pull": false - } + "id": 13, + "path": "kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba", + "uid": "aba", + "default_branch": "main", + "git_url": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git" } - }, - "head": { - "label": "feature", - "ref": "feature", - "sha": "2eba238e33607c1fa49253182e9fff42baafa1eb", - "repo_id": 6589, + }, + "ref": { + "name": "refs/heads/b", "repo": { - "id": 6589, - "owner": { - "id": 6641, - "login": "jcitizen", - "full_name": "", - "email": "jane@example.com", - "avatar_url": "https://secure.gravatar.com/avatar/66f07ff48e6a9cb393de7a34e03bb52a?d=identicon", - "language": "en-US", - "username": "jcitizen" - }, - "name": "my-repo", - "full_name": "jcitizen/my-repo", - "description": "", - "empty": false, - "private": false, - "fork": false, - "parent": null, - "mirror": false, - "size": 64, - "html_url": "https://try.gitea.io/jcitizen/my-repo", - "ssh_url": "git@try.gitea.io:jcitizen/my-repo.git", - "clone_url": "https://try.gitea.io/jcitizen/my-repo.git", - "website": "", - "stars_count": 0, - "forks_count": 0, - "watchers_count": 1, - "open_issues_count": 0, - "default_branch": "master", - "created_at": "2018-07-06T00:08:02Z", - "updated_at": "2018-07-06T01:06:56Z", - "permissions": { - "admin": false, - "push": false, - "pull": false - } + "id": 13, + "path": "kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba", + "uid": "aba", + "default_branch": "main", + "git_url": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git" } - }, - "merge_base": "39af58f1eff02aa308e16913e887c8d50362b474", - "due_date": null, - "created_at": "2018-07-06T00:37:47Z", - "updated_at": "2018-07-06T00:37:47Z", - "closed_at": null - }, - "repository": { - "id": 6589, - "owner": { - "id": 6641, - "login": "jcitizen", - "full_name": "", - "email": "jane@example.com", - "avatar_url": "https://secure.gravatar.com/avatar/66f07ff48e6a9cb393de7a34e03bb52a?d=identicon", - "language": "en-US", - "username": "jcitizen" - }, - "name": "my-repo", - "full_name": "jcitizen/my-repo", - "description": "", - "empty": false, - "private": false, - "fork": false, - "parent": null, - "mirror": false, - "size": 64, - "html_url": "https://try.gitea.io/jcitizen/my-repo", - "ssh_url": "git@try.gitea.io:jcitizen/my-repo.git", - "clone_url": "https://try.gitea.io/jcitizen/my-repo.git", - "website": "", - "stars_count": 0, - "forks_count": 0, - "watchers_count": 1, - "open_issues_count": 0, - "default_branch": "master", - "created_at": "2018-07-06T00:08:02Z", - "updated_at": "2018-07-06T01:06:56Z", - "permissions": { - "admin": false, - "push": false, - "pull": false - } }, - "sender": { - "id": 6641, - "login": "jcitizen", - "full_name": "", - "email": "jane@example.com", - "avatar_url": "https://secure.gravatar.com/avatar/66f07ff48e6a9cb393de7a34e03bb52a?d=identicon", - "language": "en-US", - "username": "jcitizen" + "sha": "d74b1ebfe520ac01b209dd9085f005884cc9f4cd", + "commit": { + "sha": "d74b1ebfe520ac01b209dd9085f005884cc9f4cd", + "message": "Update b.txt", + "author": { + "identity": { + "name": "Admin", + "email": "admin@harness.io" + }, + "when": "2023-01-31T22:01:55-08:00" + }, + "committer": { + "identity": { + "name": "Admin", + "email": "admin@harness.io" + }, + "when": "2023-01-31T22:01:55-08:00" + } } } \ No newline at end of file diff --git a/scm/driver/harness/testdata/webhooks/pull_request_opened.json.golden b/scm/driver/harness/testdata/webhooks/pull_request_opened.json.golden index b44944b2d..936a53c7a 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_opened.json.golden +++ b/scm/driver/harness/testdata/webhooks/pull_request_opened.json.golden @@ -1,47 +1,42 @@ { - "Action": "opened", + "Action": "created", "Repo": { - "ID": "6589", - "Namespace": "jcitizen", - "Name": "my-repo", - "Perm": { - "Pull": false, - "Push": false, - "Admin": false - }, - "Branch": "master", + "ID": "aba", + "Namespace": "", + "Name": "", + "Branch": "main", "Private": false, - "Clone": "https://try.gitea.io/jcitizen/my-repo.git", - "CloneSSH": "git@try.gitea.io:jcitizen/my-repo.git", - "Link": "https://try.gitea.io/jcitizen/my-repo", + "Clone": "", + "CloneSSH": "", + "Link": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git", "Created": "0001-01-01T00:00:00Z", "Updated": "0001-01-01T00:00:00Z" }, "PullRequest": { - "Number": 1, - "Title": "Add License File", - "Body": "Using a BSD License", - "Sha": "2eba238e33607c1fa49253182e9fff42baafa1eb", - "Ref": "refs/pull/1/head", - "Source": "feature", - "Target": "master", - "Fork": "jcitizen/my-repo", - "Link": "https://try.gitea.io/jcitizen/my-repo/pulls/1", + "Number": 4, + "Title": "aw", + "Body": "", + "Sha": "d74b1ebfe520ac01b209dd9085f005884cc9f4cd", + "Ref": "", + "Source": "13", + "Target": "13", + "Fork": "fork", + "Link": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git", "Closed": false, "Merged": false, "Author": { - "Login": "jcitizen", + "Login": "", "Name": "", - "Email": "jane@example.com", - "Avatar": "https://secure.gravatar.com/avatar/66f07ff48e6a9cb393de7a34e03bb52a?d=identicon" + "Email": "", + "Avatar": "" }, "Created": "0001-01-01T00:00:00Z", "Updated": "0001-01-01T00:00:00Z" }, "Sender": { - "Login": "jcitizen", + "Login": "", "Name": "", - "Email": "jane@example.com", - "Avatar": "https://secure.gravatar.com/avatar/66f07ff48e6a9cb393de7a34e03bb52a?d=identicon" + "Email": "default@harness.io", + "Avatar": "" } } \ No newline at end of file diff --git a/scm/driver/harness/testdata/webhooks/pull_request_reopened.json b/scm/driver/harness/testdata/webhooks/pull_request_reopened.json new file mode 100644 index 000000000..c6549d374 --- /dev/null +++ b/scm/driver/harness/testdata/webhooks/pull_request_reopened.json @@ -0,0 +1,69 @@ +{ + "trigger": "pullreq_reopened", + "repo": { + "id": 13, + "path": "kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba", + "uid": "aba", + "default_branch": "main", + "git_url": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git" + }, + "principal": { + "id": 8, + "uid": "0osgWsTZRsSZ8RWfjLRkEg", + "display_name": "default", + "email": "default@harness.io", + "type": "user", + "created": 1675390885380, + "updated": 1675390885380 + }, + "pull_req": { + "number": 4, + "state": "open", + "is_draft": false, + "title": "aw", + "source_repo_id": 13, + "source_branch": "b", + "target_repo_id": 13, + "target_branch": "main", + "merge_strategy": null + }, + "target_ref": { + "name": "refs/heads/main", + "repo": { + "id": 13, + "path": "kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba", + "uid": "aba", + "default_branch": "main", + "git_url": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git" + } + }, + "ref": { + "name": "refs/heads/b", + "repo": { + "id": 13, + "path": "kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba", + "uid": "aba", + "default_branch": "main", + "git_url": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git" + } + }, + "sha": "f74f3d2a88d1b7cb19ff3bf069aa423763d341ef", + "commit": { + "sha": "f74f3d2a88d1b7cb19ff3bf069aa423763d341ef", + "message": "updated b2", + "author": { + "identity": { + "name": "Admin", + "email": "admin@harness.io" + }, + "when": "2023-02-01T13:28:55-08:00" + }, + "committer": { + "identity": { + "name": "Admin", + "email": "admin@harness.io" + }, + "when": "2023-02-01T13:28:55-08:00" + } + } +} \ No newline at end of file diff --git a/scm/driver/harness/testdata/webhooks/pull_request_reopened.json.golden b/scm/driver/harness/testdata/webhooks/pull_request_reopened.json.golden new file mode 100644 index 000000000..17b0f8657 --- /dev/null +++ b/scm/driver/harness/testdata/webhooks/pull_request_reopened.json.golden @@ -0,0 +1,42 @@ +{ + "Action": "reopened", + "Repo": { + "ID": "aba", + "Namespace": "", + "Name": "", + "Branch": "main", + "Private": false, + "Clone": "", + "CloneSSH": "", + "Link": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "PullRequest": { + "Number": 4, + "Title": "aw", + "Body": "", + "Sha": "f74f3d2a88d1b7cb19ff3bf069aa423763d341ef", + "Ref": "", + "Source": "13", + "Target": "13", + "Fork": "fork", + "Link": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git", + "Closed": false, + "Merged": false, + "Author": { + "Login": "", + "Name": "", + "Email": "", + "Avatar": "" + }, + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Sender": { + "Login": "", + "Name": "", + "Email": "default@harness.io", + "Avatar": "" + } +} \ No newline at end of file diff --git a/scm/driver/harness/webhook.go b/scm/driver/harness/webhook.go index 4f7bc187c..6b8c2777e 100644 --- a/scm/driver/harness/webhook.go +++ b/scm/driver/harness/webhook.go @@ -29,18 +29,16 @@ func (s *webhookService) Parse(req *http.Request, fn scm.SecretFunc) (scm.Webhoo } var hook scm.Webhook - switch req.Header.Get("X-Gitea-Event") { - case "push": + switch req.Header.Get("X-Harness-Trigger") { + // case "create": + // hook, err = s.parseCreateHook(data) + // case "delete": + // hook, err = s.parseDeleteHook(data) + // case "issues": + // hook, err = s.parseIssueHook(data) + case "branch_created": hook, err = s.parsePushHook(data) - case "create": - hook, err = s.parseCreateHook(data) - case "delete": - hook, err = s.parseDeleteHook(data) - case "issues": - hook, err = s.parseIssueHook(data) - case "issue_comment": - hook, err = s.parseIssueCommentHook(data) - case "pull_request": + case "pullreq_created", "pullreq_reopened", "pullreq_branch_updated": hook, err = s.parsePullRequestHook(data) default: return nil, scm.ErrUnknownEvent @@ -80,102 +78,106 @@ func (s *webhookService) Parse(req *http.Request, fn scm.SecretFunc) (scm.Webhoo return hook, nil } -func (s *webhookService) parsePushHook(data []byte) (scm.Webhook, error) { - dst := new(pushHook) - err := json.Unmarshal(data, dst) - return convertPushHook(dst), err -} - -func (s *webhookService) parseCreateHook(data []byte) (scm.Webhook, error) { - dst := new(createHook) - err := json.Unmarshal(data, dst) - switch dst.RefType { - case "tag": - return convertTagHook(dst, scm.ActionCreate), err - case "branch": - return convertBranchHook(dst, scm.ActionCreate), err - default: - return nil, scm.ErrUnknownEvent - } -} - -func (s *webhookService) parseDeleteHook(data []byte) (scm.Webhook, error) { - dst := new(createHook) - err := json.Unmarshal(data, dst) - switch dst.RefType { - case "tag": - return convertTagHook(dst, scm.ActionDelete), err - case "branch": - return convertBranchHook(dst, scm.ActionDelete), err - default: - return nil, scm.ErrUnknownEvent - } -} - -func (s *webhookService) parseIssueHook(data []byte) (scm.Webhook, error) { - dst := new(issueHook) - err := json.Unmarshal(data, dst) - return convertIssueHook(dst), err -} - -func (s *webhookService) parseIssueCommentHook(data []byte) (scm.Webhook, error) { - dst := new(issueHook) - err := json.Unmarshal(data, dst) - if dst.Issue.PullRequest != nil { - return convertPullRequestCommentHook(dst), err - } - return convertIssueCommentHook(dst), err -} - func (s *webhookService) parsePullRequestHook(data []byte) (scm.Webhook, error) { dst := new(pullRequestHook) err := json.Unmarshal(data, dst) return convertPullRequestHook(dst), err } -// -// native data structures -// +func (s *webhookService) parsePushHook(data []byte) (scm.Webhook, error) { + dst := new(pushHook) + err := json.Unmarshal(data, dst) + return convertPushHook(dst), err +} +// native data structures type ( - // gitea push webhook payload - pushHook struct { - Ref string `json:"ref"` - Before string `json:"before"` - After string `json:"after"` - Compare string `json:"compare_url"` - Commits []commit `json:"commits"` - Repository repository `json:"repository"` - Pusher user `json:"pusher"` - Sender user `json:"sender"` - } - - // gitea create webhook payload - createHook struct { - Ref string `json:"ref"` - RefType string `json:"ref_type"` - Sha string `json:"sha"` - DefaultBranch string `json:"default_branch"` - Repository repository `json:"repository"` - Sender user `json:"sender"` - } - - // gitea issue webhook payload - issueHook struct { - Action string `json:"action"` - Issue issue `json:"issue"` - Comment issueComment `json:"comment"` - Repository repository `json:"repository"` - Sender user `json:"sender"` - } - - // gitea pull request webhook payload + repo struct { + ID int `json:"id"` + Path string `json:"path"` + UID string `json:"uid"` + DefaultBranch string `json:"default_branch"` + GitURL string `json:"git_url"` + } + principal struct { + ID int `json:"id"` + UID string `json:"uid"` + DisplayName string `json:"display_name"` + Email string `json:"email"` + Type string `json:"type"` + Created int64 `json:"created"` + Updated int64 `json:"updated"` + } + pullReq struct { + Number int `json:"number"` + State string `json:"state"` + IsDraft bool `json:"is_draft"` + Title string `json:"title"` + SourceRepoID int `json:"source_repo_id"` + SourceBranch string `json:"source_branch"` + TargetRepoID int `json:"target_repo_id"` + TargetBranch string `json:"target_branch"` + MergeStrategy interface{} `json:"merge_strategy"` + } + targetRef struct { + Name string `json:"name"` + Repo struct { + ID int `json:"id"` + Path string `json:"path"` + UID string `json:"uid"` + DefaultBranch string `json:"default_branch"` + GitURL string `json:"git_url"` + } `json:"repo"` + } + ref struct { + Name string `json:"name"` + Repo struct { + ID int `json:"id"` + Path string `json:"path"` + UID string `json:"uid"` + DefaultBranch string `json:"default_branch"` + GitURL string `json:"git_url"` + } `json:"repo"` + } + hookCommit struct { + Sha string `json:"sha"` + Message string `json:"message"` + Author struct { + Identity struct { + Name string `json:"name"` + Email string `json:"email"` + } `json:"identity"` + When string `json:"when"` + } `json:"author"` + Committer struct { + Identity struct { + Name string `json:"name"` + Email string `json:"email"` + } `json:"identity"` + When string `json:"when"` + } `json:"committer"` + } + // harness pull request webhook payload pullRequestHook struct { - Action string `json:"action"` - Number int `json:"number"` - PullRequest pr `json:"pull_request"` - Repository repository `json:"repository"` - Sender user `json:"sender"` + Trigger string `json:"trigger"` + Repo repo `json:"repo"` + Principal principal `json:"principal"` + PullReq pullReq `json:"pull_req"` + TargetRef targetRef `json:"target_ref"` + Ref ref `json:"ref"` + Sha string `json:"sha"` + Commit hookCommit `json:"commit"` + } + // harness push webhook payload + pushHook struct { + Trigger string `json:"trigger"` + Repo repo `json:"repo"` + Principal principal `json:"principal"` + Ref ref `json:"ref"` + Commit hookCommit `json:"commit"` + Sha string `json:"sha"` + OldSha string `json:"old_sha"` + Forced bool `json:"forced"` } ) @@ -183,178 +185,60 @@ type ( // native data structure conversion // -func convertTagHook(dst *createHook, action scm.Action) *scm.TagHook { - return &scm.TagHook{ - Action: action, - Ref: scm.Reference{ - Name: dst.Ref, - Sha: dst.Sha, +func convertPullRequestHook(dst *pullRequestHook) *scm.PullRequestHook { + return &scm.PullRequestHook{ + Action: convertAction(dst.Trigger), + PullRequest: scm.PullRequest{ + Number: dst.PullReq.Number, + Title: dst.PullReq.Title, + Closed: dst.PullReq.State != "open", + Source: fmt.Sprintf("%d", dst.PullReq.SourceRepoID), + Target: fmt.Sprintf("%d", dst.PullReq.TargetRepoID), + Fork: "fork", + Link: dst.Ref.Repo.GitURL, + Sha: dst.Commit.Sha, }, - Repo: *convertRepository(&dst.Repository), - Sender: *convertUser(&dst.Sender), - } -} - -func convertBranchHook(dst *createHook, action scm.Action) *scm.BranchHook { - return &scm.BranchHook{ - Action: action, - Ref: scm.Reference{ - Name: dst.Ref, + Repo: scm.Repository{ + ID: dst.Repo.UID, + Branch: dst.Repo.DefaultBranch, + Link: dst.Repo.GitURL, + }, + Sender: scm.User{ + Email: dst.Principal.Email, }, - Repo: *convertRepository(&dst.Repository), - Sender: *convertUser(&dst.Sender), } } func convertPushHook(dst *pushHook) *scm.PushHook { - if len(dst.Commits) > 0 { - var commits []scm.Commit - for _, c := range dst.Commits { - commits = append(commits, - scm.Commit{ - Sha: c.ID, - Message: c.Message, - Link: c.URL, - Author: scm.Signature{ - Login: c.Author.Username, - Email: c.Author.Email, - Name: c.Author.Name, - Date: c.Timestamp, - }, - Committer: scm.Signature{ - Login: c.Committer.Username, - Email: c.Committer.Email, - Name: c.Committer.Name, - Date: c.Timestamp, - }, - }) - } - - return &scm.PushHook{ - Ref: dst.Ref, - Before: dst.Before, - Commit: scm.Commit{ - Sha: dst.After, - Message: dst.Commits[0].Message, - Link: dst.Compare, - Author: scm.Signature{ - Login: dst.Commits[0].Author.Username, - Email: dst.Commits[0].Author.Email, - Name: dst.Commits[0].Author.Name, - Date: dst.Commits[0].Timestamp, - }, - Committer: scm.Signature{ - Login: dst.Commits[0].Committer.Username, - Email: dst.Commits[0].Committer.Email, - Name: dst.Commits[0].Committer.Name, - Date: dst.Commits[0].Timestamp, - }, - }, - Commits: commits, - Repo: *convertRepository(&dst.Repository), - Sender: *convertUser(&dst.Sender), - } - } return &scm.PushHook{ - Ref: dst.Ref, + Ref: dst.Sha, + Before: dst.OldSha, + After: dst.Sha, + Repo: scm.Repository{ + Name: dst.Repo.UID, + }, Commit: scm.Commit{ - Sha: dst.After, - Link: dst.Compare, + Sha: dst.Commit.Sha, + Message: dst.Commit.Message, Author: scm.Signature{ - Login: dst.Pusher.Login, - Email: dst.Pusher.Email, - Name: dst.Pusher.Fullname, - }, - Committer: scm.Signature{ - Login: dst.Pusher.Login, - Email: dst.Pusher.Email, - Name: dst.Pusher.Fullname, + Name: dst.Commit.Author.Identity.Name, + Email: dst.Commit.Author.Identity.Email, }, }, - Repo: *convertRepository(&dst.Repository), - Sender: *convertUser(&dst.Sender), - } -} - -func convertPullRequestHook(dst *pullRequestHook) *scm.PullRequestHook { - return &scm.PullRequestHook{ - Action: convertAction(dst.Action), - PullRequest: scm.PullRequest{ - Number: dst.PullRequest.Number, - Title: dst.PullRequest.Title, - Body: dst.PullRequest.Body, - Closed: dst.PullRequest.State == "closed", - Author: scm.User{ - Login: dst.PullRequest.User.Login, - Email: dst.PullRequest.User.Email, - Avatar: dst.PullRequest.User.Avatar, - }, - Merged: dst.PullRequest.Merged, - // Created: nil, - // Updated: nil, - Source: dst.PullRequest.Head.Name, - Target: dst.PullRequest.Base.Name, - Fork: "fork", - Link: dst.PullRequest.HTMLURL, - Ref: fmt.Sprintf("refs/pull/%d/head", dst.PullRequest.Number), - Sha: dst.PullRequest.Head.Sha, + Sender: scm.User{ + Name: dst.Principal.DisplayName, }, - Repo: *convertRepository(&dst.Repository), - Sender: *convertUser(&dst.Sender), - } -} - -func convertPullRequestCommentHook(dst *issueHook) *scm.PullRequestCommentHook { - return &scm.PullRequestCommentHook{ - Action: convertAction(dst.Action), - PullRequest: *convertPullRequestFromIssue(&dst.Issue), - Comment: *convertIssueComment(&dst.Comment), - Repo: *convertRepository(&dst.Repository), - Sender: *convertUser(&dst.Sender), - } -} - -func convertIssueHook(dst *issueHook) *scm.IssueHook { - return &scm.IssueHook{ - Action: convertAction(dst.Action), - Issue: *convertIssue(&dst.Issue), - Repo: *convertRepository(&dst.Repository), - Sender: *convertUser(&dst.Sender), - } -} - -func convertIssueCommentHook(dst *issueHook) *scm.IssueCommentHook { - return &scm.IssueCommentHook{ - Action: convertAction(dst.Action), - Issue: *convertIssue(&dst.Issue), - Comment: *convertIssueComment(&dst.Comment), - Repo: *convertRepository(&dst.Repository), - Sender: *convertUser(&dst.Sender), } } func convertAction(src string) (action scm.Action) { switch src { - case "create", "created": + case "pullreq_created": return scm.ActionCreate - case "delete", "deleted": - return scm.ActionDelete - case "update", "updated", "edit", "edited": + case "pullreq_branch_updated": return scm.ActionUpdate - case "open", "opened": - return scm.ActionOpen - case "reopen", "reopened": + case "pullreq_reopened": return scm.ActionReopen - case "close", "closed": - return scm.ActionClose - case "label", "labeled": - return scm.ActionLabel - case "unlabel", "unlabeled": - return scm.ActionUnlabel - case "merge", "merged": - return scm.ActionMerge - case "synchronize", "synchronized": - return scm.ActionSync default: return } diff --git a/scm/driver/harness/webhook_test.go b/scm/driver/harness/webhook_test.go index 5d232e2ff..4e38687be 100644 --- a/scm/driver/harness/webhook_test.go +++ b/scm/driver/harness/webhook_test.go @@ -3,3 +3,116 @@ // license that can be found in the LICENSE file. package harness + +import ( + "bytes" + "encoding/json" + "io/ioutil" + "net/http" + "os" + "testing" + + "github.com/drone/go-scm/scm" + "github.com/google/go-cmp/cmp" +) + +func TestWebhooks(t *testing.T) { + tests := []struct { + event string + before string + after string + obj interface{} + }{ + // + // branch events + // + // push branch create + { + event: "branch_created", + before: "testdata/webhooks/branch_create.json", + after: "testdata/webhooks/branch_create.json.golden", + obj: new(scm.PushHook), + }, + // + // pull request events + // + // pull request opened + { + event: "pullreq_created", + before: "testdata/webhooks/pull_request_opened.json", + after: "testdata/webhooks/pull_request_opened.json.golden", + obj: new(scm.PullRequestHook), + }, + // pull request reopened + { + event: "pullreq_reopened", + before: "testdata/webhooks/pull_request_reopened.json", + after: "testdata/webhooks/pull_request_reopened.json.golden", + obj: new(scm.PullRequestHook), + }, + // pull request branch updated + { + event: "pullreq_branch_updated", + before: "testdata/webhooks/pull_request_branch_updated.json", + after: "testdata/webhooks/pull_request_branch_updated.json.golden", + obj: new(scm.PullRequestHook), + }, + } + + for _, test := range tests { + before, err := ioutil.ReadFile(test.before) + if err != nil { + t.Error(err) + continue + } + after, err := ioutil.ReadFile(test.after) + if err != nil { + t.Error(err) + continue + } + + buf := bytes.NewBuffer(before) + r, _ := http.NewRequest("GET", "/", buf) + r.Header.Set("X-Harness-Trigger", test.event) + + s := new(webhookService) + o, err := s.Parse(r, secretFunc) + if err != nil && err != scm.ErrSignatureInvalid { + t.Error(err) + continue + } + + err = json.Unmarshal(after, test.obj) + if err != nil { + t.Error(err) + continue + } + + if diff := cmp.Diff(test.obj, o); diff != "" { + t.Errorf("Error unmarshaling %s", test.before) + t.Log(diff) + + // debug only. remove once implemented + _ = json.NewEncoder(os.Stdout).Encode(o) + + } + + // switch event := o.(type) { + // case *scm.PushHook: + // if !strings.HasPrefix(event.Ref, "refs/") { + // t.Errorf("Push hook reference must start with refs/") + // } + // case *scm.BranchHook: + // if strings.HasPrefix(event.Ref.Name, "refs/") { + // t.Errorf("Branch hook reference must not start with refs/") + // } + // case *scm.TagHook: + // if strings.HasPrefix(event.Ref.Name, "refs/") { + // t.Errorf("Branch hook reference must not start with refs/") + // } + // } + } +} +func secretFunc(scm.Webhook) (string, error) { + return "topsecret", nil +} From ff7deab27e87e4fede0a76c9443163e164f4322c Mon Sep 17 00:00:00 2001 From: TP Honey Date: Wed, 8 Feb 2023 14:51:40 +0000 Subject: [PATCH 051/195] (feat) harness, add list webhooks --- scm/driver/harness/repo.go | 42 ++++++++++++++++++- scm/driver/harness/repo_test.go | 38 +++++++++++++++++ scm/driver/harness/testdata/hooks.json | 19 +++++++++ scm/driver/harness/testdata/hooks.json.golden | 10 +++++ 4 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 scm/driver/harness/testdata/hooks.json create mode 100644 scm/driver/harness/testdata/hooks.json.golden diff --git a/scm/driver/harness/repo.go b/scm/driver/harness/repo.go index 33fbc832c..5046d56c2 100644 --- a/scm/driver/harness/repo.go +++ b/scm/driver/harness/repo.go @@ -49,7 +49,11 @@ 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) { - return nil, nil, scm.ErrNotSupported + harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + path := fmt.Sprintf("api/v1/repos/%s/webhooks?sort=display_name&order=asc&%s", harnessURI, encodeListOptions(opts)) + out := []*hook{} + res, err := s.client.do(ctx, "GET", path, nil, &out) + return convertHookList(out), res, err } func (s *repositoryService) ListStatus(ctx context.Context, repo string, ref string, opts scm.ListOptions) ([]*scm.Status, *scm.Response, error) { @@ -97,6 +101,23 @@ type ( NumMergedPulls int `json:"num_merged_pulls"` GitURL string `json:"git_url"` } + hook struct { + Created int `json:"created"` + CreatedBy int `json:"created_by"` + Description string `json:"description"` + DisplayName string `json:"display_name"` + Enabled bool `json:"enabled"` + HasSecret bool `json:"has_secret"` + ID int `json:"id"` + Insecure bool `json:"insecure"` + LatestExecutionResult string `json:"latest_execution_result"` + ParentID int `json:"parent_id"` + ParentType string `json:"parent_type"` + Triggers []string `json:"triggers"` + Updated int `json:"updated"` + URL string `json:"url"` + Version int `json:"version"` + } ) // @@ -125,3 +146,22 @@ func convertRepository(src *repository) *scm.Repository { // Updated: time.Unix(src.Updated, 0), } } + +func convertHookList(from []*hook) []*scm.Hook { + to := []*scm.Hook{} + for _, v := range from { + to = append(to, convertHook(v)) + } + return to +} + +func convertHook(from *hook) *scm.Hook { + return &scm.Hook{ + ID: strconv.Itoa(from.ID), + Name: from.DisplayName, + Active: from.Enabled, + Target: from.URL, + Events: from.Triggers, + SkipVerify: from.Insecure, + } +} diff --git a/scm/driver/harness/repo_test.go b/scm/driver/harness/repo_test.go index 812866cba..777aadbc2 100644 --- a/scm/driver/harness/repo_test.go +++ b/scm/driver/harness/repo_test.go @@ -89,3 +89,41 @@ func TestRepositoryList(t *testing.T) { t.Log(diff) } } + +func TestRepositoryHookList(t *testing.T) { + if harnessPAT == "" { + defer gock.Off() + + gock.New(gockOrigin). + Get("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/webhooks"). + MatchParam("page", "1"). + MatchParam("limit", "30"). + MatchParam("sort", "display_name"). + MatchParam("order", "asc"). + Reply(200). + Type("application/json"). + File("testdata/hooks.json") + } + client, _ := New(gockOrigin, harnessOrg, harnessAccount, harnessProject) + client.Client = &http.Client{ + Transport: &transport.Custom{ + Before: func(r *http.Request) { + r.Header.Set("x-api-key", harnessPAT) + }, + }, + } + got, _, err := client.Repositories.ListHooks(context.Background(), harnessRepo, scm.ListOptions{Page: 1, Size: 30}) + if err != nil { + t.Error(err) + return + } + + want := []*scm.Hook{} + raw, _ := ioutil.ReadFile("testdata/hooks.json.golden") + _ = json.Unmarshal(raw, &want) + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } +} diff --git a/scm/driver/harness/testdata/hooks.json b/scm/driver/harness/testdata/hooks.json new file mode 100644 index 000000000..372ad34a7 --- /dev/null +++ b/scm/driver/harness/testdata/hooks.json @@ -0,0 +1,19 @@ +[ + { + "id": 6, + "version": 1, + "parent_id": 11, + "parent_type": "repo", + "created_by": 14, + "created": 1675867490853, + "updated": 1675867531549, + "display_name": "webhookname", + "description": "webhookdescription", + "url": "http://1.1.1.1", + "enabled": true, + "insecure": true, + "triggers": [], + "latest_execution_result": "success", + "has_secret": true + } +] \ No newline at end of file diff --git a/scm/driver/harness/testdata/hooks.json.golden b/scm/driver/harness/testdata/hooks.json.golden new file mode 100644 index 000000000..f21533cbe --- /dev/null +++ b/scm/driver/harness/testdata/hooks.json.golden @@ -0,0 +1,10 @@ +[ + { + "ID": "6", + "Name": "webhookname", + "Target": "http://1.1.1.1", + "Events": [], + "Active": true, + "SkipVerify": true + } +] \ No newline at end of file From b8eea16f4bb0ef6038e0b6747511fbf12d2ec41f Mon Sep 17 00:00:00 2001 From: TP Honey Date: Wed, 8 Feb 2023 15:34:10 +0000 Subject: [PATCH 052/195] (feat) harness, add find hook --- scm/driver/harness/repo.go | 6 +++- scm/driver/harness/repo_test.go | 34 ++++++++++++++++++++ scm/driver/harness/testdata/hook.json | 17 ++++++++++ scm/driver/harness/testdata/hook.json.golden | 8 +++++ 4 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 scm/driver/harness/testdata/hook.json create mode 100644 scm/driver/harness/testdata/hook.json.golden diff --git a/scm/driver/harness/repo.go b/scm/driver/harness/repo.go index 5046d56c2..289d85e23 100644 --- a/scm/driver/harness/repo.go +++ b/scm/driver/harness/repo.go @@ -33,7 +33,11 @@ func (s *repositoryService) Find(ctx context.Context, repo string) (*scm.Reposit } func (s *repositoryService) FindHook(ctx context.Context, repo string, id string) (*scm.Hook, *scm.Response, error) { - return nil, nil, scm.ErrNotSupported + harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + path := fmt.Sprintf("api/v1/repos/%s/webhooks/%s", harnessURI, id) + out := new(hook) + res, err := s.client.do(ctx, "GET", path, nil, &out) + return convertHook(out), res, err } func (s *repositoryService) FindPerms(ctx context.Context, repo string) (*scm.Perm, *scm.Response, error) { diff --git a/scm/driver/harness/repo_test.go b/scm/driver/harness/repo_test.go index 777aadbc2..082dbb4f1 100644 --- a/scm/driver/harness/repo_test.go +++ b/scm/driver/harness/repo_test.go @@ -127,3 +127,37 @@ func TestRepositoryHookList(t *testing.T) { t.Log(diff) } } + +func TestRepositoryFindHook(t *testing.T) { + if harnessPAT == "" { + defer gock.Off() + + gock.New(gockOrigin). + Get("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/webhooks/6"). + Reply(200). + Type("application/json"). + File("testdata/hook.json") + } + client, _ := New(gockOrigin, harnessOrg, harnessAccount, harnessProject) + client.Client = &http.Client{ + Transport: &transport.Custom{ + Before: func(r *http.Request) { + r.Header.Set("x-api-key", harnessPAT) + }, + }, + } + got, _, err := client.Repositories.FindHook(context.Background(), harnessRepo, "6") + if err != nil { + t.Error(err) + return + } + + want := new(scm.Hook) + raw, _ := ioutil.ReadFile("testdata/hook.json.golden") + _ = json.Unmarshal(raw, &want) + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } +} diff --git a/scm/driver/harness/testdata/hook.json b/scm/driver/harness/testdata/hook.json new file mode 100644 index 000000000..994de6ed8 --- /dev/null +++ b/scm/driver/harness/testdata/hook.json @@ -0,0 +1,17 @@ +{ + "id": 6, + "version": 1, + "parent_id": 11, + "parent_type": "repo", + "created_by": 14, + "created": 1675867490853, + "updated": 1675867531549, + "display_name": "webhookname", + "description": "webhookdescription", + "url": "http://1.1.1.1", + "enabled": true, + "insecure": true, + "triggers": [], + "latest_execution_result": "success", + "has_secret": true +} \ No newline at end of file diff --git a/scm/driver/harness/testdata/hook.json.golden b/scm/driver/harness/testdata/hook.json.golden new file mode 100644 index 000000000..53463fce4 --- /dev/null +++ b/scm/driver/harness/testdata/hook.json.golden @@ -0,0 +1,8 @@ +{ + "ID": "6", + "Name": "webhookname", + "Target": "http://1.1.1.1", + "Events": [], + "Active": true, + "SkipVerify": true +} \ No newline at end of file From d6e3618f2eb2e2762cbbda158c7ce9aa67e20bf8 Mon Sep 17 00:00:00 2001 From: TP Honey Date: Wed, 8 Feb 2023 16:18:32 +0000 Subject: [PATCH 053/195] (feat) harness, add create / delete webhook --- scm/driver/harness/repo.go | 20 +++++- scm/driver/harness/repo_test.go | 64 +++++++++++++++++++ scm/driver/harness/testdata/hook_create.json | 17 +++++ .../harness/testdata/hook_create.json.golden | 8 +++ 4 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 scm/driver/harness/testdata/hook_create.json create mode 100644 scm/driver/harness/testdata/hook_create.json.golden diff --git a/scm/driver/harness/repo.go b/scm/driver/harness/repo.go index 289d85e23..a55089516 100644 --- a/scm/driver/harness/repo.go +++ b/scm/driver/harness/repo.go @@ -65,7 +65,20 @@ func (s *repositoryService) ListStatus(ctx context.Context, repo string, ref str } func (s *repositoryService) CreateHook(ctx context.Context, repo string, input *scm.HookInput) (*scm.Hook, *scm.Response, error) { - return nil, nil, scm.ErrNotSupported + harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + path := fmt.Sprintf("api/v1/repos/%s/webhooks", harnessURI) + in := new(hook) + in.Enabled = true + in.DisplayName = input.Name + in.Secret = input.Secret + in.Insecure = input.SkipVerify + in.URL = input.Target + in.Triggers = append( + input.NativeEvents, + ) + out := new(hook) + res, err := s.client.do(ctx, "POST", path, in, out) + return convertHook(out), res, err } func (s *repositoryService) CreateStatus(ctx context.Context, repo string, ref string, input *scm.StatusInput) (*scm.Status, *scm.Response, error) { @@ -77,7 +90,9 @@ func (s *repositoryService) UpdateHook(ctx context.Context, repo, id string, inp } func (s *repositoryService) DeleteHook(ctx context.Context, repo string, id string) (*scm.Response, error) { - return nil, scm.ErrNotSupported + harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + path := fmt.Sprintf("api/v1/repos/%s/webhooks/%s", harnessURI, id) + return s.client.do(ctx, "DELETE", path, nil, nil) } // @@ -112,6 +127,7 @@ type ( DisplayName string `json:"display_name"` Enabled bool `json:"enabled"` HasSecret bool `json:"has_secret"` + Secret string `json:"secret"` ID int `json:"id"` Insecure bool `json:"insecure"` LatestExecutionResult string `json:"latest_execution_result"` diff --git a/scm/driver/harness/repo_test.go b/scm/driver/harness/repo_test.go index 082dbb4f1..8cd9a3a22 100644 --- a/scm/driver/harness/repo_test.go +++ b/scm/driver/harness/repo_test.go @@ -7,6 +7,7 @@ package harness import ( "context" "encoding/json" + "fmt" "io/ioutil" "net/http" "testing" @@ -14,6 +15,7 @@ import ( "github.com/drone/go-scm/scm" "github.com/drone/go-scm/scm/transport" "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" "github.com/h2non/gock" ) @@ -161,3 +163,65 @@ func TestRepositoryFindHook(t *testing.T) { t.Log(diff) } } + +func TestRepositoryHookCreateDelete(t *testing.T) { + if harnessPAT == "" { + defer gock.Off() + + gock.New(gockOrigin). + Post("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/webhooks"). + Reply(200). + Type("application/json"). + File("testdata/hook_create.json") + } + client, _ := New(gockOrigin, harnessOrg, harnessAccount, harnessProject) + client.Client = &http.Client{ + Transport: &transport.Custom{ + Before: func(r *http.Request) { + r.Header.Set("x-api-key", harnessPAT) + }, + }, + } + in := &scm.HookInput{ + Name: "drone", + Target: "https://example.com", + Secret: "topsecret", + SkipVerify: true, + } + got, _, err := client.Repositories.CreateHook(context.Background(), harnessRepo, in) + if err != nil { + t.Error(err) + return + } + + want := new(scm.Hook) + raw, _ := ioutil.ReadFile("testdata/hook_create.json.golden") + _ = json.Unmarshal(raw, want) + + if diff := cmp.Diff(got, want, cmpopts.IgnoreFields(scm.Hook{}, "ID")); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } + // delete webhook + if harnessPAT == "" { + defer gock.Off() + + gock.New(gockOrigin). + Delete(fmt.Sprintf("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/webhooks/%s", got.ID)). + Reply(204) + } + client, _ = New(gockOrigin, harnessOrg, harnessAccount, harnessProject) + client.Client = &http.Client{ + Transport: &transport.Custom{ + Before: func(r *http.Request) { + r.Header.Set("x-api-key", harnessPAT) + }, + }, + } + + _, deleteErr := client.Repositories.DeleteHook(context.Background(), harnessRepo, got.ID) + if deleteErr != nil { + t.Error(deleteErr) + return + } +} diff --git a/scm/driver/harness/testdata/hook_create.json b/scm/driver/harness/testdata/hook_create.json new file mode 100644 index 000000000..131b6d7cb --- /dev/null +++ b/scm/driver/harness/testdata/hook_create.json @@ -0,0 +1,17 @@ +{ + "id": 9, + "version": 1, + "parent_id": 11, + "parent_type": "repo", + "created_by": 14, + "created": 1675872629243, + "updated": 1675872777592, + "display_name": "drone", + "description": "", + "url": "https://example.com", + "enabled": true, + "insecure": true, + "triggers": [], + "latest_execution_result": "success", + "has_secret": true +} \ No newline at end of file diff --git a/scm/driver/harness/testdata/hook_create.json.golden b/scm/driver/harness/testdata/hook_create.json.golden new file mode 100644 index 000000000..06e9a45dc --- /dev/null +++ b/scm/driver/harness/testdata/hook_create.json.golden @@ -0,0 +1,8 @@ +{ + "ID": "9", + "Name": "drone", + "Target": "https://example.com", + "Events": [], + "Active": true, + "SkipVerify": true +} \ No newline at end of file From df6c516a40d3f1b1902049487d9caadaadd6f2ee Mon Sep 17 00:00:00 2001 From: Dev Mittal Date: Tue, 7 Feb 2023 15:00:05 +0530 Subject: [PATCH 054/195] fetch branch for bitbucket onprem --- scm/driver/stash/repo.go | 14 ++++++++- scm/driver/stash/repo_test.go | 30 +++++++++++++++++++ scm/driver/stash/testdata/content_list.json | 3 +- .../stash/testdata/content_list.json.golden | 4 +++ scm/driver/stash/testdata/default_branch.json | 8 +++++ scm/driver/stash/testdata/repo.json.golden | 2 +- 6 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 scm/driver/stash/testdata/default_branch.json diff --git a/scm/driver/stash/repo.go b/scm/driver/stash/repo.go index 70f4c01de..070bfd373 100644 --- a/scm/driver/stash/repo.go +++ b/scm/driver/stash/repo.go @@ -103,7 +103,19 @@ func (s *repositoryService) Find(ctx context.Context, repo string) (*scm.Reposit path := fmt.Sprintf("rest/api/1.0/projects/%s/repos/%s", namespace, name) out := new(repository) res, err := s.client.do(ctx, "GET", path, nil, out) - return convertRepository(out), res, err + outputRepo := convertRepository(out) + + branch := new(branch) + pathBranch := fmt.Sprintf("rest/api/1.0/projects/%s/repos/%s/branches/default", namespace, name) + _, errBranch := s.client.do(ctx, "GET", pathBranch, nil, branch) + if errBranch == nil { + outputRepo.Branch = branch.DisplayID + } + if err == nil { + err = errBranch + } + + return outputRepo, res, err } // FindHook returns a repository hook. diff --git a/scm/driver/stash/repo_test.go b/scm/driver/stash/repo_test.go index 83924a8ba..ee337dc24 100644 --- a/scm/driver/stash/repo_test.go +++ b/scm/driver/stash/repo_test.go @@ -25,6 +25,12 @@ func TestRepositoryFind(t *testing.T) { Type("application/json"). File("testdata/repo.json") + gock.New("http://example.com:7990"). + Get("/rest/api/1.0/projects/PRJ/repos/my-repo/branches/default"). + Reply(200). + Type("application/json"). + File("testdata/default_branch.json") + client, _ := New("http://example.com:7990") got, _, err := client.Repositories.Find(context.Background(), "PRJ/my-repo") if err != nil { @@ -76,6 +82,12 @@ func TestRepositoryPerms(t *testing.T) { Type("application/json"). File("testdata/webhooks.json") + gock.New("http://example.com:7990"). + Get("/rest/api/1.0/projects/PRJ/repos/my-repo/branches/default"). + Reply(200). + Type("application/json"). + File("testdata/default_branch.json") + client, _ := New("http://example.com:7990") got, _, err := client.Repositories.FindPerms(context.Background(), "PRJ/my-repo") if err != nil { @@ -117,6 +129,12 @@ func TestRepositoryPerms_ReadOnly(t *testing.T) { Type("application/json"). File("testdata/repo.json") + gock.New("http://example.com:7990"). + Get("/rest/api/1.0/projects/PRJ/repos/my-repo/branches/default"). + Reply(200). + Type("application/json"). + File("testdata/default_branch.json") + client, _ := New("http://example.com:7990") got, _, err := client.Repositories.FindPerms(context.Background(), "PRJ/my-repo") if err != nil { @@ -162,6 +180,12 @@ func TestRepositoryPerms_Write(t *testing.T) { Type("application/json"). File("testdata/repos.json") + gock.New("http://example.com:7990"). + Get("/rest/api/1.0/projects/PRJ/repos/my-repo/branches/default"). + Reply(200). + Type("application/json"). + File("testdata/default_branch.json") + client, _ := New("http://example.com:7990") got, _, err := client.Repositories.FindPerms(context.Background(), "PRJ/my-repo") if err != nil { @@ -207,6 +231,12 @@ func TestRepositoryPermsDifferentProjectName_Write(t *testing.T) { Type("application/json"). File("testdata/repos.json") + gock.New("http://example.com:7990"). + Get("/rest/api/1.0/projects/PRJ/repos/quux/branches/default"). + Reply(200). + Type("application/json"). + File("testdata/default_branch.json") + client, _ := New("http://example.com:7990") got, _, err := client.Repositories.FindPerms(context.Background(), "PRJ/quux") if err != nil { diff --git a/scm/driver/stash/testdata/content_list.json b/scm/driver/stash/testdata/content_list.json index ec0447795..4d5f72873 100644 --- a/scm/driver/stash/testdata/content_list.json +++ b/scm/driver/stash/testdata/content_list.json @@ -27,7 +27,8 @@ "testdata/branches.json.golden", "testdata/changes.json", "testdata/changes.json.golden", - "testdata/commit.json" + "testdata/commit.json", + "testdata/default_branch.json" ], "start": 0, "nextPageStart": 25 diff --git a/scm/driver/stash/testdata/content_list.json.golden b/scm/driver/stash/testdata/content_list.json.golden index 72d6fcf30..f02920ac4 100644 --- a/scm/driver/stash/testdata/content_list.json.golden +++ b/scm/driver/stash/testdata/content_list.json.golden @@ -98,5 +98,9 @@ { "path": "testdata/commit.json", "kind": "file" + }, + { + "path": "testdata/default_branch.json", + "kind": "file" } ] diff --git a/scm/driver/stash/testdata/default_branch.json b/scm/driver/stash/testdata/default_branch.json new file mode 100644 index 000000000..ceeec302e --- /dev/null +++ b/scm/driver/stash/testdata/default_branch.json @@ -0,0 +1,8 @@ +{ + "id": "refs/heads/feature_branch", + "displayId": "feature_branch", + "type": "BRANCH", + "latestCommit": "c567b3f4a2980299e2a1148360f23ffb0f4c9764", + "latestChangeset": "c567b3f4a2980299e2a1148360f23ffb0f4c9764", + "isDefault": true +} \ No newline at end of file diff --git a/scm/driver/stash/testdata/repo.json.golden b/scm/driver/stash/testdata/repo.json.golden index e7257362f..66414388a 100644 --- a/scm/driver/stash/testdata/repo.json.golden +++ b/scm/driver/stash/testdata/repo.json.golden @@ -3,7 +3,7 @@ "Namespace": "PRJ", "Name": "my-repo", "Perm": null, - "Branch": "master", + "Branch": "feature_branch", "Private": true, "Clone": "http://example.com:7990/scm/prj/my-repo.git", "CloneSSH": "ssh://git@example.com:7999/prj/my-repo.git", From 85d76f0df54862b7eddee0513dc57c160136a0e8 Mon Sep 17 00:00:00 2001 From: TP Honey Date: Wed, 8 Feb 2023 17:22:31 +0000 Subject: [PATCH 055/195] (feat) harness, add list commits / branches --- scm/driver/harness/git.go | 153 +++++++--------- scm/driver/harness/git_test.go | 170 ++++++++++++++++++ scm/driver/harness/repo_test.go | 5 +- scm/driver/harness/testdata/branch.json | 23 +++ .../harness/testdata/branch.json.golden | 5 + scm/driver/harness/testdata/branches.json | 25 +++ .../harness/testdata/branches.json.golden | 7 + scm/driver/harness/testdata/commit.json | 19 ++ .../harness/testdata/commit.json.golden | 19 ++ scm/driver/harness/testdata/commits.json | 21 +++ .../harness/testdata/commits.json.golden | 21 +++ 11 files changed, 379 insertions(+), 89 deletions(-) create mode 100644 scm/driver/harness/testdata/branch.json create mode 100644 scm/driver/harness/testdata/branch.json.golden create mode 100644 scm/driver/harness/testdata/branches.json create mode 100644 scm/driver/harness/testdata/branches.json.golden create mode 100644 scm/driver/harness/testdata/commit.json create mode 100644 scm/driver/harness/testdata/commit.json.golden create mode 100644 scm/driver/harness/testdata/commits.json create mode 100644 scm/driver/harness/testdata/commits.json.golden diff --git a/scm/driver/harness/git.go b/scm/driver/harness/git.go index 47b228021..3cbee37ee 100644 --- a/scm/driver/harness/git.go +++ b/scm/driver/harness/git.go @@ -7,7 +7,6 @@ package harness import ( "context" "fmt" - "net/url" "time" "github.com/drone/go-scm/scm" @@ -18,19 +17,23 @@ type gitService struct { } func (s *gitService) CreateBranch(ctx context.Context, repo string, params *scm.ReferenceInput) (*scm.Response, error) { - return nil, scm.ErrNotSupported + harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + path := fmt.Sprintf("api/v1/repos/%s/branches", harnessURI) + out := new(branch) + return s.client.do(ctx, "GET", path, nil, out) } func (s *gitService) FindBranch(ctx context.Context, repo, name string) (*scm.Reference, *scm.Response, error) { - path := fmt.Sprintf("api/v1/repos/%s/branches/%s", repo, name) + harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + path := fmt.Sprintf("api/v1/repos/%s/branches/%s", harnessURI, name) out := new(branch) res, err := s.client.do(ctx, "GET", path, nil, out) return convertBranch(out), res, err } func (s *gitService) FindCommit(ctx context.Context, repo, ref string) (*scm.Commit, *scm.Response, error) { - ref = scm.TrimRef(ref) - path := fmt.Sprintf("api/v1/repos/%s/git/commits/%s", repo, url.PathEscape(ref)) + harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + path := fmt.Sprintf("api/v1/repos/%s/commits/%s", harnessURI, ref) out := new(commitInfo) res, err := s.client.do(ctx, "GET", path, nil, out) return convertCommitInfo(out), res, err @@ -41,14 +44,16 @@ func (s *gitService) FindTag(ctx context.Context, repo, name string) (*scm.Refer } func (s *gitService) ListBranches(ctx context.Context, repo string, opts scm.ListOptions) ([]*scm.Reference, *scm.Response, error) { - path := fmt.Sprintf("api/v1/repos/%s/branches?%s", repo, encodeListOptions(opts)) + harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + path := fmt.Sprintf("api/v1/repos/%s/branches?%s", harnessURI, encodeListOptions(opts)) out := []*branch{} res, err := s.client.do(ctx, "GET", path, nil, &out) return convertBranchList(out), res, err } func (s *gitService) ListCommits(ctx context.Context, repo string, _ scm.CommitListOptions) ([]*scm.Commit, *scm.Response, error) { - path := fmt.Sprintf("api/v1/repos/%s/commits", repo) + harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + path := fmt.Sprintf("api/v1/repos/%s/commits", harnessURI) out := []*commitInfo{} res, err := s.client.do(ctx, "GET", path, nil, &out) return convertCommitList(out), res, err @@ -66,52 +71,50 @@ func (s *gitService) CompareChanges(ctx context.Context, repo, source, target st return nil, nil, scm.ErrNotSupported } -// // native data structures -// - type ( - // gitea branch object. - branch struct { - Name string `json:"name"` - Commit commit `json:"commit"` - } - - // gitea commit object. - commit struct { - ID string `json:"id"` - Sha string `json:"sha"` - Message string `json:"message"` - URL string `json:"url"` - Author signature `json:"author"` - Committer signature `json:"committer"` - Timestamp time.Time `json:"timestamp"` - } - - // gitea commit info object. commitInfo struct { - Sha string `json:"sha"` - Commit commit `json:"commit"` - Author user `json:"author"` - Committer user `json:"committer"` - } - - // gitea signature object. - signature struct { - Name string `json:"name"` - Email string `json:"email"` - Username string `json:"username"` + Author struct { + Identity struct { + Email string `json:"email"` + Name string `json:"name"` + } `json:"identity"` + When time.Time `json:"when"` + } `json:"author"` + Committer struct { + Identity struct { + Email string `json:"email"` + Name string `json:"name"` + } `json:"identity"` + When time.Time `json:"when"` + } `json:"committer"` + Message string `json:"message"` + Sha string `json:"sha"` + Title string `json:"title"` } - // gitea tag object - tag struct { - Ref string `json:"ref"` - URL string `json:"url"` - Object struct { - Type string `json:"type"` - Sha string `json:"sha"` - URL string `json:"url"` - } `json:"object"` + branch struct { + Commit struct { + Author struct { + Identity struct { + Email string `json:"email"` + Name string `json:"name"` + } `json:"identity"` + When time.Time `json:"when"` + } `json:"author"` + Committer struct { + Identity struct { + Email string `json:"email"` + Name string `json:"name"` + } `json:"identity"` + When time.Time `json:"when"` + } `json:"committer"` + Message string `json:"message"` + Sha string `json:"sha"` + Title string `json:"title"` + } `json:"commit"` + Name string `json:"name"` + Sha string `json:"sha"` } ) @@ -129,9 +132,9 @@ func convertBranchList(src []*branch) []*scm.Reference { func convertBranch(src *branch) *scm.Reference { return &scm.Reference{ - Name: scm.TrimRef(src.Name), + Name: src.Name, Path: scm.ExpandRef(src.Name, "refs/heads/"), - Sha: src.Commit.ID, + Sha: src.Sha, } } @@ -145,43 +148,17 @@ func convertCommitList(src []*commitInfo) []*scm.Commit { func convertCommitInfo(src *commitInfo) *scm.Commit { return &scm.Commit{ - Sha: src.Sha, - Link: src.Commit.URL, - Message: src.Commit.Message, - Author: convertUserSignature(src.Author), - Committer: convertUserSignature(src.Committer), - } -} - -func convertSignature(src signature) scm.Signature { - return scm.Signature{ - Login: src.Username, - Email: src.Email, - Name: src.Name, - } -} - -func convertUserSignature(src user) scm.Signature { - return scm.Signature{ - Login: userLogin(&src), - Email: src.Email, - Name: src.Fullname, - Avatar: src.Avatar, - } -} - -func convertTagList(src []*tag) []*scm.Reference { - var dst []*scm.Reference - for _, v := range src { - dst = append(dst, convertTag(v)) - } - return dst -} - -func convertTag(src *tag) *scm.Reference { - return &scm.Reference{ - Name: scm.TrimRef(src.Ref), - Path: src.Ref, - Sha: src.Object.Sha, + Sha: src.Sha, + Message: src.Message, + Author: scm.Signature{ + Name: src.Author.Identity.Name, + Email: src.Author.Identity.Email, + Date: src.Author.When, + }, + Committer: scm.Signature{ + Name: src.Committer.Identity.Name, + Email: src.Committer.Identity.Email, + Date: src.Committer.When, + }, } } diff --git a/scm/driver/harness/git_test.go b/scm/driver/harness/git_test.go index 5d232e2ff..133905253 100644 --- a/scm/driver/harness/git_test.go +++ b/scm/driver/harness/git_test.go @@ -3,3 +3,173 @@ // license that can be found in the LICENSE file. package harness + +import ( + "context" + "encoding/json" + "io/ioutil" + "net/http" + "testing" + + "github.com/drone/go-scm/scm" + "github.com/drone/go-scm/scm/transport" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/h2non/gock" +) + +func TestListCommits(t *testing.T) { + if harnessPAT == "" { + defer gock.Off() + + gock.New(gockOrigin). + Get("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/commits"). + Reply(200). + Type("application/json"). + File("testdata/commits.json") + } + client, _ := New(gockOrigin, harnessOrg, harnessAccount, harnessProject) + client.Client = &http.Client{ + Transport: &transport.Custom{ + Before: func(r *http.Request) { + r.Header.Set("x-api-key", harnessPAT) + }, + }, + } + got, _, err := client.Git.ListCommits(context.Background(), harnessRepo, scm.CommitListOptions{}) + if err != nil { + t.Error(err) + return + } + + want := []*scm.Commit{} + raw, _ := ioutil.ReadFile("testdata/commits.json.golden") + wantErr := json.Unmarshal(raw, &want) + if wantErr != nil { + t.Error(wantErr) + return + } + if harnessPAT != "" && len(got) > 0 { + // if testing against a real system and we get commits + return + } + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } +} + +func TestFindCommit(t *testing.T) { + if harnessPAT == "" { + defer gock.Off() + + gock.New(gockOrigin). + Get("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/commits/1d640265d8bdd818175fa736f0fcbad2c9b716c9"). + Reply(200). + Type("application/json"). + File("testdata/commit.json") + } + client, _ := New(gockOrigin, harnessOrg, harnessAccount, harnessProject) + client.Client = &http.Client{ + Transport: &transport.Custom{ + Before: func(r *http.Request) { + r.Header.Set("x-api-key", harnessPAT) + }, + }, + } + got, _, err := client.Git.FindCommit(context.Background(), harnessRepo, "1d640265d8bdd818175fa736f0fcbad2c9b716c9") + if err != nil { + t.Error(err) + return + } + + want := new(scm.Commit) + raw, _ := ioutil.ReadFile("testdata/commit.json.golden") + wantErr := json.Unmarshal(raw, &want) + if wantErr != nil { + t.Error(wantErr) + return + } + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } +} + +func TestFindBranch(t *testing.T) { + if harnessPAT == "" { + defer gock.Off() + + gock.New(gockOrigin). + Get("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/branches/main"). + Reply(200). + Type("application/json"). + File("testdata/branch.json") + } + client, _ := New(gockOrigin, harnessOrg, harnessAccount, harnessProject) + client.Client = &http.Client{ + Transport: &transport.Custom{ + Before: func(r *http.Request) { + r.Header.Set("x-api-key", harnessPAT) + }, + }, + } + got, _, err := client.Git.FindBranch(context.Background(), harnessRepo, "main") + if err != nil { + t.Error(err) + return + } + + want := new(scm.Reference) + raw, _ := ioutil.ReadFile("testdata/branch.json.golden") + wantErr := json.Unmarshal(raw, &want) + if wantErr != nil { + t.Error(wantErr) + return + } + + if diff := cmp.Diff(got, want, cmpopts.IgnoreFields(scm.Reference{}, "Sha")); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } +} + +func TestListBranches(t *testing.T) { + if harnessPAT == "" { + defer gock.Off() + + gock.New(gockOrigin). + Get("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/branches"). + Reply(200). + Type("application/json"). + File("testdata/branches.json") + } + client, _ := New(gockOrigin, harnessOrg, harnessAccount, harnessProject) + client.Client = &http.Client{ + Transport: &transport.Custom{ + Before: func(r *http.Request) { + r.Header.Set("x-api-key", harnessPAT) + }, + }, + } + got, _, err := client.Git.ListBranches(context.Background(), harnessRepo, scm.ListOptions{}) + if err != nil { + t.Error(err) + return + } + + want := []*scm.Reference{} + raw, _ := ioutil.ReadFile("testdata/branches.json.golden") + wantErr := json.Unmarshal(raw, &want) + if wantErr != nil { + t.Error(wantErr) + return + } + + if diff := cmp.Diff(got, want, cmpopts.IgnoreFields(scm.Reference{}, "Sha")); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } +} diff --git a/scm/driver/harness/repo_test.go b/scm/driver/harness/repo_test.go index 8cd9a3a22..d482d4bcb 100644 --- a/scm/driver/harness/repo_test.go +++ b/scm/driver/harness/repo_test.go @@ -51,7 +51,6 @@ func TestRepositoryFind(t *testing.T) { t.Errorf("Unexpected Results") t.Log(diff) } - } func TestRepositoryList(t *testing.T) { @@ -86,6 +85,10 @@ func TestRepositoryList(t *testing.T) { raw, _ := ioutil.ReadFile("testdata/repos.json.golden") _ = json.Unmarshal(raw, &want) + if harnessPAT != "" && len(got) > 0 { + // pass when running against a live harness instance and we get more than one repo + return + } if diff := cmp.Diff(got, want); diff != "" { t.Errorf("Unexpected Results") t.Log(diff) diff --git a/scm/driver/harness/testdata/branch.json b/scm/driver/harness/testdata/branch.json new file mode 100644 index 000000000..79159c0fc --- /dev/null +++ b/scm/driver/harness/testdata/branch.json @@ -0,0 +1,23 @@ +{ + "name": "main", + "sha": "1d640265d8bdd818175fa736f0fcbad2c9b716c9", + "commit": { + "sha": "1d640265d8bdd818175fa736f0fcbad2c9b716c9", + "title": "delete README.2", + "message": "delete README.2\n\ndelete README.2", + "author": { + "identity": { + "name": "thomas.honey", + "email": "thomas.honey@harness.io" + }, + "when": "2023-02-08T16:17:50Z" + }, + "committer": { + "identity": { + "name": "Harness", + "email": "noreply@harness.io" + }, + "when": "2023-02-08T16:17:50Z" + } + } +} \ No newline at end of file diff --git a/scm/driver/harness/testdata/branch.json.golden b/scm/driver/harness/testdata/branch.json.golden new file mode 100644 index 000000000..0b5426713 --- /dev/null +++ b/scm/driver/harness/testdata/branch.json.golden @@ -0,0 +1,5 @@ +{ + "Name": "main", + "Path": "refs/heads/main", + "Sha": "1d640265d8bdd818175fa736f0fcbad2c9b716c9" +} \ No newline at end of file diff --git a/scm/driver/harness/testdata/branches.json b/scm/driver/harness/testdata/branches.json new file mode 100644 index 000000000..7f87681a1 --- /dev/null +++ b/scm/driver/harness/testdata/branches.json @@ -0,0 +1,25 @@ +[ + { + "name": "main", + "sha": "1d640265d8bdd818175fa736f0fcbad2c9b716c9", + "commit": { + "sha": "1d640265d8bdd818175fa736f0fcbad2c9b716c9", + "title": "delete README.2", + "message": "delete README.2\n\ndelete README.2", + "author": { + "identity": { + "name": "thomas.honey", + "email": "thomas.honey@harness.io" + }, + "when": "2023-02-08T16:17:50Z" + }, + "committer": { + "identity": { + "name": "Harness", + "email": "noreply@harness.io" + }, + "when": "2023-02-08T16:17:50Z" + } + } + } +] \ No newline at end of file diff --git a/scm/driver/harness/testdata/branches.json.golden b/scm/driver/harness/testdata/branches.json.golden new file mode 100644 index 000000000..8946da89e --- /dev/null +++ b/scm/driver/harness/testdata/branches.json.golden @@ -0,0 +1,7 @@ +[ + { + "Name": "main", + "Path": "refs/heads/main", + "Sha": "1d640265d8bdd818175fa736f0fcbad2c9b716c9" + } +] \ No newline at end of file diff --git a/scm/driver/harness/testdata/commit.json b/scm/driver/harness/testdata/commit.json new file mode 100644 index 000000000..38a6066ad --- /dev/null +++ b/scm/driver/harness/testdata/commit.json @@ -0,0 +1,19 @@ +{ + "sha": "1d640265d8bdd818175fa736f0fcbad2c9b716c9", + "title": "delete README.2", + "message": "delete README.2\n\ndelete README.2", + "author": { + "identity": { + "name": "thomas.honey", + "email": "thomas.honey@harness.io" + }, + "when": "2023-02-08T16:17:50Z" + }, + "committer": { + "identity": { + "name": "Harness", + "email": "noreply@harness.io" + }, + "when": "2023-02-08T16:17:50Z" + } +} \ No newline at end of file diff --git a/scm/driver/harness/testdata/commit.json.golden b/scm/driver/harness/testdata/commit.json.golden new file mode 100644 index 000000000..01d7f0f40 --- /dev/null +++ b/scm/driver/harness/testdata/commit.json.golden @@ -0,0 +1,19 @@ +{ + "Sha": "1d640265d8bdd818175fa736f0fcbad2c9b716c9", + "Message": "delete README.2\n\ndelete README.2", + "Author": { + "Name": "thomas.honey", + "Email": "thomas.honey@harness.io", + "Date": "2023-02-08T16:17:50Z", + "Login": "", + "Avatar": "" + }, + "Committer": { + "Name": "Harness", + "Email": "noreply@harness.io", + "Date": "2023-02-08T16:17:50Z", + "Login": "", + "Avatar": "" + }, + "Link": "" +} \ No newline at end of file diff --git a/scm/driver/harness/testdata/commits.json b/scm/driver/harness/testdata/commits.json new file mode 100644 index 000000000..96576e18f --- /dev/null +++ b/scm/driver/harness/testdata/commits.json @@ -0,0 +1,21 @@ +[ + { + "sha": "1d640265d8bdd818175fa736f0fcbad2c9b716c9", + "title": "delete README.2", + "message": "delete README.2\n\ndelete README.2", + "author": { + "identity": { + "name": "thomas.honey", + "email": "thomas.honey@harness.io" + }, + "when": "2023-02-08T16:17:50Z" + }, + "committer": { + "identity": { + "name": "Harness", + "email": "noreply@harness.io" + }, + "when": "2023-02-08T16:17:50Z" + } + } +] \ No newline at end of file diff --git a/scm/driver/harness/testdata/commits.json.golden b/scm/driver/harness/testdata/commits.json.golden new file mode 100644 index 000000000..83570e704 --- /dev/null +++ b/scm/driver/harness/testdata/commits.json.golden @@ -0,0 +1,21 @@ +[ + { + "Sha": "1d640265d8bdd818175fa736f0fcbad2c9b716c9", + "Message": "delete README.2\n\ndelete README.2", + "Author": { + "Name": "thomas.honey", + "Email": "thomas.honey@harness.io", + "Date": "2023-02-08T16:17:50Z", + "Login": "", + "Avatar": "" + }, + "Committer": { + "Name": "Harness", + "Email": "noreply@harness.io", + "Date": "2023-02-08T16:17:50Z", + "Login": "", + "Avatar": "" + }, + "Link": "" + } +] \ No newline at end of file From 2fd14107827389c5ce21e0d03b7afd83a694e503 Mon Sep 17 00:00:00 2001 From: TP Honey Date: Thu, 9 Feb 2023 12:51:06 +0000 Subject: [PATCH 056/195] (feat) harness, add user and compare branches --- scm/driver/harness/git.go | 17 ++++++- scm/driver/harness/testdata/branches.json | 31 +++++++++-- .../harness/testdata/branches.json.golden | 5 ++ scm/driver/harness/testdata/user.json | 9 ++++ scm/driver/harness/testdata/user.json.golden | 7 +++ scm/driver/harness/user.go | 28 ++++------ scm/driver/harness/user_test.go | 51 +++++++++++++++++++ 7 files changed, 125 insertions(+), 23 deletions(-) create mode 100644 scm/driver/harness/testdata/user.json create mode 100644 scm/driver/harness/testdata/user.json.golden diff --git a/scm/driver/harness/git.go b/scm/driver/harness/git.go index 3cbee37ee..b66562797 100644 --- a/scm/driver/harness/git.go +++ b/scm/driver/harness/git.go @@ -7,6 +7,8 @@ package harness import ( "context" "fmt" + "io" + "strings" "time" "github.com/drone/go-scm/scm" @@ -68,7 +70,19 @@ func (s *gitService) ListChanges(ctx context.Context, repo, ref string, _ scm.Li } func (s *gitService) CompareChanges(ctx context.Context, repo, source, target string, _ scm.ListOptions) ([]*scm.Change, *scm.Response, error) { - return nil, nil, scm.ErrNotSupported + harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + path := fmt.Sprintf("api/v1/repos/%s/compare/%s...%s", harnessURI, source, target) + res, err := s.client.do(ctx, "GET", path, nil, nil) + // convert response to a string + buf := new(strings.Builder) + _, _ = io.Copy(buf, res.Body) + changes := []*scm.Change{ + { + Path: "not implemented", + Sha: buf.String(), + }, + } + return changes, res, err } // native data structures @@ -92,7 +106,6 @@ type ( Sha string `json:"sha"` Title string `json:"title"` } - branch struct { Commit struct { Author struct { diff --git a/scm/driver/harness/testdata/branches.json b/scm/driver/harness/testdata/branches.json index 7f87681a1..e35f84b4e 100644 --- a/scm/driver/harness/testdata/branches.json +++ b/scm/driver/harness/testdata/branches.json @@ -1,9 +1,32 @@ [ + { + "name": "bla", + "sha": "0c221fd126b9457d0ad2037641416083549f59c5", + "commit": { + "sha": "0c221fd126b9457d0ad2037641416083549f59c5", + "title": "Create bla_file", + "message": "Create bla_file", + "author": { + "identity": { + "name": "thomas.honey", + "email": "thomas.honey@harness.io" + }, + "when": "2023-02-09T11:20:14Z" + }, + "committer": { + "identity": { + "name": "Harness", + "email": "noreply@harness.io" + }, + "when": "2023-02-09T11:20:14Z" + } + } + }, { "name": "main", - "sha": "1d640265d8bdd818175fa736f0fcbad2c9b716c9", + "sha": "de2837f8911710cfb7bbb323d0de285fd2ef9155", "commit": { - "sha": "1d640265d8bdd818175fa736f0fcbad2c9b716c9", + "sha": "de2837f8911710cfb7bbb323d0de285fd2ef9155", "title": "delete README.2", "message": "delete README.2\n\ndelete README.2", "author": { @@ -11,14 +34,14 @@ "name": "thomas.honey", "email": "thomas.honey@harness.io" }, - "when": "2023-02-08T16:17:50Z" + "when": "2023-02-09T12:39:37Z" }, "committer": { "identity": { "name": "Harness", "email": "noreply@harness.io" }, - "when": "2023-02-08T16:17:50Z" + "when": "2023-02-09T12:39:37Z" } } } diff --git a/scm/driver/harness/testdata/branches.json.golden b/scm/driver/harness/testdata/branches.json.golden index 8946da89e..66ad737e5 100644 --- a/scm/driver/harness/testdata/branches.json.golden +++ b/scm/driver/harness/testdata/branches.json.golden @@ -1,4 +1,9 @@ [ + { + "Name": "bla", + "Path": "refs/heads/bla", + "Sha": "0c221fd126b9457d0ad2037641416083549f59c5" + }, { "Name": "main", "Path": "refs/heads/main", diff --git a/scm/driver/harness/testdata/user.json b/scm/driver/harness/testdata/user.json new file mode 100644 index 000000000..459c42c39 --- /dev/null +++ b/scm/driver/harness/testdata/user.json @@ -0,0 +1,9 @@ +{ + "admin": true, + "blocked": true, + "created": 0, + "display_name": "1", + "email": "2", + "uid": "3", + "updated": 0 +} \ No newline at end of file diff --git a/scm/driver/harness/testdata/user.json.golden b/scm/driver/harness/testdata/user.json.golden new file mode 100644 index 000000000..1c38875a7 --- /dev/null +++ b/scm/driver/harness/testdata/user.json.golden @@ -0,0 +1,7 @@ +{ + "ID": "3", + "Login": "2", + "Name": "1", + "Email": "2", + "Avatar": "" +} \ No newline at end of file diff --git a/scm/driver/harness/user.go b/scm/driver/harness/user.go index 18cba27b4..3bdd3514d 100644 --- a/scm/driver/harness/user.go +++ b/scm/driver/harness/user.go @@ -37,12 +37,13 @@ func (s *userService) ListEmail(context.Context, scm.ListOptions) ([]*scm.Email, // type user struct { - ID int `json:"id"` - Login string `json:"login"` - Username string `json:"username"` - Fullname string `json:"full_name"` - Email string `json:"email"` - Avatar string `json:"avatar_url"` + Admin bool `json:"admin"` + Blocked bool `json:"blocked"` + Created int `json:"created"` + DisplayName string `json:"display_name"` + Email string `json:"email"` + UID string `json:"uid"` + Updated int `json:"updated"` } // @@ -51,16 +52,9 @@ type user struct { func convertUser(src *user) *scm.User { return &scm.User{ - Login: userLogin(src), - Avatar: src.Avatar, - Email: src.Email, - Name: src.Fullname, + Login: src.Email, + Email: src.Email, + Name: src.DisplayName, + ID: src.UID, } } - -func userLogin(src *user) string { - if src.Username != "" { - return src.Username - } - return src.Login -} diff --git a/scm/driver/harness/user_test.go b/scm/driver/harness/user_test.go index 5d232e2ff..755294de3 100644 --- a/scm/driver/harness/user_test.go +++ b/scm/driver/harness/user_test.go @@ -3,3 +3,54 @@ // license that can be found in the LICENSE file. package harness + +import ( + "context" + "encoding/json" + "io/ioutil" + "net/http" + "testing" + + "github.com/drone/go-scm/scm" + "github.com/drone/go-scm/scm/transport" + "github.com/google/go-cmp/cmp" + "github.com/h2non/gock" +) + +func TestUsersFind(t *testing.T) { + + defer gock.Off() + + gock.New(gockOrigin). + Get("/gateway/code/api/v1/user"). + Reply(200). + Type("application/json"). + File("testdata/user.json") + + client, _ := New(gockOrigin, harnessOrg, harnessAccount, harnessProject) + client.Client = &http.Client{ + Transport: &transport.Custom{ + Before: func(r *http.Request) { + r.Header.Set("x-api-key", harnessPAT) + }, + }, + } + got, _, err := client.Users.Find(context.Background()) + if err != nil { + t.Error(err) + return + } + + want := new(scm.User) + raw, _ := ioutil.ReadFile("testdata/user.json.golden") + wantErr := json.Unmarshal(raw, &want) + if wantErr != nil { + t.Error(wantErr) + return + } + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } +} From f8d9958ec380bb15a84c4a10a3aef02ef94e98e5 Mon Sep 17 00:00:00 2001 From: TP Honey Date: Thu, 9 Feb 2023 16:14:19 +0000 Subject: [PATCH 057/195] (feat) harness, fix create branch, PR calls --- scm/driver/harness/git.go | 11 +- scm/driver/harness/git_test.go | 34 +++++ scm/driver/harness/issue.go | 92 ------------- scm/driver/harness/pr.go | 152 ++++++++++----------- scm/driver/harness/pr_test.go | 49 +++++++ scm/driver/harness/release.go | 2 +- scm/driver/harness/testdata/pr.json | 32 +++++ scm/driver/harness/testdata/pr.json.golden | 20 +++ 8 files changed, 218 insertions(+), 174 deletions(-) create mode 100644 scm/driver/harness/testdata/pr.json create mode 100644 scm/driver/harness/testdata/pr.json.golden diff --git a/scm/driver/harness/git.go b/scm/driver/harness/git.go index b66562797..9186112e6 100644 --- a/scm/driver/harness/git.go +++ b/scm/driver/harness/git.go @@ -21,8 +21,11 @@ type gitService struct { func (s *gitService) CreateBranch(ctx context.Context, repo string, params *scm.ReferenceInput) (*scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) path := fmt.Sprintf("api/v1/repos/%s/branches", harnessURI) - out := new(branch) - return s.client.do(ctx, "GET", path, nil, out) + in := &branchInput{ + Name: params.Name, + Target: params.Sha, + } + return s.client.do(ctx, "POST", path, in, nil) } func (s *gitService) FindBranch(ctx context.Context, repo, name string) (*scm.Reference, *scm.Response, error) { @@ -106,6 +109,10 @@ type ( Sha string `json:"sha"` Title string `json:"title"` } + branchInput struct { + Name string `json:"name"` + Target string `json:"target"` + } branch struct { Commit struct { Author struct { diff --git a/scm/driver/harness/git_test.go b/scm/driver/harness/git_test.go index 133905253..016d65e49 100644 --- a/scm/driver/harness/git_test.go +++ b/scm/driver/harness/git_test.go @@ -173,3 +173,37 @@ func TestListBranches(t *testing.T) { t.Log(diff) } } + +func TestCreateBranch(t *testing.T) { + + defer gock.Off() + + gock.New(gockOrigin). + Post("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/branches"). + Reply(200). + Type("application/json"). + File("testdata/branch.json") + + client, _ := New(gockOrigin, harnessOrg, harnessAccount, harnessProject) + client.Client = &http.Client{ + Transport: &transport.Custom{ + Before: func(r *http.Request) { + r.Header.Set("x-api-key", harnessPAT) + }, + }, + } + input := &scm.ReferenceInput{ + Name: "test", + Sha: "e8ef0374ca0cee8048e94b28eaf0d9e2e2515a14", + } + result, err := client.Git.CreateBranch(context.Background(), harnessRepo, input) + if err != nil { + t.Error(err) + return + } + + if result.Status != 200 { + t.Errorf("Unexpected Results") + } + +} diff --git a/scm/driver/harness/issue.go b/scm/driver/harness/issue.go index 6eab881c5..99d904791 100644 --- a/scm/driver/harness/issue.go +++ b/scm/driver/harness/issue.go @@ -6,7 +6,6 @@ package harness import ( "context" - "time" "github.com/drone/go-scm/scm" ) @@ -25,17 +24,14 @@ func (s *issueService) FindComment(ctx context.Context, repo string, index, id i func (s *issueService) List(ctx context.Context, repo string, opts scm.IssueListOptions) ([]*scm.Issue, *scm.Response, error) { return nil, nil, scm.ErrNotSupported - } func (s *issueService) ListComments(ctx context.Context, repo string, index int, opts scm.ListOptions) ([]*scm.Comment, *scm.Response, error) { return nil, nil, scm.ErrNotSupported - } func (s *issueService) Create(ctx context.Context, repo string, input *scm.IssueInput) (*scm.Issue, *scm.Response, error) { return nil, nil, scm.ErrNotSupported - } func (s *issueService) CreateComment(ctx context.Context, repo string, index int, input *scm.CommentInput) (*scm.Comment, *scm.Response, error) { @@ -57,91 +53,3 @@ func (s *issueService) Lock(ctx context.Context, repo string, number int) (*scm. func (s *issueService) Unlock(ctx context.Context, repo string, number int) (*scm.Response, error) { return nil, scm.ErrNotSupported } - -// -// native data structures -// - -type ( - // gitea issue response object. - issue struct { - ID int `json:"id"` - Number int `json:"number"` - User user `json:"user"` - Title string `json:"title"` - Body string `json:"body"` - State string `json:"state"` - Labels []string `json:"labels"` - Comments int `json:"comments"` - Created time.Time `json:"created_at"` - Updated time.Time `json:"updated_at"` - PullRequest *struct { - Merged bool `json:"merged"` - MergedAt interface{} `json:"merged_at"` - } `json:"pull_request"` - } - - // gitea issue request object. - issueInput struct { - Title string `json:"title"` - Body string `json:"body"` - } - - // gitea issue comment response object. - issueComment struct { - ID int `json:"id"` - HTMLURL string `json:"html_url"` - User user `json:"user"` - Body string `json:"body"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - } - - // gitea issue comment request object. - issueCommentInput struct { - Body string `json:"body"` - } -) - -// -// native data structure conversion -// - -func convertIssueList(from []*issue) []*scm.Issue { - to := []*scm.Issue{} - for _, v := range from { - to = append(to, convertIssue(v)) - } - return to -} - -func convertIssue(from *issue) *scm.Issue { - return &scm.Issue{ - Number: from.Number, - Title: from.Title, - Body: from.Body, - Link: "", // TODO construct the link to the issue. - Closed: from.State == "closed", - Author: *convertUser(&from.User), - Created: from.Created, - Updated: from.Updated, - } -} - -func convertIssueCommentList(from []*issueComment) []*scm.Comment { - to := []*scm.Comment{} - for _, v := range from { - to = append(to, convertIssueComment(v)) - } - return to -} - -func convertIssueComment(from *issueComment) *scm.Comment { - return &scm.Comment{ - ID: from.ID, - Body: from.Body, - Author: *convertUser(&from.User), - Created: from.CreatedAt, - Updated: from.UpdatedAt, - } -} diff --git a/scm/driver/harness/pr.go b/scm/driver/harness/pr.go index 631d994b7..61f802972 100644 --- a/scm/driver/harness/pr.go +++ b/scm/driver/harness/pr.go @@ -7,7 +7,6 @@ package harness import ( "context" "fmt" - "time" "github.com/drone/go-scm/scm" ) @@ -17,7 +16,11 @@ type pullService struct { } func (s *pullService) Find(ctx context.Context, repo string, index int) (*scm.PullRequest, *scm.Response, error) { - return nil, nil, scm.ErrNotSupported + harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + path := fmt.Sprintf("api/v1/repos/%s/pullreq/%d", harnessURI, index) + out := new(pr) + res, err := s.client.do(ctx, "GET", path, nil, out) + return convertPullRequest(out), res, err } @@ -61,52 +64,64 @@ func (s *pullService) Close(context.Context, string, int) (*scm.Response, error) return nil, scm.ErrNotSupported } -// // native data structures -// - -type pr struct { - ID int `json:"id"` - Number int `json:"number"` - User user `json:"user"` - Title string `json:"title"` - Body string `json:"body"` - State string `json:"state"` - HeadBranch string `json:"head_branch"` - HeadRepo repository `json:"head_repo"` - Head reference `json:"head"` - BaseBranch string `json:"base_branch"` - BaseRepo repository `json:"base_repo"` - Base reference `json:"base"` - HTMLURL string `json:"html_url"` - DiffURL string `json:"diff_url"` - Mergeable bool `json:"mergeable"` - Merged bool `json:"merged"` - Created time.Time `json:"created_at"` - Updated time.Time `json:"updated_at"` - Labels []struct { - Name string `json:"name"` - Color string `json:"color"` - } `json:"labels"` -} +type ( + pr struct { + Author struct { + Created int `json:"created"` + DisplayName string `json:"display_name"` + Email string `json:"email"` + ID int `json:"id"` + Type string `json:"type"` + UID string `json:"uid"` + Updated int `json:"updated"` + } `json:"author"` + Created int `json:"created"` + Description string `json:"description"` + Edited int `json:"edited"` + IsDraft bool `json:"is_draft"` + MergeBaseSha string `json:"merge_base_sha"` + MergeHeadSha string `json:"merge_head_sha"` + MergeStrategy string `json:"merge_strategy"` + Merged int `json:"merged"` + Merger struct { + Created int `json:"created"` + DisplayName string `json:"display_name"` + Email string `json:"email"` + ID int `json:"id"` + Type string `json:"type"` + UID string `json:"uid"` + Updated int `json:"updated"` + } `json:"merger"` + Number int `json:"number"` + SourceBranch string `json:"source_branch"` + SourceRepoID int `json:"source_repo_id"` + State string `json:"state"` + Stats struct { + Commits int `json:"commits"` + Conversations int `json:"conversations"` + FilesChanged int `json:"files_changed"` + } `json:"stats"` + TargetBranch string `json:"target_branch"` + TargetRepoID int `json:"target_repo_id"` + Title string `json:"title"` + } -type reference struct { - Repo repository `json:"repo"` - Name string `json:"ref"` - Sha string `json:"sha"` -} + reference struct { + Repo repository `json:"repo"` + Name string `json:"ref"` + Sha string `json:"sha"` + } -type prInput struct { - Title string `json:"title"` - Body string `json:"body"` - Head string `json:"head"` - Base string `json:"base"` -} + prInput struct { + Title string `json:"title"` + Body string `json:"body"` + Head string `json:"head"` + Base string `json:"base"` + } +) -// // native data structure conversion -// - func convertPullRequests(src []*pr) []*scm.PullRequest { dst := []*scm.PullRequest{} for _, v := range src { @@ -116,42 +131,21 @@ func convertPullRequests(src []*pr) []*scm.PullRequest { } func convertPullRequest(src *pr) *scm.PullRequest { - var labels []scm.Label - for _, label := range src.Labels { - labels = append(labels, scm.Label{ - Name: label.Name, - Color: label.Color, - }) - } - return &scm.PullRequest{ - Number: src.Number, - Title: src.Title, - Body: src.Body, - Sha: src.Head.Sha, - Source: src.Head.Name, - Target: src.Base.Name, - Link: src.HTMLURL, - Diff: src.DiffURL, - Fork: "fork", - Ref: fmt.Sprintf("refs/pull/%d/head", src.Number), - Closed: src.State == "closed", - Author: *convertUser(&src.User), - Merged: src.Merged, - Created: src.Created, - Updated: src.Updated, - Labels: labels, - } -} - -func convertPullRequestFromIssue(src *issue) *scm.PullRequest { return &scm.PullRequest{ - Number: src.Number, - Title: src.Title, - Body: src.Body, - Closed: src.State == "closed", - Author: *convertUser(&src.User), - Merged: src.PullRequest.Merged, - Created: src.Created, - Updated: src.Updated, + Number: src.Number, + Title: src.Title, + Body: src.Description, + Source: src.SourceBranch, + Target: src.TargetBranch, + Merged: src.Merged != 0, + Author: scm.User{ + Login: src.Author.Email, + Name: src.Author.DisplayName, + ID: src.Author.UID, + Email: src.Author.Email, + }, + Fork: "fork", + Ref: fmt.Sprintf("refs/pull/%d/head", src.Number), + Closed: src.State == "closed", } } diff --git a/scm/driver/harness/pr_test.go b/scm/driver/harness/pr_test.go index 5d232e2ff..51ab690b9 100644 --- a/scm/driver/harness/pr_test.go +++ b/scm/driver/harness/pr_test.go @@ -3,3 +3,52 @@ // license that can be found in the LICENSE file. package harness + +import ( + "context" + "encoding/json" + "io/ioutil" + "net/http" + "testing" + + "github.com/drone/go-scm/scm" + "github.com/drone/go-scm/scm/transport" + "github.com/google/go-cmp/cmp" + "github.com/h2non/gock" +) + +func TestPRFind(t *testing.T) { + if harnessPAT == "" { + defer gock.Off() + + gock.New(gockOrigin). + Get("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/pullreq/1"). + Reply(200). + Type("plain/text"). + File("testdata/pr.json") + } + client, _ := New(gockOrigin, harnessOrg, harnessAccount, harnessProject) + client.Client = &http.Client{ + Transport: &transport.Custom{ + Before: func(r *http.Request) { + r.Header.Set("x-api-key", harnessPAT) + }, + }, + } + got, _, err := client.PullRequests.Find(context.Background(), harnessRepo, 1) + if err != nil { + t.Error(err) + } + + want := new(scm.PullRequest) + raw, err := ioutil.ReadFile("testdata/pr.json.golden") + if err != nil { + t.Error(err) + } + json.Unmarshal(raw, want) + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } +} diff --git a/scm/driver/harness/release.go b/scm/driver/harness/release.go index 45e10704a..66d62cdb3 100644 --- a/scm/driver/harness/release.go +++ b/scm/driver/harness/release.go @@ -67,7 +67,7 @@ type release struct { IsPrerelease bool `json:"prerelease"` CreatedAt null.Time `json:"created_at"` PublishedAt null.Time `json:"published_at"` - Publisher *user `json:"author"` + Publisher *string `json:"author"` Attachments []*Attachment `json:"assets"` } diff --git a/scm/driver/harness/testdata/pr.json b/scm/driver/harness/testdata/pr.json new file mode 100644 index 000000000..89e773b96 --- /dev/null +++ b/scm/driver/harness/testdata/pr.json @@ -0,0 +1,32 @@ +{ + "number": 1, + "created": 1675960384081, + "edited": 1675960384081, + "state": "open", + "is_draft": false, + "title": "pull title", + "description": "pull description", + "source_repo_id": 11, + "source_branch": "bla", + "target_repo_id": 11, + "target_branch": "main", + "merged": null, + "merge_strategy": null, + "merge_head_sha": null, + "merge_base_sha": null, + "author": { + "id": 14, + "uid": "0Nnoezs6RGa_fOWvG_Ta4w", + "display_name": "thomas.honey", + "email": "thomas.honey@harness.io", + "type": "user", + "created": 1675248918372, + "updated": 1675248918372 + }, + "merger": null, + "stats": { + "conversations": 0, + "commits": 1, + "files_changed": 1 + } +} \ No newline at end of file diff --git a/scm/driver/harness/testdata/pr.json.golden b/scm/driver/harness/testdata/pr.json.golden new file mode 100644 index 000000000..224b66050 --- /dev/null +++ b/scm/driver/harness/testdata/pr.json.golden @@ -0,0 +1,20 @@ +{ + "Number": 1, + "Title": "pull title", + "Body": "pull description", + "Sha": "", + "Ref": "refs/pull/1/head", + "Source": "bla", + "Target": "main", + "Fork": "fork", + "Link": "", + "Diff": "", + "Closed": false, + "Merged": false, + "Author": { + "ID": "0Nnoezs6RGa_fOWvG_Ta4w", + "Login": "thomas.honey@harness.io", + "Name": "thomas.honey", + "Email": "thomas.honey@harness.io" + } +} \ No newline at end of file From cc7b846c96081a87a3d2518b0b65cdc9441f87b2 Mon Sep 17 00:00:00 2001 From: TP Honey Date: Fri, 10 Feb 2023 10:48:32 +0000 Subject: [PATCH 058/195] (feat) harness, add get pr commits --- scm/driver/harness/pr.go | 51 ++++++++++++++++++- scm/driver/harness/pr_test.go | 44 +++++++++++++++- scm/driver/harness/testdata/pr_commits.json | 21 ++++++++ .../harness/testdata/pr_commits.json.golden | 19 +++++++ 4 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 scm/driver/harness/testdata/pr_commits.json create mode 100644 scm/driver/harness/testdata/pr_commits.json.golden diff --git a/scm/driver/harness/pr.go b/scm/driver/harness/pr.go index 61f802972..a223b8d41 100644 --- a/scm/driver/harness/pr.go +++ b/scm/driver/harness/pr.go @@ -7,6 +7,7 @@ package harness import ( "context" "fmt" + "time" "github.com/drone/go-scm/scm" ) @@ -36,8 +37,12 @@ func (s *pullService) ListComments(context.Context, string, int, scm.ListOptions return nil, nil, scm.ErrNotSupported } -func (s *pullService) ListCommits(context.Context, string, int, scm.ListOptions) ([]*scm.Commit, *scm.Response, error) { - return nil, nil, scm.ErrNotSupported +func (s *pullService) ListCommits(ctx context.Context, repo string, index int, opts scm.ListOptions) ([]*scm.Commit, *scm.Response, error) { + harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + path := fmt.Sprintf("api/v1/repos/%s/pullreq/%d/commits?%s", harnessURI, index, encodeListOptions(opts)) + out := []*commit{} + res, err := s.client.do(ctx, "GET", path, nil, &out) + return convertCommits(out), res, err } func (s *pullService) ListChanges(context.Context, string, int, scm.ListOptions) ([]*scm.Change, *scm.Response, error) { @@ -119,6 +124,25 @@ type ( Head string `json:"head"` Base string `json:"base"` } + commit struct { + Author struct { + Identity struct { + Email string `json:"email"` + Name string `json:"name"` + } `json:"identity"` + When time.Time `json:"when"` + } `json:"author"` + Committer struct { + Identity struct { + Email string `json:"email"` + Name string `json:"name"` + } `json:"identity"` + When time.Time `json:"when"` + } `json:"committer"` + Message string `json:"message"` + Sha string `json:"sha"` + Title string `json:"title"` + } ) // native data structure conversion @@ -149,3 +173,26 @@ func convertPullRequest(src *pr) *scm.PullRequest { Closed: src.State == "closed", } } + +func convertCommits(src []*commit) []*scm.Commit { + dst := []*scm.Commit{} + for _, v := range src { + dst = append(dst, convertCommit(v)) + } + return dst +} + +func convertCommit(src *commit) *scm.Commit { + return &scm.Commit{ + Message: src.Message, + Sha: src.Sha, + Author: scm.Signature{ + Name: src.Author.Identity.Name, + Email: src.Author.Identity.Email, + }, + Committer: scm.Signature{ + Name: src.Committer.Identity.Name, + Email: src.Committer.Identity.Email, + }, + } +} diff --git a/scm/driver/harness/pr_test.go b/scm/driver/harness/pr_test.go index 51ab690b9..28f43e40f 100644 --- a/scm/driver/harness/pr_test.go +++ b/scm/driver/harness/pr_test.go @@ -45,7 +45,49 @@ func TestPRFind(t *testing.T) { if err != nil { t.Error(err) } - json.Unmarshal(raw, want) + err = json.Unmarshal(raw, want) + if err != nil { + t.Error(err) + } + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } +} + +func TestPRCommits(t *testing.T) { + if harnessPAT == "" { + defer gock.Off() + + gock.New(gockOrigin). + Get("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/pullreq/1/commits"). + Reply(200). + Type("plain/text"). + File("testdata/pr_commits.json") + } + client, _ := New(gockOrigin, harnessOrg, harnessAccount, harnessProject) + client.Client = &http.Client{ + Transport: &transport.Custom{ + Before: func(r *http.Request) { + r.Header.Set("x-api-key", harnessPAT) + }, + }, + } + got, _, err := client.PullRequests.ListCommits(context.Background(), harnessRepo, 1, scm.ListOptions{}) + if err != nil { + t.Error(err) + } + + want := []*scm.Commit{} + raw, err := ioutil.ReadFile("testdata/pr_commits.json.golden") + if err != nil { + t.Error(err) + } + err = json.Unmarshal(raw, &want) + if err != nil { + t.Error(err) + } if diff := cmp.Diff(got, want); diff != "" { t.Errorf("Unexpected Results") diff --git a/scm/driver/harness/testdata/pr_commits.json b/scm/driver/harness/testdata/pr_commits.json new file mode 100644 index 000000000..286654d14 --- /dev/null +++ b/scm/driver/harness/testdata/pr_commits.json @@ -0,0 +1,21 @@ +[ + { + "author": { + "identity": { + "email": "thomas.honey@harness.io", + "name": "thomas.honey" + }, + "when": "2023-02-09T17:12:10.976Z" + }, + "committer": { + "identity": { + "email": "noreply@harness.io", + "name": "Harness" + }, + "when": "2023-02-09T17:12:10.976Z" + }, + "message": "Create bla_file", + "sha": "0c221fd126b9457d0ad2037641416083549f59c5", + "title": "string" + } +] \ No newline at end of file diff --git a/scm/driver/harness/testdata/pr_commits.json.golden b/scm/driver/harness/testdata/pr_commits.json.golden new file mode 100644 index 000000000..aeceed89f --- /dev/null +++ b/scm/driver/harness/testdata/pr_commits.json.golden @@ -0,0 +1,19 @@ +[ + { + "Sha": "0c221fd126b9457d0ad2037641416083549f59c5", + "Message": "Create bla_file", + "Author": { + "Name": "thomas.honey", + "Email": "thomas.honey@harness.io", + "Login": "", + "Avatar": "" + }, + "Committer": { + "Name": "Harness", + "Email": "noreply@harness.io", + "Login": "", + "Avatar": "" + }, + "Link": "" + } +] \ No newline at end of file From 3d6625f3f2f927fd71496c10be05105a7977e446 Mon Sep 17 00:00:00 2001 From: TP Honey Date: Fri, 10 Feb 2023 11:18:52 +0000 Subject: [PATCH 059/195] (feat) harness, add create PR --- scm/driver/harness/pr.go | 23 ++++++++--- scm/driver/harness/pr_test.go | 40 +++++++++++++++++++ scm/driver/harness/testdata/branches.json | 23 +++++++++++ .../harness/testdata/branches.json.golden | 7 +++- 4 files changed, 87 insertions(+), 6 deletions(-) diff --git a/scm/driver/harness/pr.go b/scm/driver/harness/pr.go index a223b8d41..6e0266a0d 100644 --- a/scm/driver/harness/pr.go +++ b/scm/driver/harness/pr.go @@ -50,7 +50,17 @@ func (s *pullService) ListChanges(context.Context, string, int, scm.ListOptions) } func (s *pullService) Create(ctx context.Context, repo string, input *scm.PullRequestInput) (*scm.PullRequest, *scm.Response, error) { - return nil, nil, scm.ErrNotSupported + harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + path := fmt.Sprintf("api/v1/repos/%s/pullreq", harnessURI) + in := &prInput{ + Title: input.Title, + Description: input.Body, + SourceBranch: input.Source, + TargetBranch: input.Target, + } + out := new(pr) + res, err := s.client.do(ctx, "POST", path, in, out) + return convertPullRequest(out), res, err } func (s *pullService) CreateComment(context.Context, string, int, *scm.CommentInput) (*scm.Comment, *scm.Response, error) { @@ -119,11 +129,14 @@ type ( } prInput struct { - Title string `json:"title"` - Body string `json:"body"` - Head string `json:"head"` - Base string `json:"base"` + Description string `json:"description"` + IsDraft bool `json:"is_draft"` + SourceBranch string `json:"source_branch"` + SourceRepoRef string `json:"source_repo_ref"` + TargetBranch string `json:"target_branch"` + Title string `json:"title"` } + commit struct { Author struct { Identity struct { diff --git a/scm/driver/harness/pr_test.go b/scm/driver/harness/pr_test.go index 28f43e40f..b9bc5a631 100644 --- a/scm/driver/harness/pr_test.go +++ b/scm/driver/harness/pr_test.go @@ -94,3 +94,43 @@ func TestPRCommits(t *testing.T) { t.Log(diff) } } + +func TestPullCreate(t *testing.T) { + defer gock.Off() + gock.New(gockOrigin). + Post("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/pullreq"). + Reply(200). + Type("plain/text"). + File("testdata/pr.json") + + client, _ := New(gockOrigin, harnessOrg, harnessAccount, harnessProject) + client.Client = &http.Client{ + Transport: &transport.Custom{ + Before: func(r *http.Request) { + r.Header.Set("x-api-key", harnessPAT) + }, + }, + } + + input := scm.PullRequestInput{ + Title: "pull title", + Body: "pull description", + Source: "bla", + Target: "main", + } + + got, _, err := client.PullRequests.Create(context.Background(), harnessRepo, &input) + if err != nil { + t.Error(err) + return + } + + want := new(scm.PullRequest) + raw, _ := ioutil.ReadFile("testdata/pr.json.golden") + _ = json.Unmarshal(raw, want) + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } +} diff --git a/scm/driver/harness/testdata/branches.json b/scm/driver/harness/testdata/branches.json index e35f84b4e..2490e4ae3 100644 --- a/scm/driver/harness/testdata/branches.json +++ b/scm/driver/harness/testdata/branches.json @@ -22,6 +22,29 @@ } } }, + { + "name": "branch3", + "sha": "59e1cdf0e421fd14b106f4861fb02dfd56b4dc34", + "commit": { + "sha": "59e1cdf0e421fd14b106f4861fb02dfd56b4dc34", + "title": "delete README.2", + "message": "delete README.2\n\ndelete README.2", + "author": { + "identity": { + "name": "thomas.honey", + "email": "thomas.honey@harness.io" + }, + "when": "2023-02-09T12:39:37Z" + }, + "committer": { + "identity": { + "name": "Harness", + "email": "noreply@harness.io" + }, + "when": "2023-02-09T12:39:37Z" + } + } + }, { "name": "main", "sha": "de2837f8911710cfb7bbb323d0de285fd2ef9155", diff --git a/scm/driver/harness/testdata/branches.json.golden b/scm/driver/harness/testdata/branches.json.golden index 66ad737e5..3f2458b08 100644 --- a/scm/driver/harness/testdata/branches.json.golden +++ b/scm/driver/harness/testdata/branches.json.golden @@ -1,9 +1,14 @@ [ - { + { "Name": "bla", "Path": "refs/heads/bla", "Sha": "0c221fd126b9457d0ad2037641416083549f59c5" }, + { + "Name": "branch3", + "Path": "refs/heads/branch3", + "Sha": "59e1cdf0e421fd14b106f4861fb02dfd56b4dc34" + }, { "Name": "main", "Path": "refs/heads/main", From 643af2e8f3a4295313b75b951a4fa19d1a4a1586 Mon Sep 17 00:00:00 2001 From: TP Honey Date: Fri, 10 Feb 2023 13:54:49 +0000 Subject: [PATCH 060/195] (fix) harness, webhook fixes --- scm/driver/harness/harness.go | 2 +- scm/driver/harness/webhook.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scm/driver/harness/harness.go b/scm/driver/harness/harness.go index d26835374..9b36f87f3 100644 --- a/scm/driver/harness/harness.go +++ b/scm/driver/harness/harness.go @@ -33,7 +33,7 @@ func New(uri, account, organization, project string) (*scm.Client, error) { client := &wrapper{new(scm.Client), account, organization, project} client.BaseURL = base // initialize services - client.Driver = scm.DriverGitea + client.Driver = scm.DriverHarness client.Linker = &linker{base.String()} client.Contents = &contentService{client} client.Git = &gitService{client} diff --git a/scm/driver/harness/webhook.go b/scm/driver/harness/webhook.go index 6b8c2777e..fc89148e5 100644 --- a/scm/driver/harness/webhook.go +++ b/scm/driver/harness/webhook.go @@ -58,7 +58,7 @@ func (s *webhookService) Parse(req *http.Request, fn scm.SecretFunc) (scm.Webhoo } secret := req.FormValue("secret") - signature := req.Header.Get("X-Gitea-Signature") + signature := req.Header.Get("X-Harness-Signature") // fail if no signature passed if signature == "" && secret == "" { From f8f38dff4e0e8cd7f7d847b35b96de21ea28d426 Mon Sep 17 00:00:00 2001 From: TP Honey Date: Mon, 13 Feb 2023 12:01:02 +0000 Subject: [PATCH 061/195] (feat) harness, add finduser --- scm/driver/harness/testdata/user.json | 52 ++++++++++++-- scm/driver/harness/testdata/user.json.golden | 8 +-- scm/driver/harness/user.go | 72 +++++++++++++++----- scm/driver/harness/user_test.go | 17 +++-- 4 files changed, 115 insertions(+), 34 deletions(-) diff --git a/scm/driver/harness/testdata/user.json b/scm/driver/harness/testdata/user.json index 459c42c39..21ea693f2 100644 --- a/scm/driver/harness/testdata/user.json +++ b/scm/driver/harness/testdata/user.json @@ -1,9 +1,47 @@ { - "admin": true, - "blocked": true, - "created": 0, - "display_name": "1", - "email": "2", - "uid": "3", - "updated": 0 + "status": "SUCCESS", + "data": { + "uuid": "0Nnoezs6RGa_fOWvG_Ta4w", + "name": "thomas.honey", + "email": "thomas.honey@harness.io", + "token": null, + "defaultAccountId": "px7xd_BFRCi-pfWPYXVjvw", + "intent": null, + "accounts": [ + { + "uuid": "px7xd_BFRCi-pfWPYXVjvw", + "accountName": "harness-dev", + "companyName": "harness-dev", + "defaultExperience": "NG", + "createdFromNG": false, + "nextGenEnabled": true + }, + { + "uuid": "Ws0xvw71Sm2YmpSC7A8z4g", + "accountName": "OPA-Governance", + "companyName": "Feature-Flag", + "defaultExperience": "NG", + "createdFromNG": false, + "nextGenEnabled": true + } + ], + "admin": false, + "twoFactorAuthenticationEnabled": false, + "emailVerified": true, + "locked": false, + "disabled": false, + "signupAction": null, + "edition": null, + "billingFrequency": null, + "utmInfo": { + "utmSource": null, + "utmContent": null, + "utmMedium": null, + "utmTerm": null, + "utmCampaign": null + }, + "externallyManaged": false + }, + "metaData": null, + "correlationId": "c4014fdb-10a1-4dc4-ace0-6fad93544993" } \ No newline at end of file diff --git a/scm/driver/harness/testdata/user.json.golden b/scm/driver/harness/testdata/user.json.golden index 1c38875a7..5f81bfeba 100644 --- a/scm/driver/harness/testdata/user.json.golden +++ b/scm/driver/harness/testdata/user.json.golden @@ -1,7 +1,7 @@ { - "ID": "3", - "Login": "2", - "Name": "1", - "Email": "2", + "ID": "0Nnoezs6RGa_fOWvG_Ta4w", + "Login": "thomas.honey@harness.io", + "Name": "thomas.honey", + "Email": "thomas.honey@harness.io", "Avatar": "" } \ No newline at end of file diff --git a/scm/driver/harness/user.go b/scm/driver/harness/user.go index 3bdd3514d..500cad249 100644 --- a/scm/driver/harness/user.go +++ b/scm/driver/harness/user.go @@ -6,6 +6,8 @@ package harness import ( "context" + "fmt" + "strings" "github.com/drone/go-scm/scm" ) @@ -15,9 +17,19 @@ type userService struct { } func (s *userService) Find(ctx context.Context) (*scm.User, *scm.Response, error) { - out := new(user) - res, err := s.client.do(ctx, "GET", "api/v1/user", nil, out) - return convertUser(out), res, err + out := new(harnessUser) + // the following is for the corporate version of Harness code + tempUserService := *s + // get the basepath + basePath := tempUserService.client.BaseURL.Path + // use the NG user endpoint + basePath = strings.Replace(basePath, "code", "ng", 1) + // set the new basepath + tempUserService.client.BaseURL.Path = basePath + // set the path + path := fmt.Sprintf("api/user/currentUser") + res, err := s.client.do(ctx, "GET", path, nil, out) + return convertHarnessUser(out), res, err } func (s *userService) FindLogin(ctx context.Context, login string) (*scm.User, *scm.Response, error) { @@ -36,25 +48,53 @@ func (s *userService) ListEmail(context.Context, scm.ListOptions) ([]*scm.Email, // native data structures // -type user struct { - Admin bool `json:"admin"` - Blocked bool `json:"blocked"` - Created int `json:"created"` - DisplayName string `json:"display_name"` - Email string `json:"email"` - UID string `json:"uid"` - Updated int `json:"updated"` +type harnessUser struct { + Status string `json:"status"` + Data struct { + UUID string `json:"uuid"` + Name string `json:"name"` + Email string `json:"email"` + Token interface{} `json:"token"` + Defaultaccountid string `json:"defaultAccountId"` + Intent interface{} `json:"intent"` + Accounts []struct { + UUID string `json:"uuid"` + Accountname string `json:"accountName"` + Companyname string `json:"companyName"` + Defaultexperience string `json:"defaultExperience"` + Createdfromng bool `json:"createdFromNG"` + Nextgenenabled bool `json:"nextGenEnabled"` + } `json:"accounts"` + Admin bool `json:"admin"` + Twofactorauthenticationenabled bool `json:"twoFactorAuthenticationEnabled"` + Emailverified bool `json:"emailVerified"` + Locked bool `json:"locked"` + Disabled bool `json:"disabled"` + Signupaction interface{} `json:"signupAction"` + Edition interface{} `json:"edition"` + Billingfrequency interface{} `json:"billingFrequency"` + Utminfo struct { + Utmsource interface{} `json:"utmSource"` + Utmcontent interface{} `json:"utmContent"` + Utmmedium interface{} `json:"utmMedium"` + Utmterm interface{} `json:"utmTerm"` + Utmcampaign interface{} `json:"utmCampaign"` + } `json:"utmInfo"` + Externallymanaged bool `json:"externallyManaged"` + } `json:"data"` + Metadata interface{} `json:"metaData"` + Correlationid string `json:"correlationId"` } // // native data structure conversion // -func convertUser(src *user) *scm.User { +func convertHarnessUser(src *harnessUser) *scm.User { return &scm.User{ - Login: src.Email, - Email: src.Email, - Name: src.DisplayName, - ID: src.UID, + Login: src.Data.Email, + Email: src.Data.Email, + Name: src.Data.Name, + ID: src.Data.UUID, } } diff --git a/scm/driver/harness/user_test.go b/scm/driver/harness/user_test.go index 755294de3..886494c13 100644 --- a/scm/driver/harness/user_test.go +++ b/scm/driver/harness/user_test.go @@ -9,6 +9,7 @@ import ( "encoding/json" "io/ioutil" "net/http" + "strings" "testing" "github.com/drone/go-scm/scm" @@ -18,15 +19,17 @@ import ( ) func TestUsersFind(t *testing.T) { + if harnessPAT == "" { + defer gock.Off() - defer gock.Off() - - gock.New(gockOrigin). - Get("/gateway/code/api/v1/user"). - Reply(200). - Type("application/json"). - File("testdata/user.json") + harnessUserOrigin := strings.Replace(gockOrigin, "code", "ng", 1) + gock.New(harnessUserOrigin). + Get("/gateway/ng/api/user/currentUser"). + Reply(200). + Type("application/json"). + File("testdata/user.json") + } client, _ := New(gockOrigin, harnessOrg, harnessAccount, harnessProject) client.Client = &http.Client{ Transport: &transport.Custom{ From a9651b1e4b178182ffe8dabe12d984326050d31e Mon Sep 17 00:00:00 2001 From: TP Honey Date: Wed, 15 Feb 2023 10:23:58 +0000 Subject: [PATCH 062/195] (maint) prep for 1.29.0 --- CHANGELOG.md | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f8653ef1..0eb4ae3a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,28 @@ # Changelog -## [1.28.1](https://github.com/drone/go-scm/tree/1.28.1) (2023-01-27) +## [1.29.0](https://github.com/drone/go-scm/tree/1.29.0) (2023-02-15) -[Full Changelog](https://github.com/drone/go-scm/compare/v1.28.0...1.28.1) +[Full Changelog](https://github.com/drone/go-scm/compare/v1.28.1...1.29.0) + +**Implemented enhancements:** + +- \(feat\) harness, add finduser [\#250](https://github.com/drone/go-scm/pull/250) ([tphoney](https://github.com/tphoney)) +- \(feat\) harness, fix create branch, PR calls [\#247](https://github.com/drone/go-scm/pull/247) ([tphoney](https://github.com/tphoney)) +- \(feat\) harness, add user and compare branches [\#246](https://github.com/drone/go-scm/pull/246) ([tphoney](https://github.com/tphoney)) +- \(feat\) harness, add list commits / branches [\#245](https://github.com/drone/go-scm/pull/245) ([tphoney](https://github.com/tphoney)) +- \(feat\) harness, add webhook parsing [\#244](https://github.com/drone/go-scm/pull/244) ([tphoney](https://github.com/tphoney)) +- fetch branch for bitbucket onprem [\#242](https://github.com/drone/go-scm/pull/242) ([devkimittal](https://github.com/devkimittal)) +- \(feat\) harness, add repo list [\#241](https://github.com/drone/go-scm/pull/241) ([tphoney](https://github.com/tphoney)) +- Harness move [\#237](https://github.com/drone/go-scm/pull/237) ([tphoney](https://github.com/tphoney)) + +**Fixed bugs:** + +- \(fix\) harness, webhook fixes [\#248](https://github.com/drone/go-scm/pull/248) ([tphoney](https://github.com/tphoney)) +- fix: \[PIE-7927\]: Fix header value typo issue for BB OnPrem CSRF header [\#236](https://github.com/drone/go-scm/pull/236) ([mohitg0795](https://github.com/mohitg0795)) + +## [v1.28.1](https://github.com/drone/go-scm/tree/v1.28.1) (2023-01-27) + +[Full Changelog](https://github.com/drone/go-scm/compare/v1.28.0...v1.28.1) **Fixed bugs:** @@ -12,6 +32,10 @@ - Gogs commit fails to deserialize commitDetails in some cases [\#231](https://github.com/drone/go-scm/issues/231) +**Merged pull requests:** + +- \(maint\) prep 1.28.1 release [\#235](https://github.com/drone/go-scm/pull/235) ([tphoney](https://github.com/tphoney)) + ## [v1.28.0](https://github.com/drone/go-scm/tree/v1.28.0) (2022-11-22) [Full Changelog](https://github.com/drone/go-scm/compare/v1.27.0...v1.28.0) From 971da4d64ddd33589eeae533a7c0afb5388c49f5 Mon Sep 17 00:00:00 2001 From: Eoin McAfee <83226740+eoinmcafee00@users.noreply.github.com> Date: Wed, 15 Feb 2023 15:24:46 +0000 Subject: [PATCH 063/195] update list url to scopepath instead of path (#249) --- scm/driver/azure/content.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/scm/driver/azure/content.go b/scm/driver/azure/content.go index 18cd0402a..689f6718f 100644 --- a/scm/driver/azure/content.go +++ b/scm/driver/azure/content.go @@ -19,8 +19,8 @@ type contentService struct { func (s *contentService) Find(ctx context.Context, repo, path, ref string) (*scm.Content, *scm.Response, error) { // https://docs.microsoft.com/en-us/rest/api/azure/devops/git/items/get?view=azure-devops-rest-6.0 if s.client.project == "" { - return nil, nil, ProjectRequiredError() - } + return nil, nil, ProjectRequiredError() + } endpoint := fmt.Sprintf("%s/%s/_apis/git/repositories/%s/items?path=%s&includeContent=true&$format=json", s.client.owner, s.client.project, repo, path) endpoint += generateURIFromRef(ref) endpoint += "&api-version=6.0" @@ -37,8 +37,8 @@ func (s *contentService) Find(ctx context.Context, repo, path, ref string) (*scm func (s *contentService) Create(ctx context.Context, repo, path string, params *scm.ContentParams) (*scm.Response, error) { if s.client.project == "" { - return nil, ProjectRequiredError() - } + return nil, ProjectRequiredError() + } endpoint := fmt.Sprintf("%s/%s/_apis/git/repositories/%s/pushes?api-version=6.0", s.client.owner, s.client.project, repo) ref := refUpdate{ Name: SanitizeBranchName(params.Branch), @@ -66,8 +66,8 @@ func (s *contentService) Create(ctx context.Context, repo, path string, params * func (s *contentService) Update(ctx context.Context, repo, path string, params *scm.ContentParams) (*scm.Response, error) { if s.client.project == "" { - return nil, ProjectRequiredError() - } + return nil, ProjectRequiredError() + } endpoint := fmt.Sprintf("%s/%s/_apis/git/repositories/%s/pushes?api-version=6.0", s.client.owner, s.client.project, repo) ref := refUpdate{ Name: SanitizeBranchName(params.Branch), @@ -95,8 +95,8 @@ func (s *contentService) Update(ctx context.Context, repo, path string, params * func (s *contentService) Delete(ctx context.Context, repo, path string, params *scm.ContentParams) (*scm.Response, error) { if s.client.project == "" { - return nil, ProjectRequiredError() - } + return nil, ProjectRequiredError() + } endpoint := fmt.Sprintf("%s/%s/_apis/git/repositories/%s/pushes?api-version=6.0", s.client.owner, s.client.project, repo) ref := refUpdate{ Name: SanitizeBranchName(params.Branch), @@ -122,9 +122,9 @@ func (s *contentService) Delete(ctx context.Context, repo, path string, params * func (s *contentService) List(ctx context.Context, repo, path, ref string, _ scm.ListOptions) ([]*scm.ContentInfo, *scm.Response, error) { // https://docs.microsoft.com/en-us/rest/api/azure/devops/git/items/list?view=azure-devops-rest-6.0 if s.client.project == "" { - return nil, nil, ProjectRequiredError() - } - endpoint := fmt.Sprintf("%s/%s/_apis/git/repositories/%s/items?path=%s&recursionLevel=Full&$format=json", s.client.owner, s.client.project, repo, path) + return nil, nil, ProjectRequiredError() + } + endpoint := fmt.Sprintf("%s/%s/_apis/git/repositories/%s/items?scopePath=%s&recursionLevel=Full&$format=json", s.client.owner, s.client.project, repo, path) endpoint += generateURIFromRef(ref) out := new(contentList) res, err := s.client.do(ctx, "GET", endpoint, nil, &out) From 430a0a7800c74adb95ea72e684349649bf4fea92 Mon Sep 17 00:00:00 2001 From: Mohit Garg Date: Thu, 16 Feb 2023 02:04:36 +0530 Subject: [PATCH 064/195] add required header for bitbucket server in commit API use-case to handle csrf failures --- scm/driver/stash/stash.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scm/driver/stash/stash.go b/scm/driver/stash/stash.go index 33f3d5711..62db1c7fd 100644 --- a/scm/driver/stash/stash.go +++ b/scm/driver/stash/stash.go @@ -95,7 +95,8 @@ func (c *wrapper) do(ctx context.Context, method, path string, in, out interface req.Body = &b // write the content type that contains the length of the multipart req.Header = map[string][]string{ - "Content-Type": {mw.FormDataContentType()}, + "Content-Type": {mw.FormDataContentType()}, + "x-atlassian-token": {"no-check"}, } default: buf := new(bytes.Buffer) From 2957cd32fe5dbb0880f2590219937984d1071ed9 Mon Sep 17 00:00:00 2001 From: Eoin McAfee Date: Thu, 16 Feb 2023 10:50:11 +0000 Subject: [PATCH 065/195] release prep v1.29.1 --- CHANGELOG.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0eb4ae3a1..872d6396c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,16 @@ # Changelog -## [1.29.0](https://github.com/drone/go-scm/tree/1.29.0) (2023-02-15) +## [v1.29.1](https://github.com/drone/go-scm/tree/v1.29.1) (2023-02-16) -[Full Changelog](https://github.com/drone/go-scm/compare/v1.28.1...1.29.0) +[Full Changelog](https://github.com/drone/go-scm/compare/v1.29.0...v1.29.1) + +**Fixed bugs:** + +- \(fix\) - azure content list queryparam incorrect [\#249](https://github.com/drone/go-scm/pull/249) ([eoinmcafee00](https://github.com/eoinmcafee00)) + +## [v1.29.0](https://github.com/drone/go-scm/tree/v1.29.0) (2023-02-15) + +[Full Changelog](https://github.com/drone/go-scm/compare/v1.28.1...v1.29.0) **Implemented enhancements:** @@ -20,6 +28,10 @@ - \(fix\) harness, webhook fixes [\#248](https://github.com/drone/go-scm/pull/248) ([tphoney](https://github.com/tphoney)) - fix: \[PIE-7927\]: Fix header value typo issue for BB OnPrem CSRF header [\#236](https://github.com/drone/go-scm/pull/236) ([mohitg0795](https://github.com/mohitg0795)) +**Merged pull requests:** + +- \(maint\) prep for 1.29.0 [\#251](https://github.com/drone/go-scm/pull/251) ([tphoney](https://github.com/tphoney)) + ## [v1.28.1](https://github.com/drone/go-scm/tree/v1.28.1) (2023-01-27) [Full Changelog](https://github.com/drone/go-scm/compare/v1.28.0...v1.28.1) From bdac4837fcef86672478d5923044962eaae6dc1d Mon Sep 17 00:00:00 2001 From: Dev Mittal Date: Wed, 1 Mar 2023 17:54:53 +0530 Subject: [PATCH 066/195] fix: [CI-6978] fixed gitlab webhook parse --- .../testdata/webhooks/merge_request_comment_create.json.golden | 2 +- scm/driver/gitlab/webhook.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scm/driver/gitlab/testdata/webhooks/merge_request_comment_create.json.golden b/scm/driver/gitlab/testdata/webhooks/merge_request_comment_create.json.golden index 3b84d1116..dcc3e2448 100644 --- a/scm/driver/gitlab/testdata/webhooks/merge_request_comment_create.json.golden +++ b/scm/driver/gitlab/testdata/webhooks/merge_request_comment_create.json.golden @@ -40,7 +40,7 @@ "Source": "feature", "Target": "master", "Fork": "", - "Link": "https://gitlab.com/gitlab-org/hello-world", + "Link": "https://gitlab.com/gitlab-org/hello-world/merge_requests/1", "Diff": "", "Closed": false, "Merged": false, diff --git a/scm/driver/gitlab/webhook.go b/scm/driver/gitlab/webhook.go index b0a519739..56da8f195 100644 --- a/scm/driver/gitlab/webhook.go +++ b/scm/driver/gitlab/webhook.go @@ -237,7 +237,7 @@ func convertCommentHook(src *commentHook) (*scm.IssueCommentHook, error) { Ref: fmt.Sprintf("refs/merge-requests/%d/head", src.MergeRequest.Iid), Source: src.MergeRequest.SourceBranch, Target: src.MergeRequest.TargetBranch, - Link: src.Project.WebURL, + Link: src.MergeRequest.URL, Closed: src.MergeRequest.State != "opened", Merged: src.MergeRequest.State == "merged", Author: *convertUser(&src.User), From 194f53fb37164b85170a71b0040456191797a0fe Mon Sep 17 00:00:00 2001 From: Shalini Agrawal Date: Fri, 28 Apr 2023 15:12:29 +0530 Subject: [PATCH 067/195] fix: [CDS-67745]: fix find user email api for bitbucket in go-scm (#255) Co-authored-by: Mohit Garg --- scm/driver/bitbucket/testdata/userEmail.json | 8 +++++++ scm/driver/bitbucket/user.go | 22 +++++++++++++++++++- scm/driver/bitbucket/user_test.go | 21 ++++++++++++++++--- 3 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 scm/driver/bitbucket/testdata/userEmail.json diff --git a/scm/driver/bitbucket/testdata/userEmail.json b/scm/driver/bitbucket/testdata/userEmail.json new file mode 100644 index 000000000..80e1c227a --- /dev/null +++ b/scm/driver/bitbucket/testdata/userEmail.json @@ -0,0 +1,8 @@ +{ + "Values": [ + { + "email": "test@harness.io", + "is_primary": true + } + ] +} \ No newline at end of file diff --git a/scm/driver/bitbucket/user.go b/scm/driver/bitbucket/user.go index b349cb5c1..eba34f022 100644 --- a/scm/driver/bitbucket/user.go +++ b/scm/driver/bitbucket/user.go @@ -29,13 +29,24 @@ func (s *userService) FindLogin(ctx context.Context, login string) (*scm.User, * } func (s *userService) FindEmail(ctx context.Context) (string, *scm.Response, error) { - return "", nil, scm.ErrNotSupported + out := new(emails) + res, err := s.client.do(ctx, "GET", "2.0/user/emails", nil, &out) + return convertEmailList(out), res, err } func (s *userService) ListEmail(context.Context, scm.ListOptions) ([]*scm.Email, *scm.Response, error) { return nil, nil, scm.ErrNotSupported } +func convertEmailList(from *emails) string { + for _, v := range from.Values { + if v.IsPrimary == true { + return v.Email + } + } + return "" +} + type user struct { // The `username` field is no longer available after 29 April 2019 in // accordance with GDPR regulations. See: @@ -53,6 +64,15 @@ type user struct { UUID string `json:"uuid"` } +type email struct { + Email string `json:"email"` + IsPrimary bool `json:"is_primary"` +} + +type emails struct { + Values []*email `json:"values"` +} + func convertUser(from *user) *scm.User { return &scm.User{ Avatar: fmt.Sprintf("https://bitbucket.org/account/%s/avatar/32/", from.Username), diff --git a/scm/driver/bitbucket/user_test.go b/scm/driver/bitbucket/user_test.go index aa3b4e947..4e6b3c9f4 100644 --- a/scm/driver/bitbucket/user_test.go +++ b/scm/driver/bitbucket/user_test.go @@ -67,9 +67,24 @@ func TestUserLoginFind(t *testing.T) { } func TestUserFindEmail(t *testing.T) { + defer gock.Off() + + gock.New("https://api.bitbucket.org"). + Get("/2.0/user/emails"). + Reply(200). + Type("application/json"). + File("testdata/userEmail.json") + client, _ := New("https://api.bitbucket.org") - _, _, err := client.Users.FindEmail(context.Background()) - if err != scm.ErrNotSupported { - t.Errorf("Expect Not Supported error") + got, _, err := client.Users.FindEmail(context.Background()) + if err != nil { + t.Error(err) + } + + want := "test@harness.io" + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) } } From 5877f3846131efb292e01d717d1a5c69c851dbd9 Mon Sep 17 00:00:00 2001 From: Shalini Agrawal Date: Mon, 15 May 2023 14:58:09 +0530 Subject: [PATCH 068/195] feat: [CDS-69341]: add find user email api for github in go-scm (#256) * feat: [CDS-69341]: add find user email api for github in go-scm --- scm/driver/github/user.go | 13 +++++++++++-- scm/driver/github/user_test.go | 4 ++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/scm/driver/github/user.go b/scm/driver/github/user.go index fd6243e13..6da295679 100644 --- a/scm/driver/github/user.go +++ b/scm/driver/github/user.go @@ -31,8 +31,8 @@ func (s *userService) FindLogin(ctx context.Context, login string) (*scm.User, * } func (s *userService) FindEmail(ctx context.Context) (string, *scm.Response, error) { - user, res, err := s.Find(ctx) - return user.Email, res, err + out, res, err := s.ListEmail(ctx, scm.ListOptions{}) + return returnPrimaryEmail(out), res, err } func (s *userService) ListEmail(ctx context.Context, opts scm.ListOptions) ([]*scm.Email, *scm.Response, error) { @@ -69,6 +69,15 @@ func convertUser(from *user) *scm.User { } } +func returnPrimaryEmail(from []*scm.Email) string { + for _, v := range from { + if v.Primary == true { + return v.Value + } + } + return "" +} + // helper function to convert from the github email list to // the common email structure. func convertEmailList(from []*email) []*scm.Email { diff --git a/scm/driver/github/user_test.go b/scm/driver/github/user_test.go index e2fd64bad..8888d18a5 100644 --- a/scm/driver/github/user_test.go +++ b/scm/driver/github/user_test.go @@ -87,14 +87,14 @@ func TestUserEmailFind(t *testing.T) { defer gock.Off() gock.New("https://api.github.com"). - Get("/user"). + Get("/user/emails"). Reply(200). Type("application/json"). SetHeader("X-GitHub-Request-Id", "DD0E:6011:12F21A8:1926790:5A2064E2"). SetHeader("X-RateLimit-Limit", "60"). SetHeader("X-RateLimit-Remaining", "59"). SetHeader("X-RateLimit-Reset", "1512076018"). - File("testdata/user.json") + File("testdata/emails.json") client := NewDefault() result, res, err := client.Users.FindEmail(context.Background()) From ad21d44b0fe3a9649a24dfb4d954da7c6c5178aa Mon Sep 17 00:00:00 2001 From: TP Honey Date: Thu, 22 Jun 2023 14:00:18 +0100 Subject: [PATCH 069/195] (maint) stash/bitbucket on prem v5 add push webhook test (#257) Co-authored-by: dependabot-ci --- .../stash/testdata/webhooks/push_v5.json | 44 ++++++++++++++++ .../testdata/webhooks/push_v5.json.golden | 50 +++++++++++++++++++ scm/driver/stash/webhook_test.go | 9 +++- 3 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 scm/driver/stash/testdata/webhooks/push_v5.json create mode 100644 scm/driver/stash/testdata/webhooks/push_v5.json.golden diff --git a/scm/driver/stash/testdata/webhooks/push_v5.json b/scm/driver/stash/testdata/webhooks/push_v5.json new file mode 100644 index 000000000..444d2ff44 --- /dev/null +++ b/scm/driver/stash/testdata/webhooks/push_v5.json @@ -0,0 +1,44 @@ +{ + "eventKey": "repo:refs_changed", + "date": "2023-05-30T15:40:47-0400", + "actor": { + "name": "trangineni", + "emailAddress": "tanuja.rangineni@transamerica.com", + "id": 39725, + "displayName": "Rangineni, Tanuja", + "active": true, + "slug": "trangineni", + "type": "NORMAL" + }, + "repository": { + "slug": "transamerica.cloud.individual.tftest", + "id": 13027, + "name": "transamerica.cloud.individual.tftest", + "scmId": "git", + "state": "AVAILABLE", + "statusMessage": "Available", + "forkable": true, + "project": { + "key": "ISCLOUD", + "id": 1453, + "name": "Individual Cloud", + "description": "Project for Individual Solutions application terraform.", + "public": false, + "type": "NORMAL" + }, + "public": false + }, + "changes": [ + { + "ref": { + "id": "refs/heads/trangineni/devtfvars-1685475548410", + "displayId": "trangineni/devtfvars-1685475548410", + "type": "BRANCH" + }, + "refId": "refs/heads/trangineni/devtfvars-1685475548410", + "fromHash": "b2b710209761a3fab9fc867aad7b7725fd0fd028", + "toHash": "51a33664b6d7fb5aa15063064eb230362cd02e9e", + "type": "UPDATE" + } + ] +} \ No newline at end of file diff --git a/scm/driver/stash/testdata/webhooks/push_v5.json.golden b/scm/driver/stash/testdata/webhooks/push_v5.json.golden new file mode 100644 index 000000000..ffe8c4c87 --- /dev/null +++ b/scm/driver/stash/testdata/webhooks/push_v5.json.golden @@ -0,0 +1,50 @@ +{ + "Ref": "refs/heads/trangineni/devtfvars-1685475548410", + "After": "51a33664b6d7fb5aa15063064eb230362cd02e9e", + "Before": "b2b710209761a3fab9fc867aad7b7725fd0fd028", + "Repo": { + "ID": "13027", + "Namespace": "ISCLOUD", + "Name": "transamerica.cloud.individual.tftest", + "Perm": null, + "Branch": "master", + "Private": true, + "Clone": "", + "CloneSSH": "", + "Link": "", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Commit": { + "Sha": "51a33664b6d7fb5aa15063064eb230362cd02e9e", + "Message": "", + "Author": { + "Name": "Rangineni, Tanuja", + "Email": "tanuja.rangineni@transamerica.com", + "Date": "0001-01-01T00:00:00Z", + "Login": "trangineni", + "Avatar": "https://www.gravatar.com/avatar/1c0ba1559ee8ed291204dad48479149b.jpg" + }, + "Committer": { + "Name": "Rangineni, Tanuja", + "Email": "tanuja.rangineni@transamerica.com", + "Date": "0001-01-01T00:00:00Z", + "Login": "trangineni", + "Avatar": "https://www.gravatar.com/avatar/1c0ba1559ee8ed291204dad48479149b.jpg" + }, + "Link": "" + }, + "Commits": [ + { + "Sha": "51a33664b6d7fb5aa15063064eb230362cd02e9e", + "Message": "", + "Link": "" + } + ], + "Sender": { + "Login": "trangineni", + "Name": "Rangineni, Tanuja", + "Email": "tanuja.rangineni@transamerica.com", + "Avatar": "https://www.gravatar.com/avatar/1c0ba1559ee8ed291204dad48479149b.jpg" + } +} \ No newline at end of file diff --git a/scm/driver/stash/webhook_test.go b/scm/driver/stash/webhook_test.go index 711adc694..28e72a0ad 100644 --- a/scm/driver/stash/webhook_test.go +++ b/scm/driver/stash/webhook_test.go @@ -37,7 +37,14 @@ func TestWebhooks(t *testing.T) { after: "testdata/webhooks/push.json.golden", obj: new(scm.PushHook), }, - + // v5 test + { + sig: "71295b197fa25f4356d2fb9965df3f2379d903d7", + event: "repo:refs_changed", + before: "testdata/webhooks/push_v5.json", + after: "testdata/webhooks/push_v5.json.golden", + obj: new(scm.PushHook), + }, // // tag events // From 64a614ce5db57d436f93c9204417728578742d14 Mon Sep 17 00:00:00 2001 From: Adithya Viswanathan Date: Wed, 5 Jul 2023 16:21:06 +0530 Subject: [PATCH 070/195] [feat]: [CDS-73030]: Support for text based branch filtration --- scm/client.go | 7 + scm/driver/azure/git.go | 11 + scm/driver/azure/git_test.go | 26 +++ scm/driver/azure/testdata/branchesFilter.json | 41 ++++ .../azure/testdata/branchesFilter.json.golden | 12 ++ scm/driver/bitbucket/git.go | 7 + scm/driver/bitbucket/git_test.go | 34 +++ .../bitbucket/testdata/branchesFilter.json | 201 ++++++++++++++++++ .../testdata/branchesFilter.json.golden | 12 ++ scm/driver/bitbucket/util.go | 19 ++ scm/driver/gitea/git.go | 4 + scm/driver/gitee/git.go | 4 + scm/driver/github/git.go | 4 + scm/driver/gitlab/git.go | 7 + scm/driver/gitlab/git_test.go | 32 +++ .../gitlab/testdata/branchesFilter.json | 46 ++++ .../testdata/branchesFilter.json.golden | 12 ++ scm/driver/gitlab/util.go | 14 ++ scm/driver/gogs/git.go | 4 + scm/driver/harness/git.go | 4 + scm/driver/stash/git.go | 9 + scm/driver/stash/git_test.go | 28 +++ scm/driver/stash/testdata/branchesFilter.json | 24 +++ .../stash/testdata/branchesFilter.json.golden | 12 ++ scm/driver/stash/util.go | 16 ++ scm/git.go | 1 + 26 files changed, 591 insertions(+) create mode 100644 scm/driver/azure/testdata/branchesFilter.json create mode 100644 scm/driver/azure/testdata/branchesFilter.json.golden create mode 100644 scm/driver/bitbucket/testdata/branchesFilter.json create mode 100644 scm/driver/bitbucket/testdata/branchesFilter.json.golden create mode 100644 scm/driver/gitlab/testdata/branchesFilter.json create mode 100644 scm/driver/gitlab/testdata/branchesFilter.json.golden create mode 100644 scm/driver/stash/testdata/branchesFilter.json create mode 100644 scm/driver/stash/testdata/branchesFilter.json.golden diff --git a/scm/client.go b/scm/client.go index d3d8a7d21..ca3d1cafc 100644 --- a/scm/client.go +++ b/scm/client.go @@ -68,6 +68,13 @@ type ( Reset int64 } + // BranchListOptions specifies optional branch search term and pagination + // parameters. + BranchListOptions struct { + SearchTerm string + PageListOptions ListOptions + } + // ListOptions specifies optional pagination // parameters. ListOptions struct { diff --git a/scm/driver/azure/git.go b/scm/driver/azure/git.go index b23a0f7d7..af6656c13 100644 --- a/scm/driver/azure/git.go +++ b/scm/driver/azure/git.go @@ -63,6 +63,17 @@ func (s *gitService) ListBranches(ctx context.Context, repo string, _ scm.ListOp return convertBranchList(out.Value), res, err } +func (s *gitService) ListBranchesV2(ctx context.Context, repo string, opts scm.BranchListOptions) ([]*scm.Reference, *scm.Response, error) { + // https://docs.microsoft.com/en-us/rest/api/azure/devops/git/refs/list?view=azure-devops-rest-6.0 + if s.client.project == "" { + return nil, nil, ProjectRequiredError() + } + endpoint := fmt.Sprintf("%s/%s/_apis/git/repositories/%s/refs?api-version=6.0&filterContains=%s", s.client.owner, s.client.project, repo, opts.SearchTerm) + out := new(branchList) + res, err := s.client.do(ctx, "GET", endpoint, nil, &out) + return convertBranchList(out.Value), res, err +} + func (s *gitService) ListCommits(ctx context.Context, repo string, opts scm.CommitListOptions) ([]*scm.Commit, *scm.Response, error) { // https://docs.microsoft.com/en-us/rest/api/azure/devops/git/commits/get-commits?view=azure-devops-rest-6.0 if s.client.project == "" { diff --git a/scm/driver/azure/git_test.go b/scm/driver/azure/git_test.go index d5faf0ef7..846e2b97b 100644 --- a/scm/driver/azure/git_test.go +++ b/scm/driver/azure/git_test.go @@ -123,6 +123,32 @@ func TestGitListBranches(t *testing.T) { } } +func TestGitListBranchesV2(t *testing.T) { + defer gock.Off() + + gock.New("https:/dev.azure.com/"). + Get("/ORG/PROJ/_apis/git/repositories/REPOID/"). + Reply(200). + Type("application/json"). + File("testdata/branchesFilter.json") + + client := NewDefault("ORG", "PROJ") + got, _, err := client.Git.ListBranchesV2(context.Background(), "REPOID", scm.BranchListOptions{SearchTerm: "main"}) + if err != nil { + t.Error(err) + return + } + + want := []*scm.Reference{} + raw, _ := ioutil.ReadFile("testdata/branchesFilter.json.golden") + _ = json.Unmarshal(raw, &want) + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } +} + func TestGitCompareChanges(t *testing.T) { defer gock.Off() diff --git a/scm/driver/azure/testdata/branchesFilter.json b/scm/driver/azure/testdata/branchesFilter.json new file mode 100644 index 000000000..b9043edb5 --- /dev/null +++ b/scm/driver/azure/testdata/branchesFilter.json @@ -0,0 +1,41 @@ +{ + "value": [ + { + "name": "refs/heads/main", + "objectId": "e0aee6aa543294d62520fb906689da6710af149c", + "creator": { + "displayName": "tp", + "url": "https://spsproduks1.vssps.visualstudio.com/A93f74f38-2b8d-42d4-a5cb-74646f46666e/_apis/Identities/3ff4a20f-306e-677e-8a01-57f35e71f109", + "_links": { + "avatar": { + "href": "https://dev.azure.com/tphoney/_apis/GraphProfile/MemberAvatars/msa.M2ZmNGEyMGYtMzA2ZS03NzdlLThhMDEtNTdmMzVlNzFmMTA5" + } + }, + "id": "3ff4a20f-306e-677e-8a01-57f35e71f109", + "uniqueName": "tp@harness.io", + "imageUrl": "https://dev.azure.com/tphoney/_api/_common/identityImage?id=3ff4a20f-306e-677e-8a01-57f35e71f109", + "descriptor": "msa.M2ZmNGEyMGYtMzA2ZS03NzdlLThhMDEtNTdmMzVlNzFmMTA5" + }, + "url": "https://dev.azure.com/tphoney/d350c9c0-7749-4ff8-a78f-f9c1f0e56729/_apis/git/repositories/fde2d21f-13b9-4864-a995-83329045289a/refs?filter=heads%2Fmain" + }, + { + "name": "refs/heads/main-patch", + "objectId": "01768d964c03e97260af0bd8cd9e5cd1f9ac6356", + "creator": { + "displayName": "tp", + "url": "https://spsproduks1.vssps.visualstudio.com/A93f74f38-2b8d-42d4-a5cb-74646f46666e/_apis/Identities/3ff4a20f-306e-677e-8a01-57f35e71f109", + "_links": { + "avatar": { + "href": "https://dev.azure.com/tphoney/_apis/GraphProfile/MemberAvatars/msa.M2ZmNGEyMGYtMzA2ZS03NzdlLThhMDEtNTdmMzVlNzFmMTA5" + } + }, + "id": "3ff4a20f-306e-677e-8a01-57f35e71f109", + "uniqueName": "tp@harness.io", + "imageUrl": "https://dev.azure.com/tphoney/_api/_common/identityImage?id=3ff4a20f-306e-677e-8a01-57f35e71f109", + "descriptor": "msa.M2ZmNGEyMGYtMzA2ZS03NzdlLThhMDEtNTdmMzVlNzFmMTA5" + }, + "url": "https://dev.azure.com/tphoney/d350c9c0-7749-4ff8-a78f-f9c1f0e56729/_apis/git/repositories/fde2d21f-13b9-4864-a995-83329045289a/refs?filter=heads%2Fpr_branch" + } + ], + "count": 2 +} \ No newline at end of file diff --git a/scm/driver/azure/testdata/branchesFilter.json.golden b/scm/driver/azure/testdata/branchesFilter.json.golden new file mode 100644 index 000000000..df3589ce6 --- /dev/null +++ b/scm/driver/azure/testdata/branchesFilter.json.golden @@ -0,0 +1,12 @@ +[ + { + "Name": "main", + "Path": "refs/heads/main", + "Sha": "e0aee6aa543294d62520fb906689da6710af149c" + }, + { + "Name": "main-patch", + "Path": "refs/heads/main-patch", + "Sha": "01768d964c03e97260af0bd8cd9e5cd1f9ac6356" + } +] \ No newline at end of file diff --git a/scm/driver/bitbucket/git.go b/scm/driver/bitbucket/git.go index 4a2298d59..8efbe341e 100644 --- a/scm/driver/bitbucket/git.go +++ b/scm/driver/bitbucket/git.go @@ -64,6 +64,13 @@ func (s *gitService) ListBranches(ctx context.Context, repo string, opts scm.Lis copyPagination(out.pagination, res) return convertBranchList(out), res, err } +func (s *gitService) ListBranchesV2(ctx context.Context, repo string, opts scm.BranchListOptions) ([]*scm.Reference, *scm.Response, error) { + path := fmt.Sprintf("2.0/repositories/%s/refs/branches?%s", repo, encodeBranchListOptions(opts)) + out := new(branches) + res, err := s.client.do(ctx, "GET", path, nil, out) + copyPagination(out.pagination, res) + return convertBranchList(out), res, err +} func (s *gitService) ListCommits(ctx context.Context, repo string, opts scm.CommitListOptions) ([]*scm.Commit, *scm.Response, error) { path := fmt.Sprintf("2.0/repositories/%s/commits/%s?%s", repo, opts.Ref, encodeCommitListOptions(opts)) diff --git a/scm/driver/bitbucket/git_test.go b/scm/driver/bitbucket/git_test.go index ec3b49f43..275707a0b 100644 --- a/scm/driver/bitbucket/git_test.go +++ b/scm/driver/bitbucket/git_test.go @@ -206,6 +206,40 @@ func TestGitListBranches(t *testing.T) { t.Run("Page", testPage(res)) } +func TestGitListBranchesV2(t *testing.T) { + defer gock.Off() + + gock.New("https://api.bitbucket.org"). + Get("/2.0/repositories/atlassian/stash-example-plugin/refs"). + MatchParam("q", "name~\\\"mast\\\""). + MatchParam("page", "1"). + MatchParam("pagelen", "30"). + Reply(200). + Type("application/json"). + File("testdata/branchesFilter.json") + + client, _ := New("https://api.bitbucket.org") + got, res, err := client.Git.ListBranchesV2(context.Background(), "atlassian/stash-example-plugin", scm.BranchListOptions{SearchTerm: "mast", PageListOptions: struct { + URL string + Page int + Size int + }{Page: 1, Size: 30}}) + if err != nil { + t.Error(err) + } + + want := []*scm.Reference{} + raw, _ := ioutil.ReadFile("testdata/branchesFilter.json.golden") + json.Unmarshal(raw, &want) + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } + + t.Run("Page", testPage(res)) +} + func TestGitListTags(t *testing.T) { defer gock.Off() diff --git a/scm/driver/bitbucket/testdata/branchesFilter.json b/scm/driver/bitbucket/testdata/branchesFilter.json new file mode 100644 index 000000000..122655ec4 --- /dev/null +++ b/scm/driver/bitbucket/testdata/branchesFilter.json @@ -0,0 +1,201 @@ +{ + "pagelen": 30, + "values": [ + { + "type": "branch", + "name": "master", + "links": { + "commits": { + "href": "https:\/\/api.bitbucket.org\/2.0\/repositories\/atlassian\/stash-example-plugin\/commits\/master" + }, + "self": { + "href": "https:\/\/api.bitbucket.org\/2.0\/repositories\/atlassian\/stash-example-plugin\/refs\/branches\/master" + }, + "html": { + "href": "https:\/\/bitbucket.org\/atlassian\/stash-example-plugin\/branch\/master" + } + }, + "target": { + "hash": "a6e5e7d797edf751cbd839d6bd4aef86c941eec9", + "repository": { + "links": { + "self": { + "href": "https:\/\/api.bitbucket.org\/2.0\/repositories\/atlassian\/stash-example-plugin" + }, + "html": { + "href": "https:\/\/bitbucket.org\/atlassian\/stash-example-plugin" + }, + "avatar": { + "href": "https:\/\/bytebucket.org\/ravatar\/%7B7dd600e6-0d9c-4801-b967-cb4cc17359ff%7D?ts=default" + } + }, + "type": "repository", + "name": "stash-example-plugin", + "full_name": "atlassian\/stash-example-plugin", + "uuid": "{7dd600e6-0d9c-4801-b967-cb4cc17359ff}" + }, + "links": { + "self": { + "href": "https:\/\/api.bitbucket.org\/2.0\/repositories\/atlassian\/stash-example-plugin\/commit\/a6e5e7d797edf751cbd839d6bd4aef86c941eec9" + }, + "comments": { + "href": "https:\/\/api.bitbucket.org\/2.0\/repositories\/atlassian\/stash-example-plugin\/commit\/a6e5e7d797edf751cbd839d6bd4aef86c941eec9\/comments" + }, + "patch": { + "href": "https:\/\/api.bitbucket.org\/2.0\/repositories\/atlassian\/stash-example-plugin\/patch\/a6e5e7d797edf751cbd839d6bd4aef86c941eec9" + }, + "html": { + "href": "https:\/\/bitbucket.org\/atlassian\/stash-example-plugin\/commits\/a6e5e7d797edf751cbd839d6bd4aef86c941eec9" + }, + "diff": { + "href": "https:\/\/api.bitbucket.org\/2.0\/repositories\/atlassian\/stash-example-plugin\/diff\/a6e5e7d797edf751cbd839d6bd4aef86c941eec9" + }, + "approve": { + "href": "https:\/\/api.bitbucket.org\/2.0\/repositories\/atlassian\/stash-example-plugin\/commit\/a6e5e7d797edf751cbd839d6bd4aef86c941eec9\/approve" + }, + "statuses": { + "href": "https:\/\/api.bitbucket.org\/2.0\/repositories\/atlassian\/stash-example-plugin\/commit\/a6e5e7d797edf751cbd839d6bd4aef86c941eec9\/statuses" + } + }, + "author": { + "raw": "Adam Ahmed ", + "type": "author", + "user": { + "username": "aahmed", + "display_name": "Adam Ahmed", + "account_id": "557057:74dc5efb-ffe7-49af-b427-6abc299bb3b9", + "links": { + "self": { + "href": "https:\/\/api.bitbucket.org\/2.0\/users\/aahmed" + }, + "html": { + "href": "https:\/\/bitbucket.org\/aahmed\/" + }, + "avatar": { + "href": "https:\/\/bitbucket.org\/account\/aahmed\/avatar\/32\/" + } + }, + "type": "user", + "uuid": "{3d5de233-98d4-4138-b4af-8678fbb009ad}" + } + }, + "parents": [ + { + "hash": "5be6855032e171280a1acb860d7265c29f40487c", + "type": "commit", + "links": { + "self": { + "href": "https:\/\/api.bitbucket.org\/2.0\/repositories\/atlassian\/stash-example-plugin\/commit\/5be6855032e171280a1acb860d7265c29f40487c" + }, + "html": { + "href": "https:\/\/bitbucket.org\/atlassian\/stash-example-plugin\/commits\/5be6855032e171280a1acb860d7265c29f40487c" + } + } + } + ], + "date": "2015-08-27T03:25:04+00:00", + "message": "Add Apache 2.0 License\n", + "type": "commit" + } + }, + { + "type": "branch", + "name": "master-patch", + "links": { + "commits": { + "href": "https:\/\/api.bitbucket.org\/2.0\/repositories\/atlassian\/stash-example-plugin\/commits\/master" + }, + "self": { + "href": "https:\/\/api.bitbucket.org\/2.0\/repositories\/atlassian\/stash-example-plugin\/refs\/branches\/master" + }, + "html": { + "href": "https:\/\/bitbucket.org\/atlassian\/stash-example-plugin\/branch\/master" + } + }, + "target": { + "hash": "a6e5e7d797edf751cbd839d6bd4aef86c941eec8", + "repository": { + "links": { + "self": { + "href": "https:\/\/api.bitbucket.org\/2.0\/repositories\/atlassian\/stash-example-plugin" + }, + "html": { + "href": "https:\/\/bitbucket.org\/atlassian\/stash-example-plugin" + }, + "avatar": { + "href": "https:\/\/bytebucket.org\/ravatar\/%7B7dd600e6-0d9c-4801-b967-cb4cc17359ff%7D?ts=default" + } + }, + "type": "repository", + "name": "stash-example-plugin", + "full_name": "atlassian\/stash-example-plugin", + "uuid": "{7dd600e6-0d9c-4801-b967-cb4cc17359ff}" + }, + "links": { + "self": { + "href": "https:\/\/api.bitbucket.org\/2.0\/repositories\/atlassian\/stash-example-plugin\/commit\/a6e5e7d797edf751cbd839d6bd4aef86c941eec9" + }, + "comments": { + "href": "https:\/\/api.bitbucket.org\/2.0\/repositories\/atlassian\/stash-example-plugin\/commit\/a6e5e7d797edf751cbd839d6bd4aef86c941eec9\/comments" + }, + "patch": { + "href": "https:\/\/api.bitbucket.org\/2.0\/repositories\/atlassian\/stash-example-plugin\/patch\/a6e5e7d797edf751cbd839d6bd4aef86c941eec9" + }, + "html": { + "href": "https:\/\/bitbucket.org\/atlassian\/stash-example-plugin\/commits\/a6e5e7d797edf751cbd839d6bd4aef86c941eec9" + }, + "diff": { + "href": "https:\/\/api.bitbucket.org\/2.0\/repositories\/atlassian\/stash-example-plugin\/diff\/a6e5e7d797edf751cbd839d6bd4aef86c941eec9" + }, + "approve": { + "href": "https:\/\/api.bitbucket.org\/2.0\/repositories\/atlassian\/stash-example-plugin\/commit\/a6e5e7d797edf751cbd839d6bd4aef86c941eec9\/approve" + }, + "statuses": { + "href": "https:\/\/api.bitbucket.org\/2.0\/repositories\/atlassian\/stash-example-plugin\/commit\/a6e5e7d797edf751cbd839d6bd4aef86c941eec9\/statuses" + } + }, + "author": { + "raw": "Adam Ahmed ", + "type": "author", + "user": { + "username": "aahmed", + "display_name": "Adam Ahmed", + "account_id": "557057:74dc5efb-ffe7-49af-b427-6abc299bb3b9", + "links": { + "self": { + "href": "https:\/\/api.bitbucket.org\/2.0\/users\/aahmed" + }, + "html": { + "href": "https:\/\/bitbucket.org\/aahmed\/" + }, + "avatar": { + "href": "https:\/\/bitbucket.org\/account\/aahmed\/avatar\/32\/" + } + }, + "type": "user", + "uuid": "{3d5de233-98d4-4138-b4af-8678fbb009ad}" + } + }, + "parents": [ + { + "hash": "5be6855032e171280a1acb860d7265c29f40487c", + "type": "commit", + "links": { + "self": { + "href": "https:\/\/api.bitbucket.org\/2.0\/repositories\/atlassian\/stash-example-plugin\/commit\/5be6855032e171280a1acb860d7265c29f40487c" + }, + "html": { + "href": "https:\/\/bitbucket.org\/atlassian\/stash-example-plugin\/commits\/5be6855032e171280a1acb860d7265c29f40487c" + } + } + } + ], + "date": "2015-08-27T03:25:04+00:00", + "message": "Add Apache 2.0 License\n", + "type": "commit" + } + } + ], + "page": 1, + "next": "https:\/\/bitbucket.org\/atlassian\/stash-example-plugin\/refs\/branches?pagelen=30&page=2" +} \ No newline at end of file diff --git a/scm/driver/bitbucket/testdata/branchesFilter.json.golden b/scm/driver/bitbucket/testdata/branchesFilter.json.golden new file mode 100644 index 000000000..79754a78f --- /dev/null +++ b/scm/driver/bitbucket/testdata/branchesFilter.json.golden @@ -0,0 +1,12 @@ +[ + { + "Name": "master", + "Path": "refs/heads/master", + "Sha": "a6e5e7d797edf751cbd839d6bd4aef86c941eec9" + }, + { + "Name": "master-patch", + "Path": "refs/heads/master-patch", + "Sha": "a6e5e7d797edf751cbd839d6bd4aef86c941eec8" + } +] \ No newline at end of file diff --git a/scm/driver/bitbucket/util.go b/scm/driver/bitbucket/util.go index 03c5eaae4..b53ba777c 100644 --- a/scm/driver/bitbucket/util.go +++ b/scm/driver/bitbucket/util.go @@ -8,6 +8,7 @@ import ( "net/url" "regexp" "strconv" + "strings" "github.com/drone/go-scm/scm" ) @@ -24,6 +25,24 @@ func extractEmail(gitauthor string) (author string) { return } +func encodeBranchListOptions(opts scm.BranchListOptions) string { + params := url.Values{} + if opts.SearchTerm != "" { + var sb strings.Builder + sb.WriteString("name~\"") + sb.WriteString(opts.SearchTerm) + sb.WriteString("\"") + params.Set("q", sb.String()) + } + if opts.PageListOptions.Page != 0 { + params.Set("page", strconv.Itoa(opts.PageListOptions.Page)) + } + if opts.PageListOptions.Size != 0 { + params.Set("pagelen", strconv.Itoa(opts.PageListOptions.Size)) + } + return params.Encode() +} + func encodeListOptions(opts scm.ListOptions) string { params := url.Values{} if opts.Page != 0 { diff --git a/scm/driver/gitea/git.go b/scm/driver/gitea/git.go index 60de87bec..3fab00f7c 100644 --- a/scm/driver/gitea/git.go +++ b/scm/driver/gitea/git.go @@ -59,6 +59,10 @@ func (s *gitService) ListBranches(ctx context.Context, repo string, opts scm.Lis return convertBranchList(out), res, err } +func (s *gitService) ListBranchesV2(ctx context.Context, repo string, opts scm.BranchListOptions) ([]*scm.Reference, *scm.Response, error) { + return s.ListBranches(ctx, repo, opts.PageListOptions) +} + func (s *gitService) ListCommits(ctx context.Context, repo string, _ scm.CommitListOptions) ([]*scm.Commit, *scm.Response, error) { path := fmt.Sprintf("api/v1/repos/%s/commits", repo) out := []*commitInfo{} diff --git a/scm/driver/gitee/git.go b/scm/driver/gitee/git.go index ffbd5c0e2..2f8f93d57 100644 --- a/scm/driver/gitee/git.go +++ b/scm/driver/gitee/git.go @@ -60,6 +60,10 @@ func (s *gitService) ListBranches(ctx context.Context, repo string, _ scm.ListOp return convertBranchList(out), res, err } +func (s *gitService) ListBranchesV2(ctx context.Context, repo string, opts scm.BranchListOptions) ([]*scm.Reference, *scm.Response, error) { + return s.ListBranches(ctx, repo, opts.PageListOptions) +} + func (s *gitService) ListCommits(ctx context.Context, repo string, opts scm.CommitListOptions) ([]*scm.Commit, *scm.Response, error) { path := fmt.Sprintf("repos/%s/commits?%s", repo, encodeCommitListOptions(opts)) out := []*commit{} diff --git a/scm/driver/github/git.go b/scm/driver/github/git.go index 5a5829f4d..d6ce73d69 100644 --- a/scm/driver/github/git.go +++ b/scm/driver/github/git.go @@ -53,6 +53,10 @@ func (s *gitService) ListBranches(ctx context.Context, repo string, opts scm.Lis return convertBranchList(out), res, err } +func (s *gitService) ListBranchesV2(ctx context.Context, repo string, opts scm.BranchListOptions) ([]*scm.Reference, *scm.Response, error) { + return s.ListBranches(ctx, repo, opts.PageListOptions) +} + func (s *gitService) ListCommits(ctx context.Context, repo string, opts scm.CommitListOptions) ([]*scm.Commit, *scm.Response, error) { path := fmt.Sprintf("repos/%s/commits?%s", repo, encodeCommitListOptions(opts)) out := []*commit{} diff --git a/scm/driver/gitlab/git.go b/scm/driver/gitlab/git.go index ebada6c99..3bc37ef7d 100644 --- a/scm/driver/gitlab/git.go +++ b/scm/driver/gitlab/git.go @@ -60,6 +60,13 @@ func (s *gitService) ListBranches(ctx context.Context, repo string, opts scm.Lis return convertBranchList(out), res, err } +func (s *gitService) ListBranchesV2(ctx context.Context, repo string, opts scm.BranchListOptions) ([]*scm.Reference, *scm.Response, error) { + path := fmt.Sprintf("api/v4/projects/%s/repository/branches?%s", encode(repo), encodeBranchListOptions(opts)) + out := []*branch{} + res, err := s.client.do(ctx, "GET", path, nil, &out) + return convertBranchList(out), res, err +} + func (s *gitService) ListCommits(ctx context.Context, repo string, opts scm.CommitListOptions) ([]*scm.Commit, *scm.Response, error) { path := fmt.Sprintf("api/v4/projects/%s/repository/commits?%s", encode(repo), encodeCommitListOptions(opts)) out := []*commit{} diff --git a/scm/driver/gitlab/git_test.go b/scm/driver/gitlab/git_test.go index 32d58f6f2..ee4595398 100644 --- a/scm/driver/gitlab/git_test.go +++ b/scm/driver/gitlab/git_test.go @@ -206,6 +206,38 @@ func TestGitListBranches(t *testing.T) { t.Run("Page", testPage(res)) } +func TestGitListBranchesWithBranchFilter(t *testing.T) { + defer gock.Off() + + gock.New("https://gitlab.com"). + Get("/api/v4/projects/diaspora/diaspora/repository/branches"). + Reply(200). + Type("application/json"). + SetHeaders(mockHeaders). + SetHeaders(mockPageHeaders). + File("testdata/branchesFilter.json") + + client := NewDefault() + got, res, err := client.Git.ListBranchesV2(context.Background(), "diaspora/diaspora", scm.BranchListOptions{SearchTerm: "mast"}) + if err != nil { + t.Error(err) + return + } + + want := []*scm.Reference{} + raw, _ := ioutil.ReadFile("testdata/branchesFilter.json.golden") + json.Unmarshal(raw, &want) + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } + + t.Run("Request", testRequest(res)) + t.Run("Rate", testRate(res)) + t.Run("Page", testPage(res)) +} + func TestGitListTags(t *testing.T) { defer gock.Off() diff --git a/scm/driver/gitlab/testdata/branchesFilter.json b/scm/driver/gitlab/testdata/branchesFilter.json new file mode 100644 index 000000000..c5072e736 --- /dev/null +++ b/scm/driver/gitlab/testdata/branchesFilter.json @@ -0,0 +1,46 @@ +[ + { + "name": "master", + "merged": false, + "protected": true, + "developers_can_push": false, + "developers_can_merge": false, + "commit": { + "author_email": "john@example.com", + "author_name": "John Smith", + "authored_date": "2012-06-27T05:51:39-07:00", + "committed_date": "2012-06-28T03:44:20-07:00", + "committer_email": "john@example.com", + "committer_name": "John Smith", + "id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c", + "short_id": "7b5c3cc", + "title": "add projects API", + "message": "add projects API", + "parent_ids": [ + "4ad91d3c1144c406e50c7b33bae684bd6837faf8" + ] + } + }, + { + "name": "master-patch", + "merged": false, + "protected": true, + "developers_can_push": false, + "developers_can_merge": false, + "commit": { + "author_email": "john@example.com", + "author_name": "John Smith", + "authored_date": "2012-06-27T05:51:39-07:00", + "committed_date": "2012-06-28T03:44:20-07:00", + "committer_email": "john@example.com", + "committer_name": "John Smith", + "id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0d", + "short_id": "7b5c3cc", + "title": "add projects API", + "message": "add projects API", + "parent_ids": [ + "4ad91d3c1144c406e50c7b33bae684bd6837faf9" + ] + } + } +] \ No newline at end of file diff --git a/scm/driver/gitlab/testdata/branchesFilter.json.golden b/scm/driver/gitlab/testdata/branchesFilter.json.golden new file mode 100644 index 000000000..d6f1a9210 --- /dev/null +++ b/scm/driver/gitlab/testdata/branchesFilter.json.golden @@ -0,0 +1,12 @@ +[ + { + "Name": "master", + "Path": "refs/heads/master", + "Sha": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c" + }, + { + "Name": "master-patch", + "Path": "refs/heads/master-patch", + "Sha": "7b5c3cc8be40ee161ae89a06bba6229da1032a0d" + } +] \ No newline at end of file diff --git a/scm/driver/gitlab/util.go b/scm/driver/gitlab/util.go index 05670bcd2..55f106f71 100644 --- a/scm/driver/gitlab/util.go +++ b/scm/driver/gitlab/util.go @@ -24,6 +24,20 @@ func encodePath(s string) string { return strings.Replace(url.PathEscape(s), ".", "%2E", -1) } +func encodeBranchListOptions(opts scm.BranchListOptions) string { + params := url.Values{} + if opts.SearchTerm != "" { + params.Set("search", opts.SearchTerm) + } + if opts.PageListOptions.Page != 0 { + params.Set("page", strconv.Itoa(opts.PageListOptions.Page)) + } + if opts.PageListOptions.Size != 0 { + params.Set("per_page", strconv.Itoa(opts.PageListOptions.Size)) + } + return params.Encode() +} + func encodeListOptions(opts scm.ListOptions) string { params := url.Values{} if opts.Page != 0 { diff --git a/scm/driver/gogs/git.go b/scm/driver/gogs/git.go index aaf6a0616..15b9e7429 100644 --- a/scm/driver/gogs/git.go +++ b/scm/driver/gogs/git.go @@ -54,6 +54,10 @@ func (s *gitService) ListBranches(ctx context.Context, repo string, _ scm.ListOp return convertBranchList(out), res, err } +func (s *gitService) ListBranchesV2(ctx context.Context, repo string, opts scm.BranchListOptions) ([]*scm.Reference, *scm.Response, error) { + return s.ListBranches(ctx, repo, opts.PageListOptions) +} + func (s *gitService) ListCommits(ctx context.Context, repo string, _ scm.CommitListOptions) ([]*scm.Commit, *scm.Response, error) { return nil, nil, scm.ErrNotSupported } diff --git a/scm/driver/harness/git.go b/scm/driver/harness/git.go index 9186112e6..59c9691cf 100644 --- a/scm/driver/harness/git.go +++ b/scm/driver/harness/git.go @@ -56,6 +56,10 @@ func (s *gitService) ListBranches(ctx context.Context, repo string, opts scm.Lis return convertBranchList(out), res, err } +func (s *gitService) ListBranchesV2(ctx context.Context, repo string, opts scm.BranchListOptions) ([]*scm.Reference, *scm.Response, error) { + return s.ListBranches(ctx, repo, opts.PageListOptions) +} + func (s *gitService) ListCommits(ctx context.Context, repo string, _ scm.CommitListOptions) ([]*scm.Commit, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) path := fmt.Sprintf("api/v1/repos/%s/commits", harnessURI) diff --git a/scm/driver/stash/git.go b/scm/driver/stash/git.go index dece5d940..221b59911 100644 --- a/scm/driver/stash/git.go +++ b/scm/driver/stash/git.go @@ -79,6 +79,15 @@ func (s *gitService) ListBranches(ctx context.Context, repo string, opts scm.Lis return convertBranchList(out), res, err } +func (s *gitService) ListBranchesV2(ctx context.Context, repo string, opts scm.BranchListOptions) ([]*scm.Reference, *scm.Response, error) { + namespace, name := scm.Split(repo) + path := fmt.Sprintf("rest/api/1.0/projects/%s/repos/%s/branches?%s", namespace, name, encodeBranchListOptions(opts)) + out := new(branches) + res, err := s.client.do(ctx, "GET", path, nil, out) + copyPagination(out.pagination, res) + return convertBranchList(out), res, err +} + func (s *gitService) ListCommits(ctx context.Context, repo string, opts scm.CommitListOptions) ([]*scm.Commit, *scm.Response, error) { namespace, name := scm.Split(repo) var requestPath string diff --git a/scm/driver/stash/git_test.go b/scm/driver/stash/git_test.go index 4d92fec4e..720e8fa6f 100644 --- a/scm/driver/stash/git_test.go +++ b/scm/driver/stash/git_test.go @@ -147,6 +147,34 @@ func TestGitListBranches(t *testing.T) { // t.Run("Page", testPage(res)) } +func TestGitListBranchesWithBranchFilter(t *testing.T) { + defer gock.Off() + + gock.New("http://example.com:7990"). + Get("/rest/api/1.0/projects/PRJ/repos/my-repo/branches"). + MatchParam("filterText", "mast"). + Reply(200). + Type("application/json"). + File("testdata/branchesFilter.json") + + client, _ := New("http://example.com:7990") + got, _, err := client.Git.ListBranchesV2(context.Background(), "PRJ/my-repo", scm.BranchListOptions{SearchTerm: "mast"}) + if err != nil { + t.Error(err) + } + + want := []*scm.Reference{} + raw, _ := ioutil.ReadFile("testdata/branchesFilter.json.golden") + _ = json.Unmarshal(raw, &want) + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } + // + // t.Run("Page", testPage(res)) +} + func TestGitListTags(t *testing.T) { defer gock.Off() diff --git a/scm/driver/stash/testdata/branchesFilter.json b/scm/driver/stash/testdata/branchesFilter.json new file mode 100644 index 000000000..f6b88ab8f --- /dev/null +++ b/scm/driver/stash/testdata/branchesFilter.json @@ -0,0 +1,24 @@ +{ + "size": 1, + "limit": 25, + "isLastPage": true, + "values": [ + { + "id": "refs/heads/master", + "displayId": "master", + "type": "BRANCH", + "latestCommit": "11ce869211917dd65610e70fcee454943b35ac6e", + "latestChangeset": "11ce869211917dd65610e70fcee454943b35ac6e", + "isDefault": true + }, + { + "id": "refs/heads/master-patch", + "displayId": "master-patch", + "type": "BRANCH", + "latestCommit": "11ce869211917dd65610e70fcee454943b35ac6f", + "latestChangeset": "11ce869211917dd65610e70fcee454943b35ac6f", + "isDefault": true + } + ], + "start": 0 +} \ No newline at end of file diff --git a/scm/driver/stash/testdata/branchesFilter.json.golden b/scm/driver/stash/testdata/branchesFilter.json.golden new file mode 100644 index 000000000..a158fbac2 --- /dev/null +++ b/scm/driver/stash/testdata/branchesFilter.json.golden @@ -0,0 +1,12 @@ +[ + { + "Name": "master", + "Path": "refs/heads/master", + "Sha": "11ce869211917dd65610e70fcee454943b35ac6e" + }, + { + "Name": "master-patch", + "Path": "refs/heads/master-patch", + "Sha": "11ce869211917dd65610e70fcee454943b35ac6f" + } +] \ No newline at end of file diff --git a/scm/driver/stash/util.go b/scm/driver/stash/util.go index 64e982ba2..0de82e3fa 100644 --- a/scm/driver/stash/util.go +++ b/scm/driver/stash/util.go @@ -25,6 +25,22 @@ func encodeListOptions(opts scm.ListOptions) string { return params.Encode() } +func encodeBranchListOptions(opts scm.BranchListOptions) string { + params := url.Values{} + if opts.SearchTerm != "" { + params.Set("filterText", opts.SearchTerm) + } + if opts.PageListOptions.Page > 1 { + params.Set("start", strconv.Itoa( + (opts.PageListOptions.Page-1)*opts.PageListOptions.Size), + ) + } + if opts.PageListOptions.Size != 0 { + params.Set("limit", strconv.Itoa(opts.PageListOptions.Size)) + } + return params.Encode() +} + func encodeListRoleOptions(opts scm.ListOptions) string { params := url.Values{} if opts.Page > 1 { diff --git a/scm/git.go b/scm/git.go index eff476038..847020932 100644 --- a/scm/git.go +++ b/scm/git.go @@ -72,6 +72,7 @@ type ( // ListBranches returns a list of git branches. ListBranches(ctx context.Context, repo string, opts ListOptions) ([]*Reference, *Response, error) + ListBranchesV2(ctx context.Context, repo string, opts BranchListOptions) ([]*Reference, *Response, error) // ListCommits returns a list of git commits. ListCommits(ctx context.Context, repo string, opts CommitListOptions) ([]*Commit, *Response, error) From aefd6d1f0af9d80ac2b1a9201ac98ed8d46d7f21 Mon Sep 17 00:00:00 2001 From: Adithya Viswanathan Date: Wed, 5 Jul 2023 16:29:04 +0530 Subject: [PATCH 071/195] [feat]: [CDS-73030]: added comments --- scm/driver/gitea/git.go | 2 ++ scm/driver/gitee/git.go | 2 ++ scm/driver/github/git.go | 2 ++ scm/driver/gogs/git.go | 2 ++ scm/driver/harness/git.go | 2 ++ scm/git.go | 2 ++ 6 files changed, 12 insertions(+) diff --git a/scm/driver/gitea/git.go b/scm/driver/gitea/git.go index 3fab00f7c..aaa58134f 100644 --- a/scm/driver/gitea/git.go +++ b/scm/driver/gitea/git.go @@ -60,6 +60,8 @@ func (s *gitService) ListBranches(ctx context.Context, repo string, opts scm.Lis } func (s *gitService) ListBranchesV2(ctx context.Context, repo string, opts scm.BranchListOptions) ([]*scm.Reference, *scm.Response, error) { + // Gitea doesnt provide support listing based on searchTerm + // Hence calling the ListBranches return s.ListBranches(ctx, repo, opts.PageListOptions) } diff --git a/scm/driver/gitee/git.go b/scm/driver/gitee/git.go index 2f8f93d57..b3377a43c 100644 --- a/scm/driver/gitee/git.go +++ b/scm/driver/gitee/git.go @@ -61,6 +61,8 @@ func (s *gitService) ListBranches(ctx context.Context, repo string, _ scm.ListOp } func (s *gitService) ListBranchesV2(ctx context.Context, repo string, opts scm.BranchListOptions) ([]*scm.Reference, *scm.Response, error) { + // Gitee doesnt provide support listing based on searchTerm + // Hence calling the ListBranches return s.ListBranches(ctx, repo, opts.PageListOptions) } diff --git a/scm/driver/github/git.go b/scm/driver/github/git.go index d6ce73d69..c64ea3430 100644 --- a/scm/driver/github/git.go +++ b/scm/driver/github/git.go @@ -54,6 +54,8 @@ func (s *gitService) ListBranches(ctx context.Context, repo string, opts scm.Lis } func (s *gitService) ListBranchesV2(ctx context.Context, repo string, opts scm.BranchListOptions) ([]*scm.Reference, *scm.Response, error) { + // Github doesnt provide support listing based on searchTerm + // Hence calling the ListBranches return s.ListBranches(ctx, repo, opts.PageListOptions) } diff --git a/scm/driver/gogs/git.go b/scm/driver/gogs/git.go index 15b9e7429..30103cc7b 100644 --- a/scm/driver/gogs/git.go +++ b/scm/driver/gogs/git.go @@ -55,6 +55,8 @@ func (s *gitService) ListBranches(ctx context.Context, repo string, _ scm.ListOp } func (s *gitService) ListBranchesV2(ctx context.Context, repo string, opts scm.BranchListOptions) ([]*scm.Reference, *scm.Response, error) { + // Gogs doesnt provide support listing based on searchTerm + // Hence calling the ListBranches return s.ListBranches(ctx, repo, opts.PageListOptions) } diff --git a/scm/driver/harness/git.go b/scm/driver/harness/git.go index 59c9691cf..787eb4920 100644 --- a/scm/driver/harness/git.go +++ b/scm/driver/harness/git.go @@ -57,6 +57,8 @@ func (s *gitService) ListBranches(ctx context.Context, repo string, opts scm.Lis } func (s *gitService) ListBranchesV2(ctx context.Context, repo string, opts scm.BranchListOptions) ([]*scm.Reference, *scm.Response, error) { + // Harness doesnt provide support listing based on searchTerm + // Hence calling the ListBranches return s.ListBranches(ctx, repo, opts.PageListOptions) } diff --git a/scm/git.go b/scm/git.go index 847020932..5f0d9892a 100644 --- a/scm/git.go +++ b/scm/git.go @@ -72,6 +72,8 @@ type ( // ListBranches returns a list of git branches. ListBranches(ctx context.Context, repo string, opts ListOptions) ([]*Reference, *Response, error) + + // ListBranchesV2 returns a list of git branches based on the searchTerm passed. ListBranchesV2(ctx context.Context, repo string, opts BranchListOptions) ([]*Reference, *Response, error) // ListCommits returns a list of git commits. From 70cccf871a3ece31cf97fef21099f694749d7cb7 Mon Sep 17 00:00:00 2001 From: Adithya Viswanathan Date: Wed, 19 Jul 2023 15:31:06 +0530 Subject: [PATCH 072/195] [feat]: [CDS-73572]: Support List Repo Live Search for all git providers --- scm/client.go | 13 +++ scm/driver/azure/git_test.go | 4 +- scm/driver/azure/repo.go | 6 + ...anchesFilter.json => branches_filter.json} | 0 ...son.golden => branches_filter.json.golden} | 0 scm/driver/bitbucket/git_test.go | 13 +-- scm/driver/bitbucket/repo.go | 12 ++ scm/driver/bitbucket/repo_test.go | 31 +++++ ...anchesFilter.json => branches_filter.json} | 0 ...son.golden => branches_filter.json.golden} | 0 .../bitbucket/testdata/repos_filter.json | 110 ++++++++++++++++++ .../testdata/repos_filter.json.golden | 15 +++ scm/driver/bitbucket/util.go | 33 +++++- scm/driver/gitea/repo.go | 5 + scm/driver/gitee/repo.go | 4 + scm/driver/github/repo.go | 12 ++ scm/driver/github/repo_test.go | 42 +++++++ scm/driver/github/testdata/repos_filter.json | 107 +++++++++++++++++ .../github/testdata/repos_filter.json.golden | 20 ++++ scm/driver/github/util.go | 28 +++++ scm/driver/gitlab/git_test.go | 4 +- scm/driver/gitlab/repo.go | 8 ++ scm/driver/gitlab/repo_test.go | 39 +++++++ ...anchesFilter.json => branches_filter.json} | 0 ...son.golden => branches_filter.json.golden} | 0 scm/driver/gitlab/testdata/repos_filter.json | 59 ++++++++++ .../gitlab/testdata/repos_filter.json.golden | 20 ++++ scm/driver/gitlab/util.go | 31 ++++- scm/driver/gogs/repo.go | 5 + scm/driver/harness/repo.go | 5 + scm/driver/stash/git_test.go | 4 +- scm/driver/stash/repo.go | 12 ++ scm/driver/stash/repo_test.go | 41 +++++++ ...anchesFilter.json => branches_filter.json} | 0 ...son.golden => branches_filter.json.golden} | 0 scm/driver/stash/testdata/repos_filter.json | 49 ++++++++ .../stash/testdata/repos_filter.json.golden | 15 +++ scm/driver/stash/util.go | 37 ++++-- scm/repo.go | 3 + 39 files changed, 757 insertions(+), 30 deletions(-) rename scm/driver/azure/testdata/{branchesFilter.json => branches_filter.json} (100%) rename scm/driver/azure/testdata/{branchesFilter.json.golden => branches_filter.json.golden} (100%) rename scm/driver/bitbucket/testdata/{branchesFilter.json => branches_filter.json} (100%) rename scm/driver/bitbucket/testdata/{branchesFilter.json.golden => branches_filter.json.golden} (100%) create mode 100644 scm/driver/bitbucket/testdata/repos_filter.json create mode 100644 scm/driver/bitbucket/testdata/repos_filter.json.golden create mode 100644 scm/driver/github/testdata/repos_filter.json create mode 100644 scm/driver/github/testdata/repos_filter.json.golden rename scm/driver/gitlab/testdata/{branchesFilter.json => branches_filter.json} (100%) rename scm/driver/gitlab/testdata/{branchesFilter.json.golden => branches_filter.json.golden} (100%) create mode 100644 scm/driver/gitlab/testdata/repos_filter.json create mode 100644 scm/driver/gitlab/testdata/repos_filter.json.golden rename scm/driver/stash/testdata/{branchesFilter.json => branches_filter.json} (100%) rename scm/driver/stash/testdata/{branchesFilter.json.golden => branches_filter.json.golden} (100%) create mode 100644 scm/driver/stash/testdata/repos_filter.json create mode 100644 scm/driver/stash/testdata/repos_filter.json.golden diff --git a/scm/client.go b/scm/client.go index ca3d1cafc..0d05b3b9a 100644 --- a/scm/client.go +++ b/scm/client.go @@ -75,6 +75,19 @@ type ( PageListOptions ListOptions } + // RepoListOptions specifies optional repo search term and pagination + // parameters. + RepoListOptions struct { + ListOptions + RepoSearchTerm + } + + // RepoSearchTerm specifies searchable parameters. + RepoSearchTerm struct { + RepoName string + User string + } + // ListOptions specifies optional pagination // parameters. ListOptions struct { diff --git a/scm/driver/azure/git_test.go b/scm/driver/azure/git_test.go index 846e2b97b..f150dc38e 100644 --- a/scm/driver/azure/git_test.go +++ b/scm/driver/azure/git_test.go @@ -130,7 +130,7 @@ func TestGitListBranchesV2(t *testing.T) { Get("/ORG/PROJ/_apis/git/repositories/REPOID/"). Reply(200). Type("application/json"). - File("testdata/branchesFilter.json") + File("testdata/branches_filter.json") client := NewDefault("ORG", "PROJ") got, _, err := client.Git.ListBranchesV2(context.Background(), "REPOID", scm.BranchListOptions{SearchTerm: "main"}) @@ -140,7 +140,7 @@ func TestGitListBranchesV2(t *testing.T) { } want := []*scm.Reference{} - raw, _ := ioutil.ReadFile("testdata/branchesFilter.json.golden") + raw, _ := ioutil.ReadFile("testdata/branches_filter.json.golden") _ = json.Unmarshal(raw, &want) if diff := cmp.Diff(got, want); diff != "" { diff --git a/scm/driver/azure/repo.go b/scm/driver/azure/repo.go index 5d0427fa4..edfd4d876 100644 --- a/scm/driver/azure/repo.go +++ b/scm/driver/azure/repo.go @@ -56,6 +56,12 @@ func (s *RepositoryService) List(ctx context.Context, opts scm.ListOptions) ([]* return convertRepositoryList(out), res, err } +// ListV2 returns the user repository list. +func (s *RepositoryService) ListV2(ctx context.Context, opts scm.RepoListOptions) ([]*scm.Repository, *scm.Response, error) { + // Azure does not support search filters, hence calling List api without search filtering + return s.List(ctx, opts.ListOptions) +} + // ListHooks returns a list or repository hooks. 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 diff --git a/scm/driver/azure/testdata/branchesFilter.json b/scm/driver/azure/testdata/branches_filter.json similarity index 100% rename from scm/driver/azure/testdata/branchesFilter.json rename to scm/driver/azure/testdata/branches_filter.json diff --git a/scm/driver/azure/testdata/branchesFilter.json.golden b/scm/driver/azure/testdata/branches_filter.json.golden similarity index 100% rename from scm/driver/azure/testdata/branchesFilter.json.golden rename to scm/driver/azure/testdata/branches_filter.json.golden diff --git a/scm/driver/bitbucket/git_test.go b/scm/driver/bitbucket/git_test.go index 275707a0b..74928583f 100644 --- a/scm/driver/bitbucket/git_test.go +++ b/scm/driver/bitbucket/git_test.go @@ -216,20 +216,19 @@ func TestGitListBranchesV2(t *testing.T) { MatchParam("pagelen", "30"). Reply(200). Type("application/json"). - File("testdata/branchesFilter.json") + File("testdata/branches_filter.json") client, _ := New("https://api.bitbucket.org") - got, res, err := client.Git.ListBranchesV2(context.Background(), "atlassian/stash-example-plugin", scm.BranchListOptions{SearchTerm: "mast", PageListOptions: struct { - URL string - Page int - Size int - }{Page: 1, Size: 30}}) + got, res, err := client.Git.ListBranchesV2(context.Background(), "atlassian/stash-example-plugin", scm.BranchListOptions{ + SearchTerm: "mast", + PageListOptions: scm.ListOptions{Page: 1, Size: 30}, + }) if err != nil { t.Error(err) } want := []*scm.Reference{} - raw, _ := ioutil.ReadFile("testdata/branchesFilter.json.golden") + raw, _ := ioutil.ReadFile("testdata/branches_filter.json.golden") json.Unmarshal(raw, &want) if diff := cmp.Diff(got, want); diff != "" { diff --git a/scm/driver/bitbucket/repo.go b/scm/driver/bitbucket/repo.go index cccae00d5..5929f6080 100644 --- a/scm/driver/bitbucket/repo.go +++ b/scm/driver/bitbucket/repo.go @@ -105,6 +105,18 @@ func (s *repositoryService) List(ctx context.Context, opts scm.ListOptions) ([]* return convertRepositoryList(out), res, err } +// ListV2 returns the user repository list based on the searchTerm passed. +func (s *repositoryService) ListV2(ctx context.Context, opts scm.RepoListOptions) ([]*scm.Repository, *scm.Response, error) { + path := fmt.Sprintf("2.0/repositories?%s", encodeRepoListOptions(opts)) + if opts.ListOptions.URL != "" { + path = opts.ListOptions.URL + } + out := new(repositories) + res, err := s.client.do(ctx, "GET", path, nil, &out) + copyPagination(out.pagination, res) + return convertRepositoryList(out), res, err +} + // ListHooks returns a list or repository hooks. func (s *repositoryService) ListHooks(ctx context.Context, repo string, opts scm.ListOptions) ([]*scm.Hook, *scm.Response, error) { path := fmt.Sprintf("2.0/repositories/%s/hooks?%s", repo, encodeListOptions(opts)) diff --git a/scm/driver/bitbucket/repo_test.go b/scm/driver/bitbucket/repo_test.go index 8b8efd79d..6c1f02b1b 100644 --- a/scm/driver/bitbucket/repo_test.go +++ b/scm/driver/bitbucket/repo_test.go @@ -136,6 +136,37 @@ func TestRepositoryList(t *testing.T) { } } +func TestRepositoryListV2(t *testing.T) { + defer gock.Off() + + gock.New("https://api.bitbucket.org"). + Get("/2.0/repositories"). + MatchParam("q", "name~\\\"plugin1\\\""). + MatchParam("role", "member"). + Reply(200). + Type("application/json"). + File("testdata/repos_filter.json") + + got := []*scm.Repository{} + opts := scm.RepoListOptions{RepoSearchTerm: scm.RepoSearchTerm{RepoName: "plugin1"}} + client, _ := New("https://api.bitbucket.org") + + repos, _, err := client.Repositories.ListV2(context.Background(), opts) + if err != nil { + t.Error(err) + } + got = append(got, repos...) + + want := []*scm.Repository{} + raw, _ := ioutil.ReadFile("testdata/repos_filter.json.golden") + json.Unmarshal(raw, &want) + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } +} + func TestStatusList(t *testing.T) { defer gock.Off() diff --git a/scm/driver/bitbucket/testdata/branchesFilter.json b/scm/driver/bitbucket/testdata/branches_filter.json similarity index 100% rename from scm/driver/bitbucket/testdata/branchesFilter.json rename to scm/driver/bitbucket/testdata/branches_filter.json diff --git a/scm/driver/bitbucket/testdata/branchesFilter.json.golden b/scm/driver/bitbucket/testdata/branches_filter.json.golden similarity index 100% rename from scm/driver/bitbucket/testdata/branchesFilter.json.golden rename to scm/driver/bitbucket/testdata/branches_filter.json.golden diff --git a/scm/driver/bitbucket/testdata/repos_filter.json b/scm/driver/bitbucket/testdata/repos_filter.json new file mode 100644 index 000000000..df610e1f4 --- /dev/null +++ b/scm/driver/bitbucket/testdata/repos_filter.json @@ -0,0 +1,110 @@ +{ + "pagelen": 1, + "values": [ + { + "scm": "git", + "website": "", + "has_wiki": false, + "uuid": "{7dd600e6-0d9c-4801-b967-cb4cc17359ff}", + "links": { + "watchers": { + "href": "https:\/\/api.bitbucket.org\/2.0\/repositories\/atlassian\/stash-example-plugin1\/watchers" + }, + "branches": { + "href": "https:\/\/api.bitbucket.org\/2.0\/repositories\/atlassian\/stash-example-plugin1\/refs\/branches" + }, + "tags": { + "href": "https:\/\/api.bitbucket.org\/2.0\/repositories\/atlassian\/stash-example-plugin1\/refs\/tags" + }, + "commits": { + "href": "https:\/\/api.bitbucket.org\/2.0\/repositories\/atlassian\/stash-example-plugin1\/commits" + }, + "clone": [ + { + "href": "https:\/\/brydzewski@bitbucket.org\/atlassian\/stash-example-plugin1.git", + "name": "https" + }, + { + "href": "git@bitbucket.org:atlassian\/stash-example-plugin1.git", + "name": "ssh" + } + ], + "self": { + "href": "https:\/\/api.bitbucket.org\/2.0\/repositories\/atlassian\/stash-example-plugin1" + }, + "source": { + "href": "https:\/\/api.bitbucket.org\/2.0\/repositories\/atlassian\/stash-example-plugin1\/src" + }, + "html": { + "href": "https:\/\/bitbucket.org\/atlassian\/stash-example-plugin1" + }, + "avatar": { + "href": "https:\/\/bytebucket.org\/ravatar\/%7B7dd600e6-0d9c-4801-b967-cb4cc17359ff%7D?ts=default" + }, + "hooks": { + "href": "https:\/\/api.bitbucket.org\/2.0\/repositories\/atlassian\/stash-example-plugin1\/hooks" + }, + "forks": { + "href": "https:\/\/api.bitbucket.org\/2.0\/repositories\/atlassian\/stash-example-plugin1\/forks" + }, + "downloads": { + "href": "https:\/\/api.bitbucket.org\/2.0\/repositories\/atlassian\/stash-example-plugin1\/downloads" + }, + "pullrequests": { + "href": "https:\/\/api.bitbucket.org\/2.0\/repositories\/atlassian\/stash-example-plugin1\/pullrequests" + } + }, + "fork_policy": "allow_forks", + "name": "stash-example-plugin1", + "project": { + "key": "PROJ", + "type": "project", + "uuid": "{8b56daff-dbc7-4cae-a7a3-1228c526906b}", + "links": { + "self": { + "href": "https:\/\/api.bitbucket.org\/2.0\/teams\/atlassian\/projects\/PROJ" + }, + "html": { + "href": "https:\/\/bitbucket.org\/account\/user\/atlassian\/projects\/PROJ" + }, + "avatar": { + "href": "https:\/\/bitbucket.org\/account\/user\/atlassian\/projects\/PROJ\/avatar\/32" + } + }, + "name": "Project: Atlassian" + }, + "language": "", + "created_on": "2013-04-15T03:05:05.595458+00:00", + "mainbranch": { + "type": "branch", + "name": "master" + }, + "full_name": "atlassian\/stash-example-plugin1", + "has_issues": false, + "owner": { + "username": "atlassian", + "display_name": "Atlassian", + "type": "team", + "uuid": "{02b941e3-cfaa-40f9-9a58-cec53e20bdc3}", + "links": { + "self": { + "href": "https:\/\/api.bitbucket.org\/2.0\/teams\/atlassian" + }, + "html": { + "href": "https:\/\/bitbucket.org\/atlassian\/" + }, + "avatar": { + "href": "https:\/\/bitbucket.org\/account\/atlassian\/avatar\/32\/" + } + } + }, + "updated_on": "2018-04-01T16:36:35.970175+00:00", + "size": 1116345, + "type": "repository", + "slug": "stash-example-plugin1", + "is_private": true, + "description": "Examples on how to decorate various pages around Stash." + } + ], + "next": "https:\/\/api.bitbucket.org\/2.0\/repositories?pagelen=1&after=PLACEHOLDER&role=member" +} \ No newline at end of file diff --git a/scm/driver/bitbucket/testdata/repos_filter.json.golden b/scm/driver/bitbucket/testdata/repos_filter.json.golden new file mode 100644 index 000000000..cf1ace3ba --- /dev/null +++ b/scm/driver/bitbucket/testdata/repos_filter.json.golden @@ -0,0 +1,15 @@ +[ + { + "ID": "{7dd600e6-0d9c-4801-b967-cb4cc17359ff}", + "Namespace": "atlassian", + "Name": "stash-example-plugin1", + "Perm": null, + "Branch": "master", + "Private": true, + "Clone": "https://bitbucket.org/atlassian/stash-example-plugin1.git", + "CloneSSH": "git@bitbucket.org:atlassian/stash-example-plugin1.git", + "Link": "https://bitbucket.org/atlassian/stash-example-plugin1", + "Created": "2013-04-15T03:05:05.595458Z", + "Updated": "2018-04-01T16:36:35.970175Z" + } +] \ No newline at end of file diff --git a/scm/driver/bitbucket/util.go b/scm/driver/bitbucket/util.go index b53ba777c..e43ea71cf 100644 --- a/scm/driver/bitbucket/util.go +++ b/scm/driver/bitbucket/util.go @@ -34,11 +34,13 @@ func encodeBranchListOptions(opts scm.BranchListOptions) string { sb.WriteString("\"") params.Set("q", sb.String()) } - if opts.PageListOptions.Page != 0 { - params.Set("page", strconv.Itoa(opts.PageListOptions.Page)) - } - if opts.PageListOptions.Size != 0 { - params.Set("pagelen", strconv.Itoa(opts.PageListOptions.Size)) + if opts.PageListOptions != (scm.ListOptions{}) { + if opts.PageListOptions.Page != 0 { + params.Set("page", strconv.Itoa(opts.PageListOptions.Page)) + } + if opts.PageListOptions.Size != 0 { + params.Set("pagelen", strconv.Itoa(opts.PageListOptions.Size)) + } } return params.Encode() } @@ -66,6 +68,27 @@ func encodeListRoleOptions(opts scm.ListOptions) string { return params.Encode() } +func encodeRepoListOptions(opts scm.RepoListOptions) string { + params := url.Values{} + if opts.RepoSearchTerm.RepoName != "" { + var sb strings.Builder + sb.WriteString("name~\"") + sb.WriteString(opts.RepoSearchTerm.RepoName) + sb.WriteString("\"") + params.Set("q", sb.String()) + } + if opts.ListOptions != (scm.ListOptions{}) { + if opts.ListOptions.Page != 0 { + params.Set("page", strconv.Itoa(opts.ListOptions.Page)) + } + if opts.ListOptions.Size != 0 { + params.Set("pagelen", strconv.Itoa(opts.ListOptions.Size)) + } + } + params.Set("role", "member") + return params.Encode() +} + func encodeCommitListOptions(opts scm.CommitListOptions) string { params := url.Values{} if opts.Page != 0 { diff --git a/scm/driver/gitea/repo.go b/scm/driver/gitea/repo.go index 4a58ef2bc..a678273bf 100644 --- a/scm/driver/gitea/repo.go +++ b/scm/driver/gitea/repo.go @@ -46,6 +46,11 @@ func (s *repositoryService) List(ctx context.Context, opts scm.ListOptions) ([]* return convertRepositoryList(out), res, err } +func (s *repositoryService) ListV2(ctx context.Context, opts scm.RepoListOptions) ([]*scm.Repository, *scm.Response, error) { + // gitea does not support search filters, hence calling List api without search filtering + return s.List(ctx, opts.ListOptions) +} + func (s *repositoryService) ListHooks(ctx context.Context, repo string, opts scm.ListOptions) ([]*scm.Hook, *scm.Response, error) { path := fmt.Sprintf("api/v1/repos/%s/hooks?%s", repo, encodeListOptions(opts)) out := []*hook{} diff --git a/scm/driver/gitee/repo.go b/scm/driver/gitee/repo.go index fa14ab8ea..72c60f567 100644 --- a/scm/driver/gitee/repo.go +++ b/scm/driver/gitee/repo.go @@ -45,6 +45,10 @@ func (s *RepositoryService) List(ctx context.Context, opts scm.ListOptions) ([]* res, err := s.client.do(ctx, "GET", path, nil, &out) return convertRepositoryList(out), res, err } +func (s *RepositoryService) ListV2(ctx context.Context, opts scm.RepoListOptions) ([]*scm.Repository, *scm.Response, error) { + // gitee does not support search filters, hence calling List api without search filtering + return s.List(ctx, opts.ListOptions) +} func (s *RepositoryService) ListHooks(ctx context.Context, repo string, opts scm.ListOptions) ([]*scm.Hook, *scm.Response, error) { path := fmt.Sprintf("repos/%s/hooks?%s", repo, encodeListOptions(opts)) diff --git a/scm/driver/github/repo.go b/scm/driver/github/repo.go index cc781cb92..c9f09b7bc 100644 --- a/scm/driver/github/repo.go +++ b/scm/driver/github/repo.go @@ -40,6 +40,10 @@ type repository struct { } `json:"permissions"` } +type searchRepositoryList struct { + Repositories []*repository `json:"items"` +} + type hook struct { ID int `json:"id,omitempty"` Name string `json:"name"` @@ -110,6 +114,14 @@ func (s *RepositoryService) List(ctx context.Context, opts scm.ListOptions) ([]* return convertRepositoryList(out), res, err } +// ListV2 returns the user repository list based on the searchTerm passed. +func (s *RepositoryService) ListV2(ctx context.Context, opts scm.RepoListOptions) ([]*scm.Repository, *scm.Response, error) { + path := fmt.Sprintf("search/repositories?%s", encodeRepoListOptions(opts)) + out := new(searchRepositoryList) + res, err := s.client.do(ctx, "GET", path, nil, &out) + return convertRepositoryList(out.Repositories), res, err +} + // List returns the github app installation repository list. func (s *RepositoryService) ListByInstallation(ctx context.Context, opts scm.ListOptions) ([]*scm.Repository, *scm.Response, error) { path := fmt.Sprintf("installation/repositories?%s", encodeListOptions(opts)) diff --git a/scm/driver/github/repo_test.go b/scm/driver/github/repo_test.go index cd1d7f8b3..6af3dba6a 100644 --- a/scm/driver/github/repo_test.go +++ b/scm/driver/github/repo_test.go @@ -131,6 +131,48 @@ func TestRepositoryList(t *testing.T) { t.Run("Page", testPage(res)) } +func TestRepositoryListV2(t *testing.T) { + defer gock.Off() + + gock.New("https://api.github.com"). + Get("/search/repositories"). + MatchParam("q", "testRepoin:name"). + MatchParam("q", "user:user123"). + MatchParam("page", "1"). + MatchParam("per_page", "30"). + Reply(200). + Type("application/json"). + SetHeaders(mockHeaders). + SetHeaders(mockPageHeaders). + File("testdata/repos_filter.json") + + client := NewDefault() + got, res, err := client.Repositories.ListV2(context.Background(), scm.RepoListOptions{ + ListOptions: scm.ListOptions{Page: 1, Size: 30}, + RepoSearchTerm: scm.RepoSearchTerm{ + RepoName: "testRepo", + User: "user123", + }, + }) + if err != nil { + t.Error(err) + return + } + + want := []*scm.Repository{} + raw, _ := ioutil.ReadFile("testdata/repos_filter.json.golden") + _ = json.Unmarshal(raw, &want) + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } + + t.Run("Request", testRequest(res)) + t.Run("Rate", testRate(res)) + t.Run("Page", testPage(res)) +} + func TestGithubAppInstallationList(t *testing.T) { defer gock.Off() diff --git a/scm/driver/github/testdata/repos_filter.json b/scm/driver/github/testdata/repos_filter.json new file mode 100644 index 000000000..5e724c4a7 --- /dev/null +++ b/scm/driver/github/testdata/repos_filter.json @@ -0,0 +1,107 @@ +{ + "total_count": 5, + "incomplete_results": false, + "items": [ + { + "id": 508719340, + "node_id": "R_kgDOHlJw7A", + "name": "testRepo2", + "full_name": "user123/testRepo2", + "private": false, + "owner": { + "login": "user123", + "id": 103414561, + "node_id": "U_kgDOBin7IQ", + "avatar_url": "https://avatars.githubusercontent.com/u/103414561?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/user123", + "html_url": "https://github.com/user123", + "followers_url": "https://api.github.com/users/user123/followers", + "following_url": "https://api.github.com/users/user123/following{/other_user}", + "gists_url": "https://api.github.com/users/user123/gists{/gist_id}", + "starred_url": "https://api.github.com/users/user123/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/user123/subscriptions", + "organizations_url": "https://api.github.com/users/user123/orgs", + "repos_url": "https://api.github.com/users/user123/repos", + "events_url": "https://api.github.com/users/user123/events{/privacy}", + "received_events_url": "https://api.github.com/users/user123/received_events", + "type": "User", + "site_admin": false + }, + "html_url": "https://github.com/user123/testRepo2", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/user123/testRepo2", + "forks_url": "https://api.github.com/repos/user123/testRepo2/forks", + "keys_url": "https://api.github.com/repos/user123/testRepo2/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/user123/testRepo2/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/user123/testRepo2/teams", + "hooks_url": "https://api.github.com/repos/user123/testRepo2/hooks", + "issue_events_url": "https://api.github.com/repos/user123/testRepo2/issues/events{/number}", + "events_url": "https://api.github.com/repos/user123/testRepo2/events", + "assignees_url": "https://api.github.com/repos/user123/testRepo2/assignees{/user}", + "branches_url": "https://api.github.com/repos/user123/testRepo2/branches{/branch}", + "tags_url": "https://api.github.com/repos/user123/testRepo2/tags", + "blobs_url": "https://api.github.com/repos/user123/testRepo2/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/user123/testRepo2/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/user123/testRepo2/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/user123/testRepo2/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/user123/testRepo2/statuses/{sha}", + "languages_url": "https://api.github.com/repos/user123/testRepo2/languages", + "stargazers_url": "https://api.github.com/repos/user123/testRepo2/stargazers", + "contributors_url": "https://api.github.com/repos/user123/testRepo2/contributors", + "subscribers_url": "https://api.github.com/repos/user123/testRepo2/subscribers", + "subscription_url": "https://api.github.com/repos/user123/testRepo2/subscription", + "commits_url": "https://api.github.com/repos/user123/testRepo2/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/user123/testRepo2/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/user123/testRepo2/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/user123/testRepo2/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/user123/testRepo2/contents/{+path}", + "compare_url": "https://api.github.com/repos/user123/testRepo2/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/user123/testRepo2/merges", + "archive_url": "https://api.github.com/repos/user123/testRepo2/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/user123/testRepo2/downloads", + "issues_url": "https://api.github.com/repos/user123/testRepo2/issues{/number}", + "pulls_url": "https://api.github.com/repos/user123/testRepo2/pulls{/number}", + "milestones_url": "https://api.github.com/repos/user123/testRepo2/milestones{/number}", + "notifications_url": "https://api.github.com/repos/user123/testRepo2/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/user123/testRepo2/labels{/name}", + "releases_url": "https://api.github.com/repos/user123/testRepo2/releases{/id}", + "deployments_url": "https://api.github.com/repos/user123/testRepo2/deployments", + "created_at": "2022-06-29T14:11:36Z", + "updated_at": "2023-06-27T07:10:05Z", + "pushed_at": "2023-06-07T05:36:36Z", + "git_url": "git://github.com/user123/testRepo2.git", + "ssh_url": "git@github.com:user123/testRepo2.git", + "clone_url": "https://github.com/user123/testRepo2.git", + "svn_url": "https://github.com/user123/testRepo2", + "homepage": null, + "size": 53, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "has_discussions": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 2, + "license": null, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [], + "visibility": "public", + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "main", + "score": 1.0 + } + ] +} \ No newline at end of file diff --git a/scm/driver/github/testdata/repos_filter.json.golden b/scm/driver/github/testdata/repos_filter.json.golden new file mode 100644 index 000000000..bb164132f --- /dev/null +++ b/scm/driver/github/testdata/repos_filter.json.golden @@ -0,0 +1,20 @@ +[ + { + "ID": "508719340", + "Namespace": "user123", + "Name": "testRepo2", + "Perm": { + "Pull": false, + "Push": false, + "Admin": false + }, + "Branch": "main", + "Private": false, + "Visibility": 1, + "Clone": "https://github.com/user123/testRepo2.git", + "CloneSSH": "git@github.com:user123/testRepo2.git", + "Link": "https://github.com/user123/testRepo2", + "Created": "2022-06-29T14:11:36Z", + "Updated": "2023-06-27T07:10:05Z" + } +] \ No newline at end of file diff --git a/scm/driver/github/util.go b/scm/driver/github/util.go index 5d5fb4741..d06e474e0 100644 --- a/scm/driver/github/util.go +++ b/scm/driver/github/util.go @@ -7,6 +7,7 @@ package github import ( "net/url" "strconv" + "strings" "github.com/drone/go-scm/scm" ) @@ -22,6 +23,33 @@ func encodeListOptions(opts scm.ListOptions) string { return params.Encode() } +func encodeRepoListOptions(opts scm.RepoListOptions) string { + var sb strings.Builder + if opts.RepoSearchTerm != (scm.RepoSearchTerm{}) { + if opts.RepoSearchTerm.RepoName != "" { + sb.WriteString("q=") + sb.WriteString(opts.RepoSearchTerm.RepoName) + sb.WriteString("in:name+user:") + sb.WriteString(opts.RepoSearchTerm.User) + } else { + sb.WriteString("q=") + sb.WriteString("user:") + sb.WriteString(opts.RepoSearchTerm.User) + } + } + if opts.ListOptions != (scm.ListOptions{}) { + if opts.ListOptions.Page != 0 { + sb.WriteString("&page=") + sb.WriteString(strconv.Itoa(opts.ListOptions.Page)) + } + if opts.ListOptions.Size != 0 { + sb.WriteString("&per_page=") + sb.WriteString(strconv.Itoa(opts.ListOptions.Size)) + } + } + return sb.String() +} + func encodeCommitListOptions(opts scm.CommitListOptions) string { params := url.Values{} if opts.Page != 0 { diff --git a/scm/driver/gitlab/git_test.go b/scm/driver/gitlab/git_test.go index ee4595398..49fefee66 100644 --- a/scm/driver/gitlab/git_test.go +++ b/scm/driver/gitlab/git_test.go @@ -215,7 +215,7 @@ func TestGitListBranchesWithBranchFilter(t *testing.T) { Type("application/json"). SetHeaders(mockHeaders). SetHeaders(mockPageHeaders). - File("testdata/branchesFilter.json") + File("testdata/branches_filter.json") client := NewDefault() got, res, err := client.Git.ListBranchesV2(context.Background(), "diaspora/diaspora", scm.BranchListOptions{SearchTerm: "mast"}) @@ -225,7 +225,7 @@ func TestGitListBranchesWithBranchFilter(t *testing.T) { } want := []*scm.Reference{} - raw, _ := ioutil.ReadFile("testdata/branchesFilter.json.golden") + raw, _ := ioutil.ReadFile("testdata/branches_filter.json.golden") json.Unmarshal(raw, &want) if diff := cmp.Diff(got, want); diff != "" { diff --git a/scm/driver/gitlab/repo.go b/scm/driver/gitlab/repo.go index 23a04ffc6..dc6f39a7e 100644 --- a/scm/driver/gitlab/repo.go +++ b/scm/driver/gitlab/repo.go @@ -94,6 +94,14 @@ func (s *repositoryService) List(ctx context.Context, opts scm.ListOptions) ([]* return convertRepositoryList(out), res, err } +func (s *repositoryService) ListV2(ctx context.Context, opts scm.RepoListOptions) ([]*scm.Repository, *scm.Response, error) { + // We pass the repo searchTerm in the query params and gitlab filters repos based on this search term + path := fmt.Sprintf("api/v4/projects?%s", encodeRepoListOptions(opts)) + out := []*repository{} + res, err := s.client.do(ctx, "GET", path, nil, &out) + return convertRepositoryList(out), res, err +} + func (s *repositoryService) ListHooks(ctx context.Context, repo string, opts scm.ListOptions) ([]*scm.Hook, *scm.Response, error) { path := fmt.Sprintf("api/v4/projects/%s/hooks?%s", encode(repo), encodeListOptions(opts)) out := []*hook{} diff --git a/scm/driver/gitlab/repo_test.go b/scm/driver/gitlab/repo_test.go index 48e21db6b..293e523ff 100644 --- a/scm/driver/gitlab/repo_test.go +++ b/scm/driver/gitlab/repo_test.go @@ -163,6 +163,45 @@ func TestRepositoryList(t *testing.T) { t.Run("Page", testPage(res)) } +func TestRepositoryListV2(t *testing.T) { + defer gock.Off() + + gock.New("https://gitlab.com"). + Get("/api/v4/projects"). + MatchParam("search", "diaspora"). + MatchParam("page", "1"). + MatchParam("per_page", "30"). + MatchParam("membership", "true"). + Reply(200). + Type("application/json"). + SetHeaders(mockHeaders). + SetHeaders(mockPageHeaders). + File("testdata/repos_filter.json") + + client := NewDefault() + got, res, err := client.Repositories.ListV2(context.Background(), scm.RepoListOptions{ + ListOptions: scm.ListOptions{Page: 1, Size: 30}, + RepoSearchTerm: scm.RepoSearchTerm{RepoName: "diaspora"}, + }) + if err != nil { + t.Error(err) + return + } + + want := []*scm.Repository{} + raw, _ := ioutil.ReadFile("testdata/repos_filter.json.golden") + json.Unmarshal(raw, &want) + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } + + t.Run("Request", testRequest(res)) + t.Run("Rate", testRate(res)) + t.Run("Page", testPage(res)) +} + func TestStatusList(t *testing.T) { defer gock.Off() diff --git a/scm/driver/gitlab/testdata/branchesFilter.json b/scm/driver/gitlab/testdata/branches_filter.json similarity index 100% rename from scm/driver/gitlab/testdata/branchesFilter.json rename to scm/driver/gitlab/testdata/branches_filter.json diff --git a/scm/driver/gitlab/testdata/branchesFilter.json.golden b/scm/driver/gitlab/testdata/branches_filter.json.golden similarity index 100% rename from scm/driver/gitlab/testdata/branchesFilter.json.golden rename to scm/driver/gitlab/testdata/branches_filter.json.golden diff --git a/scm/driver/gitlab/testdata/repos_filter.json b/scm/driver/gitlab/testdata/repos_filter.json new file mode 100644 index 000000000..13f8b4de3 --- /dev/null +++ b/scm/driver/gitlab/testdata/repos_filter.json @@ -0,0 +1,59 @@ +[ + { + "id": 178504, + "description": "", + "default_branch": "master", + "tag_list": [], + "ssh_url_to_repo": "git@gitlab.com:diaspora/diaspora.git", + "http_url_to_repo": "https://gitlab.com/diaspora/diaspora.git", + "web_url": "https://gitlab.com/diaspora/diaspora", + "name": "Diaspora", + "name_with_namespace": "diaspora / Diaspora", + "path": "diaspora", + "path_with_namespace": "diaspora/diaspora", + "avatar_url": null, + "star_count": 0, + "forks_count": 0, + "created_at": "2015-03-03T18:37:05.387Z", + "last_activity_at": "2015-03-03T18:37:20.795Z", + "_links": { + "self": "http://gitlab.com/api/v4/projects/178504", + "issues": "http://gitlab.com/api/v4/projects/178504/issues", + "merge_requests": "http://gitlab.com/api/v4/projects/178504/merge_requests", + "repo_branches": "http://gitlab.com/api/v4/projects/178504/repository/branches", + "labels": "http://gitlab.com/api/v4/projects/178504/labels", + "events": "http://gitlab.com/api/v4/projects/178504/events", + "members": "http://gitlab.com/api/v4/projects/178504/members" + }, + "archived": false, + "visibility": "public", + "resolve_outdated_diff_discussions": null, + "container_registry_enabled": null, + "issues_enabled": true, + "merge_requests_enabled": true, + "wiki_enabled": true, + "jobs_enabled": true, + "snippets_enabled": false, + "shared_runners_enabled": true, + "lfs_enabled": true, + "creator_id": 57658, + "namespace": { + "id": 120836, + "name": "diaspora", + "path": "diaspora", + "kind": "group", + "full_path": "diaspora", + "parent_id": null + }, + "import_status": "finished", + "open_issues_count": 0, + "public_jobs": true, + "ci_config_path": null, + "shared_with_groups": [], + "only_allow_merge_if_pipeline_succeeds": false, + "request_access_enabled": true, + "only_allow_merge_if_all_discussions_are_resolved": null, + "printing_merge_request_link_enabled": true, + "approvals_before_merge": 0 + } +] \ No newline at end of file diff --git a/scm/driver/gitlab/testdata/repos_filter.json.golden b/scm/driver/gitlab/testdata/repos_filter.json.golden new file mode 100644 index 000000000..5780a5ebd --- /dev/null +++ b/scm/driver/gitlab/testdata/repos_filter.json.golden @@ -0,0 +1,20 @@ +[ + { + "ID": "178504", + "Namespace": "diaspora", + "Name": "diaspora", + "Perm": { + "Pull": true, + "Push": false, + "Admin": false + }, + "Branch": "master", + "Private": false, + "Visibility": 1, + "Clone": "https://gitlab.com/diaspora/diaspora.git", + "CloneSSH": "git@gitlab.com:diaspora/diaspora.git", + "Link": "https://gitlab.com/diaspora/diaspora", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + } +] \ No newline at end of file diff --git a/scm/driver/gitlab/util.go b/scm/driver/gitlab/util.go index 55f106f71..eb3f06893 100644 --- a/scm/driver/gitlab/util.go +++ b/scm/driver/gitlab/util.go @@ -29,11 +29,13 @@ func encodeBranchListOptions(opts scm.BranchListOptions) string { if opts.SearchTerm != "" { params.Set("search", opts.SearchTerm) } - if opts.PageListOptions.Page != 0 { - params.Set("page", strconv.Itoa(opts.PageListOptions.Page)) - } - if opts.PageListOptions.Size != 0 { - params.Set("per_page", strconv.Itoa(opts.PageListOptions.Size)) + if opts.PageListOptions != (scm.ListOptions{}) { + if opts.PageListOptions.Page != 0 { + params.Set("page", strconv.Itoa(opts.PageListOptions.Page)) + } + if opts.PageListOptions.Size != 0 { + params.Set("per_page", strconv.Itoa(opts.PageListOptions.Size)) + } } return params.Encode() } @@ -61,6 +63,25 @@ func encodeMemberListOptions(opts scm.ListOptions) string { return params.Encode() } +func encodeRepoListOptions(opts scm.RepoListOptions) string { + params := url.Values{} + params.Set("membership", "true") + if opts.RepoSearchTerm != (scm.RepoSearchTerm{}) { + if opts.RepoSearchTerm.RepoName != "" { + params.Set("search", opts.RepoSearchTerm.RepoName) + } + } + if opts.ListOptions != (scm.ListOptions{}) { + if opts.ListOptions.Page != 0 { + params.Set("page", strconv.Itoa(opts.ListOptions.Page)) + } + if opts.ListOptions.Size != 0 { + params.Set("per_page", strconv.Itoa(opts.ListOptions.Size)) + } + } + return params.Encode() +} + func encodeCommitListOptions(opts scm.CommitListOptions) string { params := url.Values{} if opts.Page != 0 { diff --git a/scm/driver/gogs/repo.go b/scm/driver/gogs/repo.go index d2a29fb3c..5657b5ee7 100644 --- a/scm/driver/gogs/repo.go +++ b/scm/driver/gogs/repo.go @@ -45,6 +45,11 @@ func (s *repositoryService) List(ctx context.Context, _ scm.ListOptions) ([]*scm return convertRepositoryList(out), res, err } +func (s *repositoryService) ListV2(ctx context.Context, opts scm.RepoListOptions) ([]*scm.Repository, *scm.Response, error) { + // Azure does not support search filters, hence calling List api without search filtering + return s.List(ctx, opts.ListOptions) +} + func (s *repositoryService) ListHooks(ctx context.Context, repo string, _ scm.ListOptions) ([]*scm.Hook, *scm.Response, error) { path := fmt.Sprintf("api/v1/repos/%s/hooks", repo) out := []*hook{} diff --git a/scm/driver/harness/repo.go b/scm/driver/harness/repo.go index a55089516..da4237555 100644 --- a/scm/driver/harness/repo.go +++ b/scm/driver/harness/repo.go @@ -52,6 +52,11 @@ func (s *repositoryService) List(ctx context.Context, opts scm.ListOptions) ([]* return convertRepositoryList(out), res, err } +func (s *repositoryService) ListV2(ctx context.Context, opts scm.RepoListOptions) ([]*scm.Repository, *scm.Response, error) { + // harness does not support search filters, hence calling List api without search filtering + return s.List(ctx, opts.ListOptions) +} + func (s *repositoryService) ListHooks(ctx context.Context, repo string, opts scm.ListOptions) ([]*scm.Hook, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) path := fmt.Sprintf("api/v1/repos/%s/webhooks?sort=display_name&order=asc&%s", harnessURI, encodeListOptions(opts)) diff --git a/scm/driver/stash/git_test.go b/scm/driver/stash/git_test.go index 720e8fa6f..f93952ace 100644 --- a/scm/driver/stash/git_test.go +++ b/scm/driver/stash/git_test.go @@ -155,7 +155,7 @@ func TestGitListBranchesWithBranchFilter(t *testing.T) { MatchParam("filterText", "mast"). Reply(200). Type("application/json"). - File("testdata/branchesFilter.json") + File("testdata/branches_filter.json") client, _ := New("http://example.com:7990") got, _, err := client.Git.ListBranchesV2(context.Background(), "PRJ/my-repo", scm.BranchListOptions{SearchTerm: "mast"}) @@ -164,7 +164,7 @@ func TestGitListBranchesWithBranchFilter(t *testing.T) { } want := []*scm.Reference{} - raw, _ := ioutil.ReadFile("testdata/branchesFilter.json.golden") + raw, _ := ioutil.ReadFile("testdata/branches_filter.json.golden") _ = json.Unmarshal(raw, &want) if diff := cmp.Diff(got, want); diff != "" { diff --git a/scm/driver/stash/repo.go b/scm/driver/stash/repo.go index 070bfd373..33ba4bc42 100644 --- a/scm/driver/stash/repo.go +++ b/scm/driver/stash/repo.go @@ -180,6 +180,18 @@ func (s *repositoryService) List(ctx context.Context, opts scm.ListOptions) ([]* return convertRepositoryList(out), res, err } +// ListV2 returns the user repository list based on the searchTerm passed. +func (s *repositoryService) ListV2(ctx context.Context, opts scm.RepoListOptions) ([]*scm.Repository, *scm.Response, error) { + path := fmt.Sprintf("rest/api/1.0/repos?%s", encodeRepoListOptions(opts)) + out := new(repositories) + res, err := s.client.do(ctx, "GET", path, nil, &out) + if res != nil && !out.pagination.LastPage.Bool { + res.Page.First = 1 + res.Page.Next = opts.ListOptions.Page + 1 + } + return convertRepositoryList(out), res, err +} + // listWrite returns the user repository list. func (s *repositoryService) listWrite(ctx context.Context, repo string) ([]*scm.Repository, *scm.Response, error) { _, name := scm.Split(repo) diff --git a/scm/driver/stash/repo_test.go b/scm/driver/stash/repo_test.go index ee337dc24..ff7138df1 100644 --- a/scm/driver/stash/repo_test.go +++ b/scm/driver/stash/repo_test.go @@ -319,6 +319,47 @@ func TestRepositoryList(t *testing.T) { } } +func TestRepositoryListV2(t *testing.T) { + defer gock.Off() + + gock.New("http://example.com:7990"). + Get("/rest/api/1.0/repos"). + MatchParam("name", "quux"). + MatchParam("limit", "25"). + MatchParam("start", "50"). + MatchParam("permission", "REPO_READ"). + Reply(200). + Type("application/json"). + File("testdata/repos_filter.json") + + client, _ := New("http://example.com:7990") + got, res, err := client.Repositories.ListV2(context.Background(), scm.RepoListOptions{ + ListOptions: scm.ListOptions{Page: 3, Size: 25}, + RepoSearchTerm: scm.RepoSearchTerm{ + RepoName: "quux", + }, + }) + if err != nil { + t.Error(err) + } + + if got, want := res.Page.First, 1; got != want { + t.Errorf("Want Page.First %d, got %d", want, got) + } + if got, want := res.Page.Next, 4; got != want { + t.Errorf("Want Page.Next %d, got %d", want, got) + } + + want := []*scm.Repository{} + raw, _ := ioutil.ReadFile("testdata/repos_filter.json.golden") + _ = json.Unmarshal(raw, &want) + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } +} + func TestStatusList(t *testing.T) { client, _ := New("http://example.com:7990") _, _, err := client.Repositories.ListStatus(context.Background(), "PRJ/my-repo", "a6e5e7d797edf751cbd839d6bd4aef86c941eec9", scm.ListOptions{Size: 30, Page: 1}) diff --git a/scm/driver/stash/testdata/branchesFilter.json b/scm/driver/stash/testdata/branches_filter.json similarity index 100% rename from scm/driver/stash/testdata/branchesFilter.json rename to scm/driver/stash/testdata/branches_filter.json diff --git a/scm/driver/stash/testdata/branchesFilter.json.golden b/scm/driver/stash/testdata/branches_filter.json.golden similarity index 100% rename from scm/driver/stash/testdata/branchesFilter.json.golden rename to scm/driver/stash/testdata/branches_filter.json.golden diff --git a/scm/driver/stash/testdata/repos_filter.json b/scm/driver/stash/testdata/repos_filter.json new file mode 100644 index 000000000..80bb1c9a4 --- /dev/null +++ b/scm/driver/stash/testdata/repos_filter.json @@ -0,0 +1,49 @@ +{ + "size": 25, + "limit": 25, + "isLastPage": false, + "values": [ + { + "slug": "quux", + "id": 2, + "name": "quux", + "scmId": "git", + "state": "AVAILABLE", + "statusMessage": "Available", + "forkable": true, + "project": { + "key": "PRJ", + "id": 2, + "name": "different_name", + "public": false, + "type": "NORMAL", + "links": { + "self": [ + { + "href": "http://example.com:7990/projects/PRJ" + } + ] + } + }, + "public": false, + "links": { + "clone": [ + { + "href": "ssh://git@example.com:7999/prj/quux.git", + "name": "ssh" + }, + { + "href": "http://jcitizen@example.com:7990/scm/prj/quux.git", + "name": "http" + } + ], + "self": [ + { + "href": "http://example.com:7990/projects/PRJ/repos/quux/browse" + } + ] + } + } + ], + "start": 0 +} \ No newline at end of file diff --git a/scm/driver/stash/testdata/repos_filter.json.golden b/scm/driver/stash/testdata/repos_filter.json.golden new file mode 100644 index 000000000..34ff2307b --- /dev/null +++ b/scm/driver/stash/testdata/repos_filter.json.golden @@ -0,0 +1,15 @@ +[ + { + "ID": "2", + "Namespace": "PRJ", + "Name": "quux", + "Perm": null, + "Branch": "master", + "Private": true, + "Clone": "http://example.com:7990/scm/prj/quux.git", + "CloneSSH": "ssh://git@example.com:7999/prj/quux.git", + "Link": "http://example.com:7990/projects/PRJ/repos/quux/browse", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + } +] \ No newline at end of file diff --git a/scm/driver/stash/util.go b/scm/driver/stash/util.go index 0de82e3fa..1dbcb71e8 100644 --- a/scm/driver/stash/util.go +++ b/scm/driver/stash/util.go @@ -30,13 +30,15 @@ func encodeBranchListOptions(opts scm.BranchListOptions) string { if opts.SearchTerm != "" { params.Set("filterText", opts.SearchTerm) } - if opts.PageListOptions.Page > 1 { - params.Set("start", strconv.Itoa( - (opts.PageListOptions.Page-1)*opts.PageListOptions.Size), - ) - } - if opts.PageListOptions.Size != 0 { - params.Set("limit", strconv.Itoa(opts.PageListOptions.Size)) + if opts.PageListOptions != (scm.ListOptions{}) { + if opts.PageListOptions.Page > 1 { + params.Set("start", strconv.Itoa( + (opts.PageListOptions.Page-1)*opts.PageListOptions.Size), + ) + } + if opts.PageListOptions.Size != 0 { + params.Set("limit", strconv.Itoa(opts.PageListOptions.Size)) + } } return params.Encode() } @@ -55,6 +57,27 @@ func encodeListRoleOptions(opts scm.ListOptions) string { return params.Encode() } +func encodeRepoListOptions(opts scm.RepoListOptions) string { + params := url.Values{} + if opts.RepoSearchTerm != (scm.RepoSearchTerm{}) { + if opts.RepoSearchTerm.RepoName != "" { + params.Set("name", opts.RepoSearchTerm.RepoName) + } + } + if opts.ListOptions != (scm.ListOptions{}) { + if opts.ListOptions.Page > 1 { + params.Set("start", strconv.Itoa( + (opts.ListOptions.Page-1)*opts.ListOptions.Size), + ) + } + if opts.ListOptions.Size != 0 { + params.Set("limit", strconv.Itoa(opts.ListOptions.Size)) + } + } + params.Set("permission", "REPO_READ") + return params.Encode() +} + func encodePullRequestListOptions(opts scm.PullRequestListOptions) string { params := url.Values{} if opts.Page > 1 { diff --git a/scm/repo.go b/scm/repo.go index b62b53755..1e6218fdc 100644 --- a/scm/repo.go +++ b/scm/repo.go @@ -120,6 +120,9 @@ type ( // List returns a list of repositories. List(context.Context, ListOptions) ([]*Repository, *Response, error) + // ListV2 returns a list of repositories based on the searchTerm passed. + ListV2(context.Context, RepoListOptions) ([]*Repository, *Response, error) + // ListHooks returns a list or repository hooks. ListHooks(context.Context, string, ListOptions) ([]*Hook, *Response, error) From d86848a9e2816cb48647424cfb0ef7b7a0f99926 Mon Sep 17 00:00:00 2001 From: Abhinav Singh Date: Tue, 8 Aug 2023 04:06:58 -0700 Subject: [PATCH 073/195] fix: [CODE-727]: change to gitness from harness --- scm/driver/harness/webhook.go | 4 ++-- scm/driver/harness/webhook_test.go | 2 +- scm/repo.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scm/driver/harness/webhook.go b/scm/driver/harness/webhook.go index fc89148e5..514ddaafa 100644 --- a/scm/driver/harness/webhook.go +++ b/scm/driver/harness/webhook.go @@ -29,7 +29,7 @@ func (s *webhookService) Parse(req *http.Request, fn scm.SecretFunc) (scm.Webhoo } var hook scm.Webhook - switch req.Header.Get("X-Harness-Trigger") { + switch req.Header.Get("X-Gitness-Trigger") { // case "create": // hook, err = s.parseCreateHook(data) // case "delete": @@ -58,7 +58,7 @@ func (s *webhookService) Parse(req *http.Request, fn scm.SecretFunc) (scm.Webhoo } secret := req.FormValue("secret") - signature := req.Header.Get("X-Harness-Signature") + signature := req.Header.Get("X-Gitness-Signature") // fail if no signature passed if signature == "" && secret == "" { diff --git a/scm/driver/harness/webhook_test.go b/scm/driver/harness/webhook_test.go index 4e38687be..48f66daeb 100644 --- a/scm/driver/harness/webhook_test.go +++ b/scm/driver/harness/webhook_test.go @@ -73,7 +73,7 @@ func TestWebhooks(t *testing.T) { buf := bytes.NewBuffer(before) r, _ := http.NewRequest("GET", "/", buf) - r.Header.Set("X-Harness-Trigger", test.event) + r.Header.Set("X-Gitness-Trigger", test.event) s := new(webhookService) o, err := s.Parse(r, secretFunc) diff --git a/scm/repo.go b/scm/repo.go index b62b53755..d7332dbaa 100644 --- a/scm/repo.go +++ b/scm/repo.go @@ -121,7 +121,7 @@ type ( List(context.Context, ListOptions) ([]*Repository, *Response, error) // ListHooks returns a list or repository hooks. - ListHooks(context.Context, string, ListOptions) ([]*Hook, *Response, error) + s(context.Context, string, ListOptions) ([]*Hook, *Response, error) // ListStatus returns a list of commit statuses. ListStatus(context.Context, string, string, ListOptions) ([]*Status, *Response, error) From d363e65a819bed336867c40868605a97a130ac0c Mon Sep 17 00:00:00 2001 From: Abhinav Singh Date: Tue, 8 Aug 2023 04:07:30 -0700 Subject: [PATCH 074/195] fix: [CODE-727]: change to gitness from harness --- scm/repo.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm/repo.go b/scm/repo.go index d7332dbaa..b62b53755 100644 --- a/scm/repo.go +++ b/scm/repo.go @@ -121,7 +121,7 @@ type ( List(context.Context, ListOptions) ([]*Repository, *Response, error) // ListHooks returns a list or repository hooks. - s(context.Context, string, ListOptions) ([]*Hook, *Response, error) + ListHooks(context.Context, string, ListOptions) ([]*Hook, *Response, error) // ListStatus returns a list of commit statuses. ListStatus(context.Context, string, string, ListOptions) ([]*Status, *Response, error) From 0f7857f595d60863eaa512e3c9d6613059d7aefa Mon Sep 17 00:00:00 2001 From: Dheeraj Kumar Date: Thu, 10 Aug 2023 22:06:16 +0530 Subject: [PATCH 075/195] Implemented FindMembership method in organization service for gitea driver (#263) * implementation of FindMembership method in organization service for gitea driver * gitea driver testcase for organization membership --- scm/driver/gitea/org.go | 44 ++++++++++++++++++- scm/driver/gitea/org_test.go | 27 ++++++++++-- .../gitea/testdata/membership.json.golden | 4 ++ scm/driver/gitea/testdata/permissions.json | 7 +++ 4 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 scm/driver/gitea/testdata/membership.json.golden create mode 100644 scm/driver/gitea/testdata/permissions.json diff --git a/scm/driver/gitea/org.go b/scm/driver/gitea/org.go index c7c7efc03..6ca8ec7ea 100644 --- a/scm/driver/gitea/org.go +++ b/scm/driver/gitea/org.go @@ -23,7 +23,13 @@ func (s *organizationService) Find(ctx context.Context, name string) (*scm.Organ } func (s *organizationService) FindMembership(ctx context.Context, name, username string) (*scm.Membership, *scm.Response, error) { - return nil, nil, scm.ErrNotSupported + membership := new(membership) + membership.Active = s.checkMembership(ctx, name, username) + out := new(permissions) + path := fmt.Sprintf("api/v1/users/%s/orgs/%s/permissions", username, name) + res, err := s.client.do(ctx, "GET", path, nil, out) + membership.Permissions = out + return convertMembership(membership), res, err } func (s *organizationService) List(ctx context.Context, opts scm.ListOptions) ([]*scm.Organization, *scm.Response, error) { @@ -33,6 +39,18 @@ func (s *organizationService) List(ctx context.Context, opts scm.ListOptions) ([ return convertOrgList(out), res, err } +type permissions struct { + IsOwner bool `json:"is_owner"` + IsAdmin bool `json:"is_admin"` + CanWrite bool `json:"can_write"` + CanRead bool `json:"can_read"` + CanCreateRepository bool `json:"can_create_repository"` +} +type membership struct { + Permissions *permissions + Active bool +} + // // native data structures // @@ -60,3 +78,27 @@ func convertOrg(from *org) *scm.Organization { Avatar: from.Avatar, } } + +func (s *organizationService) checkMembership(ctx context.Context, name, username string) bool { + path := fmt.Sprintf("api/v1/orgs/%s/members/%s", name, username) + res, err := s.client.do(ctx, "GET", path, nil, nil) + if err != nil { + return false + } + return res.Status == 204 +} + +func convertMembership(from *membership) *scm.Membership { + to := new(scm.Membership) + to.Active = from.Active + isAdmin := from.Permissions.IsAdmin + isMember := from.Permissions.CanRead || from.Permissions.CanWrite || from.Permissions.CanCreateRepository + if isAdmin { + to.Role = scm.RoleAdmin + } else if isMember { + to.Role = scm.RoleMember + } else { + to.Role = scm.RoleUndefined + } + return to +} diff --git a/scm/driver/gitea/org_test.go b/scm/driver/gitea/org_test.go index 90a0a193c..ceaba401b 100644 --- a/scm/driver/gitea/org_test.go +++ b/scm/driver/gitea/org_test.go @@ -42,10 +42,31 @@ func TestOrgFind(t *testing.T) { } func TestOrganizationFindMembership(t *testing.T) { + defer gock.Off() + + gock.New("https://try.gitea.io"). + Get("/api/v1/orgs/gogits/members/jcitizen"). + Reply(204) + + gock.New("https://try.gitea.io"). + Get("/api/v1/users/jcitizen/orgs/gogits/permissions"). + Reply(200). + Type("application/json"). + File("testdata/permissions.json") + client, _ := New("https://try.gitea.io") - _, _, err := client.Organizations.FindMembership(context.Background(), "gogits", "jcitizen") - if err != scm.ErrNotSupported { - t.Errorf("Expect Not Supported error") + got, _, err := client.Organizations.FindMembership(context.Background(), "gogits", "jcitizen") + if err != nil { + t.Error(err) + } + + want := new(scm.Membership) + raw, _ := ioutil.ReadFile("testdata/membership.json.golden") + json.Unmarshal(raw, &want) + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) } } diff --git a/scm/driver/gitea/testdata/membership.json.golden b/scm/driver/gitea/testdata/membership.json.golden new file mode 100644 index 000000000..96ec5685e --- /dev/null +++ b/scm/driver/gitea/testdata/membership.json.golden @@ -0,0 +1,4 @@ +{ + "Active": true, + "Role": 2 +} \ No newline at end of file diff --git a/scm/driver/gitea/testdata/permissions.json b/scm/driver/gitea/testdata/permissions.json new file mode 100644 index 000000000..77e2cff85 --- /dev/null +++ b/scm/driver/gitea/testdata/permissions.json @@ -0,0 +1,7 @@ +{ + "is_owner": true, + "is_admin": true, + "can_write": true, + "can_read": true, + "can_create_repository": true +} From cc305a69c784c50fa91da5de37b4fcad379bd421 Mon Sep 17 00:00:00 2001 From: Scott Walker Date: Mon, 14 Aug 2023 15:32:02 +0100 Subject: [PATCH 076/195] [IAC-941]: PR comment creation for BitBucket (#265) BitBucket doesn't implement support for PR comments or issues comments. The current implementation of "pullService" in BitBucket defers to the implementation of "issueService", which itself returns a "not implemented" error for all comment-related calls. PR comments and issue comments are separate in BitBucket so this commit adds explicit implementations of the comment functions to the "pullService". Most remain "not implemented" with the exception of comment creation which is now supported. --- go.sum | 11 ---- scm/driver/bitbucket/bitbucket.go | 2 +- scm/driver/bitbucket/pr.go | 38 +++++++++++++- scm/driver/bitbucket/pr_test.go | 50 ++++++++++++++++++ scm/driver/bitbucket/testdata/prcomment.json | 52 +++++++++++++++++++ .../bitbucket/testdata/prcomment.json.golden | 12 +++++ scm/driver/bitbucket/webhook.go | 6 +++ 7 files changed, 158 insertions(+), 13 deletions(-) create mode 100644 scm/driver/bitbucket/testdata/prcomment.json create mode 100644 scm/driver/bitbucket/testdata/prcomment.json.golden diff --git a/go.sum b/go.sum index 00f0342cb..6d69376b6 100644 --- a/go.sum +++ b/go.sum @@ -1,17 +1,6 @@ -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/h2non/gock v1.0.9 h1:17gCehSo8ZOgEsFKpQgqHiR7VLyjxdAG3lkhVvO9QZU= github.com/h2non/gock v1.0.9/go.mod h1:CZMcB0Lg5IWnr9bF79pPMg9WeV6WumxQiUJ1UvdO1iE= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/scm/driver/bitbucket/bitbucket.go b/scm/driver/bitbucket/bitbucket.go index d5afda370..f05ab670e 100644 --- a/scm/driver/bitbucket/bitbucket.go +++ b/scm/driver/bitbucket/bitbucket.go @@ -36,7 +36,7 @@ func New(uri string) (*scm.Client, error) { client.Issues = &issueService{client} client.Milestones = &milestoneService{client} client.Organizations = &organizationService{client} - client.PullRequests = &pullService{&issueService{client}} + client.PullRequests = &pullService{client} client.Repositories = &repositoryService{client} client.Releases = &releaseService{client} client.Reviews = &reviewService{client} diff --git a/scm/driver/bitbucket/pr.go b/scm/driver/bitbucket/pr.go index 5cc3e5ba9..ead47a821 100644 --- a/scm/driver/bitbucket/pr.go +++ b/scm/driver/bitbucket/pr.go @@ -13,7 +13,7 @@ import ( ) type pullService struct { - *issueService + client *wrapper } func (s *pullService) Find(ctx context.Context, repo string, number int) (*scm.PullRequest, *scm.Response, error) { @@ -69,6 +69,27 @@ func (s *pullService) Create(ctx context.Context, repo string, input *scm.PullRe return convertPullRequest(out), res, err } +func (s *pullService) FindComment(ctx context.Context, repo string, index, id int) (*scm.Comment, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *pullService) ListComments(ctx context.Context, repo string, index int, opts scm.ListOptions) ([]*scm.Comment, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *pullService) CreateComment(ctx context.Context, repo string, number int, input *scm.CommentInput) (*scm.Comment, *scm.Response, error) { + path := fmt.Sprintf("2.0/repositories/%s/pullrequests/%d/comments", repo, number) + in := &prCommentInput{} + in.Content.Raw = input.Body + out := new(prComment) + res, err := s.client.do(ctx, "POST", path, in, out) + return convertPullRequestComment(out), res, err +} + +func (s *pullService) DeleteComment(ctx context.Context, repo string, number, id int) (*scm.Response, error) { + return nil, scm.ErrNotSupported +} + type reference struct { Commit struct { Hash string `json:"hash"` @@ -180,3 +201,18 @@ func convertPullRequest(from *pr) *scm.PullRequest { Updated: from.UpdatedOn, } } + +func convertPullRequestComment(from *prComment) *scm.Comment { + return &scm.Comment{ + ID: from.ID, + Body: from.Content.Raw, + Author: scm.User{ + ID: from.User.UUID, + Login: from.User.Nickname, + Name: from.User.DisplayName, + Avatar: from.User.Links.Avatar.Href, + }, + Created: from.CreatedOn, + Updated: from.UpdatedOn, + } +} diff --git a/scm/driver/bitbucket/pr_test.go b/scm/driver/bitbucket/pr_test.go index 00f112f75..038ec1952 100644 --- a/scm/driver/bitbucket/pr_test.go +++ b/scm/driver/bitbucket/pr_test.go @@ -175,3 +175,53 @@ func TestPullListCommits(t *testing.T) { t.Log(diff) } } + +func TestPullRequestCommentFind(t *testing.T) { + _, _, err := NewDefault().PullRequests.FindComment(context.Background(), "", 0, 0) + if err != scm.ErrNotSupported { + t.Errorf("Expect Not Supported error") + } +} + +func TestPullRequestListComments(t *testing.T) { + _, _, err := NewDefault().PullRequests.ListComments(context.Background(), "", 0, scm.ListOptions{}) + if err != scm.ErrNotSupported { + t.Errorf("Expect Not Supported error") + } +} + +func TestPullRequestCreateComment(t *testing.T) { + defer gock.Off() + + gock.New("https://api.bitbucket.org"). + Post("/2.0/repositories/atlassian/atlaskit/pullrequests/12"). + Reply(201). + Type("application/json"). + File("testdata/prcomment.json") + + input := &scm.CommentInput{ + Body: "Lovely comment", + } + + client, _ := New("https://api.bitbucket.org") + got, _, err := client.PullRequests.CreateComment(context.Background(), "atlassian/atlaskit", 12, input) + if err != nil { + t.Error(err) + } + + want := new(scm.Comment) + raw, _ := ioutil.ReadFile("testdata/prcomment.json.golden") + json.Unmarshal(raw, want) + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } +} + +func TestPullRequestCommentDelete(t *testing.T) { + _, err := NewDefault().PullRequests.DeleteComment(context.Background(), "", 0, 0) + if err != scm.ErrNotSupported { + t.Errorf("Expect Not Supported error") + } +} diff --git a/scm/driver/bitbucket/testdata/prcomment.json b/scm/driver/bitbucket/testdata/prcomment.json new file mode 100644 index 000000000..953b2d158 --- /dev/null +++ b/scm/driver/bitbucket/testdata/prcomment.json @@ -0,0 +1,52 @@ +{ + "id": 419169807, + "created_on": "2023-08-14T11:38:53.460132+00:00", + "updated_on": "2023-08-14T11:38:53.460205+00:00", + "content": { + "type": "rendered", + "raw": "Lovely comment", + "markup": "markdown", + "html": "

Lovely comment<\/p>" + }, + "user": { + "display_name": "Brian Jacobson", + "links": { + "self": { + "href": "https:\/\/bitbucket.org\/!api\/2.0\/users\/%7B6dff94-1b8b-4f62-b37f-3069e13dfdf33e%7D" + }, + "avatar": { + "href": "http:\/\/localhost:3000\/avatars\/1" + }, + "html": { + "href": "https:\/\/bitbucket.org\/%7B6dff94-1b8b-4f62-b37f-3069e13dfdf33e%7D\/" + } + }, + "type": "user", + "uuid": "{6b408a94-1b8b-4f62-b37f-3069e13bc33e}", + "account_id": "60259ce8164527007100d945", + "nickname": "brian.jacobson" + }, + "deleted": false, + "type": "pullrequest_comment", + "links": { + "self": { + "href": "https:\/\/bitbucket.org\/!api\/2.0\/repositories\/brianharness\/test\/pullrequests\/3\/comments\/419169807" + }, + "html": { + "href": "https:\/\/bitbucket.org\/brianharness\/test\/pull-requests\/3\/_\/diff#comment-419169807" + } + }, + "pullrequest": { + "type": "pullrequest", + "id": 3, + "title": "README.md edited online with Bitbucket", + "links": { + "self": { + "href": "https:\/\/bitbucket.org\/!api\/2.0\/repositories\/brianharness\/test\/pullrequests\/3" + }, + "html": { + "href": "https:\/\/bitbucket.org\/brianharness\/test\/pull-requests\/3" + } + } + } +} \ No newline at end of file diff --git a/scm/driver/bitbucket/testdata/prcomment.json.golden b/scm/driver/bitbucket/testdata/prcomment.json.golden new file mode 100644 index 000000000..e6dea457a --- /dev/null +++ b/scm/driver/bitbucket/testdata/prcomment.json.golden @@ -0,0 +1,12 @@ +{ + "ID": 419169807, + "Body": "Lovely comment", + "Author": { + "ID": "{6b408a94-1b8b-4f62-b37f-3069e13bc33e}", + "Login": "brian.jacobson", + "Name": "Brian Jacobson", + "Avatar": "http://localhost:3000/avatars/1" + }, + "Created": "2023-08-14T11:38:53.460132+00:00", + "Updated": "2023-08-14T11:38:53.460205+00:00" +} diff --git a/scm/driver/bitbucket/webhook.go b/scm/driver/bitbucket/webhook.go index 6d88690ec..d254bba54 100644 --- a/scm/driver/bitbucket/webhook.go +++ b/scm/driver/bitbucket/webhook.go @@ -405,6 +405,12 @@ type ( UUID string `json:"uuid"` } + prCommentInput struct { + Content struct { + Raw string `json:"raw"` + } `json:"content"` + } + prComment struct { Links struct { Self link `json:"self"` From 6906e848dc03143acefe9e5f41c97cd7e13b33a3 Mon Sep 17 00:00:00 2001 From: TP Honey Date: Tue, 15 Aug 2023 10:28:13 +0100 Subject: [PATCH 077/195] (maint) v1.31.0 release prep (#266) Co-authored-by: dependabot-ci --- CHANGELOG.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 872d6396c..b5019f454 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,38 @@ # Changelog +## [v1.31.0](https://github.com/drone/go-scm/tree/v1.31.0) (2023-08-15) + +[Full Changelog](https://github.com/drone/go-scm/compare/v1.30.0...v1.31.0) + +**Implemented enhancements:** + +- \[IAC-941\]: PR comment creation for BitBucket [\#265](https://github.com/drone/go-scm/pull/265) ([scottyw-harness](https://github.com/scottyw-harness)) +- Implemented FindMembership method in organization service for gitea driver [\#263](https://github.com/drone/go-scm/pull/263) ([cod3rboy](https://github.com/cod3rboy)) + +**Closed issues:** + +- \(missing feature\) add support to check organization membership in gitea driver [\#262](https://github.com/drone/go-scm/issues/262) + +## [v1.30.0](https://github.com/drone/go-scm/tree/v1.30.0) (2023-07-19) + +[Full Changelog](https://github.com/drone/go-scm/compare/v1.29.1...v1.30.0) + +**Implemented enhancements:** + +- \[feat\]: \[CDS-73572\]: Support List Repo Live Search for all git providers [\#261](https://github.com/drone/go-scm/pull/261) ([adivishy1](https://github.com/adivishy1)) +- \[feat\]: \[CDS-73030\]: Support for text based branch filtration [\#260](https://github.com/drone/go-scm/pull/260) ([adivishy1](https://github.com/adivishy1)) +- feat: \[CDS-69341\]: add find user email api for github in go-scm [\#256](https://github.com/drone/go-scm/pull/256) ([shalini-agr](https://github.com/shalini-agr)) + +**Fixed bugs:** + +- fix: \[CDS-67745\]: fix find user email api for bitbucket in go-scm [\#255](https://github.com/drone/go-scm/pull/255) ([shalini-agr](https://github.com/shalini-agr)) +- fix: \[CI-6978\] fixed gitlab webhook parse [\#253](https://github.com/drone/go-scm/pull/253) ([devkimittal](https://github.com/devkimittal)) +- Add required header for bitbucket server in commit API use-case to handle csrf failures [\#252](https://github.com/drone/go-scm/pull/252) ([mohitg0795](https://github.com/mohitg0795)) + +**Merged pull requests:** + +- \(maint\) stash/bitbucket on prem v5 add push webhook test [\#257](https://github.com/drone/go-scm/pull/257) ([tphoney](https://github.com/tphoney)) + ## [v1.29.1](https://github.com/drone/go-scm/tree/v1.29.1) (2023-02-16) [Full Changelog](https://github.com/drone/go-scm/compare/v1.29.0...v1.29.1) From 1579795501b0ae415d6f75594751ffe3ddcaeb76 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Wed, 23 Aug 2023 14:41:04 +0530 Subject: [PATCH 078/195] Fix compare change api result for harness (#267) * Fix compare change api result for harness --- go.mod | 1 + go.sum | 2 + scm/driver/harness/git.go | 34 +++++++++----- scm/driver/harness/git_test.go | 44 +++++++++++++++++++ scm/driver/harness/testdata/gitdiff.json | 25 +++++++++++ .../harness/testdata/gitdiff.json.golden | 38 ++++++++++++++++ 6 files changed, 133 insertions(+), 11 deletions(-) create mode 100644 scm/driver/harness/testdata/gitdiff.json create mode 100644 scm/driver/harness/testdata/gitdiff.json.golden diff --git a/go.mod b/go.mod index 1a7e7c5ea..61703b6e3 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,7 @@ module github.com/drone/go-scm require ( + github.com/bluekeyes/go-gitdiff v0.7.1 github.com/google/go-cmp v0.2.0 github.com/h2non/gock v1.0.9 github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 // indirect diff --git a/go.sum b/go.sum index 6d69376b6..bce3cf429 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/bluekeyes/go-gitdiff v0.7.1 h1:graP4ElLRshr8ecu0UtqfNTCHrtSyZd3DABQm/DWesQ= +github.com/bluekeyes/go-gitdiff v0.7.1/go.mod h1:QpfYYO1E0fTVHVZAZKiRjtSGY9823iCdvGXBcEzHGbM= github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/h2non/gock v1.0.9 h1:17gCehSo8ZOgEsFKpQgqHiR7VLyjxdAG3lkhVvO9QZU= diff --git a/scm/driver/harness/git.go b/scm/driver/harness/git.go index 787eb4920..c5ca6eab1 100644 --- a/scm/driver/harness/git.go +++ b/scm/driver/harness/git.go @@ -7,10 +7,10 @@ package harness import ( "context" "fmt" - "io" "strings" "time" + "github.com/bluekeyes/go-gitdiff/gitdiff" "github.com/drone/go-scm/scm" ) @@ -81,17 +81,9 @@ func (s *gitService) ListChanges(ctx context.Context, repo, ref string, _ scm.Li func (s *gitService) CompareChanges(ctx context.Context, repo, source, target string, _ scm.ListOptions) ([]*scm.Change, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) path := fmt.Sprintf("api/v1/repos/%s/compare/%s...%s", harnessURI, source, target) - res, err := s.client.do(ctx, "GET", path, nil, nil) - // convert response to a string buf := new(strings.Builder) - _, _ = io.Copy(buf, res.Body) - changes := []*scm.Change{ - { - Path: "not implemented", - Sha: buf.String(), - }, - } - return changes, res, err + res, err := s.client.do(ctx, "GET", path, nil, buf) + return convertCompareChanges(buf.String()), res, err } // native data structures @@ -172,6 +164,26 @@ func convertCommitList(src []*commitInfo) []*scm.Commit { return dst } +func convertCompareChanges(src string) []*scm.Change { + files, _, err := gitdiff.Parse(strings.NewReader(src)) + if err != nil { + return nil + } + + changes := make([]*scm.Change, 0) + for _, f := range files { + changes = append(changes, &scm.Change{ + Path: f.NewName, + PrevFilePath: f.OldName, + Added: f.IsNew, + Deleted: f.IsDelete, + Renamed: f.IsRename, + }) + } + + return changes +} + func convertCommitInfo(src *commitInfo) *scm.Commit { return &scm.Commit{ Sha: src.Sha, diff --git a/scm/driver/harness/git_test.go b/scm/driver/harness/git_test.go index 016d65e49..8b5a5cd93 100644 --- a/scm/driver/harness/git_test.go +++ b/scm/driver/harness/git_test.go @@ -7,6 +7,7 @@ package harness import ( "context" "encoding/json" + "fmt" "io/ioutil" "net/http" "testing" @@ -207,3 +208,46 @@ func TestCreateBranch(t *testing.T) { } } + +func TestCompareChanges(t *testing.T) { + source := "a24d87c887957954d6f872bac3676f12cb9f50a2" + target := "5d1eb44a2aae537e5fa649dce3ff8c306af1527e" + defer gock.Off() + + gock.New(gockOrigin). + Get(fmt.Sprintf("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/compare/%s...%s", source, target)). + Reply(200). + Type("application/json"). + File("testdata/gitdiff.json") + + client, _ := New(gockOrigin, harnessOrg, harnessAccount, harnessProject) + client.Client = &http.Client{ + Transport: &transport.Custom{ + Before: func(r *http.Request) { + r.Header.Set("x-api-key", harnessPAT) + }, + }, + } + got, result, err := client.Git.CompareChanges(context.Background(), harnessRepo, source, target, scm.ListOptions{}) + if err != nil { + t.Error(err) + return + } + + if result.Status != 200 { + t.Errorf("Unexpected Results") + } + + want := []*scm.Change{} + raw, _ := ioutil.ReadFile("testdata/gitdiff.json.golden") + wantErr := json.Unmarshal(raw, &want) + if wantErr != nil { + t.Error(wantErr) + return + } + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } +} diff --git a/scm/driver/harness/testdata/gitdiff.json b/scm/driver/harness/testdata/gitdiff.json new file mode 100644 index 000000000..d44e597be --- /dev/null +++ b/scm/driver/harness/testdata/gitdiff.json @@ -0,0 +1,25 @@ +diff --git a/five b/five +new file mode 100644 +index 0000000..54f9d6d +--- /dev/null ++++ b/five +@@ -0,0 +1 @@ ++five +diff --git a/two b/four +similarity index 100% +rename from two +rename to four +diff --git a/one b/one +index 5626abf..9c0408b 100644 +--- a/one ++++ b/one +@@ -1 +1,2 @@ + one ++modified to two +diff --git a/three b/three +deleted file mode 100644 +index 2bdf67a..0000000 +--- a/three ++++ /dev/null +@@ -1 +0,0 @@ +-three \ No newline at end of file diff --git a/scm/driver/harness/testdata/gitdiff.json.golden b/scm/driver/harness/testdata/gitdiff.json.golden new file mode 100644 index 000000000..6439c0c09 --- /dev/null +++ b/scm/driver/harness/testdata/gitdiff.json.golden @@ -0,0 +1,38 @@ +[ + { + "Path": "five", + "Added": true, + "Renamed": false, + "Deleted": false, + "Sha": "", + "BlobID": "", + "PrevFilePath": "" + }, + { + "Path": "four", + "Added": false, + "Renamed": true, + "Deleted": false, + "Sha": "", + "BlobID": "", + "PrevFilePath": "two" + }, + { + "Path": "one", + "Added": false, + "Renamed": false, + "Deleted": false, + "Sha": "", + "BlobID": "", + "PrevFilePath": "one" + }, + { + "Path": "", + "Added": false, + "Renamed": false, + "Deleted": true, + "Sha": "", + "BlobID": "", + "PrevFilePath": "three" + } +] \ No newline at end of file From 5098db8648a082d86082116c10d854190e9e3ad3 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Tue, 29 Aug 2023 14:46:22 +0530 Subject: [PATCH 079/195] Fix api name for fetching diff in harness driver (#268) * Fix api name for fetching diff in harness driver --- scm/driver/harness/git.go | 2 +- scm/driver/harness/git_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scm/driver/harness/git.go b/scm/driver/harness/git.go index c5ca6eab1..bde9965e9 100644 --- a/scm/driver/harness/git.go +++ b/scm/driver/harness/git.go @@ -80,7 +80,7 @@ func (s *gitService) ListChanges(ctx context.Context, repo, ref string, _ scm.Li func (s *gitService) CompareChanges(ctx context.Context, repo, source, target string, _ scm.ListOptions) ([]*scm.Change, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/compare/%s...%s", harnessURI, source, target) + path := fmt.Sprintf("api/v1/repos/%s/diff/%s...%s", harnessURI, source, target) buf := new(strings.Builder) res, err := s.client.do(ctx, "GET", path, nil, buf) return convertCompareChanges(buf.String()), res, err diff --git a/scm/driver/harness/git_test.go b/scm/driver/harness/git_test.go index 8b5a5cd93..79dae39eb 100644 --- a/scm/driver/harness/git_test.go +++ b/scm/driver/harness/git_test.go @@ -215,7 +215,7 @@ func TestCompareChanges(t *testing.T) { defer gock.Off() gock.New(gockOrigin). - Get(fmt.Sprintf("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/compare/%s...%s", source, target)). + Get(fmt.Sprintf("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/diff/%s...%s", source, target)). Reply(200). Type("application/json"). File("testdata/gitdiff.json") From 8764ac057e4b9b218cda292e1e2a6b49f6f89d7e Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Tue, 29 Aug 2023 18:12:40 +0530 Subject: [PATCH 080/195] Fix diff api response conversion for harness compareChange (#269) * Fix diff api response conversion --- go.mod | 1 - go.sum | 2 - scm/driver/harness/git.go | 54 +++++++------ scm/driver/harness/git_test.go | 4 +- scm/driver/harness/testdata/gitdiff.json | 78 +++++++++++++------ .../harness/testdata/gitdiff.json.golden | 24 +++--- 6 files changed, 99 insertions(+), 64 deletions(-) diff --git a/go.mod b/go.mod index 61703b6e3..1a7e7c5ea 100644 --- a/go.mod +++ b/go.mod @@ -1,7 +1,6 @@ module github.com/drone/go-scm require ( - github.com/bluekeyes/go-gitdiff v0.7.1 github.com/google/go-cmp v0.2.0 github.com/h2non/gock v1.0.9 github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 // indirect diff --git a/go.sum b/go.sum index bce3cf429..6d69376b6 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,3 @@ -github.com/bluekeyes/go-gitdiff v0.7.1 h1:graP4ElLRshr8ecu0UtqfNTCHrtSyZd3DABQm/DWesQ= -github.com/bluekeyes/go-gitdiff v0.7.1/go.mod h1:QpfYYO1E0fTVHVZAZKiRjtSGY9823iCdvGXBcEzHGbM= github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/h2non/gock v1.0.9 h1:17gCehSo8ZOgEsFKpQgqHiR7VLyjxdAG3lkhVvO9QZU= diff --git a/scm/driver/harness/git.go b/scm/driver/harness/git.go index bde9965e9..309a125f7 100644 --- a/scm/driver/harness/git.go +++ b/scm/driver/harness/git.go @@ -7,10 +7,8 @@ package harness import ( "context" "fmt" - "strings" "time" - "github.com/bluekeyes/go-gitdiff/gitdiff" "github.com/drone/go-scm/scm" ) @@ -81,9 +79,9 @@ func (s *gitService) ListChanges(ctx context.Context, repo, ref string, _ scm.Li func (s *gitService) CompareChanges(ctx context.Context, repo, source, target string, _ scm.ListOptions) ([]*scm.Change, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) path := fmt.Sprintf("api/v1/repos/%s/diff/%s...%s", harnessURI, source, target) - buf := new(strings.Builder) - res, err := s.client.do(ctx, "GET", path, nil, buf) - return convertCompareChanges(buf.String()), res, err + out := []*fileDiff{} + res, err := s.client.do(ctx, "GET", path, nil, &out) + return convertChangeList(out), res, err } // native data structures @@ -134,6 +132,20 @@ type ( Name string `json:"name"` Sha string `json:"sha"` } + fileDiff struct { + SHA string `json:"sha"` + OldSHA string `json:"old_sha,omitempty"` + Path string `json:"path"` + OldPath string `json:"old_path,omitempty"` + Status string `json:"status"` + Additions int64 `json:"additions"` + Deletions int64 `json:"deletions"` + Changes int64 `json:"changes"` + ContentURL string `json:"content_url"` + Patch []byte `json:"patch,omitempty"` + IsBinary bool `json:"is_binary"` + IsSubmodule bool `json:"is_submodule"` + } ) // @@ -164,24 +176,12 @@ func convertCommitList(src []*commitInfo) []*scm.Commit { return dst } -func convertCompareChanges(src string) []*scm.Change { - files, _, err := gitdiff.Parse(strings.NewReader(src)) - if err != nil { - return nil - } - - changes := make([]*scm.Change, 0) - for _, f := range files { - changes = append(changes, &scm.Change{ - Path: f.NewName, - PrevFilePath: f.OldName, - Added: f.IsNew, - Deleted: f.IsDelete, - Renamed: f.IsRename, - }) +func convertChangeList(src []*fileDiff) []*scm.Change { + dst := []*scm.Change{} + for _, v := range src { + dst = append(dst, convertChange(v)) } - - return changes + return dst } func convertCommitInfo(src *commitInfo) *scm.Commit { @@ -200,3 +200,13 @@ func convertCommitInfo(src *commitInfo) *scm.Commit { }, } } + +func convertChange(src *fileDiff) *scm.Change { + return &scm.Change{ + Path: src.Path, + PrevFilePath: src.OldPath, + Added: src.Status == "ADDED", + Renamed: src.Status == "RENAMED", + Deleted: src.Status == "DELETED", + } +} diff --git a/scm/driver/harness/git_test.go b/scm/driver/harness/git_test.go index 79dae39eb..515705068 100644 --- a/scm/driver/harness/git_test.go +++ b/scm/driver/harness/git_test.go @@ -210,8 +210,8 @@ func TestCreateBranch(t *testing.T) { } func TestCompareChanges(t *testing.T) { - source := "a24d87c887957954d6f872bac3676f12cb9f50a2" - target := "5d1eb44a2aae537e5fa649dce3ff8c306af1527e" + source := "542ddabd47d7bfa79359b7b4e2af7f975354e35f" + target := "c7d0d4b21d5cfdf47475ff1f6281ef1a91883d" defer gock.Off() gock.New(gockOrigin). diff --git a/scm/driver/harness/testdata/gitdiff.json b/scm/driver/harness/testdata/gitdiff.json index d44e597be..c4dd5768d 100644 --- a/scm/driver/harness/testdata/gitdiff.json +++ b/scm/driver/harness/testdata/gitdiff.json @@ -1,25 +1,53 @@ -diff --git a/five b/five -new file mode 100644 -index 0000000..54f9d6d ---- /dev/null -+++ b/five -@@ -0,0 +1 @@ -+five -diff --git a/two b/four -similarity index 100% -rename from two -rename to four -diff --git a/one b/one -index 5626abf..9c0408b 100644 ---- a/one -+++ b/one -@@ -1 +1,2 @@ - one -+modified to two -diff --git a/three b/three -deleted file mode 100644 -index 2bdf67a..0000000 ---- a/three -+++ /dev/null -@@ -1 +0,0 @@ --three \ No newline at end of file +[ + { + "sha": "c4e897c1fcd1cae04abf761f034ae4c5e210caad", + "old_sha": "0000000000000000000000000000000000000000", + "path": "hello.go", + "old_path": "hello.go", + "status": "ADDED", + "additions": 8, + "deletions": 0, + "changes": 8, + "content_url": "/api/v1/hello.go", + "is_binary": false, + "is_submodule": false + }, + { + "sha": "0000000000000000000000000000000000000000", + "old_sha": "d7fcbf28651697b00add519d8b4402a5ab46ffc2", + "path": "null.go", + "old_path": "null.go", + "status": "DELETED", + "additions": 0, + "deletions": 118, + "changes": 118, + "content_url": "/api/v1/null.go", + "is_binary": false, + "is_submodule": false + }, + { + "sha": "ce5a2cd34b697f7a8507192e7074b33737c6740c", + "old_sha": "7697802e4d16b255e7ea22a86071cfbe9af6aa39", + "path": "version4.go", + "old_path": "version4.go", + "status": "MODIFIED", + "additions": 8, + "deletions": 7, + "changes": 15, + "content_url": "/api/v1/version4.go", + "is_binary": false, + "is_submodule": false + }, + { + "sha": "", + "path": "version_1.go", + "old_path": "version1.go", + "status": "RENAMED", + "additions": 0, + "deletions": 0, + "changes": 0, + "content_url": "/api/v1/version_1.go", + "is_binary": false, + "is_submodule": false + } +] \ No newline at end of file diff --git a/scm/driver/harness/testdata/gitdiff.json.golden b/scm/driver/harness/testdata/gitdiff.json.golden index 6439c0c09..c3258c315 100644 --- a/scm/driver/harness/testdata/gitdiff.json.golden +++ b/scm/driver/harness/testdata/gitdiff.json.golden @@ -1,38 +1,38 @@ [ { - "Path": "five", + "Path": "hello.go", "Added": true, "Renamed": false, "Deleted": false, "Sha": "", "BlobID": "", - "PrevFilePath": "" + "PrevFilePath": "hello.go" }, { - "Path": "four", + "Path": "null.go", "Added": false, - "Renamed": true, - "Deleted": false, + "Renamed": false, + "Deleted": true, "Sha": "", "BlobID": "", - "PrevFilePath": "two" + "PrevFilePath": "null.go" }, { - "Path": "one", + "Path": "version4.go", "Added": false, "Renamed": false, "Deleted": false, "Sha": "", "BlobID": "", - "PrevFilePath": "one" + "PrevFilePath": "version4.go" }, { - "Path": "", + "Path": "version_1.go", "Added": false, - "Renamed": false, - "Deleted": true, + "Renamed": true, + "Deleted": false, "Sha": "", "BlobID": "", - "PrevFilePath": "three" + "PrevFilePath": "version1.go" } ] \ No newline at end of file From bec9362d123d3e8981752a25de9ae63ea46f778d Mon Sep 17 00:00:00 2001 From: Meet Rathod Date: Tue, 29 Aug 2023 21:15:38 +0530 Subject: [PATCH 081/195] [feat]: [CDS-75848]: Add new action type for github provider --- scm/const.go | 5 + .../webhooks/pr_ready_for_review.json | 528 ++++++++++++++++++ .../webhooks/pr_ready_for_review.json.golden | 55 ++ scm/driver/github/webhook.go | 64 ++- scm/driver/github/webhook_test.go | 62 +- 5 files changed, 655 insertions(+), 59 deletions(-) create mode 100644 scm/driver/github/testdata/webhooks/pr_ready_for_review.json create mode 100644 scm/driver/github/testdata/webhooks/pr_ready_for_review.json.golden diff --git a/scm/const.go b/scm/const.go index dca74b699..b55729dd1 100644 --- a/scm/const.go +++ b/scm/const.go @@ -40,6 +40,7 @@ const ( // pull requests ActionSync ActionMerge + ActionReadyForReview // issue comment ActionEdit // release @@ -80,6 +81,8 @@ func (a Action) String() (s string) { return "prereleased" case ActionRelease: return "released" + case ActionReadyForReview: + return "ready_for_review" default: return } @@ -127,6 +130,8 @@ func (a *Action) UnmarshalJSON(data []byte) error { *a = ActionPrerelease case "released": *a = ActionRelease + case "ready_for_review": + *a = ActionReadyForReview } return nil } diff --git a/scm/driver/github/testdata/webhooks/pr_ready_for_review.json b/scm/driver/github/testdata/webhooks/pr_ready_for_review.json new file mode 100644 index 000000000..b9a7e1fdc --- /dev/null +++ b/scm/driver/github/testdata/webhooks/pr_ready_for_review.json @@ -0,0 +1,528 @@ +{ + "action": "ready_for_review", + "number": 38, + "pull_request": { + "url": "https://api.github.com/repos/wings-software/meet-git-sync-test/pulls/38", + "id": 1492580810, + "node_id": "PR_kwDOHbOleM5Y9vnK", + "html_url": "https://github.com/wings-software/meet-git-sync-test/pull/38", + "diff_url": "https://github.com/wings-software/meet-git-sync-test/pull/38.diff", + "patch_url": "https://github.com/wings-software/meet-git-sync-test/pull/38.patch", + "issue_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/issues/38", + "number": 38, + "state": "open", + "locked": false, + "title": "Update dgdggd.me", + "user": { + "login": "rathodmeetsatish", + "id": 84321134, + "node_id": "MDQ6VXNlcjg0MzIxMTM0", + "avatar_url": "https://avatars.githubusercontent.com/u/84321134?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/rathodmeetsatish", + "html_url": "https://github.com/rathodmeetsatish", + "followers_url": "https://api.github.com/users/rathodmeetsatish/followers", + "following_url": "https://api.github.com/users/rathodmeetsatish/following{/other_user}", + "gists_url": "https://api.github.com/users/rathodmeetsatish/gists{/gist_id}", + "starred_url": "https://api.github.com/users/rathodmeetsatish/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rathodmeetsatish/subscriptions", + "organizations_url": "https://api.github.com/users/rathodmeetsatish/orgs", + "repos_url": "https://api.github.com/users/rathodmeetsatish/repos", + "events_url": "https://api.github.com/users/rathodmeetsatish/events{/privacy}", + "received_events_url": "https://api.github.com/users/rathodmeetsatish/received_events", + "type": "User", + "site_admin": false + }, + "body": null, + "created_at": "2023-08-28T19:15:53Z", + "updated_at": "2023-08-28T19:16:06Z", + "closed_at": null, + "merged_at": null, + "merge_commit_sha": "d427e98e038a88f10e57d48c34f287e3ad20a0bf", + "assignee": null, + "assignees": [ + + ], + "requested_reviewers": [ + + ], + "requested_teams": [ + + ], + "labels": [ + + ], + "milestone": null, + "draft": false, + "commits_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/pulls/38/commits", + "review_comments_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/pulls/38/comments", + "review_comment_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/pulls/comments{/number}", + "comments_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/issues/38/comments", + "statuses_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/statuses/212015fb011c49a2913c4a1a860ce07c0821c362", + "head": { + "label": "wings-software:rathodmeetsatish-patch-25", + "ref": "rathodmeetsatish-patch-25", + "sha": "212015fb011c49a2913c4a1a860ce07c0821c362", + "user": { + "login": "wings-software", + "id": 18273000, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE4MjczMDAw", + "avatar_url": "https://avatars.githubusercontent.com/u/18273000?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/wings-software", + "html_url": "https://github.com/wings-software", + "followers_url": "https://api.github.com/users/wings-software/followers", + "following_url": "https://api.github.com/users/wings-software/following{/other_user}", + "gists_url": "https://api.github.com/users/wings-software/gists{/gist_id}", + "starred_url": "https://api.github.com/users/wings-software/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/wings-software/subscriptions", + "organizations_url": "https://api.github.com/users/wings-software/orgs", + "repos_url": "https://api.github.com/users/wings-software/repos", + "events_url": "https://api.github.com/users/wings-software/events{/privacy}", + "received_events_url": "https://api.github.com/users/wings-software/received_events", + "type": "Organization", + "site_admin": false + }, + "repo": { + "id": 498312568, + "node_id": "R_kgDOHbOleA", + "name": "meet-git-sync-test", + "full_name": "wings-software/meet-git-sync-test", + "private": true, + "owner": { + "login": "wings-software", + "id": 18273000, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE4MjczMDAw", + "avatar_url": "https://avatars.githubusercontent.com/u/18273000?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/wings-software", + "html_url": "https://github.com/wings-software", + "followers_url": "https://api.github.com/users/wings-software/followers", + "following_url": "https://api.github.com/users/wings-software/following{/other_user}", + "gists_url": "https://api.github.com/users/wings-software/gists{/gist_id}", + "starred_url": "https://api.github.com/users/wings-software/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/wings-software/subscriptions", + "organizations_url": "https://api.github.com/users/wings-software/orgs", + "repos_url": "https://api.github.com/users/wings-software/repos", + "events_url": "https://api.github.com/users/wings-software/events{/privacy}", + "received_events_url": "https://api.github.com/users/wings-software/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/wings-software/meet-git-sync-test", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/wings-software/meet-git-sync-test", + "forks_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/forks", + "keys_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/teams", + "hooks_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/hooks", + "issue_events_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/issues/events{/number}", + "events_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/events", + "assignees_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/assignees{/user}", + "branches_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/branches{/branch}", + "tags_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/tags", + "blobs_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/statuses/{sha}", + "languages_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/languages", + "stargazers_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/stargazers", + "contributors_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/contributors", + "subscribers_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/subscribers", + "subscription_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/subscription", + "commits_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/contents/{+path}", + "compare_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/merges", + "archive_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/downloads", + "issues_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/issues{/number}", + "pulls_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/pulls{/number}", + "milestones_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/milestones{/number}", + "notifications_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/labels{/name}", + "releases_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/releases{/id}", + "deployments_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/deployments", + "created_at": "2022-05-31T11:47:10Z", + "updated_at": "2022-05-31T11:47:35Z", + "pushed_at": "2023-08-28T19:15:54Z", + "git_url": "git://github.com/wings-software/meet-git-sync-test.git", + "ssh_url": "git@github.com:wings-software/meet-git-sync-test.git", + "clone_url": "https://github.com/wings-software/meet-git-sync-test.git", + "svn_url": "https://github.com/wings-software/meet-git-sync-test", + "homepage": null, + "size": 171, + "stargazers_count": 0, + "watchers_count": 0, + "language": "Roff", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "has_discussions": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 23, + "license": null, + "allow_forking": false, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [ + + ], + "visibility": "private", + "forks": 0, + "open_issues": 23, + "watchers": 0, + "default_branch": "main", + "allow_squash_merge": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_auto_merge": false, + "delete_branch_on_merge": false, + "allow_update_branch": false, + "use_squash_pr_title_as_default": false, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE" + } + }, + "base": { + "label": "wings-software:main", + "ref": "main", + "sha": "8b8d2b3e6a2ee6df108c8429e86c9a750e728f9d", + "user": { + "login": "wings-software", + "id": 18273000, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE4MjczMDAw", + "avatar_url": "https://avatars.githubusercontent.com/u/18273000?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/wings-software", + "html_url": "https://github.com/wings-software", + "followers_url": "https://api.github.com/users/wings-software/followers", + "following_url": "https://api.github.com/users/wings-software/following{/other_user}", + "gists_url": "https://api.github.com/users/wings-software/gists{/gist_id}", + "starred_url": "https://api.github.com/users/wings-software/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/wings-software/subscriptions", + "organizations_url": "https://api.github.com/users/wings-software/orgs", + "repos_url": "https://api.github.com/users/wings-software/repos", + "events_url": "https://api.github.com/users/wings-software/events{/privacy}", + "received_events_url": "https://api.github.com/users/wings-software/received_events", + "type": "Organization", + "site_admin": false + }, + "repo": { + "id": 498312568, + "node_id": "R_kgDOHbOleA", + "name": "meet-git-sync-test", + "full_name": "wings-software/meet-git-sync-test", + "private": true, + "owner": { + "login": "wings-software", + "id": 18273000, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE4MjczMDAw", + "avatar_url": "https://avatars.githubusercontent.com/u/18273000?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/wings-software", + "html_url": "https://github.com/wings-software", + "followers_url": "https://api.github.com/users/wings-software/followers", + "following_url": "https://api.github.com/users/wings-software/following{/other_user}", + "gists_url": "https://api.github.com/users/wings-software/gists{/gist_id}", + "starred_url": "https://api.github.com/users/wings-software/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/wings-software/subscriptions", + "organizations_url": "https://api.github.com/users/wings-software/orgs", + "repos_url": "https://api.github.com/users/wings-software/repos", + "events_url": "https://api.github.com/users/wings-software/events{/privacy}", + "received_events_url": "https://api.github.com/users/wings-software/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/wings-software/meet-git-sync-test", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/wings-software/meet-git-sync-test", + "forks_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/forks", + "keys_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/teams", + "hooks_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/hooks", + "issue_events_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/issues/events{/number}", + "events_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/events", + "assignees_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/assignees{/user}", + "branches_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/branches{/branch}", + "tags_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/tags", + "blobs_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/statuses/{sha}", + "languages_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/languages", + "stargazers_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/stargazers", + "contributors_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/contributors", + "subscribers_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/subscribers", + "subscription_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/subscription", + "commits_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/contents/{+path}", + "compare_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/merges", + "archive_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/downloads", + "issues_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/issues{/number}", + "pulls_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/pulls{/number}", + "milestones_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/milestones{/number}", + "notifications_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/labels{/name}", + "releases_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/releases{/id}", + "deployments_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/deployments", + "created_at": "2022-05-31T11:47:10Z", + "updated_at": "2022-05-31T11:47:35Z", + "pushed_at": "2023-08-28T19:15:54Z", + "git_url": "git://github.com/wings-software/meet-git-sync-test.git", + "ssh_url": "git@github.com:wings-software/meet-git-sync-test.git", + "clone_url": "https://github.com/wings-software/meet-git-sync-test.git", + "svn_url": "https://github.com/wings-software/meet-git-sync-test", + "homepage": null, + "size": 171, + "stargazers_count": 0, + "watchers_count": 0, + "language": "Roff", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "has_discussions": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 23, + "license": null, + "allow_forking": false, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [ + + ], + "visibility": "private", + "forks": 0, + "open_issues": 23, + "watchers": 0, + "default_branch": "main", + "allow_squash_merge": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_auto_merge": false, + "delete_branch_on_merge": false, + "allow_update_branch": false, + "use_squash_pr_title_as_default": false, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE" + } + }, + "_links": { + "self": { + "href": "https://api.github.com/repos/wings-software/meet-git-sync-test/pulls/38" + }, + "html": { + "href": "https://github.com/wings-software/meet-git-sync-test/pull/38" + }, + "issue": { + "href": "https://api.github.com/repos/wings-software/meet-git-sync-test/issues/38" + }, + "comments": { + "href": "https://api.github.com/repos/wings-software/meet-git-sync-test/issues/38/comments" + }, + "review_comments": { + "href": "https://api.github.com/repos/wings-software/meet-git-sync-test/pulls/38/comments" + }, + "review_comment": { + "href": "https://api.github.com/repos/wings-software/meet-git-sync-test/pulls/comments{/number}" + }, + "commits": { + "href": "https://api.github.com/repos/wings-software/meet-git-sync-test/pulls/38/commits" + }, + "statuses": { + "href": "https://api.github.com/repos/wings-software/meet-git-sync-test/statuses/212015fb011c49a2913c4a1a860ce07c0821c362" + } + }, + "author_association": "COLLABORATOR", + "auto_merge": null, + "active_lock_reason": null, + "merged": false, + "mergeable": true, + "rebaseable": true, + "mergeable_state": "clean", + "merged_by": null, + "comments": 0, + "review_comments": 0, + "maintainer_can_modify": false, + "commits": 1, + "additions": 4, + "deletions": 1, + "changed_files": 1 + }, + "repository": { + "id": 498312568, + "node_id": "R_kgDOHbOleA", + "name": "meet-git-sync-test", + "full_name": "wings-software/meet-git-sync-test", + "private": true, + "owner": { + "login": "wings-software", + "id": 18273000, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE4MjczMDAw", + "avatar_url": "https://avatars.githubusercontent.com/u/18273000?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/wings-software", + "html_url": "https://github.com/wings-software", + "followers_url": "https://api.github.com/users/wings-software/followers", + "following_url": "https://api.github.com/users/wings-software/following{/other_user}", + "gists_url": "https://api.github.com/users/wings-software/gists{/gist_id}", + "starred_url": "https://api.github.com/users/wings-software/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/wings-software/subscriptions", + "organizations_url": "https://api.github.com/users/wings-software/orgs", + "repos_url": "https://api.github.com/users/wings-software/repos", + "events_url": "https://api.github.com/users/wings-software/events{/privacy}", + "received_events_url": "https://api.github.com/users/wings-software/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/wings-software/meet-git-sync-test", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/wings-software/meet-git-sync-test", + "forks_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/forks", + "keys_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/teams", + "hooks_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/hooks", + "issue_events_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/issues/events{/number}", + "events_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/events", + "assignees_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/assignees{/user}", + "branches_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/branches{/branch}", + "tags_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/tags", + "blobs_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/statuses/{sha}", + "languages_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/languages", + "stargazers_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/stargazers", + "contributors_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/contributors", + "subscribers_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/subscribers", + "subscription_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/subscription", + "commits_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/contents/{+path}", + "compare_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/merges", + "archive_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/downloads", + "issues_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/issues{/number}", + "pulls_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/pulls{/number}", + "milestones_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/milestones{/number}", + "notifications_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/labels{/name}", + "releases_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/releases{/id}", + "deployments_url": "https://api.github.com/repos/wings-software/meet-git-sync-test/deployments", + "created_at": "2022-05-31T11:47:10Z", + "updated_at": "2022-05-31T11:47:35Z", + "pushed_at": "2023-08-28T19:15:54Z", + "git_url": "git://github.com/wings-software/meet-git-sync-test.git", + "ssh_url": "git@github.com:wings-software/meet-git-sync-test.git", + "clone_url": "https://github.com/wings-software/meet-git-sync-test.git", + "svn_url": "https://github.com/wings-software/meet-git-sync-test", + "homepage": null, + "size": 171, + "stargazers_count": 0, + "watchers_count": 0, + "language": "Roff", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "has_discussions": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 23, + "license": null, + "allow_forking": false, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [ + + ], + "visibility": "private", + "forks": 0, + "open_issues": 23, + "watchers": 0, + "default_branch": "main" + }, + "organization": { + "login": "wings-software", + "id": 18273000, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE4MjczMDAw", + "url": "https://api.github.com/orgs/wings-software", + "repos_url": "https://api.github.com/orgs/wings-software/repos", + "events_url": "https://api.github.com/orgs/wings-software/events", + "hooks_url": "https://api.github.com/orgs/wings-software/hooks", + "issues_url": "https://api.github.com/orgs/wings-software/issues", + "members_url": "https://api.github.com/orgs/wings-software/members{/member}", + "public_members_url": "https://api.github.com/orgs/wings-software/public_members{/member}", + "avatar_url": "https://avatars.githubusercontent.com/u/18273000?v=4", + "description": "" + }, + "enterprise": { + "id": 6657, + "slug": "harness", + "name": "Harness", + "node_id": "MDEwOkVudGVycHJpc2U2NjU3", + "avatar_url": "https://avatars.githubusercontent.com/b/6657?v=4", + "description": "", + "website_url": "https://harness.io", + "html_url": "https://github.com/enterprises/harness", + "created_at": "2021-04-13T17:56:36Z", + "updated_at": "2023-02-06T20:48:35Z" + }, + "sender": { + "login": "rathodmeetsatish", + "id": 84321134, + "node_id": "MDQ6VXNlcjg0MzIxMTM0", + "avatar_url": "https://avatars.githubusercontent.com/u/84321134?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/rathodmeetsatish", + "html_url": "https://github.com/rathodmeetsatish", + "followers_url": "https://api.github.com/users/rathodmeetsatish/followers", + "following_url": "https://api.github.com/users/rathodmeetsatish/following{/other_user}", + "gists_url": "https://api.github.com/users/rathodmeetsatish/gists{/gist_id}", + "starred_url": "https://api.github.com/users/rathodmeetsatish/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rathodmeetsatish/subscriptions", + "organizations_url": "https://api.github.com/users/rathodmeetsatish/orgs", + "repos_url": "https://api.github.com/users/rathodmeetsatish/repos", + "events_url": "https://api.github.com/users/rathodmeetsatish/events{/privacy}", + "received_events_url": "https://api.github.com/users/rathodmeetsatish/received_events", + "type": "User", + "site_admin": false + } +} diff --git a/scm/driver/github/testdata/webhooks/pr_ready_for_review.json.golden b/scm/driver/github/testdata/webhooks/pr_ready_for_review.json.golden new file mode 100644 index 000000000..97932e5ab --- /dev/null +++ b/scm/driver/github/testdata/webhooks/pr_ready_for_review.json.golden @@ -0,0 +1,55 @@ +{ + "Action": "ready_for_review", + "Repo": { + "ID": "498312568", + "Namespace": "wings-software", + "Name": "meet-git-sync-test", + "Perm": null, + "Branch": "main", + "Private": true, + "Visibility": 3, + "Clone": "https://github.com/wings-software/meet-git-sync-test.git", + "CloneSSH": "git@github.com:wings-software/meet-git-sync-test.git", + "Link": "https://github.com/wings-software/meet-git-sync-test", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "PullRequest": { + "Number": 38, + "Title": "Update dgdggd.me", + "Body": null, + "Sha": "212015fb011c49a2913c4a1a860ce07c0821c362", + "Ref": "refs/pull/38/head", + "Target": "main", + "Source": "rathodmeetsatish-patch-25", + "Fork": "wings-software/meet-git-sync-test", + "Link": "https://github.com/wings-software/meet-git-sync-test/pull/38", + "Diff": "https://github.com/wings-software/meet-git-sync-test/pull/38.diff", + "Closed": null, + "Merged": null, + "Base": { + "Sha": "8b8d2b3e6a2ee6df108c8429e86c9a750e728f9d", + "Path": "refs/heads/main", + "Name": "main" + }, + "Head": { + "Sha": "212015fb011c49a2913c4a1a860ce07c0821c362", + "Path": "refs/heads/rathodmeetsatish-patch-25", + "Name": "rathodmeetsatish-patch-25" + }, + "Author": { + "Login": "rathodmeetsatish", + "Name": "", + "Email": "", + "Avatar": "https://avatars.githubusercontent.com/u/84321134?v=4" + }, + "Created": "2023-08-28T19:15:53Z", + "Updated": "2023-08-28T19:16:06Z" + }, + "Sender": { + "Login": "rathodmeetsatish", + "Name": "", + "Email": "", + "Avatar": "https://avatars.githubusercontent.com/u/84321134?v=4" + } +} diff --git a/scm/driver/github/webhook.go b/scm/driver/github/webhook.go index 57d3ed9ed..9d75d5303 100644 --- a/scm/driver/github/webhook.go +++ b/scm/driver/github/webhook.go @@ -172,7 +172,9 @@ func (s *webhookService) parsePullRequestHook(data []byte) (scm.Webhook, error) dst.Action = scm.ActionReopen case "synchronize": dst.Action = scm.ActionSync - case "assigned", "unassigned", "review_requested", "review_request_removed", "ready_for_review", "locked", "unlocked": + case "ready_for_review": + dst.Action = scm.ActionReadyForReview + case "assigned", "unassigned", "review_requested", "review_request_removed", "locked", "unlocked": dst.Action = scm.ActionUnknown default: dst.Action = scm.ActionUnknown @@ -186,7 +188,7 @@ func (s *webhookService) parseReleaseHook(data []byte) (scm.Webhook, error) { if err != nil { return nil, err } - dst := convertReleaseHook(src) + dst := convertReleaseHook(src) switch src.Action { case "created": dst.Action = scm.ActionCreate @@ -332,24 +334,24 @@ type ( } `json:"comment"` } - // github release webhook payload + // github release webhook payload releaseHook struct { - Action string `json:"action"` - Release struct { - ID int `json:"id"` - Title string `json:"name"` - Description string `json:"body"` - Link string `json:"html_url,omitempty"` - Tag string `json:"tag_name,omitempty"` - Commitish string `json:"target_commitish,omitempty"` - Draft bool `json:"draft"` - Prerelease bool `json:"prerelease"` - Created time.Time `json:"created_at"` - Published time.Time `json:"published_at"` - } `json:"release"` - Repository repository `json:"repository"` - Sender user `json:"sender"` - } + Action string `json:"action"` + Release struct { + ID int `json:"id"` + Title string `json:"name"` + Description string `json:"body"` + Link string `json:"html_url,omitempty"` + Tag string `json:"tag_name,omitempty"` + Commitish string `json:"target_commitish,omitempty"` + Draft bool `json:"draft"` + Prerelease bool `json:"prerelease"` + Created time.Time `json:"created_at"` + Published time.Time `json:"published_at"` + } `json:"release"` + Repository repository `json:"repository"` + Sender user `json:"sender"` + } ) // @@ -551,18 +553,18 @@ func convertIssueCommentHook(src *issueCommentHook) *scm.IssueCommentHook { func convertReleaseHook(src *releaseHook) *scm.ReleaseHook { dst := &scm.ReleaseHook{ - Release: scm.Release{ - ID: src.Release.ID, - Title: src.Release.Title, - Description: src.Release.Description, - Link: src.Release.Link, - Tag: src.Release.Tag, - Commitish: src.Release.Commitish, - Draft: src.Release.Draft, - Prerelease: src.Release.Prerelease, - Created: src.Release.Created, - Published: src.Release.Published, - }, + Release: scm.Release{ + ID: src.Release.ID, + Title: src.Release.Title, + Description: src.Release.Description, + Link: src.Release.Link, + Tag: src.Release.Tag, + Commitish: src.Release.Commitish, + Draft: src.Release.Draft, + Prerelease: src.Release.Prerelease, + Created: src.Release.Created, + Published: src.Release.Published, + }, Repo: scm.Repository{ ID: fmt.Sprint(src.Repository.ID), Namespace: src.Repository.Owner.Login, diff --git a/scm/driver/github/webhook_test.go b/scm/driver/github/webhook_test.go index 7d3621c94..f7c63c3fd 100644 --- a/scm/driver/github/webhook_test.go +++ b/scm/driver/github/webhook_test.go @@ -28,7 +28,6 @@ func TestWebhooks(t *testing.T) { // // push events // - // push hooks { event: "push", @@ -126,6 +125,13 @@ func TestWebhooks(t *testing.T) { after: "testdata/webhooks/pr_sync.json.golden", obj: new(scm.PullRequestHook), }, + // pull request ready for review + { + event: "pull_request", + before: "testdata/webhooks/pr_ready_for_review.json", + after: "testdata/webhooks/pr_ready_for_review.json.golden", + obj: new(scm.PullRequestHook), + }, // pull request opened { event: "pull_request", @@ -185,9 +191,9 @@ func TestWebhooks(t *testing.T) { after: "testdata/webhooks/deployment_commit.json.golden", obj: new(scm.DeployHook), }, - // - // release - // + // + // release + // { event: "release", before: "testdata/webhooks/release_published.json", @@ -195,40 +201,40 @@ func TestWebhooks(t *testing.T) { obj: new(scm.ReleaseHook), }, { - event: "release", - before: "testdata/webhooks/release_unpublished.json", - after: "testdata/webhooks/release_unpublished.json.golden", - obj: new(scm.ReleaseHook), + event: "release", + before: "testdata/webhooks/release_unpublished.json", + after: "testdata/webhooks/release_unpublished.json.golden", + obj: new(scm.ReleaseHook), }, { - event: "release", - before: "testdata/webhooks/release_created.json", - after: "testdata/webhooks/release_created.json.golden", - obj: new(scm.ReleaseHook), + event: "release", + before: "testdata/webhooks/release_created.json", + after: "testdata/webhooks/release_created.json.golden", + obj: new(scm.ReleaseHook), }, { - event: "release", - before: "testdata/webhooks/release_edited.json", - after: "testdata/webhooks/release_edited.json.golden", - obj: new(scm.ReleaseHook), + event: "release", + before: "testdata/webhooks/release_edited.json", + after: "testdata/webhooks/release_edited.json.golden", + obj: new(scm.ReleaseHook), }, { - event: "release", - before: "testdata/webhooks/release_deleted.json", - after: "testdata/webhooks/release_deleted.json.golden", - obj: new(scm.ReleaseHook), + event: "release", + before: "testdata/webhooks/release_deleted.json", + after: "testdata/webhooks/release_deleted.json.golden", + obj: new(scm.ReleaseHook), }, { - event: "release", - before: "testdata/webhooks/release_prereleased.json", - after: "testdata/webhooks/release_prereleased.json.golden", - obj: new(scm.ReleaseHook), + event: "release", + before: "testdata/webhooks/release_prereleased.json", + after: "testdata/webhooks/release_prereleased.json.golden", + obj: new(scm.ReleaseHook), }, { - event: "release", - before: "testdata/webhooks/release_released.json", - after: "testdata/webhooks/release_released.json.golden", - obj: new(scm.ReleaseHook), + event: "release", + before: "testdata/webhooks/release_released.json", + after: "testdata/webhooks/release_released.json.golden", + obj: new(scm.ReleaseHook), }, } From b2bdb6d01452290e4b1a3ea9d37d213c36a261d0 Mon Sep 17 00:00:00 2001 From: Abhinav Singh Date: Wed, 30 Aug 2023 10:45:42 -0700 Subject: [PATCH 082/195] fix: [CODE-727]: change to gitness from harness --- scm/driver/harness/webhook.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/scm/driver/harness/webhook.go b/scm/driver/harness/webhook.go index 514ddaafa..bb7a75a79 100644 --- a/scm/driver/harness/webhook.go +++ b/scm/driver/harness/webhook.go @@ -7,7 +7,6 @@ package harness import ( "crypto/sha256" "encoding/json" - "fmt" "io" "io/ioutil" "net/http" @@ -192,8 +191,8 @@ func convertPullRequestHook(dst *pullRequestHook) *scm.PullRequestHook { Number: dst.PullReq.Number, Title: dst.PullReq.Title, Closed: dst.PullReq.State != "open", - Source: fmt.Sprintf("%d", dst.PullReq.SourceRepoID), - Target: fmt.Sprintf("%d", dst.PullReq.TargetRepoID), + Source: dst.PullReq.SourceBranch, + Target: dst.PullReq.TargetBranch, Fork: "fork", Link: dst.Ref.Repo.GitURL, Sha: dst.Commit.Sha, From c91f42489e53ac72791fd82d460aeef4d142b0dc Mon Sep 17 00:00:00 2001 From: Abhinav Singh Date: Wed, 30 Aug 2023 10:46:49 -0700 Subject: [PATCH 083/195] fix: [CODE-727]: change to gitness from harness --- scm/driver/harness/webhook_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm/driver/harness/webhook_test.go b/scm/driver/harness/webhook_test.go index 48f66daeb..4e38687be 100644 --- a/scm/driver/harness/webhook_test.go +++ b/scm/driver/harness/webhook_test.go @@ -73,7 +73,7 @@ func TestWebhooks(t *testing.T) { buf := bytes.NewBuffer(before) r, _ := http.NewRequest("GET", "/", buf) - r.Header.Set("X-Gitness-Trigger", test.event) + r.Header.Set("X-Harness-Trigger", test.event) s := new(webhookService) o, err := s.Parse(r, secretFunc) From 8d6a8e37135477a664e0912022979b5704c0f6c3 Mon Sep 17 00:00:00 2001 From: Abhinav Singh Date: Wed, 30 Aug 2023 10:47:52 -0700 Subject: [PATCH 084/195] fix: [CODE-727]: change to gitness from harness --- scm/driver/harness/webhook.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scm/driver/harness/webhook.go b/scm/driver/harness/webhook.go index bb7a75a79..1aa2d45fb 100644 --- a/scm/driver/harness/webhook.go +++ b/scm/driver/harness/webhook.go @@ -28,7 +28,7 @@ func (s *webhookService) Parse(req *http.Request, fn scm.SecretFunc) (scm.Webhoo } var hook scm.Webhook - switch req.Header.Get("X-Gitness-Trigger") { + switch req.Header.Get("X-Harness-Trigger") { // case "create": // hook, err = s.parseCreateHook(data) // case "delete": @@ -57,7 +57,7 @@ func (s *webhookService) Parse(req *http.Request, fn scm.SecretFunc) (scm.Webhoo } secret := req.FormValue("secret") - signature := req.Header.Get("X-Gitness-Signature") + signature := req.Header.Get("X-Harness-Signature") // fail if no signature passed if signature == "" && secret == "" { From 13e99fa40ec1514ef0467ea3851a233af0c55a22 Mon Sep 17 00:00:00 2001 From: Abhinav Singh Date: Wed, 30 Aug 2023 10:54:09 -0700 Subject: [PATCH 085/195] fix: [CODE-727]: change to gitness from harness --- .../testdata/webhooks/pull_request_branch_updated.json.golden | 4 ++-- .../harness/testdata/webhooks/pull_request_opened.json.golden | 4 ++-- .../testdata/webhooks/pull_request_reopened.json.golden | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json.golden b/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json.golden index d978a3b13..9a768dde2 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json.golden +++ b/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json.golden @@ -18,8 +18,8 @@ "Body": "", "Sha": "f74f3d2a88d1b7cb19ff3bf069aa423763d341ef", "Ref": "", - "Source": "13", - "Target": "13", + "Source": "b", + "Target": "main", "Fork": "fork", "Link": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git", "Closed": false, diff --git a/scm/driver/harness/testdata/webhooks/pull_request_opened.json.golden b/scm/driver/harness/testdata/webhooks/pull_request_opened.json.golden index 936a53c7a..e45f24bc5 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_opened.json.golden +++ b/scm/driver/harness/testdata/webhooks/pull_request_opened.json.golden @@ -18,8 +18,8 @@ "Body": "", "Sha": "d74b1ebfe520ac01b209dd9085f005884cc9f4cd", "Ref": "", - "Source": "13", - "Target": "13", + "Source": "b", + "Target": "main", "Fork": "fork", "Link": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git", "Closed": false, diff --git a/scm/driver/harness/testdata/webhooks/pull_request_reopened.json.golden b/scm/driver/harness/testdata/webhooks/pull_request_reopened.json.golden index 17b0f8657..bbea80558 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_reopened.json.golden +++ b/scm/driver/harness/testdata/webhooks/pull_request_reopened.json.golden @@ -18,8 +18,8 @@ "Body": "", "Sha": "f74f3d2a88d1b7cb19ff3bf069aa423763d341ef", "Ref": "", - "Source": "13", - "Target": "13", + "Source": "b", + "Target": "main", "Fork": "fork", "Link": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git", "Closed": false, From 84d449ac1a67a5028ea2fa32bc66c7e5c1ab2a7f Mon Sep 17 00:00:00 2001 From: Meet Rathod Date: Fri, 8 Sep 2023 01:40:14 +0530 Subject: [PATCH 086/195] Add review ready action for gitlab --- scm/const.go | 10 +- .../webhooks/pr_ready_for_review.json.golden | 2 +- scm/driver/github/webhook.go | 2 +- .../webhooks/pull_request_review_ready.json | 154 ++++++++++++++++++ .../pull_request_review_ready.json.golden | 43 +++++ scm/driver/gitlab/webhook.go | 7 + scm/driver/gitlab/webhook_test.go | 6 + 7 files changed, 217 insertions(+), 7 deletions(-) create mode 100644 scm/driver/gitlab/testdata/webhooks/pull_request_review_ready.json create mode 100644 scm/driver/gitlab/testdata/webhooks/pull_request_review_ready.json.golden diff --git a/scm/const.go b/scm/const.go index b55729dd1..73fa7a9e6 100644 --- a/scm/const.go +++ b/scm/const.go @@ -40,7 +40,7 @@ const ( // pull requests ActionSync ActionMerge - ActionReadyForReview + ActionReviewReady // issue comment ActionEdit // release @@ -81,8 +81,8 @@ func (a Action) String() (s string) { return "prereleased" case ActionRelease: return "released" - case ActionReadyForReview: - return "ready_for_review" + case ActionReviewReady: + return "review_ready" default: return } @@ -130,8 +130,8 @@ func (a *Action) UnmarshalJSON(data []byte) error { *a = ActionPrerelease case "released": *a = ActionRelease - case "ready_for_review": - *a = ActionReadyForReview + case "review_ready": + *a = ActionReviewReady } return nil } diff --git a/scm/driver/github/testdata/webhooks/pr_ready_for_review.json.golden b/scm/driver/github/testdata/webhooks/pr_ready_for_review.json.golden index 97932e5ab..653a28b1e 100644 --- a/scm/driver/github/testdata/webhooks/pr_ready_for_review.json.golden +++ b/scm/driver/github/testdata/webhooks/pr_ready_for_review.json.golden @@ -1,5 +1,5 @@ { - "Action": "ready_for_review", + "Action": "review_ready", "Repo": { "ID": "498312568", "Namespace": "wings-software", diff --git a/scm/driver/github/webhook.go b/scm/driver/github/webhook.go index 9d75d5303..6c01a711d 100644 --- a/scm/driver/github/webhook.go +++ b/scm/driver/github/webhook.go @@ -173,7 +173,7 @@ func (s *webhookService) parsePullRequestHook(data []byte) (scm.Webhook, error) case "synchronize": dst.Action = scm.ActionSync case "ready_for_review": - dst.Action = scm.ActionReadyForReview + dst.Action = scm.ActionReviewReady case "assigned", "unassigned", "review_requested", "review_request_removed", "locked", "unlocked": dst.Action = scm.ActionUnknown default: diff --git a/scm/driver/gitlab/testdata/webhooks/pull_request_review_ready.json b/scm/driver/gitlab/testdata/webhooks/pull_request_review_ready.json new file mode 100644 index 000000000..5a25b03ef --- /dev/null +++ b/scm/driver/gitlab/testdata/webhooks/pull_request_review_ready.json @@ -0,0 +1,154 @@ +{ + "object_kind": "merge_request", + "event_type": "merge_request", + "user": { + "id": 13900456, + "name": "Meet Rathod", + "username": "rathod.meetsatish", + "avatar_url": "https://secure.gravatar.com/avatar/0e68aaeb6c49dd6ba280370c96280803?s=80&d=identicon", + "email": "[REDACTED]" + }, + "project": { + "id": 44067058, + "name": "meet", + "description": null, + "web_url": "https://gitlab.com/rathod.meetsatish/meet", + "avatar_url": null, + "git_ssh_url": "git@gitlab.com:rathod.meetsatish/meet.git", + "git_http_url": "https://gitlab.com/rathod.meetsatish/meet.git", + "namespace": "Meet Rathod", + "visibility_level": 0, + "path_with_namespace": "rathod.meetsatish/meet", + "default_branch": "main", + "ci_config_path": "", + "homepage": "https://gitlab.com/rathod.meetsatish/meet", + "url": "git@gitlab.com:rathod.meetsatish/meet.git", + "ssh_url": "git@gitlab.com:rathod.meetsatish/meet.git", + "http_url": "https://gitlab.com/rathod.meetsatish/meet.git" + }, + "object_attributes": { + "assignee_id": null, + "author_id": 13900456, + "created_at": "2023-09-07 19:42:34 UTC", + "description": "", + "draft": true, + "head_pipeline_id": null, + "id": 248466002, + "iid": 3, + "last_edited_at": null, + "last_edited_by_id": null, + "merge_commit_sha": null, + "merge_error": null, + "merge_params": { + "force_remove_source_branch": "1" + }, + "merge_status": "can_be_merged", + "merge_user_id": null, + "merge_when_pipeline_succeeds": false, + "milestone_id": null, + "source_branch": "main1234", + "source_project_id": 44067058, + "state_id": 1, + "target_branch": "main", + "target_project_id": 44067058, + "time_estimate": 0, + "title": "Draft: Update README.md", + "updated_at": "2023-09-07 19:42:45 UTC", + "updated_by_id": 13900456, + "url": "https://gitlab.com/rathod.meetsatish/meet/-/merge_requests/3", + "source": { + "id": 44067058, + "name": "meet", + "description": null, + "web_url": "https://gitlab.com/rathod.meetsatish/meet", + "avatar_url": null, + "git_ssh_url": "git@gitlab.com:rathod.meetsatish/meet.git", + "git_http_url": "https://gitlab.com/rathod.meetsatish/meet.git", + "namespace": "Meet Rathod", + "visibility_level": 0, + "path_with_namespace": "rathod.meetsatish/meet", + "default_branch": "main", + "ci_config_path": "", + "homepage": "https://gitlab.com/rathod.meetsatish/meet", + "url": "git@gitlab.com:rathod.meetsatish/meet.git", + "ssh_url": "git@gitlab.com:rathod.meetsatish/meet.git", + "http_url": "https://gitlab.com/rathod.meetsatish/meet.git" + }, + "target": { + "id": 44067058, + "name": "meet", + "description": null, + "web_url": "https://gitlab.com/rathod.meetsatish/meet", + "avatar_url": null, + "git_ssh_url": "git@gitlab.com:rathod.meetsatish/meet.git", + "git_http_url": "https://gitlab.com/rathod.meetsatish/meet.git", + "namespace": "Meet Rathod", + "visibility_level": 0, + "path_with_namespace": "rathod.meetsatish/meet", + "default_branch": "main", + "ci_config_path": "", + "homepage": "https://gitlab.com/rathod.meetsatish/meet", + "url": "git@gitlab.com:rathod.meetsatish/meet.git", + "ssh_url": "git@gitlab.com:rathod.meetsatish/meet.git", + "http_url": "https://gitlab.com/rathod.meetsatish/meet.git" + }, + "last_commit": { + "id": "ffd71529ecdfb41a530ee13f91b8fdd3e743c754", + "message": "Update README.md", + "title": "Update README.md", + "timestamp": "2023-09-07T19:42:21+00:00", + "url": "https://gitlab.com/rathod.meetsatish/meet/-/commit/ffd71529ecdfb41a530ee13f91b8fdd3e743c754", + "author": { + "name": "Meet Rathod", + "email": "[REDACTED]" + } + }, + "work_in_progress": true, + "total_time_spent": 0, + "time_change": 0, + "human_total_time_spent": null, + "human_time_change": null, + "human_time_estimate": null, + "assignee_ids": [ + + ], + "reviewer_ids": [ + + ], + "labels": [ + + ], + "state": "opened", + "blocking_discussions_resolved": true, + "first_contribution": true, + "detailed_merge_status": "draft_status", + "action": "update" + }, + "labels": [ + + ], + "changes": { + "draft": { + "previous": false, + "current": true + }, + "title": { + "previous": "Update README.md", + "current": "Draft: Update README.md" + }, + "updated_at": { + "previous": "2023-09-07 19:42:35 UTC", + "current": "2023-09-07 19:42:45 UTC" + }, + "updated_by_id": { + "previous": null, + "current": 13900456 + } + }, + "repository": { + "name": "meet", + "url": "git@gitlab.com:rathod.meetsatish/meet.git", + "description": null, + "homepage": "https://gitlab.com/rathod.meetsatish/meet" + } +} diff --git a/scm/driver/gitlab/testdata/webhooks/pull_request_review_ready.json.golden b/scm/driver/gitlab/testdata/webhooks/pull_request_review_ready.json.golden new file mode 100644 index 000000000..c75213032 --- /dev/null +++ b/scm/driver/gitlab/testdata/webhooks/pull_request_review_ready.json.golden @@ -0,0 +1,43 @@ +{ + "Action": "review_ready", + "Repo": { + "ID": "44067058", + "Namespace": "rathod.meetsatish", + "Name": "meet", + "Perm": null, + "Branch": "main", + "Private": false, + "Clone": "https://gitlab.com/rathod.meetsatish/meet.git", + "CloneSSH": "git@gitlab.com:rathod.meetsatish/meet.git", + "Link": "https://gitlab.com/rathod.meetsatish/meet", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "PullRequest": { + "Number": 3, + "Title": "Draft: Update README.md", + "Body": "", + "Sha": "ffd71529ecdfb41a530ee13f91b8fdd3e743c754", + "Ref": "refs/merge-requests/3/head", + "Source": "main1234", + "Target": "main", + "Fork": "Meet Rathod/meet", + "Link": "https://gitlab.com/rathod.meetsatish/meet/-/merge_requests/3", + "Closed": false, + "Merged": false, + "Author": { + "Login": "rathod.meetsatish", + "Name": "Meet Rathod", + "Email": "", + "Avatar": "https://secure.gravatar.com/avatar/0e68aaeb6c49dd6ba280370c96280803?s=80&d=identicon" + }, + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Sender": { + "Login": "rathod.meetsatish", + "Name": "Meet Rathod", + "Email": "", + "Avatar": "https://secure.gravatar.com/avatar/0e68aaeb6c49dd6ba280370c96280803?s=80&d=identicon" + } +} diff --git a/scm/driver/gitlab/webhook.go b/scm/driver/gitlab/webhook.go index 56da8f195..3bd8d3008 100644 --- a/scm/driver/gitlab/webhook.go +++ b/scm/driver/gitlab/webhook.go @@ -338,6 +338,9 @@ func convertPullRequestHook(src *pullRequestHook) *scm.PullRequestHook { action = scm.ActionMerge case "update": action = scm.ActionSync + if src.Changes.Draft.Previous.Bool == false { + action = scm.ActionReviewReady + } } fork := scm.Join( src.ObjectAttributes.Source.Namespace, @@ -860,6 +863,10 @@ type ( } `json:"object_attributes"` Labels []interface{} `json:"labels"` Changes struct { + Draft struct { + Previous null.Bool `json:"previous"` + Current null.Bool `json:"current"` + } `json:"draft"` } `json:"changes"` Repository struct { Name string `json:"name"` diff --git a/scm/driver/gitlab/webhook_test.go b/scm/driver/gitlab/webhook_test.go index 1eb6cf527..e766cada4 100644 --- a/scm/driver/gitlab/webhook_test.go +++ b/scm/driver/gitlab/webhook_test.go @@ -97,6 +97,12 @@ func TestWebhooks(t *testing.T) { after: "testdata/webhooks/pull_request_close.json.golden", obj: new(scm.PullRequestHook), }, + { + event: "Merge Request Hook", + before: "testdata/webhooks/pull_request_review_ready.json", + after: "testdata/webhooks/pull_request_review_ready.json.golden", + obj: new(scm.PullRequestHook), + }, { event: "Merge Request Hook", before: "testdata/webhooks/pull_request_reopen.json", From 2d64e5c57c97172a34b674f78fe64a73ffc112fc Mon Sep 17 00:00:00 2001 From: Meet Rathod Date: Tue, 12 Sep 2023 00:36:26 +0530 Subject: [PATCH 087/195] address comments --- scm/driver/gitlab/webhook.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm/driver/gitlab/webhook.go b/scm/driver/gitlab/webhook.go index 3bd8d3008..2cc785fb7 100644 --- a/scm/driver/gitlab/webhook.go +++ b/scm/driver/gitlab/webhook.go @@ -338,7 +338,7 @@ func convertPullRequestHook(src *pullRequestHook) *scm.PullRequestHook { action = scm.ActionMerge case "update": action = scm.ActionSync - if src.Changes.Draft.Previous.Bool == false { + if src.Changes.Draft.Previous.Bool == false && src.Changes.Draft.Current.Bool == true { action = scm.ActionReviewReady } } From e0123f7f716d66b83a7c8c78fc8d94286b6ad16e Mon Sep 17 00:00:00 2001 From: dependabot-ci Date: Tue, 12 Sep 2023 11:00:37 +0100 Subject: [PATCH 088/195] (maint) release prep for 1.32.0 --- CHANGELOG.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5019f454..60338158a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,31 @@ # Changelog +## [v1.32.0](https://github.com/drone/go-scm/tree/v1.32.0) (2023-09-12) + +[Full Changelog](https://github.com/drone/go-scm/compare/v1.31.2...v1.32.0) + +**Implemented enhancements:** + +- \[feat\]: \[CDS-75848\]: Add new action type for github provider [\#270](https://github.com/drone/go-scm/pull/270) ([rathodmeetsatish](https://github.com/rathodmeetsatish)) + +## [v1.31.2](https://github.com/drone/go-scm/tree/v1.31.2) (2023-08-31) + +[Full Changelog](https://github.com/drone/go-scm/compare/v1.31.1...v1.31.2) + +**Fixed bugs:** + +- fix: \[CODE-727\]: change branch in source and target for harness provider [\#264](https://github.com/drone/go-scm/pull/264) ([abhinav-harness](https://github.com/abhinav-harness)) + +## [v1.31.1](https://github.com/drone/go-scm/tree/v1.31.1) (2023-08-29) + +[Full Changelog](https://github.com/drone/go-scm/compare/v1.31.0...v1.31.1) + +**Fixed bugs:** + +- Fix diff api response conversion for harness compareChange [\#269](https://github.com/drone/go-scm/pull/269) ([shubham149](https://github.com/shubham149)) +- Fix api name for fetching diff in harness driver [\#268](https://github.com/drone/go-scm/pull/268) ([shubham149](https://github.com/shubham149)) +- Fix compare change api result for harness [\#267](https://github.com/drone/go-scm/pull/267) ([shubham149](https://github.com/shubham149)) + ## [v1.31.0](https://github.com/drone/go-scm/tree/v1.31.0) (2023-08-15) [Full Changelog](https://github.com/drone/go-scm/compare/v1.30.0...v1.31.0) @@ -13,6 +39,10 @@ - \(missing feature\) add support to check organization membership in gitea driver [\#262](https://github.com/drone/go-scm/issues/262) +**Merged pull requests:** + +- \(maint\) v1.31.0 release prep [\#266](https://github.com/drone/go-scm/pull/266) ([tphoney](https://github.com/tphoney)) + ## [v1.30.0](https://github.com/drone/go-scm/tree/v1.30.0) (2023-07-19) [Full Changelog](https://github.com/drone/go-scm/compare/v1.29.1...v1.30.0) From 13e5d45573afc53c47d0169cc4d40413aafd4fc7 Mon Sep 17 00:00:00 2001 From: dependabot-ci Date: Tue, 12 Sep 2023 11:18:26 +0100 Subject: [PATCH 089/195] (maint) clean integration testing for stash --- scm/driver/stash/integration/content_test.go | 4 ++-- scm/driver/stash/integration/git_test.go | 16 ++++++++-------- scm/driver/stash/integration/integration.go | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/scm/driver/stash/integration/content_test.go b/scm/driver/stash/integration/content_test.go index a65b1b838..d6a22bbcb 100644 --- a/scm/driver/stash/integration/content_test.go +++ b/scm/driver/stash/integration/content_test.go @@ -11,8 +11,8 @@ import ( ) func TestCreateUpdateDeleteFileStash(t *testing.T) { - if token == "" { - t.Skip("Skipping, Acceptance test") + if token == "" || username == "" { + t.Skip("Skipping, Acceptance test. Missing BITBUCKET_SERVER_TOKEN or BITBUCKET_USERNAME") } client, _ = stash.New(endpoint) client.Client = &http.Client{ diff --git a/scm/driver/stash/integration/git_test.go b/scm/driver/stash/integration/git_test.go index 6ef33fee7..d1607f8de 100644 --- a/scm/driver/stash/integration/git_test.go +++ b/scm/driver/stash/integration/git_test.go @@ -11,8 +11,8 @@ import ( ) func TestCreateBranch(t *testing.T) { - if token == "" { - t.Skip("Skipping, Acceptance test") + if token == "" || username == "" { + t.Skip("Skipping, Acceptance test. Missing BITBUCKET_SERVER_TOKEN or BITBUCKET_USERNAME") } client, _ = stash.New(endpoint) client.Client = &http.Client{ @@ -37,8 +37,8 @@ func TestCreateBranch(t *testing.T) { } func TestGetLatestCommitOfBranch(t *testing.T) { - if token == "" { - t.Skip("Skipping, Acceptance test") + if token == "" || username == "" { + t.Skip("Skipping, Acceptance test. Missing BITBUCKET_SERVER_TOKEN or BITBUCKET_USERNAME") } client, _ = stash.New(endpoint) client.Client = &http.Client{ @@ -64,8 +64,8 @@ func TestGetLatestCommitOfBranch(t *testing.T) { } func TestGetLatestCommitOfNonDefaultBranch(t *testing.T) { - if token == "" { - t.Skip("Skipping, Acceptance test") + if token == "" || username == "" { + t.Skip("Skipping, Acceptance test. Missing BITBUCKET_SERVER_TOKEN or BITBUCKET_USERNAME") } client, _ = stash.New(endpoint) client.Client = &http.Client{ @@ -91,8 +91,8 @@ func TestGetLatestCommitOfNonDefaultBranch(t *testing.T) { } func TestGetLatestCommitOfBranchWhenNoRefPassed(t *testing.T) { - if token == "" { - t.Skip("Skipping, Acceptance test") + if token == "" || username == "" { + t.Skip("Skipping, Acceptance test. Missing BITBUCKET_SERVER_TOKEN or BITBUCKET_USERNAME") } client, _ = stash.New(endpoint) client.Client = &http.Client{ diff --git a/scm/driver/stash/integration/integration.go b/scm/driver/stash/integration/integration.go index 7a3dfce71..56cae697d 100644 --- a/scm/driver/stash/integration/integration.go +++ b/scm/driver/stash/integration/integration.go @@ -13,7 +13,7 @@ var ( endpoint = "https://bitbucket.dev.harness.io/" repoID = "har/scm-integration-test-repo" - username = "harnessadmin" + username = os.Getenv("BITBUCKET_USERNAME") ) func GetCurrentCommitOfBranch(client *scm.Client, branch string) (string, error) { From 3ce608d262be0d22d6a7f45f7993cf5eabc54e32 Mon Sep 17 00:00:00 2001 From: Abhinav Singh Date: Wed, 27 Sep 2023 02:59:06 -0700 Subject: [PATCH 090/195] fix: Gitness get content missing query param --- scm/driver/harness/content.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scm/driver/harness/content.go b/scm/driver/harness/content.go index 7eac5b990..a5a0848d3 100644 --- a/scm/driver/harness/content.go +++ b/scm/driver/harness/content.go @@ -19,7 +19,7 @@ type contentService struct { func (s *contentService) Find(ctx context.Context, repo, path, ref string) (*scm.Content, *scm.Response, error) { repo = buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - endpoint := fmt.Sprintf("api/v1/repos/%s/content/%s?%s&include_commit=true", repo, path, ref) + endpoint := fmt.Sprintf("api/v1/repos/%s/content/%s?git_ref=%s&include_commit=true", repo, path, ref) out := new(fileContent) res, err := s.client.do(ctx, "GET", endpoint, nil, out) // decode raw output content @@ -94,7 +94,7 @@ func (s *contentService) Delete(ctx context.Context, repo, path string, params * func (s *contentService) List(ctx context.Context, repo, path, ref string, _ scm.ListOptions) ([]*scm.ContentInfo, *scm.Response, error) { repo = buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - endpoint := fmt.Sprintf("api/v1/repos/%s/content/%s?%s&include_commit=true", repo, path, ref) + endpoint := fmt.Sprintf("api/v1/repos/%s/content/%s?git_ref=%s&include_commit=true", repo, path, ref) out := new(contentList) res, err := s.client.do(ctx, "GET", endpoint, nil, &out) return convertContentInfoList(out.Content.Entries), res, err From b66c7e14982b832e9392f8b09aa23bcbad0ee0c0 Mon Sep 17 00:00:00 2001 From: dependabot-ci Date: Wed, 27 Sep 2023 11:16:22 +0100 Subject: [PATCH 091/195] (maint) prep for 1.32.1 --- CHANGELOG.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60338158a..192ce1fe7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## [v1.32.1](https://github.com/drone/go-scm/tree/v1.32.1) (2023-09-27) + +[Full Changelog](https://github.com/drone/go-scm/compare/v1.32.0...v1.32.1) + +**Fixed bugs:** + +- fix: Gitness get content missing query param [\#275](https://github.com/drone/go-scm/pull/275) ([abhinav-harness](https://github.com/abhinav-harness)) + +**Merged pull requests:** + +- \(maint\) clean integration testing for stash [\#273](https://github.com/drone/go-scm/pull/273) ([tphoney](https://github.com/tphoney)) + ## [v1.32.0](https://github.com/drone/go-scm/tree/v1.32.0) (2023-09-12) [Full Changelog](https://github.com/drone/go-scm/compare/v1.31.2...v1.32.0) @@ -8,6 +20,10 @@ - \[feat\]: \[CDS-75848\]: Add new action type for github provider [\#270](https://github.com/drone/go-scm/pull/270) ([rathodmeetsatish](https://github.com/rathodmeetsatish)) +**Merged pull requests:** + +- \(maint\) release prep for 1.32.0 [\#272](https://github.com/drone/go-scm/pull/272) ([tphoney](https://github.com/tphoney)) + ## [v1.31.2](https://github.com/drone/go-scm/tree/v1.31.2) (2023-08-31) [Full Changelog](https://github.com/drone/go-scm/compare/v1.31.1...v1.31.2) From 3b21a0f7851a60a9103bcc6d489d6dbf28fce48f Mon Sep 17 00:00:00 2001 From: Abhinav Singh Date: Tue, 3 Oct 2023 03:20:00 -0700 Subject: [PATCH 092/195] fix: Harness list commits api update as per new spec (#277) --- scm/driver/harness/git.go | 14 ++++++--- scm/driver/harness/testdata/commits.json | 40 +++++++++++++----------- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/scm/driver/harness/git.go b/scm/driver/harness/git.go index 309a125f7..85b17bff1 100644 --- a/scm/driver/harness/git.go +++ b/scm/driver/harness/git.go @@ -63,7 +63,7 @@ func (s *gitService) ListBranchesV2(ctx context.Context, repo string, opts scm.B func (s *gitService) ListCommits(ctx context.Context, repo string, _ scm.CommitListOptions) ([]*scm.Commit, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) path := fmt.Sprintf("api/v1/repos/%s/commits", harnessURI) - out := []*commitInfo{} + out := new(commits) res, err := s.client.do(ctx, "GET", path, nil, &out) return convertCommitList(out), res, err } @@ -86,6 +86,10 @@ func (s *gitService) CompareChanges(ctx context.Context, repo, source, target st // native data structures type ( + commits struct { + Commits []commitInfo `json:"commits"` + } + commitInfo struct { Author struct { Identity struct { @@ -168,10 +172,10 @@ func convertBranch(src *branch) *scm.Reference { } } -func convertCommitList(src []*commitInfo) []*scm.Commit { - dst := []*scm.Commit{} - for _, v := range src { - dst = append(dst, convertCommitInfo(v)) +func convertCommitList(src *commits) []*scm.Commit { + var dst []*scm.Commit + for _, v := range src.Commits { + dst = append(dst, convertCommitInfo(&v)) } return dst } diff --git a/scm/driver/harness/testdata/commits.json b/scm/driver/harness/testdata/commits.json index 96576e18f..4045985d6 100644 --- a/scm/driver/harness/testdata/commits.json +++ b/scm/driver/harness/testdata/commits.json @@ -1,21 +1,23 @@ -[ - { - "sha": "1d640265d8bdd818175fa736f0fcbad2c9b716c9", - "title": "delete README.2", - "message": "delete README.2\n\ndelete README.2", - "author": { - "identity": { - "name": "thomas.honey", - "email": "thomas.honey@harness.io" +{ + "commits": [ + { + "sha": "1d640265d8bdd818175fa736f0fcbad2c9b716c9", + "title": "delete README.2", + "message": "delete README.2\n\ndelete README.2", + "author": { + "identity": { + "name": "thomas.honey", + "email": "thomas.honey@harness.io" + }, + "when": "2023-02-08T16:17:50Z" }, - "when": "2023-02-08T16:17:50Z" - }, - "committer": { - "identity": { - "name": "Harness", - "email": "noreply@harness.io" - }, - "when": "2023-02-08T16:17:50Z" + "committer": { + "identity": { + "name": "Harness", + "email": "noreply@harness.io" + }, + "when": "2023-02-08T16:17:50Z" + } } - } -] \ No newline at end of file + ] +} \ No newline at end of file From 166ac922322037bbc30492ebe5c639a492e52759 Mon Sep 17 00:00:00 2001 From: Abhinav Singh Date: Wed, 11 Oct 2023 03:24:49 -0700 Subject: [PATCH 093/195] fix: ref should have pullreq instead of pull for gitness (#278) --- scm/driver/harness/pr.go | 2 +- scm/driver/harness/testdata/pr.json.golden | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scm/driver/harness/pr.go b/scm/driver/harness/pr.go index 6e0266a0d..9b5e05724 100644 --- a/scm/driver/harness/pr.go +++ b/scm/driver/harness/pr.go @@ -182,7 +182,7 @@ func convertPullRequest(src *pr) *scm.PullRequest { Email: src.Author.Email, }, Fork: "fork", - Ref: fmt.Sprintf("refs/pull/%d/head", src.Number), + Ref: fmt.Sprintf("refs/pullreq/%d/head", src.Number), Closed: src.State == "closed", } } diff --git a/scm/driver/harness/testdata/pr.json.golden b/scm/driver/harness/testdata/pr.json.golden index 224b66050..5c4a83864 100644 --- a/scm/driver/harness/testdata/pr.json.golden +++ b/scm/driver/harness/testdata/pr.json.golden @@ -3,7 +3,7 @@ "Title": "pull title", "Body": "pull description", "Sha": "", - "Ref": "refs/pull/1/head", + "Ref": "refs/pullreq/1/head", "Source": "bla", "Target": "main", "Fork": "fork", From 6982ab89b53ef118c8bd52a81e1511d736d46e24 Mon Sep 17 00:00:00 2001 From: Abhinav Singh Date: Wed, 11 Oct 2023 04:03:55 -0700 Subject: [PATCH 094/195] feat: add more parsed data in harness webhook parsing (#279) --- .../webhooks/pull_request_branch_updated.json.golden | 8 ++++---- .../testdata/webhooks/pull_request_opened.json.golden | 8 ++++---- .../testdata/webhooks/pull_request_reopened.json.golden | 8 ++++---- scm/driver/harness/webhook.go | 6 ++++++ 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json.golden b/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json.golden index 9a768dde2..6be31bb70 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json.golden +++ b/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json.golden @@ -6,7 +6,7 @@ "Name": "", "Branch": "main", "Private": false, - "Clone": "", + "Clone": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git", "CloneSSH": "", "Link": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git", "Created": "0001-01-01T00:00:00Z", @@ -17,7 +17,7 @@ "Title": "aw", "Body": "", "Sha": "f74f3d2a88d1b7cb19ff3bf069aa423763d341ef", - "Ref": "", + "Ref": "refs/heads/b", "Source": "b", "Target": "main", "Fork": "fork", @@ -26,8 +26,8 @@ "Merged": false, "Author": { "Login": "", - "Name": "", - "Email": "", + "Name": "Admin", + "Email": "admin@harness.io", "Avatar": "" }, "Created": "0001-01-01T00:00:00Z", diff --git a/scm/driver/harness/testdata/webhooks/pull_request_opened.json.golden b/scm/driver/harness/testdata/webhooks/pull_request_opened.json.golden index e45f24bc5..2928bf6a1 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_opened.json.golden +++ b/scm/driver/harness/testdata/webhooks/pull_request_opened.json.golden @@ -6,7 +6,7 @@ "Name": "", "Branch": "main", "Private": false, - "Clone": "", + "Clone": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git", "CloneSSH": "", "Link": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git", "Created": "0001-01-01T00:00:00Z", @@ -17,7 +17,7 @@ "Title": "aw", "Body": "", "Sha": "d74b1ebfe520ac01b209dd9085f005884cc9f4cd", - "Ref": "", + "Ref": "refs/heads/b", "Source": "b", "Target": "main", "Fork": "fork", @@ -26,8 +26,8 @@ "Merged": false, "Author": { "Login": "", - "Name": "", - "Email": "", + "Name": "Admin", + "Email": "admin@harness.io", "Avatar": "" }, "Created": "0001-01-01T00:00:00Z", diff --git a/scm/driver/harness/testdata/webhooks/pull_request_reopened.json.golden b/scm/driver/harness/testdata/webhooks/pull_request_reopened.json.golden index bbea80558..03f8b54df 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_reopened.json.golden +++ b/scm/driver/harness/testdata/webhooks/pull_request_reopened.json.golden @@ -6,7 +6,7 @@ "Name": "", "Branch": "main", "Private": false, - "Clone": "", + "Clone": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git", "CloneSSH": "", "Link": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git", "Created": "0001-01-01T00:00:00Z", @@ -17,7 +17,7 @@ "Title": "aw", "Body": "", "Sha": "f74f3d2a88d1b7cb19ff3bf069aa423763d341ef", - "Ref": "", + "Ref": "refs/heads/b", "Source": "b", "Target": "main", "Fork": "fork", @@ -26,8 +26,8 @@ "Merged": false, "Author": { "Login": "", - "Name": "", - "Email": "", + "Name": "Admin", + "Email": "admin@harness.io", "Avatar": "" }, "Created": "0001-01-01T00:00:00Z", diff --git a/scm/driver/harness/webhook.go b/scm/driver/harness/webhook.go index 1aa2d45fb..cc077a6ca 100644 --- a/scm/driver/harness/webhook.go +++ b/scm/driver/harness/webhook.go @@ -196,11 +196,17 @@ func convertPullRequestHook(dst *pullRequestHook) *scm.PullRequestHook { Fork: "fork", Link: dst.Ref.Repo.GitURL, Sha: dst.Commit.Sha, + Ref: dst.Ref.Name, + Author: scm.User{ + Name: dst.Commit.Committer.Identity.Name, + Email: dst.Commit.Committer.Identity.Email, + }, }, Repo: scm.Repository{ ID: dst.Repo.UID, Branch: dst.Repo.DefaultBranch, Link: dst.Repo.GitURL, + Clone: dst.Repo.GitURL, }, Sender: scm.User{ Email: dst.Principal.Email, From a5db7f41d8f7cc95b3077f49d61bb7d795521f19 Mon Sep 17 00:00:00 2001 From: Abhinav Singh Date: Tue, 24 Oct 2023 23:42:54 -0700 Subject: [PATCH 095/195] feat: Add pr_comment webhook for harness (#280) --- .../webhooks/branch_create.json.golden | 17 ++- .../webhooks/pull_request_branch_updated.json | 11 +- .../pull_request_branch_updated.json.golden | 20 ++- .../pull_request_comment_created.json | 63 +++++++++ .../pull_request_comment_created.json.golden | 51 +++++++ .../webhooks/pull_request_opened.json | 11 +- .../webhooks/pull_request_opened.json.golden | 20 ++- .../webhooks/pull_request_reopened.json | 11 +- .../pull_request_reopened.json.golden | 20 ++- scm/driver/harness/webhook.go | 131 ++++++++++++------ scm/driver/harness/webhook_test.go | 7 + 11 files changed, 289 insertions(+), 73 deletions(-) create mode 100644 scm/driver/harness/testdata/webhooks/pull_request_comment_created.json create mode 100644 scm/driver/harness/testdata/webhooks/pull_request_comment_created.json.golden diff --git a/scm/driver/harness/testdata/webhooks/branch_create.json.golden b/scm/driver/harness/testdata/webhooks/branch_create.json.golden index 00e4ce11b..0b0dad736 100644 --- a/scm/driver/harness/testdata/webhooks/branch_create.json.golden +++ b/scm/driver/harness/testdata/webhooks/branch_create.json.golden @@ -3,15 +3,15 @@ "Before": "0000000000000000000000000000000000000000", "After": "aeafa0e2e4ec6909ad75cb8fad57c0b1eb5986e6", "Repo": { - "ID": "", + "ID": "13", "Namespace": "", "Name": "aba", "Perm": null, - "Branch": "", + "Branch": "main", "Private": false, - "Clone": "", + "Clone": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git", "CloneSSH": "", - "Link": "", + "Link": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git", "Created": "0001-01-01T00:00:00Z", "Updated": "0001-01-01T00:00:00Z" }, @@ -35,9 +35,12 @@ "Link": "" }, "Sender": { - "Login": "", + "ID": "0osgWsTZRsSZ8RWfjLRkEg", + "Login": "0osgWsTZRsSZ8RWfjLRkEg", "Name": "default", - "Email": "", - "Avatar": "" + "Email": "default@harness.io", + "Avatar": "", + "Created": "2023-02-02T18:21:25.38-08:00", + "Updated": "2023-02-02T18:21:25.38-08:00" } } \ No newline at end of file diff --git a/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json b/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json index 7509798e9..2709b46dc 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json +++ b/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json @@ -25,7 +25,16 @@ "source_branch": "b", "target_repo_id": 13, "target_branch": "main", - "merge_strategy": null + "merge_strategy": null, + "author": { + "id": 8, + "uid": "0osgWsTZRsSZ8RWfjLRkEg", + "display_name": "Admin", + "email": "admin@harness.io", + "type": "user", + "created": 1675390885380, + "updated": 1675390885380 + } }, "target_ref": { "name": "refs/heads/main", diff --git a/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json.golden b/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json.golden index 6be31bb70..05c42eb0f 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json.golden +++ b/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json.golden @@ -1,9 +1,9 @@ { "Action": "updated", "Repo": { - "ID": "aba", + "ID": "13", "Namespace": "", - "Name": "", + "Name": "aba", "Branch": "main", "Private": false, "Clone": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git", @@ -25,18 +25,24 @@ "Closed": false, "Merged": false, "Author": { - "Login": "", + "ID": "0osgWsTZRsSZ8RWfjLRkEg", + "Login": "0osgWsTZRsSZ8RWfjLRkEg", "Name": "Admin", "Email": "admin@harness.io", - "Avatar": "" + "Avatar": "", + "Created": "2023-02-02T18:21:25.38-08:00", + "Updated": "2023-02-02T18:21:25.38-08:00" }, "Created": "0001-01-01T00:00:00Z", "Updated": "0001-01-01T00:00:00Z" }, "Sender": { - "Login": "", - "Name": "", + "ID": "0osgWsTZRsSZ8RWfjLRkEg", + "Login": "0osgWsTZRsSZ8RWfjLRkEg", + "Name": "default", "Email": "default@harness.io", - "Avatar": "" + "Avatar": "", + "Created": "2023-02-02T18:21:25.38-08:00", + "Updated": "2023-02-02T18:21:25.38-08:00" } } \ No newline at end of file diff --git a/scm/driver/harness/testdata/webhooks/pull_request_comment_created.json b/scm/driver/harness/testdata/webhooks/pull_request_comment_created.json new file mode 100644 index 000000000..3b39a54fd --- /dev/null +++ b/scm/driver/harness/testdata/webhooks/pull_request_comment_created.json @@ -0,0 +1,63 @@ +{ + "trigger": "pullreq_comment_created", + "repo": { + "id": 18, + "path": "asd/demo", + "uid": "demo", + "default_branch": "main", + "git_url": "http://localhost:3000/git/asd/demo.git" + }, + "principal": { + "id": 3, + "uid": "admin", + "display_name": "Administrator", + "email": "admin@gitness.io", + "type": "user", + "created": 1696332021613, + "updated": 1696332021613 + }, + "pull_req": { + "number": 2, + "state": "open", + "is_draft": false, + "title": "Update test.txt", + "source_repo_id": 18, + "source_branch": "pr2", + "target_repo_id": 18, + "target_branch": "main", + "merge_strategy": null, + "author": { + "id": 8, + "uid": "0osgWsTZRsSZ8RWfjLRkEg", + "display_name": "Admin", + "email": "admin@harness.io", + "type": "user", + "created": 1675390885380, + "updated": 1675390885380 + } + }, + "target_ref": { + "name": "refs/heads/main", + "repo": { + "id": 18, + "path": "asd/demo", + "uid": "demo", + "default_branch": "main", + "git_url": "http://localhost:3000/git/asd/demo.git" + } + }, + "ref": { + "name": "refs/heads/pr2", + "repo": { + "id": 18, + "path": "asd/demo", + "uid": "demo", + "default_branch": "main", + "git_url": "http://localhost:3000/git/asd/demo.git" + } + }, + "comment": { + "id": 1, + "text": "pr comment" + } +} \ No newline at end of file diff --git a/scm/driver/harness/testdata/webhooks/pull_request_comment_created.json.golden b/scm/driver/harness/testdata/webhooks/pull_request_comment_created.json.golden new file mode 100644 index 000000000..ed14715f7 --- /dev/null +++ b/scm/driver/harness/testdata/webhooks/pull_request_comment_created.json.golden @@ -0,0 +1,51 @@ +{ + "Repo": { + "ID": "18", + "Namespace": "", + "Name": "demo", + "Branch": "main", + "Private": false, + "Clone": "http://localhost:3000/git/asd/demo.git", + "CloneSSH": "", + "Link": "http://localhost:3000/git/asd/demo.git", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "PullRequest": { + "Number": 2, + "Title": "Update test.txt", + "Body": "", + "Sha": "", + "Ref": "refs/heads/pr2", + "Source": "pr2", + "Target": "main", + "Fork": "fork", + "Link": "http://localhost:3000/git/asd/demo.git", + "Closed": false, + "Merged": false, + "Author": { + "ID": "0osgWsTZRsSZ8RWfjLRkEg", + "Login": "0osgWsTZRsSZ8RWfjLRkEg", + "Name": "Admin", + "Email": "admin@harness.io", + "Avatar": "", + "Created": "2023-02-02T18:21:25.38-08:00", + "Updated": "2023-02-02T18:21:25.38-08:00" + }, + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Comment": { + "ID": 1, + "Body": "pr comment" + }, + "Sender": { + "ID": "admin", + "Login": "admin", + "Name": "Administrator", + "Email": "admin@gitness.io", + "Avatar": "", + "Created": "2023-10-03T04:20:21.613-07:00", + "Updated": "2023-10-03T04:20:21.613-07:00" + } +} \ No newline at end of file diff --git a/scm/driver/harness/testdata/webhooks/pull_request_opened.json b/scm/driver/harness/testdata/webhooks/pull_request_opened.json index a7fd7666b..45b76600c 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_opened.json +++ b/scm/driver/harness/testdata/webhooks/pull_request_opened.json @@ -25,7 +25,16 @@ "source_branch": "b", "target_repo_id": 13, "target_branch": "main", - "merge_strategy": null + "merge_strategy": null, + "author": { + "id": 8, + "uid": "0osgWsTZRsSZ8RWfjLRkEg", + "display_name": "Admin", + "email": "admin@harness.io", + "type": "user", + "created": 1675390885380, + "updated": 1675390885380 + } }, "target_ref": { "name": "refs/heads/main", diff --git a/scm/driver/harness/testdata/webhooks/pull_request_opened.json.golden b/scm/driver/harness/testdata/webhooks/pull_request_opened.json.golden index 2928bf6a1..94b221212 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_opened.json.golden +++ b/scm/driver/harness/testdata/webhooks/pull_request_opened.json.golden @@ -1,9 +1,9 @@ { "Action": "created", "Repo": { - "ID": "aba", + "ID": "13", "Namespace": "", - "Name": "", + "Name": "aba", "Branch": "main", "Private": false, "Clone": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git", @@ -25,18 +25,24 @@ "Closed": false, "Merged": false, "Author": { - "Login": "", + "ID": "0osgWsTZRsSZ8RWfjLRkEg", + "Login": "0osgWsTZRsSZ8RWfjLRkEg", "Name": "Admin", "Email": "admin@harness.io", - "Avatar": "" + "Avatar": "", + "Created": "2023-02-02T18:21:25.38-08:00", + "Updated": "2023-02-02T18:21:25.38-08:00" }, "Created": "0001-01-01T00:00:00Z", "Updated": "0001-01-01T00:00:00Z" }, "Sender": { - "Login": "", - "Name": "", + "ID": "0osgWsTZRsSZ8RWfjLRkEg", + "Login": "0osgWsTZRsSZ8RWfjLRkEg", + "Name": "default", "Email": "default@harness.io", - "Avatar": "" + "Avatar": "", + "Created": "2023-02-02T18:21:25.38-08:00", + "Updated": "2023-02-02T18:21:25.38-08:00" } } \ No newline at end of file diff --git a/scm/driver/harness/testdata/webhooks/pull_request_reopened.json b/scm/driver/harness/testdata/webhooks/pull_request_reopened.json index c6549d374..d8a8b2d86 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_reopened.json +++ b/scm/driver/harness/testdata/webhooks/pull_request_reopened.json @@ -25,7 +25,16 @@ "source_branch": "b", "target_repo_id": 13, "target_branch": "main", - "merge_strategy": null + "merge_strategy": null, + "author": { + "id": 8, + "uid": "0osgWsTZRsSZ8RWfjLRkEg", + "display_name": "Admin", + "email": "admin@harness.io", + "type": "user", + "created": 1675390885380, + "updated": 1675390885380 + } }, "target_ref": { "name": "refs/heads/main", diff --git a/scm/driver/harness/testdata/webhooks/pull_request_reopened.json.golden b/scm/driver/harness/testdata/webhooks/pull_request_reopened.json.golden index 03f8b54df..56968a689 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_reopened.json.golden +++ b/scm/driver/harness/testdata/webhooks/pull_request_reopened.json.golden @@ -1,9 +1,9 @@ { "Action": "reopened", "Repo": { - "ID": "aba", + "ID": "13", "Namespace": "", - "Name": "", + "Name": "aba", "Branch": "main", "Private": false, "Clone": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git", @@ -25,18 +25,24 @@ "Closed": false, "Merged": false, "Author": { - "Login": "", + "ID": "0osgWsTZRsSZ8RWfjLRkEg", + "Login": "0osgWsTZRsSZ8RWfjLRkEg", "Name": "Admin", "Email": "admin@harness.io", - "Avatar": "" + "Avatar": "", + "Created": "2023-02-02T18:21:25.38-08:00", + "Updated": "2023-02-02T18:21:25.38-08:00" }, "Created": "0001-01-01T00:00:00Z", "Updated": "0001-01-01T00:00:00Z" }, "Sender": { - "Login": "", - "Name": "", + "ID": "0osgWsTZRsSZ8RWfjLRkEg", + "Login": "0osgWsTZRsSZ8RWfjLRkEg", + "Name": "default", "Email": "default@harness.io", - "Avatar": "" + "Avatar": "", + "Created": "2023-02-02T18:21:25.38-08:00", + "Updated": "2023-02-02T18:21:25.38-08:00" } } \ No newline at end of file diff --git a/scm/driver/harness/webhook.go b/scm/driver/harness/webhook.go index cc077a6ca..1c63738aa 100644 --- a/scm/driver/harness/webhook.go +++ b/scm/driver/harness/webhook.go @@ -10,6 +10,8 @@ import ( "io" "io/ioutil" "net/http" + "strconv" + "time" "github.com/drone/go-scm/scm" "github.com/drone/go-scm/scm/driver/internal/hmac" @@ -39,6 +41,8 @@ func (s *webhookService) Parse(req *http.Request, fn scm.SecretFunc) (scm.Webhoo hook, err = s.parsePushHook(data) case "pullreq_created", "pullreq_reopened", "pullreq_branch_updated": hook, err = s.parsePullRequestHook(data) + case "pullreq_comment_created": + hook, err = s.parsePullRequestCommentHook(data) default: return nil, scm.ErrUnknownEvent } @@ -89,6 +93,12 @@ func (s *webhookService) parsePushHook(data []byte) (scm.Webhook, error) { return convertPushHook(dst), err } +func (s *webhookService) parsePullRequestCommentHook(data []byte) (scm.Webhook, error) { + dst := new(pullRequestCommentHook) + err := json.Unmarshal(data, dst) + return convertPullRequestCommentHook(dst), err +} + // native data structures type ( repo struct { @@ -117,6 +127,7 @@ type ( TargetRepoID int `json:"target_repo_id"` TargetBranch string `json:"target_branch"` MergeStrategy interface{} `json:"merge_strategy"` + Author principal `json:"author"` } targetRef struct { Name string `json:"name"` @@ -156,6 +167,10 @@ type ( When string `json:"when"` } `json:"committer"` } + comment struct { + ID int `json:"id"` + Text string `json:"text"` + } // harness pull request webhook payload pullRequestHook struct { Trigger string `json:"trigger"` @@ -178,61 +193,57 @@ type ( OldSha string `json:"old_sha"` Forced bool `json:"forced"` } + // harness pull request comment webhook payload + pullRequestCommentHook struct { + Trigger string `json:"trigger"` + Repo repo `json:"repo"` + Principal principal `json:"principal"` + PullReq pullReq `json:"pull_req"` + TargetRef targetRef `json:"target_ref"` + Ref ref `json:"ref"` + Sha string `json:"sha"` + Commit hookCommit `json:"commit"` + Comment comment `json:"comment"` + } ) -// // native data structure conversion -// - -func convertPullRequestHook(dst *pullRequestHook) *scm.PullRequestHook { +func convertPullRequestHook(src *pullRequestHook) *scm.PullRequestHook { return &scm.PullRequestHook{ - Action: convertAction(dst.Trigger), - PullRequest: scm.PullRequest{ - Number: dst.PullReq.Number, - Title: dst.PullReq.Title, - Closed: dst.PullReq.State != "open", - Source: dst.PullReq.SourceBranch, - Target: dst.PullReq.TargetBranch, - Fork: "fork", - Link: dst.Ref.Repo.GitURL, - Sha: dst.Commit.Sha, - Ref: dst.Ref.Name, - Author: scm.User{ - Name: dst.Commit.Committer.Identity.Name, - Email: dst.Commit.Committer.Identity.Email, - }, - }, - Repo: scm.Repository{ - ID: dst.Repo.UID, - Branch: dst.Repo.DefaultBranch, - Link: dst.Repo.GitURL, - Clone: dst.Repo.GitURL, - }, - Sender: scm.User{ - Email: dst.Principal.Email, - }, + Action: convertAction(src.Trigger), + PullRequest: convertPullReq(src.PullReq, src.Ref, src.Commit), + Repo: convertRepo(src.Repo), + Sender: convertUser(src.Principal), } } -func convertPushHook(dst *pushHook) *scm.PushHook { +func convertPushHook(src *pushHook) *scm.PushHook { return &scm.PushHook{ - Ref: dst.Sha, - Before: dst.OldSha, - After: dst.Sha, - Repo: scm.Repository{ - Name: dst.Repo.UID, - }, + Ref: src.Sha, + Before: src.OldSha, + After: src.Sha, + Repo: convertRepo(src.Repo), Commit: scm.Commit{ - Sha: dst.Commit.Sha, - Message: dst.Commit.Message, + Sha: src.Commit.Sha, + Message: src.Commit.Message, Author: scm.Signature{ - Name: dst.Commit.Author.Identity.Name, - Email: dst.Commit.Author.Identity.Email, + Name: src.Commit.Author.Identity.Name, + Email: src.Commit.Author.Identity.Email, }, }, - Sender: scm.User{ - Name: dst.Principal.DisplayName, + Sender: convertUser(src.Principal), + } +} + +func convertPullRequestCommentHook(src *pullRequestCommentHook) *scm.PullRequestCommentHook { + return &scm.PullRequestCommentHook{ + PullRequest: convertPullReq(src.PullReq, src.Ref, src.Commit), + Repo: convertRepo(src.Repo), + Comment: scm.Comment{ + Body: src.Comment.Text, + ID: src.Comment.ID, }, + Sender: convertUser(src.Principal), } } @@ -248,3 +259,39 @@ func convertAction(src string) (action scm.Action) { return } } + +func convertPullReq(pr pullReq, ref ref, commit hookCommit) scm.PullRequest { + return scm.PullRequest{ + Number: pr.Number, + Title: pr.Title, + Closed: pr.State != "open", + Source: pr.SourceBranch, + Target: pr.TargetBranch, + Fork: "fork", + Link: ref.Repo.GitURL, + Sha: commit.Sha, + Ref: ref.Name, + Author: convertUser(pr.Author), + } +} + +func convertRepo(repo repo) scm.Repository { + return scm.Repository{ + ID: strconv.Itoa(repo.ID), + Name: repo.UID, + Branch: repo.DefaultBranch, + Link: repo.GitURL, + Clone: repo.GitURL, + } +} + +func convertUser(principal principal) scm.User { + return scm.User{ + Name: principal.DisplayName, + ID: principal.UID, + Login: principal.UID, + Email: principal.Email, + Created: time.Unix(0, principal.Created*int64(time.Millisecond)), + Updated: time.Unix(0, principal.Updated*int64(time.Millisecond)), + } +} diff --git a/scm/driver/harness/webhook_test.go b/scm/driver/harness/webhook_test.go index 4e38687be..175115e61 100644 --- a/scm/driver/harness/webhook_test.go +++ b/scm/driver/harness/webhook_test.go @@ -57,6 +57,13 @@ func TestWebhooks(t *testing.T) { after: "testdata/webhooks/pull_request_branch_updated.json.golden", obj: new(scm.PullRequestHook), }, + // pull request comment created + { + event: "pullreq_comment_created", + before: "testdata/webhooks/pull_request_comment_created.json", + after: "testdata/webhooks/pull_request_comment_created.json.golden", + obj: new(scm.PullRequestCommentHook), + }, } for _, test := range tests { From dc565fcc0b5b0557706473cb5addc60f7ab5c38b Mon Sep 17 00:00:00 2001 From: dependabot-ci Date: Fri, 27 Oct 2023 11:02:48 +0100 Subject: [PATCH 096/195] (maint) prep 1.33.0 --- CHANGELOG.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 192ce1fe7..804c053d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,30 @@ # Changelog +## [v1.33.0](https://github.com/drone/go-scm/tree/v1.33.0) (2023-10-27) + +[Full Changelog](https://github.com/drone/go-scm/compare/v1.32.3...v1.33.0) + +**Implemented enhancements:** + +- feat: Add pr\_comment webhook for harness [\#280](https://github.com/drone/go-scm/pull/280) ([abhinav-harness](https://github.com/abhinav-harness)) + +## [v1.32.3](https://github.com/drone/go-scm/tree/v1.32.3) (2023-10-11) + +[Full Changelog](https://github.com/drone/go-scm/compare/v1.32.2...v1.32.3) + +**Fixed bugs:** + +- fix: ref should have pullreq instead of pull for gitness [\#279](https://github.com/drone/go-scm/pull/279) ([abhinav-harness](https://github.com/abhinav-harness)) +- fix: ref should have pullreq instead of pull for gitness [\#278](https://github.com/drone/go-scm/pull/278) ([abhinav-harness](https://github.com/abhinav-harness)) + +## [v1.32.2](https://github.com/drone/go-scm/tree/v1.32.2) (2023-10-03) + +[Full Changelog](https://github.com/drone/go-scm/compare/v1.32.1...v1.32.2) + +**Implemented enhancements:** + +- feat: Harness list commits api update as per new spec [\#277](https://github.com/drone/go-scm/pull/277) ([abhinav-harness](https://github.com/abhinav-harness)) + ## [v1.32.1](https://github.com/drone/go-scm/tree/v1.32.1) (2023-09-27) [Full Changelog](https://github.com/drone/go-scm/compare/v1.32.0...v1.32.1) @@ -10,6 +35,7 @@ **Merged pull requests:** +- \(maint\) prep for 1.32.1 [\#276](https://github.com/drone/go-scm/pull/276) ([tphoney](https://github.com/tphoney)) - \(maint\) clean integration testing for stash [\#273](https://github.com/drone/go-scm/pull/273) ([tphoney](https://github.com/tphoney)) ## [v1.32.0](https://github.com/drone/go-scm/tree/v1.32.0) (2023-09-12) From a802ce1843efbc49b09d2e88ce6bb97f0e7e20b9 Mon Sep 17 00:00:00 2001 From: Abhinav Singh Date: Thu, 7 Dec 2023 03:26:10 +0530 Subject: [PATCH 097/195] feat: add support for branch update for gitness (#283) --- .../webhooks/branch_create.json.golden | 4 +- .../testdata/webhooks/branch_updated.json | 50 +++++++++++++++++++ .../webhooks/branch_updated.json.golden | 46 +++++++++++++++++ scm/driver/harness/webhook.go | 6 ++- scm/driver/harness/webhook_test.go | 7 +++ 5 files changed, 110 insertions(+), 3 deletions(-) create mode 100644 scm/driver/harness/testdata/webhooks/branch_updated.json create mode 100644 scm/driver/harness/testdata/webhooks/branch_updated.json.golden diff --git a/scm/driver/harness/testdata/webhooks/branch_create.json.golden b/scm/driver/harness/testdata/webhooks/branch_create.json.golden index 0b0dad736..9bc611b39 100644 --- a/scm/driver/harness/testdata/webhooks/branch_create.json.golden +++ b/scm/driver/harness/testdata/webhooks/branch_create.json.golden @@ -26,8 +26,8 @@ "Avatar": "" }, "Committer": { - "Name": "", - "Email": "", + "Name": "Admin", + "Email": "admin@harness.io", "Date": "0001-01-01T00:00:00Z", "Login": "", "Avatar": "" diff --git a/scm/driver/harness/testdata/webhooks/branch_updated.json b/scm/driver/harness/testdata/webhooks/branch_updated.json new file mode 100644 index 000000000..903fea7dd --- /dev/null +++ b/scm/driver/harness/testdata/webhooks/branch_updated.json @@ -0,0 +1,50 @@ +{ + "trigger": "branch_updated", + "repo": { + "id": 68, + "path": "vpCkHKsDSxK9_KYfjCTMKA/default/Repo_With_PR_checks/abhinav-git-sync", + "uid": "abhinav-git-sync", + "default_branch": "master", + "git_url": "https://git.harness.io/vpCkHKsDSxK9_KYfjCTMKA/default/Repo_With_PR_checks/abhinav-git-sync.git" + }, + "principal": { + "id": 59, + "uid": "ec9UfvFwTf663F47Hlqxbg", + "display_name": "abhinav.singh@harness.io", + "email": "abhinav.singh@harness.io", + "type": "user", + "created": 1697617589873, + "updated": 1697617589873 + }, + "ref": { + "name": "refs/heads/master", + "repo": { + "id": 68, + "path": "vpCkHKsDSxK9_KYfjCTMKA/default/Repo_With_PR_checks/abhinav-git-sync", + "uid": "abhinav-git-sync", + "default_branch": "master", + "git_url": "https://git.harness.io/vpCkHKsDSxK9_KYfjCTMKA/default/Repo_With_PR_checks/abhinav-git-sync.git" + } + }, + "sha": "92e21bfcddc1418079cddbb518ad6fd72917798a", + "commit": { + "sha": "92e21bfcddc1418079cddbb518ad6fd72917798a", + "message": "Create asdsad (#2)", + "author": { + "identity": { + "name": "abhinav.singh@harness.io", + "email": "abhinav.singh@harness.io" + }, + "when": "2023-12-05T11:59:39Z" + }, + "committer": { + "identity": { + "name": "Harness", + "email": "noreply@harness.io" + }, + "when": "2023-12-05T11:59:39Z" + } + }, + "old_sha": "a273c385628167932e10caaa58e12550c491f241", + "forced": false +} \ No newline at end of file diff --git a/scm/driver/harness/testdata/webhooks/branch_updated.json.golden b/scm/driver/harness/testdata/webhooks/branch_updated.json.golden new file mode 100644 index 000000000..1537f8d87 --- /dev/null +++ b/scm/driver/harness/testdata/webhooks/branch_updated.json.golden @@ -0,0 +1,46 @@ +{ + "Ref": "92e21bfcddc1418079cddbb518ad6fd72917798a", + "Before": "a273c385628167932e10caaa58e12550c491f241", + "After": "92e21bfcddc1418079cddbb518ad6fd72917798a", + "Repo": { + "ID": "68", + "Namespace": "", + "Name": "abhinav-git-sync", + "Perm": null, + "Branch": "master", + "Private": false, + "Clone": "https://git.harness.io/vpCkHKsDSxK9_KYfjCTMKA/default/Repo_With_PR_checks/abhinav-git-sync.git", + "CloneSSH": "", + "Link": "https://git.harness.io/vpCkHKsDSxK9_KYfjCTMKA/default/Repo_With_PR_checks/abhinav-git-sync.git", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Commit": { + "Sha": "92e21bfcddc1418079cddbb518ad6fd72917798a", + "Message": "Create asdsad (#2)", + "Author": { + "Name": "abhinav.singh@harness.io", + "Email": "abhinav.singh@harness.io", + "Date" : "0001-01-01T00:00:00Z", + "Login": "", + "Avatar": "" + }, + "Committer": { + "Name": "Harness", + "Email": "noreply@harness.io", + "Date": "0001-01-01T00:00:00Z", + "Login": "", + "Avatar": "" + }, + "Link": "" + }, + "Sender": { + "ID": "ec9UfvFwTf663F47Hlqxbg", + "Login": "ec9UfvFwTf663F47Hlqxbg", + "Name": "abhinav.singh@harness.io", + "Email": "abhinav.singh@harness.io", + "Avatar": "", + "Created": "2023-10-18T13:56:29.873+05:30", + "Updated": "2023-10-18T13:56:29.873+05:30" + } +} \ No newline at end of file diff --git a/scm/driver/harness/webhook.go b/scm/driver/harness/webhook.go index 1c63738aa..d1ce064fd 100644 --- a/scm/driver/harness/webhook.go +++ b/scm/driver/harness/webhook.go @@ -37,7 +37,7 @@ func (s *webhookService) Parse(req *http.Request, fn scm.SecretFunc) (scm.Webhoo // hook, err = s.parseDeleteHook(data) // case "issues": // hook, err = s.parseIssueHook(data) - case "branch_created": + case "branch_created", "branch_updated": hook, err = s.parsePushHook(data) case "pullreq_created", "pullreq_reopened", "pullreq_branch_updated": hook, err = s.parsePullRequestHook(data) @@ -230,6 +230,10 @@ func convertPushHook(src *pushHook) *scm.PushHook { Name: src.Commit.Author.Identity.Name, Email: src.Commit.Author.Identity.Email, }, + Committer: scm.Signature{ + Name: src.Commit.Committer.Identity.Name, + Email: src.Commit.Committer.Identity.Email, + }, }, Sender: convertUser(src.Principal), } diff --git a/scm/driver/harness/webhook_test.go b/scm/driver/harness/webhook_test.go index 175115e61..5e8d7cdf2 100644 --- a/scm/driver/harness/webhook_test.go +++ b/scm/driver/harness/webhook_test.go @@ -33,6 +33,13 @@ func TestWebhooks(t *testing.T) { after: "testdata/webhooks/branch_create.json.golden", obj: new(scm.PushHook), }, + // push branch update + { + event: "branch_updated", + before: "testdata/webhooks/branch_updated.json", + after: "testdata/webhooks/branch_updated.json.golden", + obj: new(scm.PushHook), + }, // // pull request events // From 96d3e4faf81ea872b5abb3db321e6e21d6ca0f68 Mon Sep 17 00:00:00 2001 From: dependabot-ci Date: Thu, 7 Dec 2023 14:50:26 +0000 Subject: [PATCH 098/195] (maint) v1.34.0 prep --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 804c053d6..2c912f256 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [v1.34.0](https://github.com/drone/go-scm/tree/v1.34.0) (2023-12-07) + +[Full Changelog](https://github.com/drone/go-scm/compare/v1.33.0...v1.34.0) + +**Implemented enhancements:** + +- feat: add support for branch update for gitness [\#283](https://github.com/drone/go-scm/pull/283) ([abhinav-harness](https://github.com/abhinav-harness)) + ## [v1.33.0](https://github.com/drone/go-scm/tree/v1.33.0) (2023-10-27) [Full Changelog](https://github.com/drone/go-scm/compare/v1.32.3...v1.33.0) @@ -8,6 +16,10 @@ - feat: Add pr\_comment webhook for harness [\#280](https://github.com/drone/go-scm/pull/280) ([abhinav-harness](https://github.com/abhinav-harness)) +**Merged pull requests:** + +- \(maint\) prep 1.33.0 [\#281](https://github.com/drone/go-scm/pull/281) ([tphoney](https://github.com/tphoney)) + ## [v1.32.3](https://github.com/drone/go-scm/tree/v1.32.3) (2023-10-11) [Full Changelog](https://github.com/drone/go-scm/compare/v1.32.2...v1.32.3) From 05fe67f7db9b3a7c664aa7ce697c0e4852a9a00b Mon Sep 17 00:00:00 2001 From: Abhinav Singh Date: Fri, 8 Dec 2023 14:04:21 +0530 Subject: [PATCH 099/195] fix: use opts for harness list commits --- scm/driver/harness/git.go | 4 ++-- scm/driver/harness/util.go | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/scm/driver/harness/git.go b/scm/driver/harness/git.go index 85b17bff1..25923a56e 100644 --- a/scm/driver/harness/git.go +++ b/scm/driver/harness/git.go @@ -60,9 +60,9 @@ func (s *gitService) ListBranchesV2(ctx context.Context, repo string, opts scm.B return s.ListBranches(ctx, repo, opts.PageListOptions) } -func (s *gitService) ListCommits(ctx context.Context, repo string, _ scm.CommitListOptions) ([]*scm.Commit, *scm.Response, error) { +func (s *gitService) ListCommits(ctx context.Context, repo string, opts scm.CommitListOptions) ([]*scm.Commit, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/commits", harnessURI) + path := fmt.Sprintf("api/v1/repos/%s/commits?%s", harnessURI, encodeCommitListOptions(opts)) out := new(commits) res, err := s.client.do(ctx, "GET", path, nil, &out) return convertCommitList(out), res, err diff --git a/scm/driver/harness/util.go b/scm/driver/harness/util.go index fe7778d9e..78fc8cc9e 100644 --- a/scm/driver/harness/util.go +++ b/scm/driver/harness/util.go @@ -114,3 +114,20 @@ func encodeReleaseListOptions(o ListOptions) string { query.Add("limit", fmt.Sprintf("%d", o.PageSize)) return query.Encode() } + +func encodeCommitListOptions(opts scm.CommitListOptions) string { + params := url.Values{} + if opts.Page != 0 { + params.Set("page", strconv.Itoa(opts.Page)) + } + if opts.Size != 0 { + params.Set("limit", strconv.Itoa(opts.Size)) + } + if opts.Ref != "" { + params.Set("git_ref", opts.Ref) + } + if opts.Path != "" { + params.Set("path", opts.Path) + } + return params.Encode() +} From 8ddff1fafaec51daece9145d341464ed1ece804a Mon Sep 17 00:00:00 2001 From: dependabot-ci Date: Fri, 8 Dec 2023 13:22:22 +0000 Subject: [PATCH 100/195] (maint) v1.34.1 release prep --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c912f256..739e13c01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [v1.34.1](https://github.com/drone/go-scm/tree/v1.34.1) (2023-12-08) + +[Full Changelog](https://github.com/drone/go-scm/compare/v1.34.0...v1.34.1) + +**Fixed bugs:** + +- fix: use opts for harness list commits [\#286](https://github.com/drone/go-scm/pull/286) ([abhinav-harness](https://github.com/abhinav-harness)) + ## [v1.34.0](https://github.com/drone/go-scm/tree/v1.34.0) (2023-12-07) [Full Changelog](https://github.com/drone/go-scm/compare/v1.33.0...v1.34.0) @@ -8,6 +16,10 @@ - feat: add support for branch update for gitness [\#283](https://github.com/drone/go-scm/pull/283) ([abhinav-harness](https://github.com/abhinav-harness)) +**Merged pull requests:** + +- \(maint\) v1.34.0 prep [\#284](https://github.com/drone/go-scm/pull/284) ([tphoney](https://github.com/tphoney)) + ## [v1.33.0](https://github.com/drone/go-scm/tree/v1.33.0) (2023-10-27) [Full Changelog](https://github.com/drone/go-scm/compare/v1.32.3...v1.33.0) From e6556d14011a4ae33c38f77d211f4f54458e278c Mon Sep 17 00:00:00 2001 From: Abhinav Singh Date: Wed, 20 Dec 2023 14:58:17 +0530 Subject: [PATCH 101/195] feat: support more events in webhook parse in go-scm for gitness (#289) --- .../webhooks/pull_request_closed.json | 77 ++++++++++++++++++ .../webhooks/pull_request_closed.json.golden | 48 ++++++++++++ .../webhooks/pull_request_merged.json | 78 +++++++++++++++++++ .../webhooks/pull_request_merged.json.golden | 48 ++++++++++++ scm/driver/harness/webhook.go | 7 +- scm/driver/harness/webhook_test.go | 14 ++++ 6 files changed, 271 insertions(+), 1 deletion(-) create mode 100644 scm/driver/harness/testdata/webhooks/pull_request_closed.json create mode 100644 scm/driver/harness/testdata/webhooks/pull_request_closed.json.golden create mode 100644 scm/driver/harness/testdata/webhooks/pull_request_merged.json create mode 100644 scm/driver/harness/testdata/webhooks/pull_request_merged.json.golden diff --git a/scm/driver/harness/testdata/webhooks/pull_request_closed.json b/scm/driver/harness/testdata/webhooks/pull_request_closed.json new file mode 100644 index 000000000..f4f038ce7 --- /dev/null +++ b/scm/driver/harness/testdata/webhooks/pull_request_closed.json @@ -0,0 +1,77 @@ +{ + "trigger": "pullreq_closed", + "repo": { + "id": 22, + "path": "codeowners/asdsad", + "uid": "asdsad", + "default_branch": "main", + "git_url": "http://localhost:3000/git/codeowners/asdsad.git" + }, + "principal": { + "id": 3, + "uid": "admin", + "display_name": "Administrator", + "email": "admin@gitness.io", + "type": "user", + "created": 1696332021613, + "updated": 1696332021613 + }, + "pull_req": { + "number": 6, + "state": "closed", + "is_draft": false, + "title": "Create sad", + "source_repo_id": 22, + "source_branch": "asdxsa", + "target_repo_id": 22, + "target_branch": "main", + "author": { + "id": 3, + "uid": "admin", + "display_name": "Administrator", + "email": "admin@gitness.io", + "type": "user", + "created": 1696332021613, + "updated": 1696332021613 + } + }, + "target_ref": { + "name": "refs/heads/main", + "repo": { + "id": 22, + "path": "codeowners/asdsad", + "uid": "asdsad", + "default_branch": "main", + "git_url": "http://localhost:3000/git/codeowners/asdsad.git" + } + }, + "ref": { + "name": "refs/heads/asdxsa", + "repo": { + "id": 22, + "path": "codeowners/asdsad", + "uid": "asdsad", + "default_branch": "main", + "git_url": "http://localhost:3000/git/codeowners/asdsad.git" + } + }, + "sha": "27822dd2ec788f924c97b0b194c5bfd906f2e574", + "commit": { + "sha": "27822dd2ec788f924c97b0b194c5bfd906f2e574", + "message": "", + "author": { + "identity": { + "name": "Administrator", + "email": "admin@gitness.io" + }, + "when": "2023-12-20T13:10:47+05:30" + }, + "committer": { + "identity": { + "name": "Gitness", + "email": "system@gitness.io" + }, + "when": "2023-12-20T13:10:47+05:30" + } + } +} \ No newline at end of file diff --git a/scm/driver/harness/testdata/webhooks/pull_request_closed.json.golden b/scm/driver/harness/testdata/webhooks/pull_request_closed.json.golden new file mode 100644 index 000000000..fad057ac1 --- /dev/null +++ b/scm/driver/harness/testdata/webhooks/pull_request_closed.json.golden @@ -0,0 +1,48 @@ +{ + "Action": "closed", + "Repo": { + "ID": "22", + "Namespace": "", + "Name": "asdsad", + "Branch": "main", + "Private": false, + "Clone": "http://localhost:3000/git/codeowners/asdsad.git", + "CloneSSH": "", + "Link": "http://localhost:3000/git/codeowners/asdsad.git", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "PullRequest": { + "Number": 6, + "Title": "Create sad", + "Body": "", + "Sha": "27822dd2ec788f924c97b0b194c5bfd906f2e574", + "Ref": "refs/heads/asdxsa", + "Source": "asdxsa", + "Target": "main", + "Fork": "fork", + "Link": "http://localhost:3000/git/codeowners/asdsad.git", + "Closed": true, + "Merged": false, + "Author": { + "ID": "admin", + "Login": "admin", + "Name": "Administrator", + "Email": "admin@gitness.io", + "Avatar": "", + "Created": "2023-10-03T16:50:21.613+05:30", + "Updated": "2023-10-03T16:50:21.613+05:30" + }, + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Sender": { + "ID": "admin", + "Login": "admin", + "Name": "Administrator", + "Email": "admin@gitness.io", + "Avatar": "", + "Created": "2023-10-03T16:50:21.613+05:30", + "Updated": "2023-10-03T16:50:21.613+05:30" + } +} \ No newline at end of file diff --git a/scm/driver/harness/testdata/webhooks/pull_request_merged.json b/scm/driver/harness/testdata/webhooks/pull_request_merged.json new file mode 100644 index 000000000..32f2dcc8a --- /dev/null +++ b/scm/driver/harness/testdata/webhooks/pull_request_merged.json @@ -0,0 +1,78 @@ +{ + "trigger": "pullreq_merged", + "repo": { + "id": 22, + "path": "codeowners/asdsad", + "uid": "asdsad", + "default_branch": "main", + "git_url": "http://localhost:3000/git/codeowners/asdsad.git" + }, + "principal": { + "id": 3, + "uid": "admin", + "display_name": "Administrator", + "email": "admin@gitness.io", + "type": "user", + "created": 1696332021613, + "updated": 1696332021613 + }, + "pull_req": { + "number": 10, + "state": "merged", + "is_draft": false, + "title": "Create xxasc", + "source_repo_id": 22, + "source_branch": "xas", + "target_repo_id": 22, + "target_branch": "main", + "merge_strategy": "squash", + "author": { + "id": 3, + "uid": "admin", + "display_name": "Administrator", + "email": "admin@gitness.io", + "type": "user", + "created": 1696332021613, + "updated": 1696332021613 + } + }, + "target_ref": { + "name": "refs/heads/main", + "repo": { + "id": 22, + "path": "codeowners/asdsad", + "uid": "asdsad", + "default_branch": "main", + "git_url": "http://localhost:3000/git/codeowners/asdsad.git" + } + }, + "ref": { + "name": "refs/heads/xas", + "repo": { + "id": 22, + "path": "codeowners/asdsad", + "uid": "asdsad", + "default_branch": "main", + "git_url": "http://localhost:3000/git/codeowners/asdsad.git" + } + }, + "sha": "4ec41187008f77222a60dfa21cdbd980f6490443", + "commit": { + "sha": "4ec41187008f77222a60dfa21cdbd980f6490443", + "message": "", + "author": { + "identity": { + "name": "Administrator", + "email": "admin@gitness.io" + }, + "when": "2023-12-20T13:40:52+05:30" + }, + "committer": { + "identity": { + "name": "Gitness", + "email": "system@gitness.io" + }, + "when": "2023-12-20T13:40:52+05:30" + } + } +} \ No newline at end of file diff --git a/scm/driver/harness/testdata/webhooks/pull_request_merged.json.golden b/scm/driver/harness/testdata/webhooks/pull_request_merged.json.golden new file mode 100644 index 000000000..fe707ce6e --- /dev/null +++ b/scm/driver/harness/testdata/webhooks/pull_request_merged.json.golden @@ -0,0 +1,48 @@ +{ + "Action": "merged", + "Repo": { + "ID": "22", + "Namespace": "", + "Name": "asdsad", + "Branch": "main", + "Private": false, + "Clone": "http://localhost:3000/git/codeowners/asdsad.git", + "CloneSSH": "", + "Link": "http://localhost:3000/git/codeowners/asdsad.git", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "PullRequest": { + "Number": 10, + "Title": "Create xxasc", + "Body": "", + "Sha": "4ec41187008f77222a60dfa21cdbd980f6490443", + "Ref": "refs/heads/xas", + "Source": "xas", + "Target": "main", + "Fork": "fork", + "Link": "http://localhost:3000/git/codeowners/asdsad.git", + "Closed": true, + "Merged": true, + "Author": { + "ID": "admin", + "Login": "admin", + "Name": "Administrator", + "Email": "admin@gitness.io", + "Avatar": "", + "Created": "2023-10-03T16:50:21.613+05:30", + "Updated": "2023-10-03T16:50:21.613+05:30" + }, + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Sender": { + "ID": "admin", + "Login": "admin", + "Name": "Administrator", + "Email": "admin@gitness.io", + "Avatar": "", + "Created": "2023-10-03T16:50:21.613+05:30", + "Updated": "2023-10-03T16:50:21.613+05:30" + } +} \ No newline at end of file diff --git a/scm/driver/harness/webhook.go b/scm/driver/harness/webhook.go index d1ce064fd..10f808e9a 100644 --- a/scm/driver/harness/webhook.go +++ b/scm/driver/harness/webhook.go @@ -39,7 +39,7 @@ func (s *webhookService) Parse(req *http.Request, fn scm.SecretFunc) (scm.Webhoo // hook, err = s.parseIssueHook(data) case "branch_created", "branch_updated": hook, err = s.parsePushHook(data) - case "pullreq_created", "pullreq_reopened", "pullreq_branch_updated": + case "pullreq_created", "pullreq_reopened", "pullreq_branch_updated", "pullreq_closed", "pullreq_merged": hook, err = s.parsePullRequestHook(data) case "pullreq_comment_created": hook, err = s.parsePullRequestCommentHook(data) @@ -259,6 +259,10 @@ func convertAction(src string) (action scm.Action) { return scm.ActionUpdate case "pullreq_reopened": return scm.ActionReopen + case "pullreq_closed": + return scm.ActionClose + case "pullreq_merged": + return scm.ActionMerge default: return } @@ -271,6 +275,7 @@ func convertPullReq(pr pullReq, ref ref, commit hookCommit) scm.PullRequest { Closed: pr.State != "open", Source: pr.SourceBranch, Target: pr.TargetBranch, + Merged: pr.State == "merged", Fork: "fork", Link: ref.Repo.GitURL, Sha: commit.Sha, diff --git a/scm/driver/harness/webhook_test.go b/scm/driver/harness/webhook_test.go index 5e8d7cdf2..26966db2b 100644 --- a/scm/driver/harness/webhook_test.go +++ b/scm/driver/harness/webhook_test.go @@ -71,6 +71,20 @@ func TestWebhooks(t *testing.T) { after: "testdata/webhooks/pull_request_comment_created.json.golden", obj: new(scm.PullRequestCommentHook), }, + // pull request closed + { + event: "pullreq_reopened", + before: "testdata/webhooks/pull_request_closed.json", + after: "testdata/webhooks/pull_request_closed.json.golden", + obj: new(scm.PullRequestHook), + }, + // pull request merged + { + event: "pullreq_reopened", + before: "testdata/webhooks/pull_request_merged.json", + after: "testdata/webhooks/pull_request_merged.json.golden", + obj: new(scm.PullRequestHook), + }, } for _, test := range tests { From 2877ffa2539608595859c0e94bf365cc9e94ed90 Mon Sep 17 00:00:00 2001 From: Abhinav Singh Date: Wed, 20 Dec 2023 14:58:29 +0530 Subject: [PATCH 102/195] fix: ref should be branch name for harness code (#288) * fix: ref should be branch name for harness code * fix: add uid for harness webhook --- scm/driver/harness/repo.go | 2 ++ scm/driver/harness/testdata/webhooks/branch_create.json.golden | 2 +- scm/driver/harness/testdata/webhooks/branch_updated.json.golden | 2 +- scm/driver/harness/webhook.go | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/scm/driver/harness/repo.go b/scm/driver/harness/repo.go index da4237555..b467a03db 100644 --- a/scm/driver/harness/repo.go +++ b/scm/driver/harness/repo.go @@ -75,6 +75,7 @@ func (s *repositoryService) CreateHook(ctx context.Context, repo string, input * in := new(hook) in.Enabled = true in.DisplayName = input.Name + in.UID = input.Name in.Secret = input.Secret in.Insecure = input.SkipVerify in.URL = input.Target @@ -134,6 +135,7 @@ type ( HasSecret bool `json:"has_secret"` Secret string `json:"secret"` ID int `json:"id"` + UID string `json:"uid"` Insecure bool `json:"insecure"` LatestExecutionResult string `json:"latest_execution_result"` ParentID int `json:"parent_id"` diff --git a/scm/driver/harness/testdata/webhooks/branch_create.json.golden b/scm/driver/harness/testdata/webhooks/branch_create.json.golden index 9bc611b39..a534de4c2 100644 --- a/scm/driver/harness/testdata/webhooks/branch_create.json.golden +++ b/scm/driver/harness/testdata/webhooks/branch_create.json.golden @@ -1,5 +1,5 @@ { - "Ref": "aeafa0e2e4ec6909ad75cb8fad57c0b1eb5986e6", + "Ref": "refs/heads/new2", "Before": "0000000000000000000000000000000000000000", "After": "aeafa0e2e4ec6909ad75cb8fad57c0b1eb5986e6", "Repo": { diff --git a/scm/driver/harness/testdata/webhooks/branch_updated.json.golden b/scm/driver/harness/testdata/webhooks/branch_updated.json.golden index 1537f8d87..550cf3b1d 100644 --- a/scm/driver/harness/testdata/webhooks/branch_updated.json.golden +++ b/scm/driver/harness/testdata/webhooks/branch_updated.json.golden @@ -1,5 +1,5 @@ { - "Ref": "92e21bfcddc1418079cddbb518ad6fd72917798a", + "Ref": "refs/heads/master", "Before": "a273c385628167932e10caaa58e12550c491f241", "After": "92e21bfcddc1418079cddbb518ad6fd72917798a", "Repo": { diff --git a/scm/driver/harness/webhook.go b/scm/driver/harness/webhook.go index 10f808e9a..73a3d8130 100644 --- a/scm/driver/harness/webhook.go +++ b/scm/driver/harness/webhook.go @@ -219,7 +219,7 @@ func convertPullRequestHook(src *pullRequestHook) *scm.PullRequestHook { func convertPushHook(src *pushHook) *scm.PushHook { return &scm.PushHook{ - Ref: src.Sha, + Ref: src.Ref.Name, Before: src.OldSha, After: src.Sha, Repo: convertRepo(src.Repo), From 93042b767ef7fe212e4636d64491a84e8a69f929 Mon Sep 17 00:00:00 2001 From: Abhinav Singh Date: Thu, 21 Dec 2023 01:51:08 +0530 Subject: [PATCH 103/195] feat: add pr link as coming from new webhook (#290) --- .../harness/testdata/webhooks/pull_request_branch_updated.json | 3 ++- .../testdata/webhooks/pull_request_branch_updated.json.golden | 2 +- scm/driver/harness/testdata/webhooks/pull_request_closed.json | 3 ++- .../harness/testdata/webhooks/pull_request_closed.json.golden | 2 +- .../testdata/webhooks/pull_request_comment_created.json | 3 ++- .../testdata/webhooks/pull_request_comment_created.json.golden | 2 +- scm/driver/harness/testdata/webhooks/pull_request_merged.json | 3 ++- .../harness/testdata/webhooks/pull_request_merged.json.golden | 2 +- scm/driver/harness/testdata/webhooks/pull_request_opened.json | 3 ++- .../harness/testdata/webhooks/pull_request_opened.json.golden | 2 +- .../harness/testdata/webhooks/pull_request_reopened.json | 3 ++- .../testdata/webhooks/pull_request_reopened.json.golden | 2 +- scm/driver/harness/webhook.go | 3 ++- 13 files changed, 20 insertions(+), 13 deletions(-) diff --git a/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json b/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json index 2709b46dc..144fc3f3e 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json +++ b/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json @@ -34,7 +34,8 @@ "type": "user", "created": 1675390885380, "updated": 1675390885380 - } + }, + "pr_url": "http://localhost:3000/codeowners/asdsad/pulls/14" }, "target_ref": { "name": "refs/heads/main", diff --git a/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json.golden b/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json.golden index 05c42eb0f..2b4f2a643 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json.golden +++ b/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json.golden @@ -21,7 +21,7 @@ "Source": "b", "Target": "main", "Fork": "fork", - "Link": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git", + "Link": "http://localhost:3000/codeowners/asdsad/pulls/14", "Closed": false, "Merged": false, "Author": { diff --git a/scm/driver/harness/testdata/webhooks/pull_request_closed.json b/scm/driver/harness/testdata/webhooks/pull_request_closed.json index f4f038ce7..496e01610 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_closed.json +++ b/scm/driver/harness/testdata/webhooks/pull_request_closed.json @@ -33,7 +33,8 @@ "type": "user", "created": 1696332021613, "updated": 1696332021613 - } + }, + "pr_url": "http://localhost:3000/codeowners/asdsad/pulls/14" }, "target_ref": { "name": "refs/heads/main", diff --git a/scm/driver/harness/testdata/webhooks/pull_request_closed.json.golden b/scm/driver/harness/testdata/webhooks/pull_request_closed.json.golden index fad057ac1..8b5fc2143 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_closed.json.golden +++ b/scm/driver/harness/testdata/webhooks/pull_request_closed.json.golden @@ -21,7 +21,7 @@ "Source": "asdxsa", "Target": "main", "Fork": "fork", - "Link": "http://localhost:3000/git/codeowners/asdsad.git", + "Link": "http://localhost:3000/codeowners/asdsad/pulls/14", "Closed": true, "Merged": false, "Author": { diff --git a/scm/driver/harness/testdata/webhooks/pull_request_comment_created.json b/scm/driver/harness/testdata/webhooks/pull_request_comment_created.json index 3b39a54fd..52ae75598 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_comment_created.json +++ b/scm/driver/harness/testdata/webhooks/pull_request_comment_created.json @@ -34,7 +34,8 @@ "type": "user", "created": 1675390885380, "updated": 1675390885380 - } + }, + "pr_url": "http://localhost:3000/codeowners/asdsad/pulls/14" }, "target_ref": { "name": "refs/heads/main", diff --git a/scm/driver/harness/testdata/webhooks/pull_request_comment_created.json.golden b/scm/driver/harness/testdata/webhooks/pull_request_comment_created.json.golden index ed14715f7..cb96e2634 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_comment_created.json.golden +++ b/scm/driver/harness/testdata/webhooks/pull_request_comment_created.json.golden @@ -20,7 +20,7 @@ "Source": "pr2", "Target": "main", "Fork": "fork", - "Link": "http://localhost:3000/git/asd/demo.git", + "Link": "http://localhost:3000/codeowners/asdsad/pulls/14", "Closed": false, "Merged": false, "Author": { diff --git a/scm/driver/harness/testdata/webhooks/pull_request_merged.json b/scm/driver/harness/testdata/webhooks/pull_request_merged.json index 32f2dcc8a..54beca25c 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_merged.json +++ b/scm/driver/harness/testdata/webhooks/pull_request_merged.json @@ -34,7 +34,8 @@ "type": "user", "created": 1696332021613, "updated": 1696332021613 - } + }, + "pr_url": "http://localhost:3000/codeowners/asdsad/pulls/14" }, "target_ref": { "name": "refs/heads/main", diff --git a/scm/driver/harness/testdata/webhooks/pull_request_merged.json.golden b/scm/driver/harness/testdata/webhooks/pull_request_merged.json.golden index fe707ce6e..3bef4116c 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_merged.json.golden +++ b/scm/driver/harness/testdata/webhooks/pull_request_merged.json.golden @@ -21,7 +21,7 @@ "Source": "xas", "Target": "main", "Fork": "fork", - "Link": "http://localhost:3000/git/codeowners/asdsad.git", + "Link": "http://localhost:3000/codeowners/asdsad/pulls/14", "Closed": true, "Merged": true, "Author": { diff --git a/scm/driver/harness/testdata/webhooks/pull_request_opened.json b/scm/driver/harness/testdata/webhooks/pull_request_opened.json index 45b76600c..abc82426c 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_opened.json +++ b/scm/driver/harness/testdata/webhooks/pull_request_opened.json @@ -34,7 +34,8 @@ "type": "user", "created": 1675390885380, "updated": 1675390885380 - } + }, + "pr_url": "http://localhost:3000/codeowners/asdsad/pulls/14" }, "target_ref": { "name": "refs/heads/main", diff --git a/scm/driver/harness/testdata/webhooks/pull_request_opened.json.golden b/scm/driver/harness/testdata/webhooks/pull_request_opened.json.golden index 94b221212..9ea430e3d 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_opened.json.golden +++ b/scm/driver/harness/testdata/webhooks/pull_request_opened.json.golden @@ -21,7 +21,7 @@ "Source": "b", "Target": "main", "Fork": "fork", - "Link": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git", + "Link": "http://localhost:3000/codeowners/asdsad/pulls/14", "Closed": false, "Merged": false, "Author": { diff --git a/scm/driver/harness/testdata/webhooks/pull_request_reopened.json b/scm/driver/harness/testdata/webhooks/pull_request_reopened.json index d8a8b2d86..ab57a9e14 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_reopened.json +++ b/scm/driver/harness/testdata/webhooks/pull_request_reopened.json @@ -34,7 +34,8 @@ "type": "user", "created": 1675390885380, "updated": 1675390885380 - } + }, + "pr_url": "http://localhost:3000/codeowners/asdsad/pulls/14" }, "target_ref": { "name": "refs/heads/main", diff --git a/scm/driver/harness/testdata/webhooks/pull_request_reopened.json.golden b/scm/driver/harness/testdata/webhooks/pull_request_reopened.json.golden index 56968a689..32bc95964 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_reopened.json.golden +++ b/scm/driver/harness/testdata/webhooks/pull_request_reopened.json.golden @@ -21,7 +21,7 @@ "Source": "b", "Target": "main", "Fork": "fork", - "Link": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/myOrg/myProject/aba.git", + "Link": "http://localhost:3000/codeowners/asdsad/pulls/14", "Closed": false, "Merged": false, "Author": { diff --git a/scm/driver/harness/webhook.go b/scm/driver/harness/webhook.go index 73a3d8130..4a087d629 100644 --- a/scm/driver/harness/webhook.go +++ b/scm/driver/harness/webhook.go @@ -128,6 +128,7 @@ type ( TargetBranch string `json:"target_branch"` MergeStrategy interface{} `json:"merge_strategy"` Author principal `json:"author"` + PrURL string `json:"pr_url"` } targetRef struct { Name string `json:"name"` @@ -277,7 +278,7 @@ func convertPullReq(pr pullReq, ref ref, commit hookCommit) scm.PullRequest { Target: pr.TargetBranch, Merged: pr.State == "merged", Fork: "fork", - Link: ref.Repo.GitURL, + Link: pr.PrURL, Sha: commit.Sha, Ref: ref.Name, Author: convertUser(pr.Author), From 5a98a57b714fee467dbc1368f901d421294c280d Mon Sep 17 00:00:00 2001 From: Vivek Dixit Date: Mon, 8 Jan 2024 12:01:56 +0530 Subject: [PATCH 104/195] Update content.go --- scm/driver/github/content.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scm/driver/github/content.go b/scm/driver/github/content.go index 709cf705f..19c734e6a 100644 --- a/scm/driver/github/content.go +++ b/scm/driver/github/content.go @@ -8,6 +8,7 @@ import ( "context" "encoding/base64" "fmt" + "net/url" "github.com/drone/go-scm/scm" ) @@ -17,7 +18,8 @@ type contentService struct { } func (s *contentService) Find(ctx context.Context, repo, path, ref string) (*scm.Content, *scm.Response, error) { - endpoint := fmt.Sprintf("repos/%s/contents/%s?ref=%s", repo, path, ref) + urlEncodedRef := url.QueryEscape(ref) + endpoint := fmt.Sprintf("repos/%s/contents/%s?ref=%s", repo, path, urlEncodedRef) out := new(content) res, err := s.client.do(ctx, "GET", endpoint, nil, out) raw, _ := base64.StdEncoding.DecodeString(out.Content) From b4f0d9b87888f45f782e183a35b1ad8008af920b Mon Sep 17 00:00:00 2001 From: Vivek Dixit Date: Mon, 8 Jan 2024 15:36:00 +0530 Subject: [PATCH 105/195] Update content.go --- scm/driver/azure/content.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scm/driver/azure/content.go b/scm/driver/azure/content.go index 689f6718f..b300049f6 100644 --- a/scm/driver/azure/content.go +++ b/scm/driver/azure/content.go @@ -8,6 +8,7 @@ import ( "context" "encoding/base64" "fmt" + "net/url" "github.com/drone/go-scm/scm" ) @@ -21,8 +22,9 @@ func (s *contentService) Find(ctx context.Context, repo, path, ref string) (*scm if s.client.project == "" { return nil, nil, ProjectRequiredError() } + urlEncodedRef := url.QueryEscape(ref) endpoint := fmt.Sprintf("%s/%s/_apis/git/repositories/%s/items?path=%s&includeContent=true&$format=json", s.client.owner, s.client.project, repo, path) - endpoint += generateURIFromRef(ref) + endpoint += generateURIFromRef(urlEncodedRef) endpoint += "&api-version=6.0" out := new(content) res, err := s.client.do(ctx, "GET", endpoint, nil, out) From c1465b7c085af0b07be0c8382923c73ce2b8ac3d Mon Sep 17 00:00:00 2001 From: Vivek Dixit Date: Tue, 9 Jan 2024 13:47:37 +0530 Subject: [PATCH 106/195] Update content.go --- scm/driver/gitlab/content.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scm/driver/gitlab/content.go b/scm/driver/gitlab/content.go index feef351f1..118802220 100644 --- a/scm/driver/gitlab/content.go +++ b/scm/driver/gitlab/content.go @@ -19,7 +19,8 @@ type contentService struct { } func (s *contentService) Find(ctx context.Context, repo, path, ref string) (*scm.Content, *scm.Response, error) { - endpoint := fmt.Sprintf("api/v4/projects/%s/repository/files/%s?ref=%s", encode(repo), encodePath(path), ref) + urlEncodedRef := url.QueryEscape(ref) + endpoint := fmt.Sprintf("api/v4/projects/%s/repository/files/%s?ref=%s", encode(repo), encodePath(path), urlEncodedRef) out := new(content) res, err := s.client.do(ctx, "GET", endpoint, nil, out) raw, berr := base64.StdEncoding.DecodeString(out.Content) From 64261e5cdfcadafcd4d4dabfcc2953224eca2ca0 Mon Sep 17 00:00:00 2001 From: Vivek Dixit Date: Tue, 9 Jan 2024 16:24:26 +0530 Subject: [PATCH 107/195] Update content.go --- scm/driver/bitbucket/content.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scm/driver/bitbucket/content.go b/scm/driver/bitbucket/content.go index 3501de53f..1f9d7e358 100644 --- a/scm/driver/bitbucket/content.go +++ b/scm/driver/bitbucket/content.go @@ -8,6 +8,7 @@ import ( "bytes" "context" "fmt" + "net/url" "github.com/drone/go-scm/scm" ) @@ -17,7 +18,8 @@ type contentService struct { } func (s *contentService) Find(ctx context.Context, repo, path, ref string) (*scm.Content, *scm.Response, error) { - endpoint := fmt.Sprintf("/2.0/repositories/%s/src/%s/%s", repo, ref, path) + urlEncodedRef := url.QueryEscape(ref) + endpoint := fmt.Sprintf("/2.0/repositories/%s/src/%s/%s", repo, urlEncodedRef, path) out := new(bytes.Buffer) res, err := s.client.do(ctx, "GET", endpoint, nil, out) content := &scm.Content{ From de9fc725c24a2dc72a499cca8c3bdb8e34d760d9 Mon Sep 17 00:00:00 2001 From: Vivek Dixit Date: Tue, 9 Jan 2024 16:27:52 +0530 Subject: [PATCH 108/195] Update content.go --- scm/driver/bitbucket/content.go | 1 + 1 file changed, 1 insertion(+) diff --git a/scm/driver/bitbucket/content.go b/scm/driver/bitbucket/content.go index 1f9d7e358..1b2bccc86 100644 --- a/scm/driver/bitbucket/content.go +++ b/scm/driver/bitbucket/content.go @@ -18,6 +18,7 @@ type contentService struct { } func (s *contentService) Find(ctx context.Context, repo, path, ref string) (*scm.Content, *scm.Response, error) { + fmt.Println("ref->", ref) urlEncodedRef := url.QueryEscape(ref) endpoint := fmt.Sprintf("/2.0/repositories/%s/src/%s/%s", repo, urlEncodedRef, path) out := new(bytes.Buffer) From f637c3c3e2a4f8e5852fe9f1bfb39e362bb94c55 Mon Sep 17 00:00:00 2001 From: Vivek Dixit Date: Tue, 9 Jan 2024 16:32:11 +0530 Subject: [PATCH 109/195] Update content.go --- scm/driver/bitbucket/content.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scm/driver/bitbucket/content.go b/scm/driver/bitbucket/content.go index 1b2bccc86..14b07d160 100644 --- a/scm/driver/bitbucket/content.go +++ b/scm/driver/bitbucket/content.go @@ -21,6 +21,7 @@ func (s *contentService) Find(ctx context.Context, repo, path, ref string) (*scm fmt.Println("ref->", ref) urlEncodedRef := url.QueryEscape(ref) endpoint := fmt.Sprintf("/2.0/repositories/%s/src/%s/%s", repo, urlEncodedRef, path) + fmt.Println("endpoint->", endpoint) out := new(bytes.Buffer) res, err := s.client.do(ctx, "GET", endpoint, nil, out) content := &scm.Content{ @@ -30,7 +31,7 @@ func (s *contentService) Find(ctx context.Context, repo, path, ref string) (*scm if err != nil { return content, res, err } - metaEndpoint := fmt.Sprintf("/2.0/repositories/%s/src/%s/%s?format=meta", repo, ref, path) + metaEndpoint := fmt.Sprintf("/2.0/repositories/%s/src/%s/%s?format=meta", repo, urlEncodedRef, path) metaOut := new(metaContent) metaRes, metaErr := s.client.do(ctx, "GET", metaEndpoint, nil, metaOut) if metaErr == nil { From 6ee41cf70bb2094c64a784a0c9546e50cd81009a Mon Sep 17 00:00:00 2001 From: Vivek Dixit Date: Tue, 9 Jan 2024 16:35:09 +0530 Subject: [PATCH 110/195] Update content.go --- scm/driver/bitbucket/content.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/scm/driver/bitbucket/content.go b/scm/driver/bitbucket/content.go index 14b07d160..3bb2960cf 100644 --- a/scm/driver/bitbucket/content.go +++ b/scm/driver/bitbucket/content.go @@ -18,10 +18,8 @@ type contentService struct { } func (s *contentService) Find(ctx context.Context, repo, path, ref string) (*scm.Content, *scm.Response, error) { - fmt.Println("ref->", ref) urlEncodedRef := url.QueryEscape(ref) endpoint := fmt.Sprintf("/2.0/repositories/%s/src/%s/%s", repo, urlEncodedRef, path) - fmt.Println("endpoint->", endpoint) out := new(bytes.Buffer) res, err := s.client.do(ctx, "GET", endpoint, nil, out) content := &scm.Content{ From 9982b163bac05f12d55ebf975f1d975d15a9a0fb Mon Sep 17 00:00:00 2001 From: Vivek Dixit Date: Tue, 9 Jan 2024 16:37:17 +0530 Subject: [PATCH 111/195] Update content.go --- scm/driver/stash/content.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scm/driver/stash/content.go b/scm/driver/stash/content.go index f03b6b1bc..fe921e528 100644 --- a/scm/driver/stash/content.go +++ b/scm/driver/stash/content.go @@ -8,6 +8,7 @@ import ( "bytes" "context" "fmt" + "net/url" "github.com/drone/go-scm/scm" ) @@ -17,8 +18,9 @@ type contentService struct { } func (s *contentService) Find(ctx context.Context, repo, path, ref string) (*scm.Content, *scm.Response, error) { + urlEncodedRef := url.QueryEscape(ref) namespace, name := scm.Split(repo) - endpoint := fmt.Sprintf("rest/api/1.0/projects/%s/repos/%s/raw/%s?at=%s", namespace, name, path, ref) + endpoint := fmt.Sprintf("rest/api/1.0/projects/%s/repos/%s/raw/%s?at=%s", namespace, name, path, urlEncodedRef) out := new(bytes.Buffer) res, err := s.client.do(ctx, "GET", endpoint, nil, out) return &scm.Content{ From da64c1c0c9b3f70d7f3c4a35da9157fe45c020fc Mon Sep 17 00:00:00 2001 From: Vivek Dixit Date: Tue, 9 Jan 2024 16:38:15 +0530 Subject: [PATCH 112/195] Update content.go --- scm/driver/harness/content.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scm/driver/harness/content.go b/scm/driver/harness/content.go index a5a0848d3..348bd7bde 100644 --- a/scm/driver/harness/content.go +++ b/scm/driver/harness/content.go @@ -9,6 +9,7 @@ import ( "encoding/base64" "fmt" "time" + "net/url" "github.com/drone/go-scm/scm" ) @@ -18,8 +19,9 @@ type contentService struct { } func (s *contentService) Find(ctx context.Context, repo, path, ref string) (*scm.Content, *scm.Response, error) { + urlEncodedRef := url.QueryEscape(ref) repo = buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - endpoint := fmt.Sprintf("api/v1/repos/%s/content/%s?git_ref=%s&include_commit=true", repo, path, ref) + endpoint := fmt.Sprintf("api/v1/repos/%s/content/%s?git_ref=%s&include_commit=true", repo, path, urlEncodedRef) out := new(fileContent) res, err := s.client.do(ctx, "GET", endpoint, nil, out) // decode raw output content From be2ecb2f4ef98f9ee7626921afb9062f871be52d Mon Sep 17 00:00:00 2001 From: Vivek Dixit Date: Tue, 9 Jan 2024 20:41:04 +0530 Subject: [PATCH 113/195] Update content.go --- scm/driver/harness/content.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/scm/driver/harness/content.go b/scm/driver/harness/content.go index 348bd7bde..a5a0848d3 100644 --- a/scm/driver/harness/content.go +++ b/scm/driver/harness/content.go @@ -9,7 +9,6 @@ import ( "encoding/base64" "fmt" "time" - "net/url" "github.com/drone/go-scm/scm" ) @@ -19,9 +18,8 @@ type contentService struct { } func (s *contentService) Find(ctx context.Context, repo, path, ref string) (*scm.Content, *scm.Response, error) { - urlEncodedRef := url.QueryEscape(ref) repo = buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - endpoint := fmt.Sprintf("api/v1/repos/%s/content/%s?git_ref=%s&include_commit=true", repo, path, urlEncodedRef) + endpoint := fmt.Sprintf("api/v1/repos/%s/content/%s?git_ref=%s&include_commit=true", repo, path, ref) out := new(fileContent) res, err := s.client.do(ctx, "GET", endpoint, nil, out) // decode raw output content From 474ee0b147fba1e48bed86a99ca844e86c093fca Mon Sep 17 00:00:00 2001 From: Vivek Dixit Date: Wed, 10 Jan 2024 13:27:52 +0530 Subject: [PATCH 114/195] Added UTs --- scm/driver/azure/content_test.go | 3 ++- scm/driver/github/content_test.go | 29 +++++++++++++++++++++++++++++ scm/driver/gitlab/content_test.go | 29 +++++++++++++++++++++++++++++ scm/driver/stash/content_test.go | 22 ++++++++++++++++++++++ 4 files changed, 82 insertions(+), 1 deletion(-) diff --git a/scm/driver/azure/content_test.go b/scm/driver/azure/content_test.go index e674ccdaf..ad857ccd9 100644 --- a/scm/driver/azure/content_test.go +++ b/scm/driver/azure/content_test.go @@ -17,6 +17,7 @@ func TestContentFind(t *testing.T) { gock.New("https:/dev.azure.com/"). Get("/ORG/PROJ/_apis/git/repositories/REPOID/items"). MatchParam("path", "README"). + MatchParam("versionDescriptor.version", "b1&b2"). Reply(200). Type("application/json"). File("testdata/content.json") @@ -26,7 +27,7 @@ func TestContentFind(t *testing.T) { context.Background(), "REPOID", "README", - "", + "b1&b2", ) if err != nil { t.Error(err) diff --git a/scm/driver/github/content_test.go b/scm/driver/github/content_test.go index 06923bf74..c1e8d4110 100644 --- a/scm/driver/github/content_test.go +++ b/scm/driver/github/content_test.go @@ -47,6 +47,35 @@ func TestContentFind(t *testing.T) { t.Log(diff) } + gock.New("https://api.github.com"). + Get("/repos/octocat/hello-world/contents/README"). + MatchParam("ref", "b1&b2"). + Reply(200). + Type("application/json"). + SetHeaders(mockHeaders). + File("testdata/content.json") + + client = NewDefault() + got, res, err = client.Contents.Find( + context.Background(), + "octocat/hello-world", + "README", + "b1&b2", + ) + if err != nil { + t.Error(err) + return + } + + want = new(scm.Content) + raw, _ = ioutil.ReadFile("testdata/content.json.golden") + _ = json.Unmarshal(raw, want) + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } + t.Run("Request", testRequest(res)) t.Run("Rate", testRate(res)) } diff --git a/scm/driver/gitlab/content_test.go b/scm/driver/gitlab/content_test.go index d7baa5bbe..11cfa50a7 100644 --- a/scm/driver/gitlab/content_test.go +++ b/scm/driver/gitlab/content_test.go @@ -48,6 +48,35 @@ func TestContentFind(t *testing.T) { t.Log(diff) } + gock.New("https://gitlab.com"). + Get("/api/v4/projects/diaspora/diaspora/repository/files/app/models/key.rb"). + MatchParam("ref", "b1&b2"). + Reply(200). + Type("application/json"). + SetHeaders(mockHeaders). + File("testdata/content.json") + + client = NewDefault() + got, res, err = client.Contents.Find( + context.Background(), + "diaspora/diaspora", + "app/models/key.rb", + "b1&b2", + ) + if err != nil { + t.Error(err) + return + } + + want = new(scm.Content) + raw, _ = ioutil.ReadFile("testdata/content.json.golden") + json.Unmarshal(raw, want) + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } + t.Run("Request", testRequest(res)) t.Run("Rate", testRate(res)) } diff --git a/scm/driver/stash/content_test.go b/scm/driver/stash/content_test.go index f5ff36965..68f84f050 100644 --- a/scm/driver/stash/content_test.go +++ b/scm/driver/stash/content_test.go @@ -40,6 +40,28 @@ func TestContentFind(t *testing.T) { t.Errorf("Unexpected Results") t.Log(diff) } + + gock.New("http://example.com:7990"). + Get("/rest/api/1.0/projects/PRJ/repos/my-repo/raw/README"). + MatchParam("at", "b1&b2"). + Reply(200). + Type("text/plain"). + File("testdata/content.txt") + + client, _ = New("http://example.com:7990") + got, _, err = client.Contents.Find(context.Background(), "PRJ/my-repo", "README", "b1&b2") + if err != nil { + t.Error(err) + } + + want = new(scm.Content) + raw, _ = ioutil.ReadFile("testdata/content.json.golden") + _ = json.Unmarshal(raw, want) + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } } func TestContentCreate(t *testing.T) { From f5e5a7510a7bedcd391b0a0e257b261bbaee1601 Mon Sep 17 00:00:00 2001 From: raghavharness Date: Tue, 6 Feb 2024 19:30:46 +0530 Subject: [PATCH 115/195] set query params for pagination in bitbucket server --- scm/driver/stash/pr.go | 2 +- scm/driver/stash/util.go | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/scm/driver/stash/pr.go b/scm/driver/stash/pr.go index 87cdb8fda..e1229e271 100644 --- a/scm/driver/stash/pr.go +++ b/scm/driver/stash/pr.go @@ -67,7 +67,7 @@ func (s *pullService) ListComments(context.Context, string, int, scm.ListOptions func (s *pullService) ListCommits(ctx context.Context, repo string, number int, opts scm.ListOptions) ([]*scm.Commit, *scm.Response, error) { namespace, name := scm.Split(repo) - path := fmt.Sprintf("rest/api/1.0/projects/%s/repos/%s/pull-requests/%d/commits", namespace, name, number) + path := fmt.Sprintf("rest/api/1.0/projects/%s/repos/%s/pull-requests/%d/commits?%s", namespace, name, number, encodeListOptionsV2(opts)) out := new(commits) res, err := s.client.do(ctx, "GET", path, nil, out) if !out.pagination.LastPage.Bool { diff --git a/scm/driver/stash/util.go b/scm/driver/stash/util.go index 1dbcb71e8..c0e1c2825 100644 --- a/scm/driver/stash/util.go +++ b/scm/driver/stash/util.go @@ -12,6 +12,10 @@ import ( "github.com/drone/go-scm/scm" ) +const ( + DEFAULT_LIMIT = 25 +) + func encodeListOptions(opts scm.ListOptions) string { params := url.Values{} if opts.Page > 1 { @@ -25,6 +29,22 @@ func encodeListOptions(opts scm.ListOptions) string { return params.Encode() } +func encodeListOptionsV2(opts scm.ListOptions) string { + params := url.Values{} + limit := DEFAULT_LIMIT + if opts.Size != 0 { + limit = opts.Size + } + params.Set("limit", strconv.Itoa(limit)) + + if opts.Page > 0 { + params.Set("start", strconv.Itoa( + (opts.Page-1)*limit), + ) + } + return params.Encode() +} + func encodeBranchListOptions(opts scm.BranchListOptions) string { params := url.Values{} if opts.SearchTerm != "" { From 8a567836e95de3ded93e368b43260a244a86ac9a Mon Sep 17 00:00:00 2001 From: raghavharness Date: Tue, 6 Feb 2024 20:15:41 +0530 Subject: [PATCH 116/195] set query params for pagination in bitbucket server --- scm/driver/stash/util.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scm/driver/stash/util.go b/scm/driver/stash/util.go index c0e1c2825..f034fb9ff 100644 --- a/scm/driver/stash/util.go +++ b/scm/driver/stash/util.go @@ -13,7 +13,7 @@ import ( ) const ( - DEFAULT_LIMIT = 25 + defaultLimit = 25 ) func encodeListOptions(opts scm.ListOptions) string { @@ -31,7 +31,7 @@ func encodeListOptions(opts scm.ListOptions) string { func encodeListOptionsV2(opts scm.ListOptions) string { params := url.Values{} - limit := DEFAULT_LIMIT + limit := defaultLimit if opts.Size != 0 { limit = opts.Size } From 4f7b529d3ac9fd2260862f56df2e10a9db00e11e Mon Sep 17 00:00:00 2001 From: raghavharness Date: Tue, 6 Feb 2024 20:19:57 +0530 Subject: [PATCH 117/195] set query params for pagination in bitbucket server --- scm/driver/stash/util_test.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/scm/driver/stash/util_test.go b/scm/driver/stash/util_test.go index 86e2e331d..d9e86101c 100644 --- a/scm/driver/stash/util_test.go +++ b/scm/driver/stash/util_test.go @@ -32,6 +32,28 @@ func Test_encodeListOptions(t *testing.T) { } } +func Test_encodeListOptionsV2(t *testing.T) { + tests := []struct { + page int + size int + text string + }{ + {page: 0, size: 30, text: "limit=30"}, + {page: 1, size: 30, text: "limit=30&start=0"}, + {page: 5, size: 30, text: "limit=30&start=120"}, + {page: 2, size: 5, text: "limit=5&start=5"}, + } + for _, test := range tests { + opts := scm.ListOptions{ + Page: test.page, + Size: test.size, + } + if got, want := encodeListOptionsV2(opts), test.text; got != want { + t.Errorf("Want encoded list options %q, got %q", want, got) + } + } +} + func Test_encodePullRequestListOptions(t *testing.T) { t.Parallel() opts := scm.PullRequestListOptions{ From 9d3ec6b9c3ed771602699ca406a825c7e71a9a04 Mon Sep 17 00:00:00 2001 From: Abhinav Singh Date: Sat, 10 Feb 2024 04:58:36 +0530 Subject: [PATCH 118/195] feat: change as per new contract of webhook in harness code (#294) * feat: change as per new contract of webhook in harness code * feat: change as per new contract of webhook in harness code * feat: change as per new contract of webhook in harness code * feat: change as per new contract of webhook in harness code * feat: change as per new contract of webhook in harness code * feat: change as per new contract of webhook in harness code * feat: change as per new contract of webhook in harness code * feat: change as per new contract of webhook in harness code --- scm/driver/harness/git.go | 15 ++- scm/driver/harness/harness.go | 4 - scm/driver/harness/pr.go | 43 +++++++- scm/driver/harness/repo.go | 12 +-- scm/driver/harness/testdata/hook.json | 3 +- scm/driver/harness/testdata/hook.json.golden | 2 +- scm/driver/harness/testdata/hook_create.json | 2 +- scm/driver/harness/testdata/hooks.json | 3 +- scm/driver/harness/testdata/hooks.json.golden | 2 +- .../testdata/webhooks/branch_create.json | 18 ++++ .../testdata/webhooks/branch_updated.json | 18 ++++ .../webhooks/pull_request_branch_updated.json | 18 ++++ .../webhooks/pull_request_closed.json | 18 ++++ .../webhooks/pull_request_merged.json | 18 ++++ .../webhooks/pull_request_opened.json | 18 ++++ .../webhooks/pull_request_reopened.json | 18 ++++ scm/driver/harness/util.go | 8 +- scm/driver/harness/webhook.go | 102 ++++++++++-------- 18 files changed, 252 insertions(+), 70 deletions(-) diff --git a/scm/driver/harness/git.go b/scm/driver/harness/git.go index 25923a56e..0416338b5 100644 --- a/scm/driver/harness/git.go +++ b/scm/driver/harness/git.go @@ -7,6 +7,7 @@ package harness import ( "context" "fmt" + "strings" "time" "github.com/drone/go-scm/scm" @@ -72,8 +73,12 @@ func (s *gitService) ListTags(ctx context.Context, repo string, _ scm.ListOption return nil, nil, scm.ErrNotSupported } -func (s *gitService) ListChanges(ctx context.Context, repo, ref string, _ scm.ListOptions) ([]*scm.Change, *scm.Response, error) { - return nil, nil, scm.ErrNotSupported +func (s *gitService) ListChanges(ctx context.Context, repo, ref string, opts scm.ListOptions) ([]*scm.Change, *scm.Response, error) { + harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + path := fmt.Sprintf("api/v1/repos/%s/commits/%s/diff?%s", harnessURI, ref, encodeListOptions(opts)) + out := []*fileDiff{} + res, err := s.client.do(ctx, "POST", path, nil, &out) + return convertFileDiffs(out), res, err } func (s *gitService) CompareChanges(ctx context.Context, repo, source, target string, _ scm.ListOptions) ([]*scm.Change, *scm.Response, error) { @@ -209,8 +214,8 @@ func convertChange(src *fileDiff) *scm.Change { return &scm.Change{ Path: src.Path, PrevFilePath: src.OldPath, - Added: src.Status == "ADDED", - Renamed: src.Status == "RENAMED", - Deleted: src.Status == "DELETED", + Added: strings.EqualFold(src.Status, "ADDED"), + Renamed: strings.EqualFold(src.Status, "RENAMED"), + Deleted: strings.EqualFold(src.Status, "DELETED"), } } diff --git a/scm/driver/harness/harness.go b/scm/driver/harness/harness.go index 9b36f87f3..1feb6a463 100644 --- a/scm/driver/harness/harness.go +++ b/scm/driver/harness/harness.go @@ -9,7 +9,6 @@ import ( "context" "encoding/json" "errors" - "fmt" "io" "net/http" "net/url" @@ -20,9 +19,6 @@ import ( // New returns a new gitness API client. func New(uri, account, organization, project string) (*scm.Client, error) { - if !((organization == "" && account == "" && project == "") || (organization != "" && account != "" && project != "")) { - return nil, fmt.Errorf("harness account, organization and project are required") - } base, err := url.Parse(uri) if err != nil { return nil, err diff --git a/scm/driver/harness/pr.go b/scm/driver/harness/pr.go index 9b5e05724..7acf07124 100644 --- a/scm/driver/harness/pr.go +++ b/scm/driver/harness/pr.go @@ -7,6 +7,7 @@ package harness import ( "context" "fmt" + "strings" "time" "github.com/drone/go-scm/scm" @@ -30,7 +31,11 @@ func (s *pullService) FindComment(context.Context, string, int, int) (*scm.Comme } func (s *pullService) List(ctx context.Context, repo string, opts scm.PullRequestListOptions) ([]*scm.PullRequest, *scm.Response, error) { - return nil, nil, scm.ErrNotSupported + harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + path := fmt.Sprintf("api/v1/repos/%s/pullreq?%s", harnessURI, encodePullRequestListOptions(opts)) + out := []*pr{} + res, err := s.client.do(ctx, "GET", path, nil, &out) + return convertPullRequestList(out), res, err } func (s *pullService) ListComments(context.Context, string, int, scm.ListOptions) ([]*scm.Comment, *scm.Response, error) { @@ -45,8 +50,12 @@ func (s *pullService) ListCommits(ctx context.Context, repo string, index int, o return convertCommits(out), res, err } -func (s *pullService) ListChanges(context.Context, string, int, scm.ListOptions) ([]*scm.Change, *scm.Response, error) { - return nil, nil, scm.ErrNotSupported +func (s *pullService) ListChanges(ctx context.Context, repo string, number int, _ scm.ListOptions) ([]*scm.Change, *scm.Response, error) { + harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + path := fmt.Sprintf("api/v1/repos/%s/pullreq/%d/diff", harnessURI, number) + out := []*fileDiff{} + res, err := s.client.do(ctx, "POST", path, nil, &out) + return convertFileDiffs(out), res, err } func (s *pullService) Create(ctx context.Context, repo string, input *scm.PullRequestInput) (*scm.PullRequest, *scm.Response, error) { @@ -209,3 +218,31 @@ func convertCommit(src *commit) *scm.Commit { }, } } + +func convertFileDiffs(diff []*fileDiff) []*scm.Change { + var dst []*scm.Change + for _, v := range diff { + dst = append(dst, convertFileDiff(v)) + } + return dst +} + +func convertFileDiff(diff *fileDiff) *scm.Change { + return &scm.Change{ + Path: diff.Path, + Added: strings.EqualFold(diff.Status, "ADDED"), + Renamed: strings.EqualFold(diff.Status, "RENAMED"), + Deleted: strings.EqualFold(diff.Status, "DELETED"), + Sha: diff.SHA, + BlobID: "", + PrevFilePath: diff.OldPath, + } +} + +func convertPullRequestList(from []*pr) []*scm.PullRequest { + to := []*scm.PullRequest{} + for _, v := range from { + to = append(to, convertPullRequest(v)) + } + return to +} diff --git a/scm/driver/harness/repo.go b/scm/driver/harness/repo.go index b467a03db..496bc1492 100644 --- a/scm/driver/harness/repo.go +++ b/scm/driver/harness/repo.go @@ -74,8 +74,7 @@ func (s *repositoryService) CreateHook(ctx context.Context, repo string, input * path := fmt.Sprintf("api/v1/repos/%s/webhooks", harnessURI) in := new(hook) in.Enabled = true - in.DisplayName = input.Name - in.UID = input.Name + in.Identifier = input.Name in.Secret = input.Secret in.Insecure = input.SkipVerify in.URL = input.Target @@ -130,12 +129,10 @@ type ( Created int `json:"created"` CreatedBy int `json:"created_by"` Description string `json:"description"` - DisplayName string `json:"display_name"` Enabled bool `json:"enabled"` HasSecret bool `json:"has_secret"` Secret string `json:"secret"` - ID int `json:"id"` - UID string `json:"uid"` + Identifier string `json:"identifier"` Insecure bool `json:"insecure"` LatestExecutionResult string `json:"latest_execution_result"` ParentID int `json:"parent_id"` @@ -184,8 +181,9 @@ func convertHookList(from []*hook) []*scm.Hook { func convertHook(from *hook) *scm.Hook { return &scm.Hook{ - ID: strconv.Itoa(from.ID), - Name: from.DisplayName, + // keeping id same as name + ID: from.Identifier, + Name: from.Identifier, Active: from.Enabled, Target: from.URL, Events: from.Triggers, diff --git a/scm/driver/harness/testdata/hook.json b/scm/driver/harness/testdata/hook.json index 994de6ed8..cfae54972 100644 --- a/scm/driver/harness/testdata/hook.json +++ b/scm/driver/harness/testdata/hook.json @@ -1,12 +1,11 @@ { - "id": 6, "version": 1, "parent_id": 11, "parent_type": "repo", "created_by": 14, "created": 1675867490853, "updated": 1675867531549, - "display_name": "webhookname", + "identifier": "webhookname", "description": "webhookdescription", "url": "http://1.1.1.1", "enabled": true, diff --git a/scm/driver/harness/testdata/hook.json.golden b/scm/driver/harness/testdata/hook.json.golden index 53463fce4..686b5db97 100644 --- a/scm/driver/harness/testdata/hook.json.golden +++ b/scm/driver/harness/testdata/hook.json.golden @@ -1,5 +1,5 @@ { - "ID": "6", + "ID": "webhookname", "Name": "webhookname", "Target": "http://1.1.1.1", "Events": [], diff --git a/scm/driver/harness/testdata/hook_create.json b/scm/driver/harness/testdata/hook_create.json index 131b6d7cb..cd88b4357 100644 --- a/scm/driver/harness/testdata/hook_create.json +++ b/scm/driver/harness/testdata/hook_create.json @@ -6,7 +6,7 @@ "created_by": 14, "created": 1675872629243, "updated": 1675872777592, - "display_name": "drone", + "identifier": "drone", "description": "", "url": "https://example.com", "enabled": true, diff --git a/scm/driver/harness/testdata/hooks.json b/scm/driver/harness/testdata/hooks.json index 372ad34a7..9e539cecd 100644 --- a/scm/driver/harness/testdata/hooks.json +++ b/scm/driver/harness/testdata/hooks.json @@ -1,13 +1,12 @@ [ { - "id": 6, "version": 1, "parent_id": 11, "parent_type": "repo", "created_by": 14, "created": 1675867490853, "updated": 1675867531549, - "display_name": "webhookname", + "identifier": "webhookname", "description": "webhookdescription", "url": "http://1.1.1.1", "enabled": true, diff --git a/scm/driver/harness/testdata/hooks.json.golden b/scm/driver/harness/testdata/hooks.json.golden index f21533cbe..317aa8125 100644 --- a/scm/driver/harness/testdata/hooks.json.golden +++ b/scm/driver/harness/testdata/hooks.json.golden @@ -1,6 +1,6 @@ [ { - "ID": "6", + "ID": "webhookname", "Name": "webhookname", "Target": "http://1.1.1.1", "Events": [], diff --git a/scm/driver/harness/testdata/webhooks/branch_create.json b/scm/driver/harness/testdata/webhooks/branch_create.json index 51ff0b383..426f9c54e 100644 --- a/scm/driver/harness/testdata/webhooks/branch_create.json +++ b/scm/driver/harness/testdata/webhooks/branch_create.json @@ -45,6 +45,24 @@ "when": "2023-02-01T13:21:15-08:00" } }, + "head_commit": { + "sha": "aeafa0e2e4ec6909ad75cb8fad57c0b1eb5986e6", + "message": "version 4", + "author": { + "identity": { + "name": "Admin", + "email": "admin@harness.io" + }, + "when": "2023-02-01T13:21:15-08:00" + }, + "committer": { + "identity": { + "name": "Admin", + "email": "admin@harness.io" + }, + "when": "2023-02-01T13:21:15-08:00" + } + }, "old_sha": "0000000000000000000000000000000000000000", "forced": false } \ No newline at end of file diff --git a/scm/driver/harness/testdata/webhooks/branch_updated.json b/scm/driver/harness/testdata/webhooks/branch_updated.json index 903fea7dd..844bcfd03 100644 --- a/scm/driver/harness/testdata/webhooks/branch_updated.json +++ b/scm/driver/harness/testdata/webhooks/branch_updated.json @@ -45,6 +45,24 @@ "when": "2023-12-05T11:59:39Z" } }, + "head_commit": { + "sha": "92e21bfcddc1418079cddbb518ad6fd72917798a", + "message": "Create asdsad (#2)", + "author": { + "identity": { + "name": "abhinav.singh@harness.io", + "email": "abhinav.singh@harness.io" + }, + "when": "2023-12-05T11:59:39Z" + }, + "committer": { + "identity": { + "name": "Harness", + "email": "noreply@harness.io" + }, + "when": "2023-12-05T11:59:39Z" + } + }, "old_sha": "a273c385628167932e10caaa58e12550c491f241", "forced": false } \ No newline at end of file diff --git a/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json b/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json index 144fc3f3e..8a88fc594 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json +++ b/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json @@ -76,6 +76,24 @@ "when": "2023-02-01T13:28:55-08:00" } }, + "head_commit": { + "sha": "f74f3d2a88d1b7cb19ff3bf069aa423763d341ef", + "message": "updated b2", + "author": { + "identity": { + "name": "Admin", + "email": "admin@harness.io" + }, + "when": "2023-02-01T13:28:55-08:00" + }, + "committer": { + "identity": { + "name": "Admin", + "email": "admin@harness.io" + }, + "when": "2023-02-01T13:28:55-08:00" + } + }, "old_sha": "d74b1ebfe520ac01b209dd9085f005884cc9f4cd", "forced": false } \ No newline at end of file diff --git a/scm/driver/harness/testdata/webhooks/pull_request_closed.json b/scm/driver/harness/testdata/webhooks/pull_request_closed.json index 496e01610..4f47de5fa 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_closed.json +++ b/scm/driver/harness/testdata/webhooks/pull_request_closed.json @@ -74,5 +74,23 @@ }, "when": "2023-12-20T13:10:47+05:30" } + }, + "head_commit": { + "sha": "27822dd2ec788f924c97b0b194c5bfd906f2e574", + "message": "", + "author": { + "identity": { + "name": "Administrator", + "email": "admin@gitness.io" + }, + "when": "2023-12-20T13:10:47+05:30" + }, + "committer": { + "identity": { + "name": "Gitness", + "email": "system@gitness.io" + }, + "when": "2023-12-20T13:10:47+05:30" + } } } \ No newline at end of file diff --git a/scm/driver/harness/testdata/webhooks/pull_request_merged.json b/scm/driver/harness/testdata/webhooks/pull_request_merged.json index 54beca25c..f8cd669b8 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_merged.json +++ b/scm/driver/harness/testdata/webhooks/pull_request_merged.json @@ -75,5 +75,23 @@ }, "when": "2023-12-20T13:40:52+05:30" } + }, + "head_commit": { + "sha": "4ec41187008f77222a60dfa21cdbd980f6490443", + "message": "", + "author": { + "identity": { + "name": "Administrator", + "email": "admin@gitness.io" + }, + "when": "2023-12-20T13:40:52+05:30" + }, + "committer": { + "identity": { + "name": "Gitness", + "email": "system@gitness.io" + }, + "when": "2023-12-20T13:40:52+05:30" + } } } \ No newline at end of file diff --git a/scm/driver/harness/testdata/webhooks/pull_request_opened.json b/scm/driver/harness/testdata/webhooks/pull_request_opened.json index abc82426c..7c1715f19 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_opened.json +++ b/scm/driver/harness/testdata/webhooks/pull_request_opened.json @@ -75,5 +75,23 @@ }, "when": "2023-01-31T22:01:55-08:00" } + }, + "head_commit": { + "sha": "d74b1ebfe520ac01b209dd9085f005884cc9f4cd", + "message": "Update b.txt", + "author": { + "identity": { + "name": "Admin", + "email": "admin@harness.io" + }, + "when": "2023-01-31T22:01:55-08:00" + }, + "committer": { + "identity": { + "name": "Admin", + "email": "admin@harness.io" + }, + "when": "2023-01-31T22:01:55-08:00" + } } } \ No newline at end of file diff --git a/scm/driver/harness/testdata/webhooks/pull_request_reopened.json b/scm/driver/harness/testdata/webhooks/pull_request_reopened.json index ab57a9e14..a7408779f 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_reopened.json +++ b/scm/driver/harness/testdata/webhooks/pull_request_reopened.json @@ -75,5 +75,23 @@ }, "when": "2023-02-01T13:28:55-08:00" } + }, + "head_commit": { + "sha": "f74f3d2a88d1b7cb19ff3bf069aa423763d341ef", + "message": "updated b2", + "author": { + "identity": { + "name": "Admin", + "email": "admin@harness.io" + }, + "when": "2023-02-01T13:28:55-08:00" + }, + "committer": { + "identity": { + "name": "Admin", + "email": "admin@harness.io" + }, + "when": "2023-02-01T13:28:55-08:00" + } } } \ No newline at end of file diff --git a/scm/driver/harness/util.go b/scm/driver/harness/util.go index 78fc8cc9e..d094c8257 100644 --- a/scm/driver/harness/util.go +++ b/scm/driver/harness/util.go @@ -15,7 +15,13 @@ import ( func buildHarnessURI(account, organization, project, repo string) (uri string) { if account != "" { - uri = fmt.Sprintf("%s/%s/%s/", account, organization, project) + if project != "" { + uri = fmt.Sprintf("%s/%s/%s/", account, organization, project) + } else if organization != "" { + uri = fmt.Sprintf("%s/%s/", account, organization) + } else { + uri = fmt.Sprintf("%s/", account) + } if repo != "" { uri += fmt.Sprintf("%s/+", repo) } else { diff --git a/scm/driver/harness/webhook.go b/scm/driver/harness/webhook.go index 4a087d629..73e7bd920 100644 --- a/scm/driver/harness/webhook.go +++ b/scm/driver/harness/webhook.go @@ -167,6 +167,9 @@ type ( } `json:"identity"` When string `json:"when"` } `json:"committer"` + Added []string `json:"added"` + Modified []string `json:"modified"` + Removed []string `json:"removed"` } comment struct { ID int `json:"id"` @@ -174,37 +177,41 @@ type ( } // harness pull request webhook payload pullRequestHook struct { - Trigger string `json:"trigger"` - Repo repo `json:"repo"` - Principal principal `json:"principal"` - PullReq pullReq `json:"pull_req"` - TargetRef targetRef `json:"target_ref"` - Ref ref `json:"ref"` - Sha string `json:"sha"` - Commit hookCommit `json:"commit"` + Trigger string `json:"trigger"` + Repo repo `json:"repo"` + Principal principal `json:"principal"` + PullReq pullReq `json:"pull_req"` + TargetRef targetRef `json:"target_ref"` + Ref ref `json:"ref"` + Sha string `json:"sha"` + HeadCommit hookCommit `json:"head_commit"` + Commits []hookCommit `json:"commits"` + TotalCommitsCount int64 `json:"total_commits_count"` } // harness push webhook payload pushHook struct { - Trigger string `json:"trigger"` - Repo repo `json:"repo"` - Principal principal `json:"principal"` - Ref ref `json:"ref"` - Commit hookCommit `json:"commit"` - Sha string `json:"sha"` - OldSha string `json:"old_sha"` - Forced bool `json:"forced"` + Trigger string `json:"trigger"` + Repo repo `json:"repo"` + Principal principal `json:"principal"` + Ref ref `json:"ref"` + HeadCommit hookCommit `json:"head_commit"` + Sha string `json:"sha"` + OldSha string `json:"old_sha"` + Forced bool `json:"forced"` + Commits []hookCommit `json:"commits"` + TotalCommitsCount int64 `json:"total_commits_count"` } // harness pull request comment webhook payload pullRequestCommentHook struct { - Trigger string `json:"trigger"` - Repo repo `json:"repo"` - Principal principal `json:"principal"` - PullReq pullReq `json:"pull_req"` - TargetRef targetRef `json:"target_ref"` - Ref ref `json:"ref"` - Sha string `json:"sha"` - Commit hookCommit `json:"commit"` - Comment comment `json:"comment"` + Trigger string `json:"trigger"` + Repo repo `json:"repo"` + Principal principal `json:"principal"` + PullReq pullReq `json:"pull_req"` + TargetRef targetRef `json:"target_ref"` + Ref ref `json:"ref"` + Sha string `json:"sha"` + HeadCommit hookCommit `json:"head_commit"` + Comment comment `json:"comment"` } ) @@ -212,37 +219,46 @@ type ( func convertPullRequestHook(src *pullRequestHook) *scm.PullRequestHook { return &scm.PullRequestHook{ Action: convertAction(src.Trigger), - PullRequest: convertPullReq(src.PullReq, src.Ref, src.Commit), + PullRequest: convertPullReq(src.PullReq, src.Ref, src.HeadCommit), Repo: convertRepo(src.Repo), Sender: convertUser(src.Principal), } } func convertPushHook(src *pushHook) *scm.PushHook { + var commits []scm.Commit + for _, c := range src.Commits { + commits = append(commits, convertHookCommit(c)) + } return &scm.PushHook{ - Ref: src.Ref.Name, - Before: src.OldSha, - After: src.Sha, - Repo: convertRepo(src.Repo), - Commit: scm.Commit{ - Sha: src.Commit.Sha, - Message: src.Commit.Message, - Author: scm.Signature{ - Name: src.Commit.Author.Identity.Name, - Email: src.Commit.Author.Identity.Email, - }, - Committer: scm.Signature{ - Name: src.Commit.Committer.Identity.Name, - Email: src.Commit.Committer.Identity.Email, - }, + Ref: src.Ref.Name, + Before: src.OldSha, + After: src.Sha, + Repo: convertRepo(src.Repo), + Commit: convertHookCommit(src.HeadCommit), + Sender: convertUser(src.Principal), + Commits: commits, + } +} + +func convertHookCommit(c hookCommit) scm.Commit { + return scm.Commit{ + Sha: c.Sha, + Message: c.Message, + Author: scm.Signature{ + Name: c.Author.Identity.Name, + Email: c.Author.Identity.Email, + }, + Committer: scm.Signature{ + Name: c.Committer.Identity.Name, + Email: c.Committer.Identity.Email, }, - Sender: convertUser(src.Principal), } } func convertPullRequestCommentHook(src *pullRequestCommentHook) *scm.PullRequestCommentHook { return &scm.PullRequestCommentHook{ - PullRequest: convertPullReq(src.PullReq, src.Ref, src.Commit), + PullRequest: convertPullReq(src.PullReq, src.Ref, src.HeadCommit), Repo: convertRepo(src.Repo), Comment: scm.Comment{ Body: src.Comment.Text, From 91387e9cb7fe112a4678a057c8a14dfc58570614 Mon Sep 17 00:00:00 2001 From: Nasser Gonzalez Gonzalez Date: Wed, 21 Feb 2024 08:56:20 +0000 Subject: [PATCH 119/195] Add harness comment (#295) * Add the implementation of CreateComment for Harness Code * Add the implementation of CreateComment for Harness Code --- CHANGELOG.md | 35 ++++++++++ scm/driver/harness/pr.go | 65 ++++++++++++++++++- scm/driver/harness/pr_test.go | 44 +++++++++++++ scm/driver/harness/testdata/comment.json | 25 +++++++ .../harness/testdata/comment.json.golden | 15 +++++ 5 files changed, 182 insertions(+), 2 deletions(-) create mode 100644 scm/driver/harness/testdata/comment.json create mode 100644 scm/driver/harness/testdata/comment.json.golden diff --git a/CHANGELOG.md b/CHANGELOG.md index 739e13c01..d63a81137 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,36 @@ # Changelog +## [Unreleased](https://github.com/drone/go-scm/tree/HEAD) + +[Full Changelog](https://github.com/drone/go-scm/compare/v1.34.3...HEAD) + +**Closed issues:** + +- Cron Jobs don't run with Gitea-scm [\#292](https://github.com/drone/go-scm/issues/292) + +**Merged pull requests:** + +- feat: change as per new contract of webhook in harness code [\#294](https://github.com/drone/go-scm/pull/294) ([abhinav-harness](https://github.com/abhinav-harness)) +- Stash pr commits pagination [\#293](https://github.com/drone/go-scm/pull/293) ([raghavharness](https://github.com/raghavharness)) +- Added support for branch names containing '&' and '\#' for GetFile Operations. [\#291](https://github.com/drone/go-scm/pull/291) ([senjucanon2](https://github.com/senjucanon2)) + +## [v1.34.3](https://github.com/drone/go-scm/tree/v1.34.3) (2023-12-20) + +[Full Changelog](https://github.com/drone/go-scm/compare/v1.34.2...v1.34.3) + +**Merged pull requests:** + +- feat: add pr link as coming from new webhook [\#290](https://github.com/drone/go-scm/pull/290) ([abhinav-harness](https://github.com/abhinav-harness)) + +## [v1.34.2](https://github.com/drone/go-scm/tree/v1.34.2) (2023-12-20) + +[Full Changelog](https://github.com/drone/go-scm/compare/v1.34.1...v1.34.2) + +**Merged pull requests:** + +- feat: support more events in webhook parse in go-scm for gitness [\#289](https://github.com/drone/go-scm/pull/289) ([abhinav-harness](https://github.com/abhinav-harness)) +- fix: ref should be branch name for harness code [\#288](https://github.com/drone/go-scm/pull/288) ([abhinav-harness](https://github.com/abhinav-harness)) + ## [v1.34.1](https://github.com/drone/go-scm/tree/v1.34.1) (2023-12-08) [Full Changelog](https://github.com/drone/go-scm/compare/v1.34.0...v1.34.1) @@ -8,6 +39,10 @@ - fix: use opts for harness list commits [\#286](https://github.com/drone/go-scm/pull/286) ([abhinav-harness](https://github.com/abhinav-harness)) +**Merged pull requests:** + +- \(maint\) v1.34.1 release prep [\#287](https://github.com/drone/go-scm/pull/287) ([tphoney](https://github.com/tphoney)) + ## [v1.34.0](https://github.com/drone/go-scm/tree/v1.34.0) (2023-12-07) [Full Changelog](https://github.com/drone/go-scm/compare/v1.33.0...v1.34.0) diff --git a/scm/driver/harness/pr.go b/scm/driver/harness/pr.go index 7acf07124..f84012655 100644 --- a/scm/driver/harness/pr.go +++ b/scm/driver/harness/pr.go @@ -7,6 +7,7 @@ package harness import ( "context" "fmt" + "strconv" "strings" "time" @@ -72,8 +73,15 @@ func (s *pullService) Create(ctx context.Context, repo string, input *scm.PullRe return convertPullRequest(out), res, err } -func (s *pullService) CreateComment(context.Context, string, int, *scm.CommentInput) (*scm.Comment, *scm.Response, error) { - return nil, nil, scm.ErrNotSupported +func (s *pullService) CreateComment(ctx context.Context, repo string, prNumber int, input *scm.CommentInput) (*scm.Comment, *scm.Response, error) { + harnessQueryParams := fmt.Sprintf("?accountIdentifier=%s&orgIdentifier=%s&projectIdentifier=%s", s.client.account, s.client.organization, s.client.project) + path := fmt.Sprintf("api/v1/repos/%s/pullreq/%d/comments%s", repo, prNumber, harnessQueryParams) + in := &prComment{ + Text: input.Body, + } + out := new(prCommentResponse) + res, err := s.client.do(ctx, "POST", path, in, out) + return convertComment(out), res, err } func (s *pullService) DeleteComment(context.Context, string, int, int) (*scm.Response, error) { @@ -165,6 +173,42 @@ type ( Sha string `json:"sha"` Title string `json:"title"` } + prComment struct { + LineEnd int `json:"line_end"` + LineEndNew bool `json:"line_end_new"` + LineStart int `json:"line_start"` + LineStartNew bool `json:"line_start_new"` + ParentID int `json:"parent_id"` + Path string `json:"path"` + SourceCommitSha string `json:"source_commit_sha"` + TargetCommitSha string `json:"target_commit_sha"` + Text string `json:"text"` + } + prCommentResponse struct { + Id int `json:"id"` + Created int64 `json:"created"` + Updated int64 `json:"updated"` + Edited int64 `json:"edited"` + ParentId interface{} `json:"parent_id"` + RepoId int `json:"repo_id"` + PullreqId int `json:"pullreq_id"` + Order int `json:"order"` + SubOrder int `json:"sub_order"` + Type string `json:"type"` + Kind string `json:"kind"` + Text string `json:"text"` + Payload struct{} `json:"payload"` + Metadata interface{} `json:"metadata"` + Author struct { + Id int `json:"id"` + Uid string `json:"uid"` + DisplayName string `json:"display_name"` + Email string `json:"email"` + Type string `json:"type"` + Created int64 `json:"created"` + Updated int64 `json:"updated"` + } `json:"author"` + } ) // native data structure conversion @@ -246,3 +290,20 @@ func convertPullRequestList(from []*pr) []*scm.PullRequest { } return to } + +func convertComment(comment *prCommentResponse) *scm.Comment { + return &scm.Comment{ + ID: comment.Id, + Body: comment.Text, + Author: scm.User{ + Login: comment.Author.Uid, + Name: comment.Author.DisplayName, + ID: strconv.Itoa(comment.Author.Id), + Email: comment.Author.Email, + Created: time.UnixMilli(comment.Author.Created), + Updated: time.UnixMilli(comment.Author.Updated), + }, + Created: time.UnixMilli(comment.Created), + Updated: time.UnixMilli(comment.Updated), + } +} diff --git a/scm/driver/harness/pr_test.go b/scm/driver/harness/pr_test.go index b9bc5a631..951690164 100644 --- a/scm/driver/harness/pr_test.go +++ b/scm/driver/harness/pr_test.go @@ -7,6 +7,8 @@ package harness import ( "context" "encoding/json" + "fmt" + "github.com/google/go-cmp/cmp/cmpopts" "io/ioutil" "net/http" "testing" @@ -134,3 +136,45 @@ func TestPullCreate(t *testing.T) { t.Log(diff) } } + +func TestPRComment(t *testing.T) { + defer gock.Off() + gock.New(gockOrigin). + Post(fmt.Sprintf("/gateway/code/api/v1/repos/%s/pullreq/1/comments", harnessRepo)). + MatchParam("accountIdentifier", harnessAccount). + MatchParam("orgIdentifier", harnessOrg). + MatchParam("projectIdentifier", harnessProject). + Reply(201). + Type("plain/text"). + File("testdata/comment.json") + + client, _ := New(gockOrigin, harnessAccount, harnessOrg, harnessProject) + client.Client = &http.Client{ + Transport: &transport.Custom{ + Before: func(r *http.Request) { + r.Header.Set("x-api-key", harnessPAT) + }, + }, + } + + input := scm.CommentInput{ + Body: "Comment to be created in the PR", + } + + got, _, err := client.PullRequests.CreateComment(context.Background(), harnessRepo, 1, &input) + if err != nil { + t.Error(err) + return + } + + want := new(scm.Comment) + raw, _ := ioutil.ReadFile("testdata/comment.json.golden") + _ = json.Unmarshal(raw, want) + + if diff := cmp.Diff(got, want, + cmpopts.IgnoreFields(scm.Comment{}, "Created", "Updated"), + cmpopts.IgnoreFields(scm.User{}, "Created", "Updated")); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } +} diff --git a/scm/driver/harness/testdata/comment.json b/scm/driver/harness/testdata/comment.json new file mode 100644 index 000000000..fa1a823f5 --- /dev/null +++ b/scm/driver/harness/testdata/comment.json @@ -0,0 +1,25 @@ +{ + "id": 123, + "created": 1708354973112, + "updated": 1708354973112, + "edited": 1708354973112, + "parent_id": null, + "repo_id": 123, + "pullreq_id": 123, + "order": 1, + "sub_order": 0, + "type": "comment", + "kind": "comment", + "text": "Comment to be created in the PR", + "payload": {}, + "metadata": null, + "author": { + "id": 1, + "uid": "identifier", + "display_name": "displayName", + "email": "email@emailprovider.com", + "type": "service", + "created": 1695706039266, + "updated": 1695706039266 + } +} \ No newline at end of file diff --git a/scm/driver/harness/testdata/comment.json.golden b/scm/driver/harness/testdata/comment.json.golden new file mode 100644 index 000000000..f2e347a95 --- /dev/null +++ b/scm/driver/harness/testdata/comment.json.golden @@ -0,0 +1,15 @@ +{ + "ID": 123, + "Body": "Comment to be created in the PR", + "Author": { + "ID": "1", + "Login": "identifier", + "Name": "displayName", + "Email": "email@emailprovider.com", + "Avatar": "", + "Created": 1695706039266, + "Updated": 1695706039266 + }, + "Created": 1708354973112, + "Updated": 1708354973112 +} \ No newline at end of file From 290c4aad736c684f14e083dd24d84dab391119db Mon Sep 17 00:00:00 2001 From: Abhinav Singh Date: Fri, 1 Mar 2024 08:18:18 +0530 Subject: [PATCH 120/195] feat: follow new api convention (#296) * feat: follow new api convention * feat: follow new api convention --- scm/driver/harness/content.go | 40 ++++++++++++++++++++++++--------- scm/driver/harness/git.go | 42 +++++++++++++++++++++++++++++------ scm/driver/harness/pr.go | 38 +++++++++++++++++++++++++------ scm/driver/harness/repo.go | 39 +++++++++++++++++++++++++------- scm/driver/harness/util.go | 35 +++++++++++++++++++++++++++++ 5 files changed, 162 insertions(+), 32 deletions(-) diff --git a/scm/driver/harness/content.go b/scm/driver/harness/content.go index a5a0848d3..91e72ecee 100644 --- a/scm/driver/harness/content.go +++ b/scm/driver/harness/content.go @@ -18,8 +18,12 @@ type contentService struct { } func (s *contentService) Find(ctx context.Context, repo, path, ref string) (*scm.Content, *scm.Response, error) { - repo = buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - endpoint := fmt.Sprintf("api/v1/repos/%s/content/%s?git_ref=%s&include_commit=true", repo, path, ref) + slug := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + repoId, queryParams, err := getRepoAndQueryParams(slug) + if err != nil { + return nil, nil, err + } + endpoint := fmt.Sprintf("api/v1/repos/%s/content/%s?git_ref=%s&include_commit=true&%s", repoId, path, ref, queryParams) out := new(fileContent) res, err := s.client.do(ctx, "GET", endpoint, nil, out) // decode raw output content @@ -33,8 +37,12 @@ func (s *contentService) Find(ctx context.Context, repo, path, ref string) (*scm } func (s *contentService) Create(ctx context.Context, repo, path string, params *scm.ContentParams) (*scm.Response, error) { - repo = buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - endpoint := fmt.Sprintf("api/v1/repos/%s/commits", repo) + slug := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + repoId, queryParams, err := getRepoAndQueryParams(slug) + if err != nil { + return nil, err + } + endpoint := fmt.Sprintf("api/v1/repos/%s/commits?%s", repoId, queryParams) a := action{ Action: "CREATE", Path: path, @@ -53,8 +61,12 @@ func (s *contentService) Create(ctx context.Context, repo, path string, params * } func (s *contentService) Update(ctx context.Context, repo, path string, params *scm.ContentParams) (*scm.Response, error) { - repo = buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - endpoint := fmt.Sprintf("api/v1/repos/%s/commits", repo) + slug := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + repoId, queryParams, err := getRepoAndQueryParams(slug) + if err != nil { + return nil, err + } + endpoint := fmt.Sprintf("api/v1/repos/%s/commits?%s", repoId, queryParams) a := action{ Action: "UPDATE", Path: path, @@ -74,8 +86,12 @@ func (s *contentService) Update(ctx context.Context, repo, path string, params * } func (s *contentService) Delete(ctx context.Context, repo, path string, params *scm.ContentParams) (*scm.Response, error) { - repo = buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - endpoint := fmt.Sprintf("api/v1/repos/%s/commits", repo) + slug := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + repoId, queryParams, err := getRepoAndQueryParams(slug) + if err != nil { + return nil, err + } + endpoint := fmt.Sprintf("api/v1/repos/%s/commits?%s", repoId, queryParams) a := action{ Action: "DELETE", Path: path, @@ -93,8 +109,12 @@ func (s *contentService) Delete(ctx context.Context, repo, path string, params * } func (s *contentService) List(ctx context.Context, repo, path, ref string, _ scm.ListOptions) ([]*scm.ContentInfo, *scm.Response, error) { - repo = buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - endpoint := fmt.Sprintf("api/v1/repos/%s/content/%s?git_ref=%s&include_commit=true", repo, path, ref) + slug := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + repoId, queryParams, err := getRepoAndQueryParams(slug) + if err != nil { + return nil, nil, err + } + endpoint := fmt.Sprintf("api/v1/repos/%s/content/%s?git_ref=%s&include_commit=true&%s", repoId, path, ref, queryParams) out := new(contentList) res, err := s.client.do(ctx, "GET", endpoint, nil, &out) return convertContentInfoList(out.Content.Entries), res, err diff --git a/scm/driver/harness/git.go b/scm/driver/harness/git.go index 0416338b5..adbd34c26 100644 --- a/scm/driver/harness/git.go +++ b/scm/driver/harness/git.go @@ -19,7 +19,11 @@ type gitService struct { func (s *gitService) CreateBranch(ctx context.Context, repo string, params *scm.ReferenceInput) (*scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/branches", harnessURI) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/branches?%s", repoId, queryParams) in := &branchInput{ Name: params.Name, Target: params.Sha, @@ -29,7 +33,11 @@ func (s *gitService) CreateBranch(ctx context.Context, repo string, params *scm. func (s *gitService) FindBranch(ctx context.Context, repo, name string) (*scm.Reference, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/branches/%s", harnessURI, name) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/branches/%s?%s", repoId, name, queryParams) out := new(branch) res, err := s.client.do(ctx, "GET", path, nil, out) return convertBranch(out), res, err @@ -37,7 +45,11 @@ func (s *gitService) FindBranch(ctx context.Context, repo, name string) (*scm.Re func (s *gitService) FindCommit(ctx context.Context, repo, ref string) (*scm.Commit, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/commits/%s", harnessURI, ref) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/commits/%s?%s", repoId, ref, queryParams) out := new(commitInfo) res, err := s.client.do(ctx, "GET", path, nil, out) return convertCommitInfo(out), res, err @@ -49,7 +61,11 @@ func (s *gitService) FindTag(ctx context.Context, repo, name string) (*scm.Refer func (s *gitService) ListBranches(ctx context.Context, repo string, opts scm.ListOptions) ([]*scm.Reference, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/branches?%s", harnessURI, encodeListOptions(opts)) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/branches?%s&%s", repoId, encodeListOptions(opts), queryParams) out := []*branch{} res, err := s.client.do(ctx, "GET", path, nil, &out) return convertBranchList(out), res, err @@ -63,7 +79,11 @@ func (s *gitService) ListBranchesV2(ctx context.Context, repo string, opts scm.B func (s *gitService) ListCommits(ctx context.Context, repo string, opts scm.CommitListOptions) ([]*scm.Commit, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/commits?%s", harnessURI, encodeCommitListOptions(opts)) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/commits?%s&%s", repoId, encodeCommitListOptions(opts), queryParams) out := new(commits) res, err := s.client.do(ctx, "GET", path, nil, &out) return convertCommitList(out), res, err @@ -75,7 +95,11 @@ func (s *gitService) ListTags(ctx context.Context, repo string, _ scm.ListOption func (s *gitService) ListChanges(ctx context.Context, repo, ref string, opts scm.ListOptions) ([]*scm.Change, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/commits/%s/diff?%s", harnessURI, ref, encodeListOptions(opts)) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/commits/%s/diff?%s&%s", repoId, ref, encodeListOptions(opts), queryParams) out := []*fileDiff{} res, err := s.client.do(ctx, "POST", path, nil, &out) return convertFileDiffs(out), res, err @@ -83,7 +107,11 @@ func (s *gitService) ListChanges(ctx context.Context, repo, ref string, opts scm func (s *gitService) CompareChanges(ctx context.Context, repo, source, target string, _ scm.ListOptions) ([]*scm.Change, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/diff/%s...%s", harnessURI, source, target) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/diff/%s...%s?%s", repoId, source, target, queryParams) out := []*fileDiff{} res, err := s.client.do(ctx, "GET", path, nil, &out) return convertChangeList(out), res, err diff --git a/scm/driver/harness/pr.go b/scm/driver/harness/pr.go index f84012655..35cadd20a 100644 --- a/scm/driver/harness/pr.go +++ b/scm/driver/harness/pr.go @@ -20,7 +20,11 @@ type pullService struct { func (s *pullService) Find(ctx context.Context, repo string, index int) (*scm.PullRequest, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/pullreq/%d", harnessURI, index) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/pullreq/%d?%s", repoId, index, queryParams) out := new(pr) res, err := s.client.do(ctx, "GET", path, nil, out) return convertPullRequest(out), res, err @@ -33,7 +37,11 @@ func (s *pullService) FindComment(context.Context, string, int, int) (*scm.Comme func (s *pullService) List(ctx context.Context, repo string, opts scm.PullRequestListOptions) ([]*scm.PullRequest, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/pullreq?%s", harnessURI, encodePullRequestListOptions(opts)) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/pullreq?%s&%s", repoId, encodePullRequestListOptions(opts), queryParams) out := []*pr{} res, err := s.client.do(ctx, "GET", path, nil, &out) return convertPullRequestList(out), res, err @@ -45,7 +53,11 @@ func (s *pullService) ListComments(context.Context, string, int, scm.ListOptions func (s *pullService) ListCommits(ctx context.Context, repo string, index int, opts scm.ListOptions) ([]*scm.Commit, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/pullreq/%d/commits?%s", harnessURI, index, encodeListOptions(opts)) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/pullreq/%d/commits?%s&%s", repoId, index, encodeListOptions(opts), queryParams) out := []*commit{} res, err := s.client.do(ctx, "GET", path, nil, &out) return convertCommits(out), res, err @@ -53,7 +65,11 @@ func (s *pullService) ListCommits(ctx context.Context, repo string, index int, o func (s *pullService) ListChanges(ctx context.Context, repo string, number int, _ scm.ListOptions) ([]*scm.Change, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/pullreq/%d/diff", harnessURI, number) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/pullreq/%d/diff?%s", repoId, number, queryParams) out := []*fileDiff{} res, err := s.client.do(ctx, "POST", path, nil, &out) return convertFileDiffs(out), res, err @@ -61,7 +77,11 @@ func (s *pullService) ListChanges(ctx context.Context, repo string, number int, func (s *pullService) Create(ctx context.Context, repo string, input *scm.PullRequestInput) (*scm.PullRequest, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/pullreq", harnessURI) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/pullreq?%s", repoId, queryParams) in := &prInput{ Title: input.Title, Description: input.Body, @@ -74,8 +94,12 @@ func (s *pullService) Create(ctx context.Context, repo string, input *scm.PullRe } func (s *pullService) CreateComment(ctx context.Context, repo string, prNumber int, input *scm.CommentInput) (*scm.Comment, *scm.Response, error) { - harnessQueryParams := fmt.Sprintf("?accountIdentifier=%s&orgIdentifier=%s&projectIdentifier=%s", s.client.account, s.client.organization, s.client.project) - path := fmt.Sprintf("api/v1/repos/%s/pullreq/%d/comments%s", repo, prNumber, harnessQueryParams) + harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/pullreq/%d/comments?%s", repoId, prNumber, queryParams) in := &prComment{ Text: input.Body, } diff --git a/scm/driver/harness/repo.go b/scm/driver/harness/repo.go index 496bc1492..dc489a267 100644 --- a/scm/driver/harness/repo.go +++ b/scm/driver/harness/repo.go @@ -18,8 +18,12 @@ type repositoryService struct { } func (s *repositoryService) Find(ctx context.Context, repo string) (*scm.Repository, *scm.Response, error) { - repo = buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s", repo) + harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s?%s", repoId, queryParams) out := new(repository) res, err := s.client.do(ctx, "GET", path, nil, out) if err != nil { @@ -34,7 +38,11 @@ func (s *repositoryService) Find(ctx context.Context, repo string) (*scm.Reposit func (s *repositoryService) FindHook(ctx context.Context, repo string, id string) (*scm.Hook, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/webhooks/%s", harnessURI, id) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/webhooks/%s?%s", repoId, id, queryParams) out := new(hook) res, err := s.client.do(ctx, "GET", path, nil, &out) return convertHook(out), res, err @@ -45,8 +53,11 @@ func (s *repositoryService) FindPerms(ctx context.Context, repo string) (*scm.Pe } func (s *repositoryService) List(ctx context.Context, opts scm.ListOptions) ([]*scm.Repository, *scm.Response, error) { - harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, "") - path := fmt.Sprintf("api/v1/spaces/%s/repos?sort=path&order=asc&%s", harnessURI, encodeListOptions(opts)) + queryParams := fmt.Sprintf("%s=%s&%s=%s&%s=%s&%s=%s", + projectIdentifier, s.client.project, orgIdentifier, s.client.organization, accountIdentifier, s.client.account, + routingId, s.client.account) + + path := fmt.Sprintf("api/v1/repos?sort=path&order=asc&%s&%s", encodeListOptions(opts), queryParams) out := []*repository{} res, err := s.client.do(ctx, "GET", path, nil, &out) return convertRepositoryList(out), res, err @@ -59,7 +70,11 @@ func (s *repositoryService) ListV2(ctx context.Context, opts scm.RepoListOptions func (s *repositoryService) ListHooks(ctx context.Context, repo string, opts scm.ListOptions) ([]*scm.Hook, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/webhooks?sort=display_name&order=asc&%s", harnessURI, encodeListOptions(opts)) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/webhooks?sort=display_name&order=asc&%s&%s", repoId, encodeListOptions(opts), queryParams) out := []*hook{} res, err := s.client.do(ctx, "GET", path, nil, &out) return convertHookList(out), res, err @@ -71,7 +86,11 @@ func (s *repositoryService) ListStatus(ctx context.Context, repo string, ref str func (s *repositoryService) CreateHook(ctx context.Context, repo string, input *scm.HookInput) (*scm.Hook, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/webhooks", harnessURI) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/webhooks?%s", repoId, queryParams) in := new(hook) in.Enabled = true in.Identifier = input.Name @@ -96,7 +115,11 @@ func (s *repositoryService) UpdateHook(ctx context.Context, repo, id string, inp func (s *repositoryService) DeleteHook(ctx context.Context, repo string, id string) (*scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/webhooks/%s", harnessURI, id) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/webhooks/%s?%s", repoId, id, queryParams) return s.client.do(ctx, "DELETE", path, nil, nil) } diff --git a/scm/driver/harness/util.go b/scm/driver/harness/util.go index d094c8257..4be210068 100644 --- a/scm/driver/harness/util.go +++ b/scm/driver/harness/util.go @@ -13,6 +13,13 @@ import ( "github.com/drone/go-scm/scm" ) +const ( + accountIdentifier = "accountIdentifier" + projectIdentifier = "projectIdentifier" + orgIdentifier = "orgIdentifier" + routingId = "routingId" +) + func buildHarnessURI(account, organization, project, repo string) (uri string) { if account != "" { if project != "" { @@ -32,6 +39,34 @@ func buildHarnessURI(account, organization, project, repo string) (uri string) { return repo } +func getRepoAndQueryParams(slug string) (string, string, error) { + params := url.Values{} + s := strings.TrimSuffix(slug, "/+") + splitSlug := strings.Split(s, "/") + if len(splitSlug) == 0 || len(splitSlug) == 1 { + return "", "", fmt.Errorf("split length: %d is small for slug %s", len(splitSlug), slug) + } + + params.Set(accountIdentifier, splitSlug[0]) + params.Set(routingId, splitSlug[0]) + var repoId string + switch len(splitSlug) { + case 2: + repoId = splitSlug[1] + case 3: + params.Set(orgIdentifier, splitSlug[1]) + repoId = splitSlug[2] + case 4: + params.Set(orgIdentifier, splitSlug[1]) + params.Set(projectIdentifier, splitSlug[2]) + repoId = splitSlug[3] + default: + return "", "", fmt.Errorf("split length more than %d encountered for slug %s", len(splitSlug), slug) + + } + return repoId, params.Encode(), nil +} + func encodeListOptions(opts scm.ListOptions) string { params := url.Values{} if opts.Page != 0 { From fcc8453fa15d03845c2017d0388d9e1e159d0831 Mon Sep 17 00:00:00 2001 From: Abhinav Singh Date: Wed, 13 Mar 2024 05:09:07 +0530 Subject: [PATCH 121/195] fix: tag webhook parse for code (#297) * fix: tag webhook parse for code * fix: tag webhook parse for code * fix: tag webhook parse for code --- .../webhooks/branch_create.json.golden | 27 +---- .../testdata/webhooks/branch_delete.json | 34 ++++++ .../webhooks/branch_delete.json.golden | 29 +++++ .../harness/testdata/webhooks/tag_create.json | 76 +++++++++++++ .../testdata/webhooks/tag_create.json.golden | 29 +++++ .../harness/testdata/webhooks/tag_delete.json | 34 ++++++ .../testdata/webhooks/tag_delete.json.golden | 29 +++++ .../harness/testdata/webhooks/tag_update.json | 100 ++++++++++++++++++ .../testdata/webhooks/tag_update.json.golden | 67 ++++++++++++ scm/driver/harness/webhook.go | 75 ++++++++++++- scm/driver/harness/webhook_test.go | 34 +++++- 11 files changed, 506 insertions(+), 28 deletions(-) create mode 100644 scm/driver/harness/testdata/webhooks/branch_delete.json create mode 100644 scm/driver/harness/testdata/webhooks/branch_delete.json.golden create mode 100644 scm/driver/harness/testdata/webhooks/tag_create.json create mode 100644 scm/driver/harness/testdata/webhooks/tag_create.json.golden create mode 100644 scm/driver/harness/testdata/webhooks/tag_delete.json create mode 100644 scm/driver/harness/testdata/webhooks/tag_delete.json.golden create mode 100644 scm/driver/harness/testdata/webhooks/tag_update.json create mode 100644 scm/driver/harness/testdata/webhooks/tag_update.json.golden diff --git a/scm/driver/harness/testdata/webhooks/branch_create.json.golden b/scm/driver/harness/testdata/webhooks/branch_create.json.golden index a534de4c2..967f51f17 100644 --- a/scm/driver/harness/testdata/webhooks/branch_create.json.golden +++ b/scm/driver/harness/testdata/webhooks/branch_create.json.golden @@ -1,7 +1,9 @@ { - "Ref": "refs/heads/new2", - "Before": "0000000000000000000000000000000000000000", - "After": "aeafa0e2e4ec6909ad75cb8fad57c0b1eb5986e6", + "Ref": { + "Name": "refs/heads/new2", + "Sha": "aeafa0e2e4ec6909ad75cb8fad57c0b1eb5986e6" + }, + "Action": "created", "Repo": { "ID": "13", "Namespace": "", @@ -15,25 +17,6 @@ "Created": "0001-01-01T00:00:00Z", "Updated": "0001-01-01T00:00:00Z" }, - "Commit": { - "Sha": "aeafa0e2e4ec6909ad75cb8fad57c0b1eb5986e6", - "Message": "version 4", - "Author": { - "Name": "Admin", - "Email": "admin@harness.io", - "Date": "0001-01-01T00:00:00Z", - "Login": "", - "Avatar": "" - }, - "Committer": { - "Name": "Admin", - "Email": "admin@harness.io", - "Date": "0001-01-01T00:00:00Z", - "Login": "", - "Avatar": "" - }, - "Link": "" - }, "Sender": { "ID": "0osgWsTZRsSZ8RWfjLRkEg", "Login": "0osgWsTZRsSZ8RWfjLRkEg", diff --git a/scm/driver/harness/testdata/webhooks/branch_delete.json b/scm/driver/harness/testdata/webhooks/branch_delete.json new file mode 100644 index 000000000..ba496b75d --- /dev/null +++ b/scm/driver/harness/testdata/webhooks/branch_delete.json @@ -0,0 +1,34 @@ +{ + "trigger": "branch_deleted", + "repo": { + "id": 16, + "path": "kmpySmUISimoRrJL6NL73w/harness-core", + "identifier": "harness-core", + "default_branch": "develop", + "git_url": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/harness-core.git", + "uid": "harness-core" + }, + "principal": { + "id": 2, + "uid": "lv0euRhKRCyiXWzS7pOg6g", + "display_name": "Admin", + "email": "admin@harness.io", + "type": "user", + "created": 1701091219051, + "updated": 1701091219051 + }, + "ref": { + "name": "refs/heads/das", + "repo": { + "id": 16, + "path": "kmpySmUISimoRrJL6NL73w/harness-core", + "identifier": "harness-core", + "default_branch": "develop", + "git_url": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/harness-core.git", + "uid": "harness-core" + } + }, + "sha": "0000000000000000000000000000000000000000", + "old_sha": "0f1835abe08473e07863540712d8389984b72dad", + "forced": false +} \ No newline at end of file diff --git a/scm/driver/harness/testdata/webhooks/branch_delete.json.golden b/scm/driver/harness/testdata/webhooks/branch_delete.json.golden new file mode 100644 index 000000000..b9a0ad8f7 --- /dev/null +++ b/scm/driver/harness/testdata/webhooks/branch_delete.json.golden @@ -0,0 +1,29 @@ +{ + "Ref": { + "Name": "refs/heads/das", + "Sha": "0000000000000000000000000000000000000000" + }, + "Action": "deleted", + "Repo": { + "ID": "16", + "Namespace": "", + "Name": "harness-core", + "Perm": null, + "Branch": "develop", + "Private": false, + "Clone": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/harness-core.git", + "CloneSSH": "", + "Link": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/harness-core.git", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Sender": { + "ID": "lv0euRhKRCyiXWzS7pOg6g", + "Login": "lv0euRhKRCyiXWzS7pOg6g", + "Name": "Admin", + "Email": "admin@harness.io", + "Avatar": "", + "Created": "2023-11-27T05:20:19.051-08:00", + "Updated": "2023-11-27T05:20:19.051-08:00" + } +} \ No newline at end of file diff --git a/scm/driver/harness/testdata/webhooks/tag_create.json b/scm/driver/harness/testdata/webhooks/tag_create.json new file mode 100644 index 000000000..f67e9700b --- /dev/null +++ b/scm/driver/harness/testdata/webhooks/tag_create.json @@ -0,0 +1,76 @@ +{ + "trigger": "tag_created", + "repo": { + "id": 16, + "path": "kmpySmUISimoRrJL6NL73w/harness-core", + "identifier": "harness-core", + "default_branch": "develop", + "git_url": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/harness-core.git", + "uid": "harness-core" + }, + "principal": { + "id": 2, + "uid": "lv0euRhKRCyiXWzS7pOg6g", + "display_name": "Admin", + "email": "admin@harness.io", + "type": "user", + "created": 1701091219051, + "updated": 1701091219051 + }, + "ref": { + "name": "refs/tags/asd", + "repo": { + "id": 16, + "path": "kmpySmUISimoRrJL6NL73w/harness-core", + "identifier": "harness-core", + "default_branch": "develop", + "git_url": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/harness-core.git", + "uid": "harness-core" + } + }, + "sha": "3e4da2d65c3631c3e84b52fabe714c978aff540b", + "head_commit": { + "sha": "0f1835abe08473e07863540712d8389984b72dad", + "message": "", + "author": { + "identity": { + "name": "admin", + "email": "admin@harness.io" + }, + "when": "2024-03-01T07:54:35-08:00" + }, + "committer": { + "identity": { + "name": "GitHub", + "email": "noreply@github.com" + }, + "when": "2024-03-01T07:54:35-08:00" + }, + "added": [], + "removed": [], + "modified": [] + }, + "commit": { + "sha": "0f1835abe08473e07863540712d8389984b72dad", + "message": "", + "author": { + "identity": { + "name": "Jenny James", + "email": "jenny.james@harness.io" + }, + "when": "2024-03-01T07:54:35-08:00" + }, + "committer": { + "identity": { + "name": "GitHub", + "email": "noreply@github.com" + }, + "when": "2024-03-01T07:54:35-08:00" + }, + "added": [], + "removed": [], + "modified": [] + }, + "old_sha": "0000000000000000000000000000000000000000", + "forced": false +} \ No newline at end of file diff --git a/scm/driver/harness/testdata/webhooks/tag_create.json.golden b/scm/driver/harness/testdata/webhooks/tag_create.json.golden new file mode 100644 index 000000000..f6a8a53e4 --- /dev/null +++ b/scm/driver/harness/testdata/webhooks/tag_create.json.golden @@ -0,0 +1,29 @@ +{ + "Ref": { + "Name": "refs/tags/asd", + "Sha": "3e4da2d65c3631c3e84b52fabe714c978aff540b" + }, + "Action": "created", + "Repo": { + "ID": "16", + "Namespace": "", + "Name": "harness-core", + "Perm": null, + "Branch": "develop", + "Private": false, + "Clone": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/harness-core.git", + "CloneSSH": "", + "Link": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/harness-core.git", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Sender": { + "ID": "lv0euRhKRCyiXWzS7pOg6g", + "Login": "lv0euRhKRCyiXWzS7pOg6g", + "Name": "Admin", + "Email": "admin@harness.io", + "Avatar": "", + "Created": "2023-11-27T05:20:19.051-08:00", + "Updated": "2023-11-27T05:20:19.051-08:00" + } +} \ No newline at end of file diff --git a/scm/driver/harness/testdata/webhooks/tag_delete.json b/scm/driver/harness/testdata/webhooks/tag_delete.json new file mode 100644 index 000000000..3fa9348ee --- /dev/null +++ b/scm/driver/harness/testdata/webhooks/tag_delete.json @@ -0,0 +1,34 @@ +{ + "trigger": "tag_deleted", + "repo": { + "id": 16, + "path": "kmpySmUISimoRrJL6NL73w/harness-core", + "identifier": "harness-core", + "default_branch": "develop", + "git_url": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/harness-core.git", + "uid": "harness-core" + }, + "principal": { + "id": 2, + "uid": "lv0euRhKRCyiXWzS7pOg6g", + "display_name": "Admin", + "email": "admin@harness.io", + "type": "user", + "created": 1701091219051, + "updated": 1701091219051 + }, + "ref": { + "name": "refs/tags/asd", + "repo": { + "id": 16, + "path": "kmpySmUISimoRrJL6NL73w/harness-core", + "identifier": "harness-core", + "default_branch": "develop", + "git_url": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/harness-core.git", + "uid": "harness-core" + } + }, + "sha": "0000000000000000000000000000000000000000", + "old_sha": "3e4da2d65c3631c3e84b52fabe714c978aff540b", + "forced": false +} \ No newline at end of file diff --git a/scm/driver/harness/testdata/webhooks/tag_delete.json.golden b/scm/driver/harness/testdata/webhooks/tag_delete.json.golden new file mode 100644 index 000000000..cfd67a8b1 --- /dev/null +++ b/scm/driver/harness/testdata/webhooks/tag_delete.json.golden @@ -0,0 +1,29 @@ +{ + "Ref": { + "Name": "refs/tags/asd", + "Sha": "0000000000000000000000000000000000000000" + }, + "Action": "deleted", + "Repo": { + "ID": "16", + "Namespace": "", + "Name": "harness-core", + "Perm": null, + "Branch": "develop", + "Private": false, + "Clone": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/harness-core.git", + "CloneSSH": "", + "Link": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/harness-core.git", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Sender": { + "ID": "lv0euRhKRCyiXWzS7pOg6g", + "Login": "lv0euRhKRCyiXWzS7pOg6g", + "Name": "Admin", + "Email": "admin@harness.io", + "Avatar": "", + "Created": "2023-11-27T05:20:19.051-08:00", + "Updated": "2023-11-27T05:20:19.051-08:00" + } +} \ No newline at end of file diff --git a/scm/driver/harness/testdata/webhooks/tag_update.json b/scm/driver/harness/testdata/webhooks/tag_update.json new file mode 100644 index 000000000..b16eac070 --- /dev/null +++ b/scm/driver/harness/testdata/webhooks/tag_update.json @@ -0,0 +1,100 @@ +{ + "trigger": "tag_updated", + "repo": { + "id": 16, + "path": "kmpySmUISimoRrJL6NL73w/harness-core", + "identifier": "harness-core", + "default_branch": "develop", + "git_url": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/harness-core.git", + "uid": "harness-core" + }, + "principal": { + "id": 2, + "uid": "lv0euRhKRCyiXWzS7pOg6g", + "display_name": "Admin", + "email": "admin@harness.io", + "type": "user", + "created": 1701091219051, + "updated": 1701091219051 + }, + "ref": { + "name": "refs/tags/ddxas", + "repo": { + "id": 16, + "path": "kmpySmUISimoRrJL6NL73w/harness-core", + "identifier": "harness-core", + "default_branch": "develop", + "git_url": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/harness-core.git", + "uid": "harness-core" + } + }, + "sha": "700b3dab8e7a5cebf5e1ce54e7dd5bde60099912", + "head_commit": { + "sha": "700b3dab8e7a5cebf5e1ce54e7dd5bde60099912", + "message": "Asd", + "author": { + "identity": { + "name": "Abhinav Singh", + "email": "abhinav.singh@harness.io" + }, + "when": "2024-03-07T03:18:51-08:00" + }, + "committer": { + "identity": { + "name": "Abhinav Singh", + "email": "abhinav.singh@harness.io" + }, + "when": "2024-03-07T03:18:51-08:00" + }, + "added": [], + "removed": [], + "modified": [] + }, + "commits": [ + { + "sha": "700b3dab8e7a5cebf5e1ce54e7dd5bde60099912", + "message": "Asd", + "author": { + "identity": { + "name": "Abhinav Singh", + "email": "abhinav.singh@harness.io" + }, + "when": "2024-03-07T03:18:51-08:00" + }, + "committer": { + "identity": { + "name": "Abhinav Singh", + "email": "abhinav.singh@harness.io" + }, + "when": "2024-03-07T03:18:51-08:00" + }, + "added": [], + "removed": [], + "modified": [] + } + ], + "total_commits_count": 1, + "commit": { + "sha": "700b3dab8e7a5cebf5e1ce54e7dd5bde60099912", + "message": "Asd", + "author": { + "identity": { + "name": "Abhinav Singh", + "email": "abhinav.singh@harness.io" + }, + "when": "2024-03-07T03:18:51-08:00" + }, + "committer": { + "identity": { + "name": "Abhinav Singh", + "email": "abhinav.singh@harness.io" + }, + "when": "2024-03-07T03:18:51-08:00" + }, + "added": [], + "removed": [], + "modified": [] + }, + "old_sha": "0f1835abe08473e07863540712d8389984b72dad", + "forced": true +} \ No newline at end of file diff --git a/scm/driver/harness/testdata/webhooks/tag_update.json.golden b/scm/driver/harness/testdata/webhooks/tag_update.json.golden new file mode 100644 index 000000000..408447db1 --- /dev/null +++ b/scm/driver/harness/testdata/webhooks/tag_update.json.golden @@ -0,0 +1,67 @@ +{ + "Ref": "refs/tags/ddxas", + "Before": "0f1835abe08473e07863540712d8389984b72dad", + "After": "700b3dab8e7a5cebf5e1ce54e7dd5bde60099912", + "Repo": { + "ID": "16", + "Namespace": "", + "Name": "harness-core", + "Perm": null, + "Branch": "develop", + "Private": false, + "Clone": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/harness-core.git", + "CloneSSH": "", + "Link": "http://localhost:3000/git/kmpySmUISimoRrJL6NL73w/harness-core.git", + "Created": "0001-01-01T00:00:00Z", + "Updated": "0001-01-01T00:00:00Z" + }, + "Commit": { + "Sha": "700b3dab8e7a5cebf5e1ce54e7dd5bde60099912", + "Message": "Asd", + "Author": { + "Name": "Abhinav Singh", + "Email": "abhinav.singh@harness.io", + "Date": "0001-01-01T00:00:00Z", + "Login": "", + "Avatar": "" + }, + "Committer": { + "Name": "Abhinav Singh", + "Email": "abhinav.singh@harness.io", + "Date": "0001-01-01T00:00:00Z", + "Login": "", + "Avatar": "" + }, + "Link": "" + }, + "Commits": [ + { + "Sha": "700b3dab8e7a5cebf5e1ce54e7dd5bde60099912", + "Message": "Asd", + "Author": { + "Name": "Abhinav Singh", + "Email": "abhinav.singh@harness.io", + "Date": "0001-01-01T00:00:00Z", + "Login": "", + "Avatar": "" + }, + "Committer": { + "Name": "Abhinav Singh", + "Email": "abhinav.singh@harness.io", + "Date": "0001-01-01T00:00:00Z", + "Login": "", + "Avatar": "" + }, + "Link": "" + } + ], + "Sender": { + "ID": "lv0euRhKRCyiXWzS7pOg6g", + "Login": "lv0euRhKRCyiXWzS7pOg6g", + "Name": "Admin", + "Email": "admin@harness.io", + "Avatar": "", + "Created": "2023-11-27T05:20:19.051-08:00", + "Updated": "2023-11-27T05:20:19.051-08:00" + } +} \ No newline at end of file diff --git a/scm/driver/harness/webhook.go b/scm/driver/harness/webhook.go index 73e7bd920..33be360b4 100644 --- a/scm/driver/harness/webhook.go +++ b/scm/driver/harness/webhook.go @@ -11,6 +11,7 @@ import ( "io/ioutil" "net/http" "strconv" + "strings" "time" "github.com/drone/go-scm/scm" @@ -37,8 +38,12 @@ func (s *webhookService) Parse(req *http.Request, fn scm.SecretFunc) (scm.Webhoo // hook, err = s.parseDeleteHook(data) // case "issues": // hook, err = s.parseIssueHook(data) - case "branch_created", "branch_updated": + case "branch_updated", "tag_updated": hook, err = s.parsePushHook(data) + case "branch_created", "branch_deleted": + hook, err = s.parseBranchHook(data) + case "tag_created", "tag_deleted": + hook, err = s.parseTagHook(data) case "pullreq_created", "pullreq_reopened", "pullreq_branch_updated", "pullreq_closed", "pullreq_merged": hook, err = s.parsePullRequestHook(data) case "pullreq_comment_created": @@ -99,6 +104,20 @@ func (s *webhookService) parsePullRequestCommentHook(data []byte) (scm.Webhook, return convertPullRequestCommentHook(dst), err } +func (s *webhookService) parseBranchHook(data []byte) (scm.Webhook, error) { + // using pushHook object since it is same as branch events + dst := new(pushHook) + err := json.Unmarshal(data, dst) + return convertBranchHook(dst), err +} + +func (s *webhookService) parseTagHook(data []byte) (scm.Webhook, error) { + // using pushHook object since it is same as tag events + dst := new(pushHook) + err := json.Unmarshal(data, dst) + return convertTagHook(dst), err +} + // native data structures type ( repo struct { @@ -218,7 +237,7 @@ type ( // native data structure conversion func convertPullRequestHook(src *pullRequestHook) *scm.PullRequestHook { return &scm.PullRequestHook{ - Action: convertAction(src.Trigger), + Action: convertPRAction(src.Trigger), PullRequest: convertPullReq(src.PullReq, src.Ref, src.HeadCommit), Repo: convertRepo(src.Repo), Sender: convertUser(src.Principal), @@ -267,9 +286,33 @@ func convertPullRequestCommentHook(src *pullRequestCommentHook) *scm.PullRequest Sender: convertUser(src.Principal), } } +func convertBranchHook(dst *pushHook) *scm.BranchHook { + return &scm.BranchHook{ + Ref: convertRef(dst), + Repo: convertRepo(dst.Repo), + Action: convertBranchAction(dst.Trigger), + Sender: convertUser(dst.Principal), + } +} + +func convertTagHook(dst *pushHook) *scm.TagHook { + return &scm.TagHook{ + Ref: convertRef(dst), + Repo: convertRepo(dst.Repo), + Action: convertTagAction(dst.Trigger), + Sender: convertUser(dst.Principal), + } +} -func convertAction(src string) (action scm.Action) { - switch src { +func convertRef(dst *pushHook) scm.Reference { + return scm.Reference{ + Name: dst.Ref.Name, + Sha: dst.Sha, + } +} + +func convertPRAction(src string) (action scm.Action) { + switch strings.ToLower(src) { case "pullreq_created": return scm.ActionCreate case "pullreq_branch_updated": @@ -281,7 +324,29 @@ func convertAction(src string) (action scm.Action) { case "pullreq_merged": return scm.ActionMerge default: - return + return scm.ActionUnknown + } +} + +func convertBranchAction(src string) (action scm.Action) { + switch strings.ToLower(src) { + case "branch_created": + return scm.ActionCreate + case "branch_deleted": + return scm.ActionDelete + default: + return scm.ActionUnknown + } +} + +func convertTagAction(src string) (action scm.Action) { + switch strings.ToLower(src) { + case "tag_created": + return scm.ActionCreate + case "tag_deleted": + return scm.ActionDelete + default: + return scm.ActionUnknown } } diff --git a/scm/driver/harness/webhook_test.go b/scm/driver/harness/webhook_test.go index 26966db2b..a4cf093b1 100644 --- a/scm/driver/harness/webhook_test.go +++ b/scm/driver/harness/webhook_test.go @@ -31,7 +31,7 @@ func TestWebhooks(t *testing.T) { event: "branch_created", before: "testdata/webhooks/branch_create.json", after: "testdata/webhooks/branch_create.json.golden", - obj: new(scm.PushHook), + obj: new(scm.BranchHook), }, // push branch update { @@ -40,6 +40,38 @@ func TestWebhooks(t *testing.T) { after: "testdata/webhooks/branch_updated.json.golden", obj: new(scm.PushHook), }, + // push branch delete + { + event: "branch_deleted", + before: "testdata/webhooks/branch_delete.json", + after: "testdata/webhooks/branch_delete.json.golden", + obj: new(scm.BranchHook), + }, + // + // tag events + // + // push tag create + { + event: "tag_created", + before: "testdata/webhooks/tag_create.json", + after: "testdata/webhooks/tag_create.json.golden", + obj: new(scm.TagHook), + }, + // push tag update + { + event: "tag_updated", + before: "testdata/webhooks/tag_update.json", + after: "testdata/webhooks/tag_update.json.golden", + obj: new(scm.PushHook), + }, + // push tag delete + { + event: "tag_deleted", + before: "testdata/webhooks/tag_delete.json", + after: "testdata/webhooks/tag_delete.json.golden", + obj: new(scm.TagHook), + }, + // // pull request events // From 95e7cdcdc01ff8473366570aa3ff0d6d9f7d7e69 Mon Sep 17 00:00:00 2001 From: Vivek Dixit Date: Tue, 19 Mar 2024 15:49:14 +0530 Subject: [PATCH 122/195] Update util.go --- scm/driver/github/util.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scm/driver/github/util.go b/scm/driver/github/util.go index d06e474e0..874b63b9a 100644 --- a/scm/driver/github/util.go +++ b/scm/driver/github/util.go @@ -47,7 +47,8 @@ func encodeRepoListOptions(opts scm.RepoListOptions) string { sb.WriteString(strconv.Itoa(opts.ListOptions.Size)) } } - return sb.String() + + return url.QueryEscape(sb.String()) } func encodeCommitListOptions(opts scm.CommitListOptions) string { From 44a195cff382fd4750ebf38424c91b046aaf330a Mon Sep 17 00:00:00 2001 From: Vivek Dixit Date: Tue, 19 Mar 2024 15:54:00 +0530 Subject: [PATCH 123/195] Update util.go --- scm/driver/github/util.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/scm/driver/github/util.go b/scm/driver/github/util.go index 874b63b9a..41caa3e03 100644 --- a/scm/driver/github/util.go +++ b/scm/driver/github/util.go @@ -29,7 +29,7 @@ func encodeRepoListOptions(opts scm.RepoListOptions) string { if opts.RepoSearchTerm.RepoName != "" { sb.WriteString("q=") sb.WriteString(opts.RepoSearchTerm.RepoName) - sb.WriteString("in:name+user:") + sb.WriteString(" in:name+user:") sb.WriteString(opts.RepoSearchTerm.User) } else { sb.WriteString("q=") @@ -47,8 +47,9 @@ func encodeRepoListOptions(opts scm.RepoListOptions) string { sb.WriteString(strconv.Itoa(opts.ListOptions.Size)) } } - - return url.QueryEscape(sb.String()) + urlEncodedRepoListOptions := url.QueryEscape(sb.String()) + fmt.Println(urlEncodedRepoListOptions) + return urlEncodedRepoListOptions } func encodeCommitListOptions(opts scm.CommitListOptions) string { From b43614d6aa35f6c20a79d966e75b783baf8d35b0 Mon Sep 17 00:00:00 2001 From: Vivek Dixit Date: Tue, 19 Mar 2024 15:55:39 +0530 Subject: [PATCH 124/195] Update util.go --- scm/driver/github/util.go | 1 + 1 file changed, 1 insertion(+) diff --git a/scm/driver/github/util.go b/scm/driver/github/util.go index 41caa3e03..f10d2e031 100644 --- a/scm/driver/github/util.go +++ b/scm/driver/github/util.go @@ -8,6 +8,7 @@ import ( "net/url" "strconv" "strings" + "fmt" "github.com/drone/go-scm/scm" ) From 55f6df5dc458958c0c707161c689ba3610451220 Mon Sep 17 00:00:00 2001 From: Vivek Dixit Date: Tue, 19 Mar 2024 16:01:34 +0530 Subject: [PATCH 125/195] Update util.go --- scm/driver/github/util.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/scm/driver/github/util.go b/scm/driver/github/util.go index f10d2e031..db9b58100 100644 --- a/scm/driver/github/util.go +++ b/scm/driver/github/util.go @@ -30,7 +30,7 @@ func encodeRepoListOptions(opts scm.RepoListOptions) string { if opts.RepoSearchTerm.RepoName != "" { sb.WriteString("q=") sb.WriteString(opts.RepoSearchTerm.RepoName) - sb.WriteString(" in:name+user:") + sb.WriteString("%20in:name+user:") sb.WriteString(opts.RepoSearchTerm.User) } else { sb.WriteString("q=") @@ -48,9 +48,8 @@ func encodeRepoListOptions(opts scm.RepoListOptions) string { sb.WriteString(strconv.Itoa(opts.ListOptions.Size)) } } - urlEncodedRepoListOptions := url.QueryEscape(sb.String()) - fmt.Println(urlEncodedRepoListOptions) - return urlEncodedRepoListOptions + fmt.Println(sb.String()) + return sb.String() } func encodeCommitListOptions(opts scm.CommitListOptions) string { From 68b549a0a40fc987434ce0344295a99213d5c0fb Mon Sep 17 00:00:00 2001 From: Vivek Dixit Date: Tue, 19 Mar 2024 16:03:55 +0530 Subject: [PATCH 126/195] Update util.go --- scm/driver/github/util.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/scm/driver/github/util.go b/scm/driver/github/util.go index db9b58100..7f5a04a35 100644 --- a/scm/driver/github/util.go +++ b/scm/driver/github/util.go @@ -8,7 +8,6 @@ import ( "net/url" "strconv" "strings" - "fmt" "github.com/drone/go-scm/scm" ) @@ -48,7 +47,6 @@ func encodeRepoListOptions(opts scm.RepoListOptions) string { sb.WriteString(strconv.Itoa(opts.ListOptions.Size)) } } - fmt.Println(sb.String()) return sb.String() } From d2e8e4eebf20694ac77f8c697a9c245cf1a34f92 Mon Sep 17 00:00:00 2001 From: Vivek Dixit Date: Tue, 19 Mar 2024 16:07:20 +0530 Subject: [PATCH 127/195] Update util.go --- scm/driver/github/util.go | 1 + 1 file changed, 1 insertion(+) diff --git a/scm/driver/github/util.go b/scm/driver/github/util.go index 7f5a04a35..916f29fb1 100644 --- a/scm/driver/github/util.go +++ b/scm/driver/github/util.go @@ -29,6 +29,7 @@ func encodeRepoListOptions(opts scm.RepoListOptions) string { if opts.RepoSearchTerm.RepoName != "" { sb.WriteString("q=") sb.WriteString(opts.RepoSearchTerm.RepoName) + // %20 is urlEncoding of blank space. sb.WriteString("%20in:name+user:") sb.WriteString(opts.RepoSearchTerm.User) } else { From b23de2cb10d839613b37edefc15a9107986f325a Mon Sep 17 00:00:00 2001 From: Vivek Dixit Date: Wed, 20 Mar 2024 10:38:09 +0530 Subject: [PATCH 128/195] Update util.go --- scm/driver/github/util.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/scm/driver/github/util.go b/scm/driver/github/util.go index 916f29fb1..e8b3935a7 100644 --- a/scm/driver/github/util.go +++ b/scm/driver/github/util.go @@ -8,6 +8,7 @@ import ( "net/url" "strconv" "strings" + "fmt" "github.com/drone/go-scm/scm" ) @@ -29,8 +30,7 @@ func encodeRepoListOptions(opts scm.RepoListOptions) string { if opts.RepoSearchTerm.RepoName != "" { sb.WriteString("q=") sb.WriteString(opts.RepoSearchTerm.RepoName) - // %20 is urlEncoding of blank space. - sb.WriteString("%20in:name+user:") + sb.WriteString("in:name+user:") sb.WriteString(opts.RepoSearchTerm.User) } else { sb.WriteString("q=") @@ -48,7 +48,9 @@ func encodeRepoListOptions(opts scm.RepoListOptions) string { sb.WriteString(strconv.Itoa(opts.ListOptions.Size)) } } - return sb.String() + url := url.QueryEscape(sb.String()) + fmt.Println(url) + return url } func encodeCommitListOptions(opts scm.CommitListOptions) string { From 1eb765587a97b329e29ebc7944abc2328fb0249d Mon Sep 17 00:00:00 2001 From: Vivek Dixit Date: Wed, 20 Mar 2024 10:42:45 +0530 Subject: [PATCH 129/195] Update util.go --- scm/driver/github/util.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm/driver/github/util.go b/scm/driver/github/util.go index e8b3935a7..4987a4af4 100644 --- a/scm/driver/github/util.go +++ b/scm/driver/github/util.go @@ -30,7 +30,7 @@ func encodeRepoListOptions(opts scm.RepoListOptions) string { if opts.RepoSearchTerm.RepoName != "" { sb.WriteString("q=") sb.WriteString(opts.RepoSearchTerm.RepoName) - sb.WriteString("in:name+user:") + sb.WriteString(" in:name+user:") sb.WriteString(opts.RepoSearchTerm.User) } else { sb.WriteString("q=") From 39d795fa985a3a40e06eec2040cafac83f56cf3e Mon Sep 17 00:00:00 2001 From: Vivek Dixit Date: Wed, 20 Mar 2024 10:47:13 +0530 Subject: [PATCH 130/195] Update util.go --- scm/driver/github/util.go | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/scm/driver/github/util.go b/scm/driver/github/util.go index 4987a4af4..721858069 100644 --- a/scm/driver/github/util.go +++ b/scm/driver/github/util.go @@ -9,6 +9,7 @@ import ( "strconv" "strings" "fmt" + "unicode/utf8" "github.com/drone/go-scm/scm" ) @@ -48,7 +49,8 @@ func encodeRepoListOptions(opts scm.RepoListOptions) string { sb.WriteString(strconv.Itoa(opts.ListOptions.Size)) } } - url := url.QueryEscape(sb.String()) + url := encodeString(sb.String()) + // url := url.QueryEscape(sb.String()) fmt.Println(url) return url } @@ -133,3 +135,32 @@ func encodeReleaseListOptions(opts scm.ReleaseListOptions) string { } return params.Encode() } + +func encodeString(s string) string { + var encoded strings.Builder + + for _, r := range s { + if shouldEscape(r) { + encoded.WriteString(fmt.Sprintf("%%%02X", r)) + } else { + encoded.WriteRune(r) + } + } + + return encoded.String() +} + +func shouldEscape(r rune) bool { + switch { + case r >= 'A' && r <= 'Z': + return false + case r >= 'a' && r <= 'z': + return false + case r >= '0' && r <= '9': + return false + case r == '-', '_', '.', '~': + return false + default: + return true + } +} From dcd4b47d080866f852067838d3433d296d6541b5 Mon Sep 17 00:00:00 2001 From: Vivek Dixit Date: Wed, 20 Mar 2024 10:49:24 +0530 Subject: [PATCH 131/195] Update util.go --- scm/driver/github/util.go | 1 - 1 file changed, 1 deletion(-) diff --git a/scm/driver/github/util.go b/scm/driver/github/util.go index 721858069..9bda47474 100644 --- a/scm/driver/github/util.go +++ b/scm/driver/github/util.go @@ -9,7 +9,6 @@ import ( "strconv" "strings" "fmt" - "unicode/utf8" "github.com/drone/go-scm/scm" ) From c06f5b7d227e0a55319397947f901017e6511bc2 Mon Sep 17 00:00:00 2001 From: Vivek Dixit Date: Wed, 20 Mar 2024 10:59:04 +0530 Subject: [PATCH 132/195] Update util.go --- scm/driver/github/util.go | 37 +++---------------------------------- 1 file changed, 3 insertions(+), 34 deletions(-) diff --git a/scm/driver/github/util.go b/scm/driver/github/util.go index 9bda47474..45e33130a 100644 --- a/scm/driver/github/util.go +++ b/scm/driver/github/util.go @@ -30,7 +30,7 @@ func encodeRepoListOptions(opts scm.RepoListOptions) string { if opts.RepoSearchTerm.RepoName != "" { sb.WriteString("q=") sb.WriteString(opts.RepoSearchTerm.RepoName) - sb.WriteString(" in:name+user:") + sb.WriteString("+in:name+user:") sb.WriteString(opts.RepoSearchTerm.User) } else { sb.WriteString("q=") @@ -48,10 +48,8 @@ func encodeRepoListOptions(opts scm.RepoListOptions) string { sb.WriteString(strconv.Itoa(opts.ListOptions.Size)) } } - url := encodeString(sb.String()) - // url := url.QueryEscape(sb.String()) - fmt.Println(url) - return url + fmt.Println(sb.string()) + return sb.string() } func encodeCommitListOptions(opts scm.CommitListOptions) string { @@ -134,32 +132,3 @@ func encodeReleaseListOptions(opts scm.ReleaseListOptions) string { } return params.Encode() } - -func encodeString(s string) string { - var encoded strings.Builder - - for _, r := range s { - if shouldEscape(r) { - encoded.WriteString(fmt.Sprintf("%%%02X", r)) - } else { - encoded.WriteRune(r) - } - } - - return encoded.String() -} - -func shouldEscape(r rune) bool { - switch { - case r >= 'A' && r <= 'Z': - return false - case r >= 'a' && r <= 'z': - return false - case r >= '0' && r <= '9': - return false - case r == '-', '_', '.', '~': - return false - default: - return true - } -} From f8119f14e1b861e9fbdf15a8ba58bf78111dc4fc Mon Sep 17 00:00:00 2001 From: Vivek Dixit Date: Wed, 20 Mar 2024 11:02:35 +0530 Subject: [PATCH 133/195] Update util.go --- scm/driver/github/util.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scm/driver/github/util.go b/scm/driver/github/util.go index 45e33130a..c09f92752 100644 --- a/scm/driver/github/util.go +++ b/scm/driver/github/util.go @@ -48,8 +48,8 @@ func encodeRepoListOptions(opts scm.RepoListOptions) string { sb.WriteString(strconv.Itoa(opts.ListOptions.Size)) } } - fmt.Println(sb.string()) - return sb.string() + fmt.Println(sb.String()) + return sb.String() } func encodeCommitListOptions(opts scm.CommitListOptions) string { From 594c68b442bbeaebf24152713676e461abe2b6b0 Mon Sep 17 00:00:00 2001 From: Vivek Dixit Date: Wed, 20 Mar 2024 12:02:48 +0530 Subject: [PATCH 134/195] Update util.go --- scm/driver/github/util.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/scm/driver/github/util.go b/scm/driver/github/util.go index c09f92752..24a0c858c 100644 --- a/scm/driver/github/util.go +++ b/scm/driver/github/util.go @@ -8,7 +8,6 @@ import ( "net/url" "strconv" "strings" - "fmt" "github.com/drone/go-scm/scm" ) @@ -48,7 +47,6 @@ func encodeRepoListOptions(opts scm.RepoListOptions) string { sb.WriteString(strconv.Itoa(opts.ListOptions.Size)) } } - fmt.Println(sb.String()) return sb.String() } From 142ee303394e6cf3de0ad1114ea851cfb03368d5 Mon Sep 17 00:00:00 2001 From: Abhinav Singh Date: Thu, 21 Mar 2024 04:14:27 +0530 Subject: [PATCH 135/195] feat: pr harness parse all fields (#302) --- scm/driver/harness/pr.go | 90 ++++++++++++---------- scm/driver/harness/testdata/pr.json | 40 +++++----- scm/driver/harness/testdata/pr.json.golden | 39 ++++++---- 3 files changed, 97 insertions(+), 72 deletions(-) diff --git a/scm/driver/harness/pr.go b/scm/driver/harness/pr.go index 35cadd20a..167ba9bf7 100644 --- a/scm/driver/harness/pr.go +++ b/scm/driver/harness/pr.go @@ -7,6 +7,7 @@ package harness import ( "context" "fmt" + "github.com/drone/go-scm/scm/driver/internal/null" "strconv" "strings" "time" @@ -123,44 +124,38 @@ func (s *pullService) Close(context.Context, string, int) (*scm.Response, error) // native data structures type ( pr struct { - Author struct { - Created int `json:"created"` - DisplayName string `json:"display_name"` - Email string `json:"email"` - ID int `json:"id"` - Type string `json:"type"` - UID string `json:"uid"` - Updated int `json:"updated"` - } `json:"author"` - Created int `json:"created"` - Description string `json:"description"` - Edited int `json:"edited"` - IsDraft bool `json:"is_draft"` - MergeBaseSha string `json:"merge_base_sha"` - MergeHeadSha string `json:"merge_head_sha"` - MergeStrategy string `json:"merge_strategy"` - Merged int `json:"merged"` - Merger struct { - Created int `json:"created"` - DisplayName string `json:"display_name"` - Email string `json:"email"` - ID int `json:"id"` - Type string `json:"type"` - UID string `json:"uid"` - Updated int `json:"updated"` - } `json:"merger"` - Number int `json:"number"` + Author principal `json:"author"` + Created int64 `json:"created"` + Description string `json:"description"` + Edited int64 `json:"edited"` + IsDraft bool `json:"is_draft"` + + MergeTargetSHA null.String `json:"merge_target_sha"` + MergeBaseSha string `json:"merge_base_sha"` + Merged null.Int `json:"merged"` + MergeMethod null.String `json:"merge_method"` + MergeSHA null.String `json:"merge_sha"` + MergeCheckStatus string `json:"merge_check_status"` + MergeConflicts []string `json:"merge_conflicts,omitempty"` + Merger *principal `json:"merger"` + + Number int64 `json:"number"` + SourceBranch string `json:"source_branch"` - SourceRepoID int `json:"source_repo_id"` - State string `json:"state"` - Stats struct { - Commits int `json:"commits"` - Conversations int `json:"conversations"` - FilesChanged int `json:"files_changed"` - } `json:"stats"` + SourceRepoID int64 `json:"source_repo_id"` + SourceSHA string `json:"source_sha"` TargetBranch string `json:"target_branch"` - TargetRepoID int `json:"target_repo_id"` - Title string `json:"title"` + TargetRepoID int64 `json:"target_repo_id"` + + State string `json:"state"` + Stats struct { + Commits null.Int `json:"commits,omitempty"` + Conversations int `json:"conversations,omitempty"` + FilesChanged null.Int `json:"files_changed,omitempty"` + UnresolvedCount int `json:"unresolved_count,omitempty"` + } `json:"stats"` + + Title string `json:"title"` } reference struct { @@ -246,21 +241,34 @@ func convertPullRequests(src []*pr) []*scm.PullRequest { func convertPullRequest(src *pr) *scm.PullRequest { return &scm.PullRequest{ - Number: src.Number, + Number: int(src.Number), Title: src.Title, Body: src.Description, + Sha: src.SourceSHA, Source: src.SourceBranch, Target: src.TargetBranch, - Merged: src.Merged != 0, + Merged: src.Merged.Valid, Author: scm.User{ Login: src.Author.Email, Name: src.Author.DisplayName, ID: src.Author.UID, Email: src.Author.Email, }, - Fork: "fork", - Ref: fmt.Sprintf("refs/pullreq/%d/head", src.Number), - Closed: src.State == "closed", + Head: scm.Reference{ + Name: src.SourceBranch, + Path: scm.ExpandRef(src.SourceBranch, "refs/heads"), + Sha: src.SourceSHA, + }, + Base: scm.Reference{ + Name: src.TargetBranch, + Path: scm.ExpandRef(src.TargetBranch, "refs/heads"), + Sha: src.MergeTargetSHA.String, + }, + Fork: "fork", + Ref: fmt.Sprintf("refs/pullreq/%d/head", src.Number), + Closed: src.State == "closed", + Created: time.UnixMilli(src.Created), + Updated: time.UnixMilli(src.Edited), } } diff --git a/scm/driver/harness/testdata/pr.json b/scm/driver/harness/testdata/pr.json index 89e773b96..57fc7d9de 100644 --- a/scm/driver/harness/testdata/pr.json +++ b/scm/driver/harness/testdata/pr.json @@ -1,32 +1,36 @@ { "number": 1, - "created": 1675960384081, - "edited": 1675960384081, + "created": 1710818863810, + "edited": 1710818863810, "state": "open", "is_draft": false, - "title": "pull title", - "description": "pull description", - "source_repo_id": 11, - "source_branch": "bla", - "target_repo_id": 11, + "title": "feat: self as codeowner can be skipped", + "description": "123", + "source_repo_id": 7, + "source_branch": "abhinav/CODE-1508", + "source_sha": "6c4ab583f5201ed0421d0ef93ee5b0925ac08f62", + "target_repo_id": 7, "target_branch": "main", "merged": null, - "merge_strategy": null, - "merge_head_sha": null, - "merge_base_sha": null, + "merge_method": null, + "merge_check_status": "mergeable", + "merge_target_sha": "b772dca15553986cc90fc6254a0fa47f4047526c", + "merge_base_sha": "b772dca15553986cc90fc6254a0fa47f4047526c", + "merge_sha": "ff13c81504ab3b04bd76b6af71e9c368333181a5", "author": { - "id": 14, - "uid": "0Nnoezs6RGa_fOWvG_Ta4w", - "display_name": "thomas.honey", - "email": "thomas.honey@harness.io", + "id": 27, + "uid": "aqm0RQXGQI6v3m_f7u7C5A", + "display_name": "Abhinav Singh", + "email": "abhinav.singh@harness.io", "type": "user", - "created": 1675248918372, - "updated": 1675248918372 + "created": 1681264009453, + "updated": 1681264009453 }, "merger": null, "stats": { - "conversations": 0, "commits": 1, - "files_changed": 1 + "files_changed": 1, + "conversations": 1, + "unresolved_count": 1 } } \ No newline at end of file diff --git a/scm/driver/harness/testdata/pr.json.golden b/scm/driver/harness/testdata/pr.json.golden index 5c4a83864..ae5dc76da 100644 --- a/scm/driver/harness/testdata/pr.json.golden +++ b/scm/driver/harness/testdata/pr.json.golden @@ -1,20 +1,33 @@ { "Number": 1, - "Title": "pull title", - "Body": "pull description", - "Sha": "", - "Ref": "refs/pullreq/1/head", - "Source": "bla", - "Target": "main", + "Title": "feat: self as codeowner can be skipped", + "Body": "123", + "Sha": "6c4ab583f5201ed0421d0ef93ee5b0925ac08f62", + "Ref": "refs/pullreq/1/head", + "Source": "abhinav/CODE-1508", + "Target": "main", + "Fork": "fork", + "Closed": false, + "Merged": false, "Fork": "fork", "Link": "", "Diff": "", - "Closed": false, - "Merged": false, + "Base": { + "Sha": "b772dca15553986cc90fc6254a0fa47f4047526c", + "Path": "refs/heads/main", + "Name": "main" + }, + "Head": { + "Sha": "6c4ab583f5201ed0421d0ef93ee5b0925ac08f62", + "Path": "refs/heads/abhinav/CODE-1508", + "Name": "abhinav/CODE-1508" + }, "Author": { - "ID": "0Nnoezs6RGa_fOWvG_Ta4w", - "Login": "thomas.honey@harness.io", - "Name": "thomas.honey", - "Email": "thomas.honey@harness.io" - } + "ID": "aqm0RQXGQI6v3m_f7u7C5A", + "Login": "abhinav.singh@harness.io", + "Name": "Abhinav Singh", + "Email": "abhinav.singh@harness.io" + }, + "Created": "2024-03-18T20:27:43.81-07:00", + "Updated": "2024-03-18T20:27:43.81-07:00" } \ No newline at end of file From 845e4451f49fdafd56ff16c4ad8523c7ce4b8f8a Mon Sep 17 00:00:00 2001 From: Brad Rydzewski Date: Tue, 16 Apr 2024 15:00:41 -0400 Subject: [PATCH 136/195] Update .drone.yml --- .drone.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.drone.yml b/.drone.yml index 74ace6a27..f723ac8f8 100644 --- a/.drone.yml +++ b/.drone.yml @@ -8,7 +8,7 @@ pool: steps: - name: vet - image: golang:1.15 + image: golang:1.22 commands: - go vet ./... volumes: @@ -18,7 +18,7 @@ steps: - clone - name: test - image: golang:1.15 + image: golang:1.22 commands: - go test -cover ./... volumes: @@ -28,7 +28,7 @@ steps: - vet - name: check go.mod is up to date - image: golang:1.15 + image: golang:1.22 commands: - cp go.mod go.mod.bak - go mod tidy From 1255b156aedb7dfe7517cd5bdba7e68191b7cbdf Mon Sep 17 00:00:00 2001 From: Hitesh Aringa Date: Tue, 16 Apr 2024 18:09:04 -0700 Subject: [PATCH 137/195] feat: fixed harness UTs based on new API convention (#303) --- scm/driver/harness/content_test.go | 30 ++++++++++++++++++++----- scm/driver/harness/git_test.go | 36 +++++++++++++++++++++++++----- scm/driver/harness/pr_test.go | 21 +++++++++++++---- scm/driver/harness/repo.go | 4 +--- scm/driver/harness/repo_test.go | 36 +++++++++++++++++++++++++----- 5 files changed, 103 insertions(+), 24 deletions(-) diff --git a/scm/driver/harness/content_test.go b/scm/driver/harness/content_test.go index 6a84ec797..f59776f2c 100644 --- a/scm/driver/harness/content_test.go +++ b/scm/driver/harness/content_test.go @@ -32,7 +32,11 @@ func TestContentFind(t *testing.T) { defer gock.Off() gock.New(gockOrigin). - Get("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/content/README.md"). + Get("/gateway/code/api/v1/repos/thomas/content/README.md"). + MatchParam("accountIdentifier", "px7xd_BFRCi-pfWPYXVjvw"). + MatchParam("orgIdentifier", "default"). + MatchParam("projectIdentifier", "codeciintegration"). + MatchParam("routingId", "px7xd_BFRCi-pfWPYXVjvw"). Reply(200). Type("plain/text"). File("testdata/content.json") @@ -68,7 +72,11 @@ func TestContentCreate(t *testing.T) { defer gock.Off() gock.New(gockOrigin). - Post("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/commits"). + Post("/gateway/code/api/v1/repos/thomas/commits"). + MatchParam("accountIdentifier", "px7xd_BFRCi-pfWPYXVjvw"). + MatchParam("orgIdentifier", "default"). + MatchParam("projectIdentifier", "codeciintegration"). + MatchParam("routingId", "px7xd_BFRCi-pfWPYXVjvw"). Reply(200). Type("plain/text"). BodyString("{\"commit_id\":\"20ecde1f8c277da0e91750bef9f3b88f228d86db\"}") @@ -105,7 +113,11 @@ func TestContentUpdate(t *testing.T) { defer gock.Off() gock.New(gockOrigin). - Post("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/commits"). + Post("/gateway/code/api/v1/repos/thomas/commits"). + MatchParam("accountIdentifier", "px7xd_BFRCi-pfWPYXVjvw"). + MatchParam("orgIdentifier", "default"). + MatchParam("projectIdentifier", "codeciintegration"). + MatchParam("routingId", "px7xd_BFRCi-pfWPYXVjvw"). Reply(200). Type("plain/text"). BodyString("{\"commit_id\":\"20ecde1f8c277da0e91750bef9f3b88f228d86db\"}") @@ -143,7 +155,11 @@ func TestContentDelete(t *testing.T) { defer gock.Off() gock.New(gockOrigin). - Post("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/commits"). + Post("/gateway/code/api/v1/repos/thomas/commits"). + MatchParam("accountIdentifier", "px7xd_BFRCi-pfWPYXVjvw"). + MatchParam("orgIdentifier", "default"). + MatchParam("projectIdentifier", "codeciintegration"). + MatchParam("routingId", "px7xd_BFRCi-pfWPYXVjvw"). Reply(200). Type("plain/text"). BodyString("{\"commit_id\":\"20ecde1f8c277da0e91750bef9f3b88f228d86db\"}") @@ -178,7 +194,11 @@ func TestContentList(t *testing.T) { defer gock.Off() gock.New(gockOrigin). - Get("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/content/docker"). + Get("/gateway/code/api/v1/repos/thomas/content/docker"). + MatchParam("accountIdentifier", "px7xd_BFRCi-pfWPYXVjvw"). + MatchParam("orgIdentifier", "default"). + MatchParam("projectIdentifier", "codeciintegration"). + MatchParam("routingId", "px7xd_BFRCi-pfWPYXVjvw"). Reply(200). Type("application/json"). File("testdata/content_list.json") diff --git a/scm/driver/harness/git_test.go b/scm/driver/harness/git_test.go index 515705068..dfbd5a99e 100644 --- a/scm/driver/harness/git_test.go +++ b/scm/driver/harness/git_test.go @@ -24,7 +24,11 @@ func TestListCommits(t *testing.T) { defer gock.Off() gock.New(gockOrigin). - Get("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/commits"). + Get("/gateway/code/api/v1/repos/thomas/commits"). + MatchParam("accountIdentifier", "px7xd_BFRCi-pfWPYXVjvw"). + MatchParam("orgIdentifier", "default"). + MatchParam("projectIdentifier", "codeciintegration"). + MatchParam("routingId", "px7xd_BFRCi-pfWPYXVjvw"). Reply(200). Type("application/json"). File("testdata/commits.json") @@ -66,7 +70,11 @@ func TestFindCommit(t *testing.T) { defer gock.Off() gock.New(gockOrigin). - Get("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/commits/1d640265d8bdd818175fa736f0fcbad2c9b716c9"). + Get("/gateway/code/api/v1/repos/thomas/commits/1d640265d8bdd818175fa736f0fcbad2c9b716c9"). + MatchParam("accountIdentifier", "px7xd_BFRCi-pfWPYXVjvw"). + MatchParam("orgIdentifier", "default"). + MatchParam("projectIdentifier", "codeciintegration"). + MatchParam("routingId", "px7xd_BFRCi-pfWPYXVjvw"). Reply(200). Type("application/json"). File("testdata/commit.json") @@ -104,7 +112,11 @@ func TestFindBranch(t *testing.T) { defer gock.Off() gock.New(gockOrigin). - Get("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/branches/main"). + Get("/gateway/code/api/v1/repos/thomas/branches/main"). + MatchParam("accountIdentifier", "px7xd_BFRCi-pfWPYXVjvw"). + MatchParam("orgIdentifier", "default"). + MatchParam("projectIdentifier", "codeciintegration"). + MatchParam("routingId", "px7xd_BFRCi-pfWPYXVjvw"). Reply(200). Type("application/json"). File("testdata/branch.json") @@ -142,7 +154,11 @@ func TestListBranches(t *testing.T) { defer gock.Off() gock.New(gockOrigin). - Get("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/branches"). + Get("/gateway/code/api/v1/repos/thomas/branches"). + MatchParam("accountIdentifier", "px7xd_BFRCi-pfWPYXVjvw"). + MatchParam("orgIdentifier", "default"). + MatchParam("projectIdentifier", "codeciintegration"). + MatchParam("routingId", "px7xd_BFRCi-pfWPYXVjvw"). Reply(200). Type("application/json"). File("testdata/branches.json") @@ -180,7 +196,11 @@ func TestCreateBranch(t *testing.T) { defer gock.Off() gock.New(gockOrigin). - Post("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/branches"). + Post("/gateway/code/api/v1/repos/thomas/branches"). + MatchParam("accountIdentifier", "px7xd_BFRCi-pfWPYXVjvw"). + MatchParam("orgIdentifier", "default"). + MatchParam("projectIdentifier", "codeciintegration"). + MatchParam("routingId", "px7xd_BFRCi-pfWPYXVjvw"). Reply(200). Type("application/json"). File("testdata/branch.json") @@ -215,7 +235,11 @@ func TestCompareChanges(t *testing.T) { defer gock.Off() gock.New(gockOrigin). - Get(fmt.Sprintf("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/diff/%s...%s", source, target)). + Get(fmt.Sprintf("/gateway/code/api/v1/repos/thomas/diff/%s...%s", source, target)). + MatchParam("accountIdentifier", "px7xd_BFRCi-pfWPYXVjvw"). + MatchParam("orgIdentifier", "default"). + MatchParam("projectIdentifier", "codeciintegration"). + MatchParam("routingId", "px7xd_BFRCi-pfWPYXVjvw"). Reply(200). Type("application/json"). File("testdata/gitdiff.json") diff --git a/scm/driver/harness/pr_test.go b/scm/driver/harness/pr_test.go index 951690164..fa26ebb4c 100644 --- a/scm/driver/harness/pr_test.go +++ b/scm/driver/harness/pr_test.go @@ -8,11 +8,12 @@ import ( "context" "encoding/json" "fmt" - "github.com/google/go-cmp/cmp/cmpopts" "io/ioutil" "net/http" "testing" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/drone/go-scm/scm" "github.com/drone/go-scm/scm/transport" "github.com/google/go-cmp/cmp" @@ -24,7 +25,11 @@ func TestPRFind(t *testing.T) { defer gock.Off() gock.New(gockOrigin). - Get("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/pullreq/1"). + Get("/gateway/code/api/v1/repos/thomas/pullreq/1"). + MatchParam("accountIdentifier", "px7xd_BFRCi-pfWPYXVjvw"). + MatchParam("orgIdentifier", "default"). + MatchParam("projectIdentifier", "codeciintegration"). + MatchParam("routingId", "px7xd_BFRCi-pfWPYXVjvw"). Reply(200). Type("plain/text"). File("testdata/pr.json") @@ -63,7 +68,11 @@ func TestPRCommits(t *testing.T) { defer gock.Off() gock.New(gockOrigin). - Get("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/pullreq/1/commits"). + Get("/gateway/code/api/v1/repos/thomas/pullreq/1/commits"). + MatchParam("accountIdentifier", "px7xd_BFRCi-pfWPYXVjvw"). + MatchParam("orgIdentifier", "default"). + MatchParam("projectIdentifier", "codeciintegration"). + MatchParam("routingId", "px7xd_BFRCi-pfWPYXVjvw"). Reply(200). Type("plain/text"). File("testdata/pr_commits.json") @@ -100,7 +109,11 @@ func TestPRCommits(t *testing.T) { func TestPullCreate(t *testing.T) { defer gock.Off() gock.New(gockOrigin). - Post("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/pullreq"). + Post("/gateway/code/api/v1/repos/thomas/pullreq"). + MatchParam("accountIdentifier", "px7xd_BFRCi-pfWPYXVjvw"). + MatchParam("orgIdentifier", "default"). + MatchParam("projectIdentifier", "codeciintegration"). + MatchParam("routingId", "px7xd_BFRCi-pfWPYXVjvw"). Reply(200). Type("plain/text"). File("testdata/pr.json") diff --git a/scm/driver/harness/repo.go b/scm/driver/harness/repo.go index dc489a267..cef50eff3 100644 --- a/scm/driver/harness/repo.go +++ b/scm/driver/harness/repo.go @@ -97,9 +97,7 @@ func (s *repositoryService) CreateHook(ctx context.Context, repo string, input * in.Secret = input.Secret in.Insecure = input.SkipVerify in.URL = input.Target - in.Triggers = append( - input.NativeEvents, - ) + in.Triggers = input.NativeEvents out := new(hook) res, err := s.client.do(ctx, "POST", path, in, out) return convertHook(out), res, err diff --git a/scm/driver/harness/repo_test.go b/scm/driver/harness/repo_test.go index d482d4bcb..1fc861084 100644 --- a/scm/driver/harness/repo_test.go +++ b/scm/driver/harness/repo_test.go @@ -24,7 +24,11 @@ func TestRepositoryFind(t *testing.T) { defer gock.Off() gock.New(gockOrigin). - Get("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/demo/+"). + Get("/gateway/code/api/v1/repos/demo"). + MatchParam("accountIdentifier", "px7xd_BFRCi-pfWPYXVjvw"). + MatchParam("orgIdentifier", "default"). + MatchParam("projectIdentifier", "codeciintegration"). + MatchParam("routingId", "px7xd_BFRCi-pfWPYXVjvw"). Reply(200). Type("application/json"). File("testdata/repo.json") @@ -58,11 +62,15 @@ func TestRepositoryList(t *testing.T) { defer gock.Off() gock.New(gockOrigin). - Get("/gateway/code/api/v1/spaces/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/+/repos"). + Get("/gateway/code/api/v1/repos"). MatchParam("page", "1"). MatchParam("limit", "20"). MatchParam("sort", "path"). MatchParam("order", "asc"). + MatchParam("accountIdentifier", "px7xd_BFRCi-pfWPYXVjvw"). + MatchParam("orgIdentifier", "default"). + MatchParam("projectIdentifier", "codeciintegration"). + MatchParam("routingId", "px7xd_BFRCi-pfWPYXVjvw"). Reply(200). Type("application/json"). File("testdata/repos.json") @@ -100,7 +108,11 @@ func TestRepositoryHookList(t *testing.T) { defer gock.Off() gock.New(gockOrigin). - Get("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/webhooks"). + Get("/gateway/code/api/v1/repos/thomas/webhooks"). + MatchParam("accountIdentifier", "px7xd_BFRCi-pfWPYXVjvw"). + MatchParam("orgIdentifier", "default"). + MatchParam("projectIdentifier", "codeciintegration"). + MatchParam("routingId", "px7xd_BFRCi-pfWPYXVjvw"). MatchParam("page", "1"). MatchParam("limit", "30"). MatchParam("sort", "display_name"). @@ -138,7 +150,11 @@ func TestRepositoryFindHook(t *testing.T) { defer gock.Off() gock.New(gockOrigin). - Get("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/webhooks/6"). + Get("/gateway/code/api/v1/repos/thomas/webhooks/6"). + MatchParam("accountIdentifier", "px7xd_BFRCi-pfWPYXVjvw"). + MatchParam("orgIdentifier", "default"). + MatchParam("projectIdentifier", "codeciintegration"). + MatchParam("routingId", "px7xd_BFRCi-pfWPYXVjvw"). Reply(200). Type("application/json"). File("testdata/hook.json") @@ -172,7 +188,11 @@ func TestRepositoryHookCreateDelete(t *testing.T) { defer gock.Off() gock.New(gockOrigin). - Post("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/webhooks"). + Post("/gateway/code/api/v1/repos/thomas/webhooks"). + MatchParam("accountIdentifier", "px7xd_BFRCi-pfWPYXVjvw"). + MatchParam("orgIdentifier", "default"). + MatchParam("projectIdentifier", "codeciintegration"). + MatchParam("routingId", "px7xd_BFRCi-pfWPYXVjvw"). Reply(200). Type("application/json"). File("testdata/hook_create.json") @@ -210,7 +230,11 @@ func TestRepositoryHookCreateDelete(t *testing.T) { defer gock.Off() gock.New(gockOrigin). - Delete(fmt.Sprintf("/gateway/code/api/v1/repos/px7xd_BFRCi-pfWPYXVjvw/default/codeciintegration/thomas/+/webhooks/%s", got.ID)). + Delete(fmt.Sprintf("/gateway/code/api/v1/repos/thomas/webhooks/%s", got.ID)). + MatchParam("accountIdentifier", "px7xd_BFRCi-pfWPYXVjvw"). + MatchParam("orgIdentifier", "default"). + MatchParam("projectIdentifier", "codeciintegration"). + MatchParam("routingId", "px7xd_BFRCi-pfWPYXVjvw"). Reply(204) } client, _ = New(gockOrigin, harnessOrg, harnessAccount, harnessProject) From bf93d79cabce0da539d0b0d63009a2f42961a443 Mon Sep 17 00:00:00 2001 From: Karan Saraswat Date: Mon, 6 May 2024 14:39:27 +0530 Subject: [PATCH 138/195] fix: [CODE-1870]: adding cloneUrl to the convertRepository method for azure driver --- scm/driver/azure/repo.go | 1 + scm/driver/azure/testdata/repo.json.golden | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/scm/driver/azure/repo.go b/scm/driver/azure/repo.go index edfd4d876..8c1882bd0 100644 --- a/scm/driver/azure/repo.go +++ b/scm/driver/azure/repo.go @@ -279,6 +279,7 @@ func convertRepository(from *repository) *scm.Repository { Name: from.Name, Link: from.URL, Branch: scm.TrimRef(from.DefaultBranch), + Clone: from.RemoteURL, } } diff --git a/scm/driver/azure/testdata/repo.json.golden b/scm/driver/azure/testdata/repo.json.golden index 92f3b874a..6ec2a9323 100644 --- a/scm/driver/azure/testdata/repo.json.golden +++ b/scm/driver/azure/testdata/repo.json.golden @@ -2,5 +2,6 @@ "ID": "91f0d4cb-4c36-49a5-b28d-2d72da089c4d", "Name": "test_project", "Branch": "main", - "Link": "https://dev.azure.com/tphoney/d350c9c0-7749-4ff8-a78f-f9c1f0e56729/_apis/git/repositories/91f0d4cb-4c36-49a5-b28d-2d72da089c4d" + "Link": "https://dev.azure.com/tphoney/d350c9c0-7749-4ff8-a78f-f9c1f0e56729/_apis/git/repositories/91f0d4cb-4c36-49a5-b28d-2d72da089c4d", + "Clone": "https://tphoney@dev.azure.com/tphoney/test_project/_git/test_project" } \ No newline at end of file From 9de001d92f7f9655b0e8c1e6e59e23a82d350279 Mon Sep 17 00:00:00 2001 From: Karan Saraswat Date: Mon, 6 May 2024 14:47:38 +0530 Subject: [PATCH 139/195] fixed tests --- scm/driver/azure/testdata/repos.json.golden | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scm/driver/azure/testdata/repos.json.golden b/scm/driver/azure/testdata/repos.json.golden index cbe9d840d..5be3b9ae3 100644 --- a/scm/driver/azure/testdata/repos.json.golden +++ b/scm/driver/azure/testdata/repos.json.golden @@ -3,12 +3,14 @@ "ID": "91f0d4cb-4c36-49a5-b28d-2d72da089c4d", "Name": "test_project", "Branch": "main", - "Link": "https://dev.azure.com/tphoney/d350c9c0-7749-4ff8-a78f-f9c1f0e56729/_apis/git/repositories/91f0d4cb-4c36-49a5-b28d-2d72da089c4d" + "Link": "https://dev.azure.com/tphoney/d350c9c0-7749-4ff8-a78f-f9c1f0e56729/_apis/git/repositories/91f0d4cb-4c36-49a5-b28d-2d72da089c4d", + "Clone": "https://tphoney@dev.azure.com/tphoney/test_project/_git/test_project" }, { "ID": "fde2d21f-13b9-4864-a995-83329045289a", "Name": "test_repo2", "Branch": "main", - "Link": "https://dev.azure.com/tphoney/d350c9c0-7749-4ff8-a78f-f9c1f0e56729/_apis/git/repositories/fde2d21f-13b9-4864-a995-83329045289a" + "Link": "https://dev.azure.com/tphoney/d350c9c0-7749-4ff8-a78f-f9c1f0e56729/_apis/git/repositories/fde2d21f-13b9-4864-a995-83329045289a", + "Clone": "https://tphoney@dev.azure.com/tphoney/test_project/_git/test_repo2" } ] \ No newline at end of file From 7d4064867b254e019f7888fa46eb93e524fdf44d Mon Sep 17 00:00:00 2001 From: Soumyajit Das Date: Mon, 6 May 2024 21:07:36 +0530 Subject: [PATCH 140/195] [feat]: [CI-12179]: Add support for gitlab basesha --- scm/driver/gitlab/pr.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/scm/driver/gitlab/pr.go b/scm/driver/gitlab/pr.go index b82951d4c..35d44e658 100644 --- a/scm/driver/gitlab/pr.go +++ b/scm/driver/gitlab/pr.go @@ -117,6 +117,11 @@ type pr struct { Updated time.Time `json:"updated_at"` Closed time.Time Labels []string `json:"labels"` + DiffRefs struct { + BaseSha string `json:"base_sha"` + HeadSha string `json:"head_sha"` + StartSha string `json:"start_sha"` + } } type changes struct { @@ -165,6 +170,9 @@ func convertPullRequest(from *pr) *scm.PullRequest { Created: from.Created, Updated: from.Updated, Labels: labels, + Base: scm.Reference{ + Sha: from.DiffRefs.BaseSha, + }, } } From 1cd57db50bb04bd39505354b1a4a3a8653774dc5 Mon Sep 17 00:00:00 2001 From: Soumyajit Das Date: Wed, 8 May 2024 19:42:29 +0530 Subject: [PATCH 141/195] add diff_refs json --- scm/driver/gitlab/pr.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm/driver/gitlab/pr.go b/scm/driver/gitlab/pr.go index 35d44e658..52548146f 100644 --- a/scm/driver/gitlab/pr.go +++ b/scm/driver/gitlab/pr.go @@ -121,7 +121,7 @@ type pr struct { BaseSha string `json:"base_sha"` HeadSha string `json:"head_sha"` StartSha string `json:"start_sha"` - } + } `json:"diff_refs"` } type changes struct { From 9b7f4379fa10d39d756196285e8ebd3f57bf03dd Mon Sep 17 00:00:00 2001 From: Karan Saraswat Date: Thu, 16 May 2024 00:09:26 +0530 Subject: [PATCH 142/195] feat: [CODE-1907]: Fix go-scm azure driver for getting namespace in the response (#307) --- scm/driver/azure/repo.go | 27 ++++++++++++--------- scm/driver/azure/testdata/repo.json.golden | 1 + scm/driver/azure/testdata/repos.json.golden | 2 ++ 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/scm/driver/azure/repo.go b/scm/driver/azure/repo.go index 8c1882bd0..d5b364555 100644 --- a/scm/driver/azure/repo.go +++ b/scm/driver/azure/repo.go @@ -8,6 +8,7 @@ import ( "context" "fmt" "net/url" + "strings" "github.com/drone/go-scm/scm" ) @@ -28,7 +29,7 @@ func (s *RepositoryService) Find(ctx context.Context, repo string) (*scm.Reposit out := new(repository) res, err := s.client.do(ctx, "GET", endpoint, nil, &out) - return convertRepository(out), res, err + return convertRepository(out, s.client.owner), res, err } // FindHook returns a repository hook. @@ -53,7 +54,7 @@ func (s *RepositoryService) List(ctx context.Context, opts scm.ListOptions) ([]* out := new(repositories) res, err := s.client.do(ctx, "GET", endpoint, nil, &out) - return convertRepositoryList(out), res, err + return convertRepositoryList(out, s.client.owner), res, err } // ListV2 returns the user repository list. @@ -261,25 +262,27 @@ type subscription struct { URL string `json:"url"` } -// helper function to convert from the gogs repository list to +// helper function to convert from the azure devops repository list to // the common repository structure. -func convertRepositoryList(from *repositories) []*scm.Repository { +func convertRepositoryList(from *repositories, owner string) []*scm.Repository { to := []*scm.Repository{} for _, v := range from.Value { - to = append(to, convertRepository(v)) + to = append(to, convertRepository(v, owner)) } return to } -// helper function to convert from the gogs repository structure +// helper function to convert from the azure devops repository structure // to the common repository structure. -func convertRepository(from *repository) *scm.Repository { +func convertRepository(from *repository, owner string) *scm.Repository { + namespace := []string{owner, from.Project.Name} return &scm.Repository{ - ID: from.ID, - Name: from.Name, - Link: from.URL, - Branch: scm.TrimRef(from.DefaultBranch), - Clone: from.RemoteURL, + ID: from.ID, + Name: from.Name, + Namespace: strings.Join(namespace, "/"), + Link: from.URL, + Branch: scm.TrimRef(from.DefaultBranch), + Clone: from.RemoteURL, } } diff --git a/scm/driver/azure/testdata/repo.json.golden b/scm/driver/azure/testdata/repo.json.golden index 6ec2a9323..c642b51e2 100644 --- a/scm/driver/azure/testdata/repo.json.golden +++ b/scm/driver/azure/testdata/repo.json.golden @@ -1,6 +1,7 @@ { "ID": "91f0d4cb-4c36-49a5-b28d-2d72da089c4d", "Name": "test_project", + "Namespace": "ORG/test_project", "Branch": "main", "Link": "https://dev.azure.com/tphoney/d350c9c0-7749-4ff8-a78f-f9c1f0e56729/_apis/git/repositories/91f0d4cb-4c36-49a5-b28d-2d72da089c4d", "Clone": "https://tphoney@dev.azure.com/tphoney/test_project/_git/test_project" diff --git a/scm/driver/azure/testdata/repos.json.golden b/scm/driver/azure/testdata/repos.json.golden index 5be3b9ae3..d4c8b140a 100644 --- a/scm/driver/azure/testdata/repos.json.golden +++ b/scm/driver/azure/testdata/repos.json.golden @@ -2,6 +2,7 @@ { "ID": "91f0d4cb-4c36-49a5-b28d-2d72da089c4d", "Name": "test_project", + "Namespace": "ORG/test_project", "Branch": "main", "Link": "https://dev.azure.com/tphoney/d350c9c0-7749-4ff8-a78f-f9c1f0e56729/_apis/git/repositories/91f0d4cb-4c36-49a5-b28d-2d72da089c4d", "Clone": "https://tphoney@dev.azure.com/tphoney/test_project/_git/test_project" @@ -9,6 +10,7 @@ { "ID": "fde2d21f-13b9-4864-a995-83329045289a", "Name": "test_repo2", + "Namespace": "ORG/test_project", "Branch": "main", "Link": "https://dev.azure.com/tphoney/d350c9c0-7749-4ff8-a78f-f9c1f0e56729/_apis/git/repositories/fde2d21f-13b9-4864-a995-83329045289a", "Clone": "https://tphoney@dev.azure.com/tphoney/test_project/_git/test_repo2" From 6e98856955497981781bafd6f9b0adf8daf2ffdc Mon Sep 17 00:00:00 2001 From: Vitalie Safronovici Date: Tue, 28 May 2024 13:54:53 +0300 Subject: [PATCH 143/195] feat: [IAC-1930]: fixed ListTags --- scm/driver/bitbucket/git.go | 2 +- scm/driver/github/git.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/scm/driver/bitbucket/git.go b/scm/driver/bitbucket/git.go index 8efbe341e..2b77d8907 100644 --- a/scm/driver/bitbucket/git.go +++ b/scm/driver/bitbucket/git.go @@ -81,7 +81,7 @@ func (s *gitService) ListCommits(ctx context.Context, repo string, opts scm.Comm } func (s *gitService) ListTags(ctx context.Context, repo string, opts scm.ListOptions) ([]*scm.Reference, *scm.Response, error) { - path := fmt.Sprintf("2.0/repositories/%s/refs/tags?%s", repo, encodeListOptions(opts)) + path := fmt.Sprintf("2.0/repositories/%s/refs/tags", repo) out := new(branches) res, err := s.client.do(ctx, "GET", path, nil, &out) copyPagination(out.pagination, res) diff --git a/scm/driver/github/git.go b/scm/driver/github/git.go index c64ea3430..a6d8ae242 100644 --- a/scm/driver/github/git.go +++ b/scm/driver/github/git.go @@ -67,8 +67,8 @@ func (s *gitService) ListCommits(ctx context.Context, repo string, opts scm.Comm } func (s *gitService) ListTags(ctx context.Context, repo string, opts scm.ListOptions) ([]*scm.Reference, *scm.Response, error) { - path := fmt.Sprintf("repos/%s/tags?%s", repo, encodeListOptions(opts)) - out := []*branch{} + path := fmt.Sprintf("repos/%s/git/refs/tags", repo) + out := []*ref{} res, err := s.client.do(ctx, "GET", path, nil, &out) return convertTagList(out), res, err } @@ -191,10 +191,10 @@ func convertRef(from *ref) *scm.Reference { } } -func convertTagList(from []*branch) []*scm.Reference { +func convertTagList(from []*ref) []*scm.Reference { to := []*scm.Reference{} for _, v := range from { - to = append(to, convertTag(v)) + to = append(to, convertRef(v)) } return to } From 34f93ff9f866379f4dfadd7023a2c6d9eff3fd36 Mon Sep 17 00:00:00 2001 From: Vitalie Safronovici Date: Thu, 30 May 2024 19:18:54 +0300 Subject: [PATCH 144/195] fixed tests --- scm/driver/bitbucket/git_test.go | 2 -- scm/driver/bitbucket/testdata/tags.json.golden | 4 ++-- scm/driver/github/git.go | 2 +- scm/driver/github/git_test.go | 2 +- scm/driver/github/testdata/tags.json | 17 +++++++++-------- scm/driver/github/testdata/tags.json.golden | 6 +++--- 6 files changed, 16 insertions(+), 17 deletions(-) diff --git a/scm/driver/bitbucket/git_test.go b/scm/driver/bitbucket/git_test.go index 74928583f..5d0e08dbf 100644 --- a/scm/driver/bitbucket/git_test.go +++ b/scm/driver/bitbucket/git_test.go @@ -244,8 +244,6 @@ func TestGitListTags(t *testing.T) { gock.New("https://api.bitbucket.org"). Get("/2.0/repositories/atlassian/atlaskit/refs/tags"). - MatchParam("page", "1"). - MatchParam("pagelen", "30"). Reply(200). Type("application/json"). File("testdata/tags.json") diff --git a/scm/driver/bitbucket/testdata/tags.json.golden b/scm/driver/bitbucket/testdata/tags.json.golden index 8cb6251e0..0e0e95ed0 100644 --- a/scm/driver/bitbucket/testdata/tags.json.golden +++ b/scm/driver/bitbucket/testdata/tags.json.golden @@ -1,7 +1,7 @@ [ { - "Name": "@atlaskit/activity@1.0.3", - "Path": "refs/tags/@atlaskit/activity@1.0.3", + "Name": "@atlaskit\/activity@1.0.3", + "Path": "refs/tags/@atlaskit\/activity@1.0.3", "Sha": "ceb01356c3f062579bdfeb15bc53fe151b9e00f0" } ] \ No newline at end of file diff --git a/scm/driver/github/git.go b/scm/driver/github/git.go index a6d8ae242..f4153423f 100644 --- a/scm/driver/github/git.go +++ b/scm/driver/github/git.go @@ -67,7 +67,7 @@ func (s *gitService) ListCommits(ctx context.Context, repo string, opts scm.Comm } func (s *gitService) ListTags(ctx context.Context, repo string, opts scm.ListOptions) ([]*scm.Reference, *scm.Response, error) { - path := fmt.Sprintf("repos/%s/git/refs/tags", repo) + path := fmt.Sprintf("repos/%s/git/refs/tags?%s", repo, encodeListOptions(opts)) out := []*ref{} res, err := s.client.do(ctx, "GET", path, nil, &out) return convertTagList(out), res, err diff --git a/scm/driver/github/git_test.go b/scm/driver/github/git_test.go index 36e18e77f..8d1ff4c5c 100644 --- a/scm/driver/github/git_test.go +++ b/scm/driver/github/git_test.go @@ -211,7 +211,7 @@ func TestGitListTags(t *testing.T) { defer gock.Off() gock.New("https://api.github.com"). - Get("/repos/octocat/hello-world/tags"). + Get("/repos/octocat/hello-world/git/refs/tags"). MatchParam("page", "1"). MatchParam("per_page", "30"). Reply(200). diff --git a/scm/driver/github/testdata/tags.json b/scm/driver/github/testdata/tags.json index 8eee0f95a..eac19260c 100644 --- a/scm/driver/github/testdata/tags.json +++ b/scm/driver/github/testdata/tags.json @@ -1,11 +1,12 @@ [ { - "name": "v0.1", - "commit": { - "sha": "c5b97d5ae6c19d5c5df71a34c7fbeeda2479ccbc", - "url": "https://api.github.com/repos/octocat/Hello-World/commits/c5b97d5ae6c19d5c5df71a34c7fbeeda2479ccbc" - }, - "zipball_url": "https://github.com/octocat/Hello-World/zipball/v0.1", - "tarball_url": "https://github.com/octocat/Hello-World/tarball/v0.1" - } + "ref": "refs/tags/v1", + "node_id": "REF_kwDOGvVo46xyZWZzL3RhZ3MvdjE", + "url": "https://api.github.com/repos/vitsafronovici/myrepo/git/refs/tags/v1", + "object": { + "sha": "85fd27bdfd87b962d1ed4a742613cbfacd5c3743", + "type": "tag", + "url": "https://api.github.com/repos/vitsafronovici/myrepo/git/tags/85fd27bdfd87b962d1ed4a742613cbfacd5c3743" + } + } ] \ No newline at end of file diff --git a/scm/driver/github/testdata/tags.json.golden b/scm/driver/github/testdata/tags.json.golden index de3d2df17..c533fd7ee 100644 --- a/scm/driver/github/testdata/tags.json.golden +++ b/scm/driver/github/testdata/tags.json.golden @@ -1,7 +1,7 @@ [ { - "Name": "v0.1", - "Path": "refs/tags/v0.1", - "Sha": "c5b97d5ae6c19d5c5df71a34c7fbeeda2479ccbc" + "Name": "v1", + "Path": "refs/tags/v1", + "Sha": "85fd27bdfd87b962d1ed4a742613cbfacd5c3743" } ] \ No newline at end of file From a2e3a61da3223ec528a8f90c0dca02532dce4cce Mon Sep 17 00:00:00 2001 From: Vitalie Safronovici Date: Thu, 30 May 2024 19:27:24 +0300 Subject: [PATCH 145/195] fixed notes --- scm/driver/github/git.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scm/driver/github/git.go b/scm/driver/github/git.go index f4153423f..11edba432 100644 --- a/scm/driver/github/git.go +++ b/scm/driver/github/git.go @@ -70,7 +70,7 @@ func (s *gitService) ListTags(ctx context.Context, repo string, opts scm.ListOpt path := fmt.Sprintf("repos/%s/git/refs/tags?%s", repo, encodeListOptions(opts)) out := []*ref{} res, err := s.client.do(ctx, "GET", path, nil, &out) - return convertTagList(out), res, err + return convertRefList(out), res, err } func (s *gitService) ListChanges(ctx context.Context, repo, ref string, _ scm.ListOptions) ([]*scm.Change, *scm.Response, error) { @@ -191,7 +191,7 @@ func convertRef(from *ref) *scm.Reference { } } -func convertTagList(from []*ref) []*scm.Reference { +func convertRefList(from []*ref) []*scm.Reference { to := []*scm.Reference{} for _, v := range from { to = append(to, convertRef(v)) From bd0004034c47c814257be2a47558528c0a56edbd Mon Sep 17 00:00:00 2001 From: Vitalie Safronovici Date: Thu, 30 May 2024 20:16:03 +0300 Subject: [PATCH 146/195] fixed notes --- scm/driver/bitbucket/git.go | 10 +++++++++- scm/driver/bitbucket/git_test.go | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/scm/driver/bitbucket/git.go b/scm/driver/bitbucket/git.go index 2b77d8907..36f47bf07 100644 --- a/scm/driver/bitbucket/git.go +++ b/scm/driver/bitbucket/git.go @@ -81,9 +81,17 @@ func (s *gitService) ListCommits(ctx context.Context, repo string, opts scm.Comm } func (s *gitService) ListTags(ctx context.Context, repo string, opts scm.ListOptions) ([]*scm.Reference, *scm.Response, error) { - path := fmt.Sprintf("2.0/repositories/%s/refs/tags", repo) + // make page params only with 'pagelen' as there is a bug with 'page' param + updatedOpts := scm.ListOptions{Size: opts.Size, Page: 0} + + path := fmt.Sprintf("2.0/repositories/%s/refs/tags?%s", repo, encodeListOptions(updatedOpts)) + + fmt.Printf("path=%s\n", path) + out := new(branches) res, err := s.client.do(ctx, "GET", path, nil, &out) + + res.Page.Next = 0 copyPagination(out.pagination, res) return convertTagList(out), res, err } diff --git a/scm/driver/bitbucket/git_test.go b/scm/driver/bitbucket/git_test.go index 5d0e08dbf..c04c26d51 100644 --- a/scm/driver/bitbucket/git_test.go +++ b/scm/driver/bitbucket/git_test.go @@ -244,6 +244,7 @@ func TestGitListTags(t *testing.T) { gock.New("https://api.bitbucket.org"). Get("/2.0/repositories/atlassian/atlaskit/refs/tags"). + MatchParam("pagelen", "30"). Reply(200). Type("application/json"). File("testdata/tags.json") From 99ca5aae45b595a2822e2c4ac406ce645fc10c6b Mon Sep 17 00:00:00 2001 From: Vitalie Safronovici Date: Thu, 30 May 2024 20:17:18 +0300 Subject: [PATCH 147/195] removed println --- scm/driver/bitbucket/git.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/scm/driver/bitbucket/git.go b/scm/driver/bitbucket/git.go index 36f47bf07..2e676151d 100644 --- a/scm/driver/bitbucket/git.go +++ b/scm/driver/bitbucket/git.go @@ -83,11 +83,8 @@ func (s *gitService) ListCommits(ctx context.Context, repo string, opts scm.Comm func (s *gitService) ListTags(ctx context.Context, repo string, opts scm.ListOptions) ([]*scm.Reference, *scm.Response, error) { // make page params only with 'pagelen' as there is a bug with 'page' param updatedOpts := scm.ListOptions{Size: opts.Size, Page: 0} - path := fmt.Sprintf("2.0/repositories/%s/refs/tags?%s", repo, encodeListOptions(updatedOpts)) - fmt.Printf("path=%s\n", path) - out := new(branches) res, err := s.client.do(ctx, "GET", path, nil, &out) From 9d071724ee90f801135107fc88dcbee565d9f70c Mon Sep 17 00:00:00 2001 From: Vitalie Safronovici Date: Thu, 30 May 2024 20:24:47 +0300 Subject: [PATCH 148/195] fixed notes --- scm/driver/bitbucket/git.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/scm/driver/bitbucket/git.go b/scm/driver/bitbucket/git.go index 2e676151d..181c9fa3a 100644 --- a/scm/driver/bitbucket/git.go +++ b/scm/driver/bitbucket/git.go @@ -82,13 +82,16 @@ func (s *gitService) ListCommits(ctx context.Context, repo string, opts scm.Comm func (s *gitService) ListTags(ctx context.Context, repo string, opts scm.ListOptions) ([]*scm.Reference, *scm.Response, error) { // make page params only with 'pagelen' as there is a bug with 'page' param - updatedOpts := scm.ListOptions{Size: opts.Size, Page: 0} - path := fmt.Sprintf("2.0/repositories/%s/refs/tags?%s", repo, encodeListOptions(updatedOpts)) + opts.Page = 0 + path := fmt.Sprintf("2.0/repositories/%s/refs/tags?%s", repo, encodeListOptions(opts)) out := new(branches) res, err := s.client.do(ctx, "GET", path, nil, &out) - res.Page.Next = 0 + if res != nil { + res.Page.Next = 0 + } + copyPagination(out.pagination, res) return convertTagList(out), res, err } From fc4336b333b86e2f1f82fae232e50ac7252e9f27 Mon Sep 17 00:00:00 2001 From: Abhinav Singh Date: Thu, 6 Jun 2024 07:50:13 +0530 Subject: [PATCH 149/195] feat: add list namespace for repos (#309) * feat: add list namespace * feat: add list namespace * feat: add list namespace * add for remaining * add for remaining * Update repo.go * address comment * address comment * Update repo.go --- scm/driver/azure/repo.go | 6 ++++++ scm/driver/bitbucket/repo.go | 11 +++++++++++ scm/driver/gitea/repo.go | 7 +++++++ scm/driver/gitee/repo.go | 4 ++++ scm/driver/github/repo.go | 8 ++++++++ scm/driver/gitlab/repo.go | 7 +++++++ scm/driver/gogs/repo.go | 7 +++++++ scm/driver/harness/repo.go | 5 +++++ scm/driver/stash/repo.go | 12 ++++++++++++ scm/repo.go | 3 +++ 10 files changed, 70 insertions(+) diff --git a/scm/driver/azure/repo.go b/scm/driver/azure/repo.go index d5b364555..25be94b80 100644 --- a/scm/driver/azure/repo.go +++ b/scm/driver/azure/repo.go @@ -63,6 +63,12 @@ func (s *RepositoryService) ListV2(ctx context.Context, opts scm.RepoListOptions return s.List(ctx, opts.ListOptions) } +// ListNamespace is of no use in azure as our client already has project information +func (s *RepositoryService) ListNamespace(ctx context.Context, _ string, opts scm.ListOptions) ([]*scm.Repository, *scm.Response, error) { + // Azure client already has org/proj information + return s.List(ctx, opts) +} + // ListHooks returns a list or repository hooks. 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 diff --git a/scm/driver/bitbucket/repo.go b/scm/driver/bitbucket/repo.go index 5929f6080..cc942c49a 100644 --- a/scm/driver/bitbucket/repo.go +++ b/scm/driver/bitbucket/repo.go @@ -117,6 +117,17 @@ func (s *repositoryService) ListV2(ctx context.Context, opts scm.RepoListOptions return convertRepositoryList(out), res, err } +func (s *repositoryService) ListNamespace(ctx context.Context, namespace string, opts scm.ListOptions) ([]*scm.Repository, *scm.Response, error) { + path := fmt.Sprintf("2.0/repositories/%s?%s", namespace, encodeListRoleOptions(opts)) + if opts.URL != "" { + path = opts.URL + } + out := new(repositories) + res, err := s.client.do(ctx, "GET", path, nil, &out) + copyPagination(out.pagination, res) + return convertRepositoryList(out), res, err +} + // ListHooks returns a list or repository hooks. func (s *repositoryService) ListHooks(ctx context.Context, repo string, opts scm.ListOptions) ([]*scm.Hook, *scm.Response, error) { path := fmt.Sprintf("2.0/repositories/%s/hooks?%s", repo, encodeListOptions(opts)) diff --git a/scm/driver/gitea/repo.go b/scm/driver/gitea/repo.go index a678273bf..81d92a5f5 100644 --- a/scm/driver/gitea/repo.go +++ b/scm/driver/gitea/repo.go @@ -51,6 +51,13 @@ func (s *repositoryService) ListV2(ctx context.Context, opts scm.RepoListOptions return s.List(ctx, opts.ListOptions) } +func (s *repositoryService) ListNamespace(ctx context.Context, namespace string, opts scm.ListOptions) ([]*scm.Repository, *scm.Response, error) { + path := fmt.Sprintf("api/v1/orgs/%s/repos?%s", namespace, encodeListOptions(opts)) + out := []*repository{} + res, err := s.client.do(ctx, "GET", path, nil, &out) + return convertRepositoryList(out), res, err +} + func (s *repositoryService) ListHooks(ctx context.Context, repo string, opts scm.ListOptions) ([]*scm.Hook, *scm.Response, error) { path := fmt.Sprintf("api/v1/repos/%s/hooks?%s", repo, encodeListOptions(opts)) out := []*hook{} diff --git a/scm/driver/gitee/repo.go b/scm/driver/gitee/repo.go index 72c60f567..967ab4f59 100644 --- a/scm/driver/gitee/repo.go +++ b/scm/driver/gitee/repo.go @@ -50,6 +50,10 @@ func (s *RepositoryService) ListV2(ctx context.Context, opts scm.RepoListOptions return s.List(ctx, opts.ListOptions) } +func (s *RepositoryService) ListNamespace(ctx context.Context, namespace string, opts scm.ListOptions) ([]*scm.Repository, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + func (s *RepositoryService) ListHooks(ctx context.Context, repo string, opts scm.ListOptions) ([]*scm.Hook, *scm.Response, error) { path := fmt.Sprintf("repos/%s/hooks?%s", repo, encodeListOptions(opts)) out := []*hook{} diff --git a/scm/driver/github/repo.go b/scm/driver/github/repo.go index c9f09b7bc..857d0a4f7 100644 --- a/scm/driver/github/repo.go +++ b/scm/driver/github/repo.go @@ -122,6 +122,14 @@ func (s *RepositoryService) ListV2(ctx context.Context, opts scm.RepoListOptions return convertRepositoryList(out.Repositories), res, err } +// ListNamespace returns the user repository list based on searchterm and namespace. +func (s *RepositoryService) ListNamespace(ctx context.Context, namespace string, opts scm.ListOptions) ([]*scm.Repository, *scm.Response, error) { + path := fmt.Sprintf("orgs/%s/repos?%s", namespace, encodeListOptions(opts)) + out := new(searchRepositoryList) + res, err := s.client.do(ctx, "GET", path, nil, &out) + return convertRepositoryList(out.Repositories), res, err +} + // List returns the github app installation repository list. func (s *RepositoryService) ListByInstallation(ctx context.Context, opts scm.ListOptions) ([]*scm.Repository, *scm.Response, error) { path := fmt.Sprintf("installation/repositories?%s", encodeListOptions(opts)) diff --git a/scm/driver/gitlab/repo.go b/scm/driver/gitlab/repo.go index dc6f39a7e..d41776144 100644 --- a/scm/driver/gitlab/repo.go +++ b/scm/driver/gitlab/repo.go @@ -102,6 +102,13 @@ func (s *repositoryService) ListV2(ctx context.Context, opts scm.RepoListOptions return convertRepositoryList(out), res, err } +func (s *repositoryService) ListNamespace(ctx context.Context, namespace string, opts scm.ListOptions) ([]*scm.Repository, *scm.Response, error) { + path := fmt.Sprintf("api/v4/groups/%s/projects?%s", namespace, encodeMemberListOptions(opts)) + out := []*repository{} + res, err := s.client.do(ctx, "GET", path, nil, &out) + return convertRepositoryList(out), res, err +} + func (s *repositoryService) ListHooks(ctx context.Context, repo string, opts scm.ListOptions) ([]*scm.Hook, *scm.Response, error) { path := fmt.Sprintf("api/v4/projects/%s/hooks?%s", encode(repo), encodeListOptions(opts)) out := []*hook{} diff --git a/scm/driver/gogs/repo.go b/scm/driver/gogs/repo.go index 5657b5ee7..0f645c1fd 100644 --- a/scm/driver/gogs/repo.go +++ b/scm/driver/gogs/repo.go @@ -50,6 +50,13 @@ func (s *repositoryService) ListV2(ctx context.Context, opts scm.RepoListOptions return s.List(ctx, opts.ListOptions) } +func (s *repositoryService) ListNamespace(ctx context.Context, namespace string, opts scm.ListOptions) ([]*scm.Repository, *scm.Response, error) { + path := fmt.Sprintf("api/v1/orgs/%s/repos", namespace) + out := []*repository{} + res, err := s.client.do(ctx, "GET", path, nil, &out) + return convertRepositoryList(out), res, err +} + func (s *repositoryService) ListHooks(ctx context.Context, repo string, _ scm.ListOptions) ([]*scm.Hook, *scm.Response, error) { path := fmt.Sprintf("api/v1/repos/%s/hooks", repo) out := []*hook{} diff --git a/scm/driver/harness/repo.go b/scm/driver/harness/repo.go index cef50eff3..82f095d21 100644 --- a/scm/driver/harness/repo.go +++ b/scm/driver/harness/repo.go @@ -68,6 +68,11 @@ func (s *repositoryService) ListV2(ctx context.Context, opts scm.RepoListOptions return s.List(ctx, opts.ListOptions) } +func (s *repositoryService) ListNamespace(ctx context.Context, _ string, opts scm.ListOptions) ([]*scm.Repository, *scm.Response, error) { + // Client already has context about namespace + return s.List(ctx, opts) +} + func (s *repositoryService) ListHooks(ctx context.Context, repo string, opts scm.ListOptions) ([]*scm.Hook, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) repoId, queryParams, err := getRepoAndQueryParams(harnessURI) diff --git a/scm/driver/stash/repo.go b/scm/driver/stash/repo.go index 33ba4bc42..f8093a145 100644 --- a/scm/driver/stash/repo.go +++ b/scm/driver/stash/repo.go @@ -192,6 +192,18 @@ func (s *repositoryService) ListV2(ctx context.Context, opts scm.RepoListOptions return convertRepositoryList(out), res, err } +// ListNamespace returns the user repository list based on searchterm and namespace. +func (s *repositoryService) ListNamespace(ctx context.Context, namespace string, opts scm.ListOptions) ([]*scm.Repository, *scm.Response, error) { + path := fmt.Sprintf("rest/api/1.0/projects/%s/repos?%s", namespace, encodeListRoleOptions(opts)) + out := new(repositories) + res, err := s.client.do(ctx, "GET", path, nil, &out) + if res != nil && !out.pagination.LastPage.Bool { + res.Page.First = 1 + res.Page.Next = opts.Page + 1 + } + return convertRepositoryList(out), res, err +} + // listWrite returns the user repository list. func (s *repositoryService) listWrite(ctx context.Context, repo string) ([]*scm.Repository, *scm.Response, error) { _, name := scm.Split(repo) diff --git a/scm/repo.go b/scm/repo.go index 1e6218fdc..8ec383c37 100644 --- a/scm/repo.go +++ b/scm/repo.go @@ -123,6 +123,9 @@ type ( // ListV2 returns a list of repositories based on the searchTerm passed. ListV2(context.Context, RepoListOptions) ([]*Repository, *Response, error) + // ListNamespace returns a list of repos in namespace + ListNamespace(context.Context, string, ListOptions) ([]*Repository, *Response, error) + // ListHooks returns a list or repository hooks. ListHooks(context.Context, string, ListOptions) ([]*Hook, *Response, error) From 2e2589d4e7a4a4056529d492b56d1a582e865531 Mon Sep 17 00:00:00 2001 From: Karan Saraswat Date: Mon, 17 Jun 2024 22:06:35 +0530 Subject: [PATCH 150/195] fix query params for List PRs API call for stash provider for pagination and state of PRs --- scm/driver/stash/pr.go | 2 +- scm/driver/stash/util.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scm/driver/stash/pr.go b/scm/driver/stash/pr.go index e1229e271..86f88c35c 100644 --- a/scm/driver/stash/pr.go +++ b/scm/driver/stash/pr.go @@ -34,7 +34,7 @@ func (s *pullService) FindComment(ctx context.Context, repo string, number int, func (s *pullService) List(ctx context.Context, repo string, opts scm.PullRequestListOptions) ([]*scm.PullRequest, *scm.Response, error) { namespace, name := scm.Split(repo) - path := fmt.Sprintf("rest/api/1.0/projects/%s/repos/%s/pull-requests", namespace, name) + path := fmt.Sprintf("rest/api/1.0/projects/%s/repos/%s/pull-requests?%s", namespace, name, encodePullRequestListOptions(opts)) out := new(prs) res, err := s.client.do(ctx, "GET", path, nil, out) if !out.pagination.LastPage.Bool { diff --git a/scm/driver/stash/util.go b/scm/driver/stash/util.go index f034fb9ff..5f56e21ed 100644 --- a/scm/driver/stash/util.go +++ b/scm/driver/stash/util.go @@ -111,7 +111,7 @@ func encodePullRequestListOptions(opts scm.PullRequestListOptions) string { if opts.Open && opts.Closed { params.Set("state", "all") } else if opts.Closed { - params.Set("state", "closed") + params.Set("state", "declined") } return params.Encode() } From ced994103824a4dc345503963df111660d4016c2 Mon Sep 17 00:00:00 2001 From: Vitalie Safronovici Date: Fri, 21 Jun 2024 16:12:57 +0300 Subject: [PATCH 151/195] feat: [IAC-2101]: added ListTags for Harness Code --- scm/driver/harness/git.go | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/scm/driver/harness/git.go b/scm/driver/harness/git.go index adbd34c26..01105bd12 100644 --- a/scm/driver/harness/git.go +++ b/scm/driver/harness/git.go @@ -89,8 +89,25 @@ func (s *gitService) ListCommits(ctx context.Context, repo string, opts scm.Comm return convertCommitList(out), res, err } -func (s *gitService) ListTags(ctx context.Context, repo string, _ scm.ListOptions) ([]*scm.Reference, *scm.Response, error) { - return nil, nil, scm.ErrNotSupported +func (s *gitService) ListTags(ctx context.Context, repo string, opts scm.ListOptions) ([]*scm.Reference, *scm.Response, error) { + fmt.Printf("ListTags %+v\n", opts) + harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/tags?%s&%s", repoId, encodeListOptions(opts), queryParams) + + fmt.Printf("ListTags path=%s\n", path) + + out := []*branch{} + res, err := s.client.do(ctx, "GET", path, nil, &out) + + fmt.Printf("ListTags res=%+v\n", res) + fmt.Printf("ListTags err=%+v\n", err) + fmt.Printf("ListTags out=%+v\n", out) + + return convertBranchList(out), res, err } func (s *gitService) ListChanges(ctx context.Context, repo, ref string, opts scm.ListOptions) ([]*scm.Change, *scm.Response, error) { From 57ce08315082493d73dc9987bbc2cc85eb18df4b Mon Sep 17 00:00:00 2001 From: Vitalie Safronovici Date: Fri, 21 Jun 2024 18:01:07 +0300 Subject: [PATCH 152/195] removed prints --- scm/driver/harness/git.go | 9 --------- 1 file changed, 9 deletions(-) diff --git a/scm/driver/harness/git.go b/scm/driver/harness/git.go index 01105bd12..867735105 100644 --- a/scm/driver/harness/git.go +++ b/scm/driver/harness/git.go @@ -90,23 +90,14 @@ func (s *gitService) ListCommits(ctx context.Context, repo string, opts scm.Comm } func (s *gitService) ListTags(ctx context.Context, repo string, opts scm.ListOptions) ([]*scm.Reference, *scm.Response, error) { - fmt.Printf("ListTags %+v\n", opts) harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) repoId, queryParams, err := getRepoAndQueryParams(harnessURI) if err != nil { return nil, nil, err } path := fmt.Sprintf("api/v1/repos/%s/tags?%s&%s", repoId, encodeListOptions(opts), queryParams) - - fmt.Printf("ListTags path=%s\n", path) - out := []*branch{} res, err := s.client.do(ctx, "GET", path, nil, &out) - - fmt.Printf("ListTags res=%+v\n", res) - fmt.Printf("ListTags err=%+v\n", err) - fmt.Printf("ListTags out=%+v\n", out) - return convertBranchList(out), res, err } From 7f588f46cf4ea12f77342eea0bb176917a3911c1 Mon Sep 17 00:00:00 2001 From: Karan Saraswat Date: Tue, 25 Jun 2024 15:52:41 +0530 Subject: [PATCH 153/195] fix unmarshalling array into Go value of type github.searchRepositoryList issue for ListNamespace --- scm/driver/github/repo.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scm/driver/github/repo.go b/scm/driver/github/repo.go index 857d0a4f7..b7b6e3362 100644 --- a/scm/driver/github/repo.go +++ b/scm/driver/github/repo.go @@ -122,12 +122,12 @@ func (s *RepositoryService) ListV2(ctx context.Context, opts scm.RepoListOptions return convertRepositoryList(out.Repositories), res, err } -// ListNamespace returns the user repository list based on searchterm and namespace. +// ListNamespace returns the orgs' repository list. func (s *RepositoryService) ListNamespace(ctx context.Context, namespace string, opts scm.ListOptions) ([]*scm.Repository, *scm.Response, error) { path := fmt.Sprintf("orgs/%s/repos?%s", namespace, encodeListOptions(opts)) - out := new(searchRepositoryList) + out := []*repository{} res, err := s.client.do(ctx, "GET", path, nil, &out) - return convertRepositoryList(out.Repositories), res, err + return convertRepositoryList(out), res, err } // List returns the github app installation repository list. @@ -230,7 +230,7 @@ func (s *RepositoryService) DeleteHook(ctx context.Context, repo, id string) (*s return s.client.do(ctx, "DELETE", path, nil, nil) } -// helper function to convert from the gogs repository list to +// helper function to convert from the github repository list to // the common repository structure. func convertRepositoryList(from []*repository) []*scm.Repository { to := []*scm.Repository{} @@ -242,7 +242,7 @@ func convertRepositoryList(from []*repository) []*scm.Repository { return to } -// helper function to convert from the gogs repository structure +// helper function to convert from the github repository structure // to the common repository structure. func convertRepository(from *repository) *scm.Repository { if from == nil { From 8ad6b66cd119acd2ed479e1f410c751c25ddb141 Mon Sep 17 00:00:00 2001 From: Karan Saraswat Date: Fri, 5 Jul 2024 16:29:22 +0530 Subject: [PATCH 154/195] setting azure devops repo visibility based on the project's visibility --- scm/driver/azure/repo.go | 23 +++++++++++--------- scm/driver/github/repo.go | 15 +------------ scm/driver/github/webhook.go | 14 ++++++------ scm/driver/gitlab/repo.go | 30 ++++---------------------- scm/driver/gitlab/repo_test.go | 19 ----------------- scm/util.go | 22 +++++++++++++++++++ scm/util_test.go | 39 ++++++++++++++++++++++++++++++++++ 7 files changed, 86 insertions(+), 76 deletions(-) diff --git a/scm/driver/azure/repo.go b/scm/driver/azure/repo.go index 25be94b80..64eead88b 100644 --- a/scm/driver/azure/repo.go +++ b/scm/driver/azure/repo.go @@ -201,10 +201,11 @@ type repository struct { ID string `json:"id"` Name string `json:"name"` Project struct { - ID string `json:"id"` - Name string `json:"name"` - State string `json:"state"` - URL string `json:"url"` + ID string `json:"id"` + Name string `json:"name"` + State string `json:"state"` + URL string `json:"url"` + Visibility string `json:"visibility"` } `json:"project"` RemoteURL string `json:"remoteUrl"` URL string `json:"url"` @@ -283,12 +284,14 @@ func convertRepositoryList(from *repositories, owner string) []*scm.Repository { func convertRepository(from *repository, owner string) *scm.Repository { namespace := []string{owner, from.Project.Name} return &scm.Repository{ - ID: from.ID, - Name: from.Name, - Namespace: strings.Join(namespace, "/"), - Link: from.URL, - Branch: scm.TrimRef(from.DefaultBranch), - Clone: from.RemoteURL, + ID: from.ID, + Name: from.Name, + Namespace: strings.Join(namespace, "/"), + Link: from.URL, + Branch: scm.TrimRef(from.DefaultBranch), + Clone: from.RemoteURL, + Private: scm.ConvertPrivate(from.Project.Visibility), + Visibility: scm.ConvertVisibility(from.Project.Visibility), } } diff --git a/scm/driver/github/repo.go b/scm/driver/github/repo.go index b7b6e3362..cad7f917f 100644 --- a/scm/driver/github/repo.go +++ b/scm/driver/github/repo.go @@ -261,7 +261,7 @@ func convertRepository(from *repository) *scm.Repository { Branch: from.DefaultBranch, Archived: from.Archived, Private: from.Private, - Visibility: convertVisibility(from.Visibility), + Visibility: scm.ConvertVisibility(from.Visibility), Clone: from.CloneURL, CloneSSH: from.SSHURL, Created: from.CreatedAt, @@ -314,19 +314,6 @@ func convertFromHookEvents(from scm.HookEvents) []string { return events } -func convertVisibility(from string) scm.Visibility { - switch from { - case "public": - return scm.VisibilityPublic - case "private": - return scm.VisibilityPrivate - case "internal": - return scm.VisibilityInternal - default: - return scm.VisibilityUndefined - } -} - type status struct { CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` diff --git a/scm/driver/github/webhook.go b/scm/driver/github/webhook.go index 6c01a711d..2fbdae938 100644 --- a/scm/driver/github/webhook.go +++ b/scm/driver/github/webhook.go @@ -408,7 +408,7 @@ func convertPushHook(src *pushHook) *scm.PushHook { Name: src.Repository.Name, Branch: src.Repository.DefaultBranch, Private: src.Repository.Private, - Visibility: convertVisibility(src.Repository.Visibility), + Visibility: scm.ConvertVisibility(src.Repository.Visibility), Clone: src.Repository.CloneURL, CloneSSH: src.Repository.SSHURL, Link: src.Repository.HTMLURL, @@ -435,7 +435,7 @@ func convertBranchHook(src *createDeleteHook) *scm.BranchHook { Name: src.Repository.Name, Branch: src.Repository.DefaultBranch, Private: src.Repository.Private, - Visibility: convertVisibility(src.Repository.Visibility), + Visibility: scm.ConvertVisibility(src.Repository.Visibility), Clone: src.Repository.CloneURL, CloneSSH: src.Repository.SSHURL, Link: src.Repository.HTMLURL, @@ -455,7 +455,7 @@ func convertTagHook(src *createDeleteHook) *scm.TagHook { Name: src.Repository.Name, Branch: src.Repository.DefaultBranch, Private: src.Repository.Private, - Visibility: convertVisibility(src.Repository.Visibility), + Visibility: scm.ConvertVisibility(src.Repository.Visibility), Clone: src.Repository.CloneURL, CloneSSH: src.Repository.SSHURL, Link: src.Repository.HTMLURL, @@ -473,7 +473,7 @@ func convertPullRequestHook(src *pullRequestHook) *scm.PullRequestHook { Name: src.Repository.Name, Branch: src.Repository.DefaultBranch, Private: src.Repository.Private, - Visibility: convertVisibility(src.Repository.Visibility), + Visibility: scm.ConvertVisibility(src.Repository.Visibility), Clone: src.Repository.CloneURL, CloneSSH: src.Repository.SSHURL, Link: src.Repository.HTMLURL, @@ -499,7 +499,7 @@ func convertDeploymentHook(src *deploymentHook) *scm.DeployHook { Name: src.Repository.Name, Branch: src.Repository.DefaultBranch, Private: src.Repository.Private, - Visibility: convertVisibility(src.Repository.Visibility), + Visibility: scm.ConvertVisibility(src.Repository.Visibility), Clone: src.Repository.CloneURL, CloneSSH: src.Repository.SSHURL, Link: src.Repository.HTMLURL, @@ -533,7 +533,7 @@ func convertIssueCommentHook(src *issueCommentHook) *scm.IssueCommentHook { Name: src.Repository.Name, Branch: src.Repository.DefaultBranch, Private: src.Repository.Private, - Visibility: convertVisibility(src.Repository.Visibility), + Visibility: scm.ConvertVisibility(src.Repository.Visibility), Clone: src.Repository.CloneURL, CloneSSH: src.Repository.SSHURL, Link: src.Repository.HTMLURL, @@ -571,7 +571,7 @@ func convertReleaseHook(src *releaseHook) *scm.ReleaseHook { Name: src.Repository.Name, Branch: src.Repository.DefaultBranch, Private: src.Repository.Private, - Visibility: convertVisibility(src.Repository.Visibility), + Visibility: scm.ConvertVisibility(src.Repository.Visibility), Clone: src.Repository.CloneURL, CloneSSH: src.Repository.SSHURL, Link: src.Repository.HTMLURL, diff --git a/scm/driver/gitlab/repo.go b/scm/driver/gitlab/repo.go index d41776144..9a44bc3bc 100644 --- a/scm/driver/gitlab/repo.go +++ b/scm/driver/gitlab/repo.go @@ -178,7 +178,7 @@ func (s *repositoryService) DeleteHook(ctx context.Context, repo string, id stri return s.client.do(ctx, "DELETE", path, nil, nil) } -// helper function to convert from the gogs repository list to +// helper function to convert from the gitlab repository list to // the common repository structure. func convertRepositoryList(from []*repository) []*scm.Repository { to := []*scm.Repository{} @@ -188,7 +188,7 @@ func convertRepositoryList(from []*repository) []*scm.Repository { return to } -// helper function to convert from the gogs repository structure +// helper function to convert from the gitlab repository structure // to the common repository structure. func convertRepository(from *repository) *scm.Repository { to := &scm.Repository{ @@ -197,8 +197,8 @@ func convertRepository(from *repository) *scm.Repository { Name: from.Path, Branch: from.DefaultBranch, Archived: from.Archived, - Private: convertPrivate(from.Visibility), - Visibility: convertVisibility(from.Visibility), + Private: scm.ConvertPrivate(from.Visibility), + Visibility: scm.ConvertVisibility(from.Visibility), Clone: from.HTTPURL, CloneSSH: from.SSHURL, Link: from.WebURL, @@ -317,28 +317,6 @@ func convertFromState(from scm.State) string { } } -func convertPrivate(from string) bool { - switch from { - case "public", "": - return false - default: - return true - } -} - -func convertVisibility(from string) scm.Visibility { - switch from { - case "public": - return scm.VisibilityPublic - case "private": - return scm.VisibilityPrivate - case "internal": - return scm.VisibilityInternal - default: - return scm.VisibilityUndefined - } -} - func canPush(proj *repository) bool { switch { case proj.Permissions.ProjectAccess.AccessLevel >= 30: diff --git a/scm/driver/gitlab/repo_test.go b/scm/driver/gitlab/repo_test.go index 293e523ff..65c175176 100644 --- a/scm/driver/gitlab/repo_test.go +++ b/scm/driver/gitlab/repo_test.go @@ -521,25 +521,6 @@ func TestConvertFromState(t *testing.T) { } } -func TestConvertPrivate(t *testing.T) { - tests := []struct { - in string - out bool - }{ - {"public", false}, - {"", false}, - {"private", true}, - {"internal", true}, - {"invalid", true}, - } - - for _, test := range tests { - if got, want := convertPrivate(test.in), test.out; got != want { - t.Errorf("Want private %v, got %v", want, got) - } - } -} - func TestCanPush(t *testing.T) { tests := []struct { in *repository diff --git a/scm/util.go b/scm/util.go index 0a8c3a2ca..6aa496834 100644 --- a/scm/util.go +++ b/scm/util.go @@ -89,3 +89,25 @@ func IsPullRequest(ref string) bool { func IsHash(s string) bool { return sha1.MatchString(s) || sha256.MatchString(s) } + +func ConvertVisibility(from string) Visibility { + switch from { + case "public": + return VisibilityPublic + case "private": + return VisibilityPrivate + case "internal": + return VisibilityInternal + default: + return VisibilityUndefined + } +} + +func ConvertPrivate(from string) bool { + switch from { + case "public", "": + return false + default: + return true + } +} diff --git a/scm/util_test.go b/scm/util_test.go index 41332276d..c2b87ae74 100644 --- a/scm/util_test.go +++ b/scm/util_test.go @@ -239,3 +239,42 @@ func TestIsHash(t *testing.T) { } } } + +func TestConvertVisibility(t *testing.T) { + tests := []struct { + in string + out Visibility + }{ + {"public", 1}, + {"", 0}, + {"private", 3}, + {"internal", 2}, + {"invalid", 0}, + {"unknown", 0}, + } + + for _, test := range tests { + if got, want := ConvertVisibility(test.in), test.out; got != want { + t.Errorf("Want %d for %v type, got %d", want, test.in, got) + } + } +} + +func TestConvertPrivate(t *testing.T) { + tests := []struct { + in string + out bool + }{ + {"public", false}, + {"", false}, + {"private", true}, + {"internal", true}, + {"invalid", true}, + } + + for _, test := range tests { + if got, want := ConvertPrivate(test.in), test.out; got != want { + t.Errorf("Want private %v, got %v", want, got) + } + } +} From 92b5486bb60f9a142a90cb093702f5b5b31355b9 Mon Sep 17 00:00:00 2001 From: Karan Saraswat Date: Fri, 5 Jul 2024 17:00:34 +0530 Subject: [PATCH 155/195] fixed test --- scm/driver/azure/testdata/repos.json | 2 +- scm/driver/azure/testdata/repos.json.golden | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/scm/driver/azure/testdata/repos.json b/scm/driver/azure/testdata/repos.json index a05b6ce13..e5d7c6a23 100644 --- a/scm/driver/azure/testdata/repos.json +++ b/scm/driver/azure/testdata/repos.json @@ -30,7 +30,7 @@ "url": "https://dev.azure.com/tphoney/_apis/projects/d350c9c0-7749-4ff8-a78f-f9c1f0e56729", "state": "wellFormed", "revision": 11, - "visibility": "private", + "visibility": "public", "lastUpdateTime": "2022-02-24T15:31:27.89Z" }, "defaultBranch": "refs/heads/main", diff --git a/scm/driver/azure/testdata/repos.json.golden b/scm/driver/azure/testdata/repos.json.golden index d4c8b140a..137b73660 100644 --- a/scm/driver/azure/testdata/repos.json.golden +++ b/scm/driver/azure/testdata/repos.json.golden @@ -5,7 +5,9 @@ "Namespace": "ORG/test_project", "Branch": "main", "Link": "https://dev.azure.com/tphoney/d350c9c0-7749-4ff8-a78f-f9c1f0e56729/_apis/git/repositories/91f0d4cb-4c36-49a5-b28d-2d72da089c4d", - "Clone": "https://tphoney@dev.azure.com/tphoney/test_project/_git/test_project" + "Clone": "https://tphoney@dev.azure.com/tphoney/test_project/_git/test_project", + "Private": true, + "Visibility": 3 }, { "ID": "fde2d21f-13b9-4864-a995-83329045289a", @@ -13,6 +15,8 @@ "Namespace": "ORG/test_project", "Branch": "main", "Link": "https://dev.azure.com/tphoney/d350c9c0-7749-4ff8-a78f-f9c1f0e56729/_apis/git/repositories/fde2d21f-13b9-4864-a995-83329045289a", - "Clone": "https://tphoney@dev.azure.com/tphoney/test_project/_git/test_repo2" + "Clone": "https://tphoney@dev.azure.com/tphoney/test_project/_git/test_repo2", + "Private": false, + "Visibility": 1 } ] \ No newline at end of file From 8df99c4fc1e4305668135888d1f72b2abee83fbb Mon Sep 17 00:00:00 2001 From: Karan Saraswat Date: Fri, 5 Jul 2024 17:07:34 +0530 Subject: [PATCH 156/195] fixed TestRepositoryFind for azure driver --- scm/driver/azure/testdata/repo.json.golden | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scm/driver/azure/testdata/repo.json.golden b/scm/driver/azure/testdata/repo.json.golden index c642b51e2..c65a2d23d 100644 --- a/scm/driver/azure/testdata/repo.json.golden +++ b/scm/driver/azure/testdata/repo.json.golden @@ -4,5 +4,7 @@ "Namespace": "ORG/test_project", "Branch": "main", "Link": "https://dev.azure.com/tphoney/d350c9c0-7749-4ff8-a78f-f9c1f0e56729/_apis/git/repositories/91f0d4cb-4c36-49a5-b28d-2d72da089c4d", - "Clone": "https://tphoney@dev.azure.com/tphoney/test_project/_git/test_project" + "Clone": "https://tphoney@dev.azure.com/tphoney/test_project/_git/test_project", + "Private": true, + "Visibility": 3 } \ No newline at end of file From 0d2baa2c732bc3f18c7a72c6f095bd25211b6b75 Mon Sep 17 00:00:00 2001 From: Vitalie Safronovici Date: Tue, 16 Jul 2024 18:12:21 +0300 Subject: [PATCH 157/195] fix: [IAC-2201]: fixed looping endless pagination --- scm/driver/bitbucket/git.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/scm/driver/bitbucket/git.go b/scm/driver/bitbucket/git.go index 181c9fa3a..e56f85084 100644 --- a/scm/driver/bitbucket/git.go +++ b/scm/driver/bitbucket/git.go @@ -88,9 +88,12 @@ func (s *gitService) ListTags(ctx context.Context, repo string, opts scm.ListOpt out := new(branches) res, err := s.client.do(ctx, "GET", path, nil, &out) - if res != nil { - res.Page.Next = 0 - } + // if res != nil { + // res.Page.Next = 0 + // } + + fmt.Printf("xxxxx res=%+v", res) + fmt.Printf("xxxxx out=%+v", out) copyPagination(out.pagination, res) return convertTagList(out), res, err From 8aca10b1b3a386a99d79fbbfbd6c7ba782aae243 Mon Sep 17 00:00:00 2001 From: Vitalie Safronovici Date: Tue, 16 Jul 2024 19:37:28 +0300 Subject: [PATCH 158/195] adjust --- scm/driver/bitbucket/git.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/scm/driver/bitbucket/git.go b/scm/driver/bitbucket/git.go index e56f85084..6c703a7b5 100644 --- a/scm/driver/bitbucket/git.go +++ b/scm/driver/bitbucket/git.go @@ -88,14 +88,15 @@ func (s *gitService) ListTags(ctx context.Context, repo string, opts scm.ListOpt out := new(branches) res, err := s.client.do(ctx, "GET", path, nil, &out) - // if res != nil { - // res.Page.Next = 0 - // } + copyPagination(out.pagination, res) + + if res != nil { + res.Page.Next = 0 + } - fmt.Printf("xxxxx res=%+v", res) - fmt.Printf("xxxxx out=%+v", out) + fmt.Printf("xxxxx res=%+v\n", res) + fmt.Printf("xxxxx out=%+v\n", out) - copyPagination(out.pagination, res) return convertTagList(out), res, err } From f3725efa115cc9ee7b7875790ed115daf20805ab Mon Sep 17 00:00:00 2001 From: Vitalie Safronovici Date: Tue, 16 Jul 2024 20:10:22 +0300 Subject: [PATCH 159/195] removed logs --- scm/driver/bitbucket/git.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/scm/driver/bitbucket/git.go b/scm/driver/bitbucket/git.go index 6c703a7b5..e0ecc5542 100644 --- a/scm/driver/bitbucket/git.go +++ b/scm/driver/bitbucket/git.go @@ -94,9 +94,6 @@ func (s *gitService) ListTags(ctx context.Context, repo string, opts scm.ListOpt res.Page.Next = 0 } - fmt.Printf("xxxxx res=%+v\n", res) - fmt.Printf("xxxxx out=%+v\n", out) - return convertTagList(out), res, err } From be67dd5203b89c912dc3dd50dc3e247480418c41 Mon Sep 17 00:00:00 2001 From: Vitalie Safronovici Date: Tue, 16 Jul 2024 20:18:53 +0300 Subject: [PATCH 160/195] fixed UT --- scm/driver/bitbucket/git_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scm/driver/bitbucket/git_test.go b/scm/driver/bitbucket/git_test.go index c04c26d51..e93499808 100644 --- a/scm/driver/bitbucket/git_test.go +++ b/scm/driver/bitbucket/git_test.go @@ -250,7 +250,7 @@ func TestGitListTags(t *testing.T) { File("testdata/tags.json") client, _ := New("https://api.bitbucket.org") - got, res, err := client.Git.ListTags(context.Background(), "atlassian/atlaskit", scm.ListOptions{Page: 1, Size: 30}) + got, _, err := client.Git.ListTags(context.Background(), "atlassian/atlaskit", scm.ListOptions{Page: 1, Size: 30}) if err != nil { t.Error(err) } @@ -264,7 +264,6 @@ func TestGitListTags(t *testing.T) { t.Log(diff) } - t.Run("Page", testPage(res)) } func TestGitListChanges(t *testing.T) { From f23ffd9afa92961b6c8f49597d6203682d5464a4 Mon Sep 17 00:00:00 2001 From: Johannes Batzill Date: Thu, 25 Jul 2024 16:39:33 -0700 Subject: [PATCH 161/195] add support for harness error message --- scm/driver/harness/harness.go | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/scm/driver/harness/harness.go b/scm/driver/harness/harness.go index 1feb6a463..cf71dd7f5 100644 --- a/scm/driver/harness/harness.go +++ b/scm/driver/harness/harness.go @@ -8,9 +8,7 @@ import ( "bytes" "context" "encoding/json" - "errors" "io" - "net/http" "net/url" "strings" @@ -82,9 +80,9 @@ func (c *wrapper) do(ctx context.Context, method, path string, in, out interface // if an error is encountered, unmarshal and return the // error response. if res.Status > 300 { - return res, errors.New( - http.StatusText(res.Status), - ) + err := new(Error) + json.NewDecoder(res.Body).Decode(err) + return res, err } if out == nil { @@ -102,3 +100,12 @@ func (c *wrapper) do(ctx context.Context, method, path string, in, out interface // the json response. return res, json.NewDecoder(res.Body).Decode(out) } + +// Error represents a Harness CODE error. +type Error struct { + Message string `json:"message"` +} + +func (e *Error) Error() string { + return e.Message +} From 845b0c5cf9d707ed8b175e0c607aa07fe7e329d7 Mon Sep 17 00:00:00 2001 From: Karan Saraswat Date: Fri, 2 Aug 2024 13:21:29 +0530 Subject: [PATCH 162/195] Add draft boolean for github and gitlab PRs --- scm/driver/github/pr.go | 2 ++ scm/driver/github/testdata/pr.json | 1 + scm/driver/github/testdata/pr.json.golden | 1 + scm/driver/github/testdata/pulls.json | 1 + scm/driver/github/testdata/pulls.json.golden | 1 + scm/driver/gitlab/pr.go | 16 +++++++++------- scm/driver/gitlab/testdata/merge.json.golden | 1 + scm/driver/gitlab/testdata/merges.json.golden | 1 + scm/driver/gitlab/webhook.go | 2 ++ scm/pr.go | 1 + 10 files changed, 20 insertions(+), 7 deletions(-) diff --git a/scm/driver/github/pr.go b/scm/driver/github/pr.go index 74da3bbf2..52e980937 100644 --- a/scm/driver/github/pr.go +++ b/scm/driver/github/pr.go @@ -76,6 +76,7 @@ type pr struct { State string `json:"state"` Title string `json:"title"` Body string `json:"body"` + Draft bool `json:"draft"` DiffURL string `json:"diff_url"` HTMLURL string `json:"html_url"` User struct { @@ -154,6 +155,7 @@ func convertPullRequest(from *pr) *scm.PullRequest { Fork: from.Head.Repo.FullName, Link: from.HTMLURL, Diff: from.DiffURL, + Draft: from.Draft, Closed: from.State != "open", Merged: from.MergedAt.String != "", Head: scm.Reference{ diff --git a/scm/driver/github/testdata/pr.json b/scm/driver/github/testdata/pr.json index edcc02d7c..3315fafbc 100644 --- a/scm/driver/github/testdata/pr.json +++ b/scm/driver/github/testdata/pr.json @@ -11,6 +11,7 @@ "comments_url": "https://api.github.com/repos/octocat/Hello-World/issues/1347/comments", "statuses_url": "https://api.github.com/repos/octocat/Hello-World/statuses/6dcb09b5b57875f334f61aebed695e2e4193db5e", "number": 1347, + "draft": false, "state": "open", "title": "new-feature", "body": "Please pull these awesome changes", diff --git a/scm/driver/github/testdata/pr.json.golden b/scm/driver/github/testdata/pr.json.golden index 2ea51c709..5bf11ba0c 100644 --- a/scm/driver/github/testdata/pr.json.golden +++ b/scm/driver/github/testdata/pr.json.golden @@ -9,6 +9,7 @@ "Fork": "octocat/Hello-World", "Link": "https://github.com/octocat/Hello-World/pull/1347", "Diff": "https://github.com/octocat/Hello-World/pull/1347.diff", + "Draft": false, "Closed": false, "Merged": true, "Base": { diff --git a/scm/driver/github/testdata/pulls.json b/scm/driver/github/testdata/pulls.json index 611d7d71d..e1f85a075 100644 --- a/scm/driver/github/testdata/pulls.json +++ b/scm/driver/github/testdata/pulls.json @@ -12,6 +12,7 @@ "comments_url": "https://api.github.com/repos/octocat/Hello-World/issues/1347/comments", "statuses_url": "https://api.github.com/repos/octocat/Hello-World/statuses/6dcb09b5b57875f334f61aebed695e2e4193db5e", "number": 1347, + "draft": false, "state": "open", "title": "new-feature", "body": "Please pull these awesome changes", diff --git a/scm/driver/github/testdata/pulls.json.golden b/scm/driver/github/testdata/pulls.json.golden index 1a6798b98..f2a97473d 100644 --- a/scm/driver/github/testdata/pulls.json.golden +++ b/scm/driver/github/testdata/pulls.json.golden @@ -10,6 +10,7 @@ "Fork": "octocat/Hello-World", "Link": "https://github.com/octocat/Hello-World/pull/1347", "Diff": "https://github.com/octocat/Hello-World/pull/1347.diff", + "Draft": false, "Closed": false, "Merged": true, "Base": { diff --git a/scm/driver/gitlab/pr.go b/scm/driver/gitlab/pr.go index 52548146f..b8f67719a 100644 --- a/scm/driver/gitlab/pr.go +++ b/scm/driver/gitlab/pr.go @@ -99,13 +99,14 @@ func (s *pullService) Close(ctx context.Context, repo string, number int) (*scm. } type pr struct { - Number int `json:"iid"` - Sha string `json:"sha"` - Title string `json:"title"` - Desc string `json:"description"` - State string `json:"state"` - Link string `json:"web_url"` - Author struct { + Number int `json:"iid"` + Sha string `json:"sha"` + Title string `json:"title"` + Desc string `json:"description"` + State string `json:"state"` + WorkInProgress bool `json:"work_in_progress"` + Link string `json:"web_url"` + Author struct { Username string `json:"username"` Email string `json:"email"` Name string `json:"name"` @@ -160,6 +161,7 @@ func convertPullRequest(from *pr) *scm.PullRequest { Source: from.SourceBranch, Target: from.TargetBranch, Link: from.Link, + Draft: from.WorkInProgress, Closed: from.State != "opened", Merged: from.State == "merged", Author: scm.User{ diff --git a/scm/driver/gitlab/testdata/merge.json.golden b/scm/driver/gitlab/testdata/merge.json.golden index 4df0d2492..5864162c3 100644 --- a/scm/driver/gitlab/testdata/merge.json.golden +++ b/scm/driver/gitlab/testdata/merge.json.golden @@ -7,6 +7,7 @@ "Source": "fix", "Target": "master", "Link": "https://gitlab.com/gitlab-org/testme/merge_requests/1", + "Draft": false, "Closed": true, "Merged": false, "Author": { diff --git a/scm/driver/gitlab/testdata/merges.json.golden b/scm/driver/gitlab/testdata/merges.json.golden index 46cb6d7c4..cf605b9ee 100644 --- a/scm/driver/gitlab/testdata/merges.json.golden +++ b/scm/driver/gitlab/testdata/merges.json.golden @@ -8,6 +8,7 @@ "Source": "fix", "Target": "master", "Link": "https://gitlab.com/gitlab-org/testme/merge_requests/1", + "Draft": false, "Closed": true, "Merged": false, "Author": { diff --git a/scm/driver/gitlab/webhook.go b/scm/driver/gitlab/webhook.go index 2cc785fb7..30992e61a 100644 --- a/scm/driver/gitlab/webhook.go +++ b/scm/driver/gitlab/webhook.go @@ -238,6 +238,7 @@ func convertCommentHook(src *commentHook) (*scm.IssueCommentHook, error) { Source: src.MergeRequest.SourceBranch, Target: src.MergeRequest.TargetBranch, Link: src.MergeRequest.URL, + Draft: src.MergeRequest.WorkInProgress, Closed: src.MergeRequest.State != "opened", Merged: src.MergeRequest.State == "merged", Author: *convertUser(&src.User), @@ -359,6 +360,7 @@ func convertPullRequestHook(src *pullRequestHook) *scm.PullRequestHook { Target: src.ObjectAttributes.TargetBranch, Fork: fork, Link: src.ObjectAttributes.URL, + Draft: src.ObjectAttributes.WorkInProgress, Closed: src.ObjectAttributes.State != "opened", Merged: src.ObjectAttributes.State == "merged", // Created : src.ObjectAttributes.CreatedAt, diff --git a/scm/pr.go b/scm/pr.go index 1fd2e5a5b..1e9a74945 100644 --- a/scm/pr.go +++ b/scm/pr.go @@ -22,6 +22,7 @@ type ( Fork string Link string Diff string + Draft bool Closed bool Merged bool Merge string From 0969f30763cb2a2d6f29091be0fa751a4d36f56c Mon Sep 17 00:00:00 2001 From: Karan Saraswat Date: Fri, 2 Aug 2024 13:45:27 +0530 Subject: [PATCH 163/195] added for azure devops too --- scm/driver/azure/pr.go | 2 ++ scm/driver/azure/testdata/pr.json | 1 + scm/driver/azure/testdata/pr.json.golden | 1 + .../testdata/webhooks/pull_request_review_ready.json.golden | 1 + 4 files changed, 5 insertions(+) diff --git a/scm/driver/azure/pr.go b/scm/driver/azure/pr.go index a5bb93479..d2e36c48f 100644 --- a/scm/driver/azure/pr.go +++ b/scm/driver/azure/pr.go @@ -107,6 +107,7 @@ type pr struct { SourceRefName string `json:"sourceRefName"` TargetRefName string `json:"targetRefName"` MergeStatus string `json:"mergeStatus"` + IsDraft bool `json:"isDraft"` MergeID string `json:"mergeId"` LastMergeSourceCommit struct { CommitID string `json:"commitId"` @@ -168,6 +169,7 @@ func convertPullRequest(from *pr) *scm.PullRequest { Source: scm.TrimRef(from.SourceRefName), Target: scm.TrimRef(from.TargetRefName), Link: from.URL, + Draft: from.IsDraft, Closed: from.ClosedDate.Valid, Merged: from.Status == "completed", Ref: fmt.Sprintf("refs/pull/%d/merge", from.PullRequestID), diff --git a/scm/driver/azure/testdata/pr.json b/scm/driver/azure/testdata/pr.json index e419af010..01c08b31e 100644 --- a/scm/driver/azure/testdata/pr.json +++ b/scm/driver/azure/testdata/pr.json @@ -30,6 +30,7 @@ "sourceRefName": "refs/heads/pr_branch", "targetRefName": "refs/heads/main", "mergeStatus": "queued", + "isDraft": false, "mergeId": "36c88bf7-3d14-437f-82aa-e38cce733261", "lastMergeSourceCommit": { "commitId": "01768d964c03e97260af0bd8cd9e5cd1f9ac6356", diff --git a/scm/driver/azure/testdata/pr.json.golden b/scm/driver/azure/testdata/pr.json.golden index 5e59c583b..23330a15e 100644 --- a/scm/driver/azure/testdata/pr.json.golden +++ b/scm/driver/azure/testdata/pr.json.golden @@ -10,6 +10,7 @@ "Fork": "", "Link": "https://dev.azure.com/tphoney/d350c9c0-7749-4ff8-a78f-f9c1f0e56729/_apis/git/repositories/fde2d21f-13b9-4864-a995-83329045289a/pullRequests/19", "Diff": "", + "Draft": false, "Closed": true, "Merged": true, "Base": { diff --git a/scm/driver/gitlab/testdata/webhooks/pull_request_review_ready.json.golden b/scm/driver/gitlab/testdata/webhooks/pull_request_review_ready.json.golden index c75213032..059b6bbd7 100644 --- a/scm/driver/gitlab/testdata/webhooks/pull_request_review_ready.json.golden +++ b/scm/driver/gitlab/testdata/webhooks/pull_request_review_ready.json.golden @@ -23,6 +23,7 @@ "Target": "main", "Fork": "Meet Rathod/meet", "Link": "https://gitlab.com/rathod.meetsatish/meet/-/merge_requests/3", + "Draft": true, "Closed": false, "Merged": false, "Author": { From 122a705e99c5b8690e0e0feb2dc2b19e9f10d520 Mon Sep 17 00:00:00 2001 From: Vivek Dixit Date: Tue, 6 Aug 2024 13:45:37 +0530 Subject: [PATCH 164/195] Update azure.go --- scm/driver/azure/azure.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/scm/driver/azure/azure.go b/scm/driver/azure/azure.go index 1832e568d..e762a6db1 100644 --- a/scm/driver/azure/azure.go +++ b/scm/driver/azure/azure.go @@ -122,8 +122,5 @@ func ProjectRequiredError() error { } func SanitizeBranchName(name string) string { - if strings.Contains(name, "/") { - return name - } return "refs/heads/" + name } From 01168531237149dd2137bd0379618f02359a7a69 Mon Sep 17 00:00:00 2001 From: Vivek Dixit Date: Wed, 7 Aug 2024 11:25:19 +0530 Subject: [PATCH 165/195] Update azure_test.go --- scm/driver/azure/azure_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scm/driver/azure/azure_test.go b/scm/driver/azure/azure_test.go index 0a4334374..c3cc56732 100644 --- a/scm/driver/azure/azure_test.go +++ b/scm/driver/azure/azure_test.go @@ -54,11 +54,11 @@ func TestSanitizeBranchName(t *testing.T) { "refs/heads/master", }, { - "refs/heads/master", + "feature/main-patch", args{ - "refs/heads/master", + "feature/main-patch", }, - "refs/heads/master", + "refs/heads/feature/main-patch", }, } for _, tt := range tests { From 1eb6efe027dab3d6a47577fdf3bbf93ec392f5da Mon Sep 17 00:00:00 2001 From: Soumyajit Das Date: Thu, 22 Aug 2024 19:56:19 +0530 Subject: [PATCH 166/195] feat: [CI-13826]: add check for bitbucket tag slash --- scm/driver/bitbucket/git.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/scm/driver/bitbucket/git.go b/scm/driver/bitbucket/git.go index e0ecc5542..df16afbcb 100644 --- a/scm/driver/bitbucket/git.go +++ b/scm/driver/bitbucket/git.go @@ -7,6 +7,7 @@ package bitbucket import ( "context" "fmt" + "strings" "time" "github.com/drone/go-scm/scm" @@ -44,7 +45,12 @@ func (s *gitService) FindCommit(ctx context.Context, repo, ref string) (*scm.Com ref = branch.Sha // replace ref with sha } } - path := fmt.Sprintf("2.0/repositories/%s/commit/%s", repo, ref) + var path string + if strings.Contains(ref, "/") { + path = fmt.Sprintf("2.0/repositories/%s/?at=%s", repo, ref) + } else { + path = fmt.Sprintf("2.0/repositories/%s/commit/%s", repo, ref) + } out := new(commit) res, err := s.client.do(ctx, "GET", path, nil, out) return convertCommit(out), res, err From 48eec0e3183d7504438633758dcd06383c0b9670 Mon Sep 17 00:00:00 2001 From: Soumyajit Das Date: Tue, 27 Aug 2024 13:43:33 +0530 Subject: [PATCH 167/195] feat: [CI-13826]: add UTs --- scm/driver/bitbucket/git_test.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/scm/driver/bitbucket/git_test.go b/scm/driver/bitbucket/git_test.go index e93499808..912434bf1 100644 --- a/scm/driver/bitbucket/git_test.go +++ b/scm/driver/bitbucket/git_test.go @@ -41,6 +41,32 @@ func TestGitFindCommit(t *testing.T) { } } +func TestGitFindCommitForTagSlash(t *testing.T) { + defer gock.Off() + + gock.New("https://api.bitbucket.org"). + Get("/2.0/repositories/atlassian/stash-example-plugin"). + MatchParam("at", "ab/cd"). + Reply(200). + Type("application/json"). + File("testdata/commit.json") + + client, _ := New("https://api.bitbucket.org") + got, _, err := client.Git.FindCommit(context.Background(), "atlassian/stash-example-plugin", "ab/cd") + if err != nil { + t.Error(err) + } + + want := new(scm.Commit) + raw, _ := ioutil.ReadFile("testdata/commit.json.golden") + json.Unmarshal(raw, &want) + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } +} + func TestGitFindCommitForBranch(t *testing.T) { defer gock.Off() From 756f053bb754ff65900b73eef08c599e25e9de38 Mon Sep 17 00:00:00 2001 From: Abhinav Singh Date: Fri, 30 Aug 2024 02:09:11 +0530 Subject: [PATCH 168/195] feat: bypass branch rules as default for file ops (#321) --- scm/driver/harness/content.go | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/scm/driver/harness/content.go b/scm/driver/harness/content.go index 91e72ecee..40dd24d6c 100644 --- a/scm/driver/harness/content.go +++ b/scm/driver/harness/content.go @@ -50,10 +50,11 @@ func (s *contentService) Create(ctx context.Context, repo, path string, params * Encoding: "string", } in := editFile{ - Branch: params.Branch, - Message: params.Message, - Title: params.Message, - Actions: []action{a}, + Branch: params.Branch, + Message: params.Message, + Title: params.Message, + Actions: []action{a}, + BypassRules: true, } res, err := s.client.do(ctx, "POST", endpoint, in, nil) @@ -75,10 +76,11 @@ func (s *contentService) Update(ctx context.Context, repo, path string, params * Sha: params.BlobID, } in := editFile{ - Branch: params.Branch, - Message: params.Message, - Title: params.Message, - Actions: []action{a}, + Branch: params.Branch, + Message: params.Message, + Title: params.Message, + Actions: []action{a}, + BypassRules: true, } res, err := s.client.do(ctx, "POST", endpoint, in, nil) @@ -98,10 +100,11 @@ func (s *contentService) Delete(ctx context.Context, repo, path string, params * Encoding: "string", } in := editFile{ - Branch: params.Branch, - Message: params.Message, - Title: params.Message, - Actions: []action{a}, + Branch: params.Branch, + Message: params.Message, + Title: params.Message, + Actions: []action{a}, + BypassRules: true, } res, err := s.client.do(ctx, "POST", endpoint, in, nil) @@ -126,6 +129,8 @@ type editFile struct { Message string `json:"message"` NewBranch string `json:"new_branch"` Title string `json:"title"` + + BypassRules bool `json:"bypass_rules"` } type action struct { From 607a21578fafa069083ce96043e2b67516b4265e Mon Sep 17 00:00:00 2001 From: Abhinav Singh Date: Wed, 18 Sep 2024 13:46:08 -0700 Subject: [PATCH 169/195] feat: bypass branch rules as default for create branch ops (#323) * feat: bypass branch rules as default for file ops * feat: bypass branch rules as default for create branch * feat: bypass branch rules as default for create branch --- scm/driver/harness/git.go | 42 ++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/scm/driver/harness/git.go b/scm/driver/harness/git.go index 867735105..f261f7756 100644 --- a/scm/driver/harness/git.go +++ b/scm/driver/harness/git.go @@ -19,25 +19,26 @@ type gitService struct { func (s *gitService) CreateBranch(ctx context.Context, repo string, params *scm.ReferenceInput) (*scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + repoID, queryParams, err := getRepoAndQueryParams(harnessURI) if err != nil { return nil, err } - path := fmt.Sprintf("api/v1/repos/%s/branches?%s", repoId, queryParams) + path := fmt.Sprintf("api/v1/repos/%s/branches?%s", repoID, queryParams) in := &branchInput{ - Name: params.Name, - Target: params.Sha, + Name: params.Name, + Target: params.Sha, + BypassRules: true, } return s.client.do(ctx, "POST", path, in, nil) } func (s *gitService) FindBranch(ctx context.Context, repo, name string) (*scm.Reference, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + repoID, queryParams, err := getRepoAndQueryParams(harnessURI) if err != nil { return nil, nil, err } - path := fmt.Sprintf("api/v1/repos/%s/branches/%s?%s", repoId, name, queryParams) + path := fmt.Sprintf("api/v1/repos/%s/branches/%s?%s", repoID, name, queryParams) out := new(branch) res, err := s.client.do(ctx, "GET", path, nil, out) return convertBranch(out), res, err @@ -45,11 +46,11 @@ func (s *gitService) FindBranch(ctx context.Context, repo, name string) (*scm.Re func (s *gitService) FindCommit(ctx context.Context, repo, ref string) (*scm.Commit, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + repoID, queryParams, err := getRepoAndQueryParams(harnessURI) if err != nil { return nil, nil, err } - path := fmt.Sprintf("api/v1/repos/%s/commits/%s?%s", repoId, ref, queryParams) + path := fmt.Sprintf("api/v1/repos/%s/commits/%s?%s", repoID, ref, queryParams) out := new(commitInfo) res, err := s.client.do(ctx, "GET", path, nil, out) return convertCommitInfo(out), res, err @@ -61,11 +62,11 @@ func (s *gitService) FindTag(ctx context.Context, repo, name string) (*scm.Refer func (s *gitService) ListBranches(ctx context.Context, repo string, opts scm.ListOptions) ([]*scm.Reference, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + repoID, queryParams, err := getRepoAndQueryParams(harnessURI) if err != nil { return nil, nil, err } - path := fmt.Sprintf("api/v1/repos/%s/branches?%s&%s", repoId, encodeListOptions(opts), queryParams) + path := fmt.Sprintf("api/v1/repos/%s/branches?%s&%s", repoID, encodeListOptions(opts), queryParams) out := []*branch{} res, err := s.client.do(ctx, "GET", path, nil, &out) return convertBranchList(out), res, err @@ -79,11 +80,11 @@ func (s *gitService) ListBranchesV2(ctx context.Context, repo string, opts scm.B func (s *gitService) ListCommits(ctx context.Context, repo string, opts scm.CommitListOptions) ([]*scm.Commit, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + repoID, queryParams, err := getRepoAndQueryParams(harnessURI) if err != nil { return nil, nil, err } - path := fmt.Sprintf("api/v1/repos/%s/commits?%s&%s", repoId, encodeCommitListOptions(opts), queryParams) + path := fmt.Sprintf("api/v1/repos/%s/commits?%s&%s", repoID, encodeCommitListOptions(opts), queryParams) out := new(commits) res, err := s.client.do(ctx, "GET", path, nil, &out) return convertCommitList(out), res, err @@ -91,11 +92,11 @@ func (s *gitService) ListCommits(ctx context.Context, repo string, opts scm.Comm func (s *gitService) ListTags(ctx context.Context, repo string, opts scm.ListOptions) ([]*scm.Reference, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + repoID, queryParams, err := getRepoAndQueryParams(harnessURI) if err != nil { return nil, nil, err } - path := fmt.Sprintf("api/v1/repos/%s/tags?%s&%s", repoId, encodeListOptions(opts), queryParams) + path := fmt.Sprintf("api/v1/repos/%s/tags?%s&%s", repoID, encodeListOptions(opts), queryParams) out := []*branch{} res, err := s.client.do(ctx, "GET", path, nil, &out) return convertBranchList(out), res, err @@ -103,11 +104,11 @@ func (s *gitService) ListTags(ctx context.Context, repo string, opts scm.ListOpt func (s *gitService) ListChanges(ctx context.Context, repo, ref string, opts scm.ListOptions) ([]*scm.Change, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + repoID, queryParams, err := getRepoAndQueryParams(harnessURI) if err != nil { return nil, nil, err } - path := fmt.Sprintf("api/v1/repos/%s/commits/%s/diff?%s&%s", repoId, ref, encodeListOptions(opts), queryParams) + path := fmt.Sprintf("api/v1/repos/%s/commits/%s/diff?%s&%s", repoID, ref, encodeListOptions(opts), queryParams) out := []*fileDiff{} res, err := s.client.do(ctx, "POST", path, nil, &out) return convertFileDiffs(out), res, err @@ -115,11 +116,11 @@ func (s *gitService) ListChanges(ctx context.Context, repo, ref string, opts scm func (s *gitService) CompareChanges(ctx context.Context, repo, source, target string, _ scm.ListOptions) ([]*scm.Change, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + repoID, queryParams, err := getRepoAndQueryParams(harnessURI) if err != nil { return nil, nil, err } - path := fmt.Sprintf("api/v1/repos/%s/diff/%s...%s?%s", repoId, source, target, queryParams) + path := fmt.Sprintf("api/v1/repos/%s/diff/%s...%s?%s", repoID, source, target, queryParams) out := []*fileDiff{} res, err := s.client.do(ctx, "GET", path, nil, &out) return convertChangeList(out), res, err @@ -151,8 +152,9 @@ type ( Title string `json:"title"` } branchInput struct { - Name string `json:"name"` - Target string `json:"target"` + Name string `json:"name"` + Target string `json:"target"` + BypassRules bool `json:"bypass_rules"` } branch struct { Commit struct { From 63abea20a1babd8a7a686feb79e651e7b859888a Mon Sep 17 00:00:00 2001 From: Deepak Puthraya Date: Mon, 7 Oct 2024 11:29:49 +0530 Subject: [PATCH 170/195] feat:[CDS-101592]: Add support for parsing Gitlab System Hooks (#324) --- scm/driver/gitlab/webhook.go | 27 +++++++++++++ scm/driver/gitlab/webhook_test.go | 67 +++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) diff --git a/scm/driver/gitlab/webhook.go b/scm/driver/gitlab/webhook.go index 30992e61a..c70569471 100644 --- a/scm/driver/gitlab/webhook.go +++ b/scm/driver/gitlab/webhook.go @@ -39,6 +39,8 @@ func (s *webhookService) Parse(req *http.Request, fn scm.SecretFunc) (scm.Webhoo hook, err = parsePullRequestHook(data) case "Note Hook": hook, err = parseIssueCommentHook(data) + case "System Hook": + hook, err = parseSystemHook(data) default: return nil, scm.ErrUnknownEvent } @@ -63,6 +65,26 @@ func (s *webhookService) Parse(req *http.Request, fn scm.SecretFunc) (scm.Webhoo return hook, nil } +func parseSystemHook(data []byte) (scm.Webhook, error) { + src := new(event) + err := json.Unmarshal(data, src) + if err != nil { + return nil, err + } + switch src.ObjectKind { + case "push", "tag_push": + return parsePushHook(data) + case "issue": + return nil, scm.ErrUnknownEvent + case "merge_request": + return parsePullRequestHook(data) + case "note": + return parseIssueCommentHook(data) + default: + return nil, scm.ErrUnknownEvent + } +} + func parseIssueCommentHook(data []byte) (scm.Webhook, error) { src := new(commentHook) err := json.Unmarshal(data, src) @@ -399,6 +421,11 @@ func parseTimeString(timeString string) time.Time { } type ( + // Generic struct to detect event type + event struct { + ObjectKind string `json:"object_kind"` + } + pushHook struct { ObjectKind string `json:"object_kind"` EventName string `json:"event_name"` diff --git a/scm/driver/gitlab/webhook_test.go b/scm/driver/gitlab/webhook_test.go index e766cada4..16041c67d 100644 --- a/scm/driver/gitlab/webhook_test.go +++ b/scm/driver/gitlab/webhook_test.go @@ -38,6 +38,18 @@ func TestWebhooks(t *testing.T) { after: "testdata/webhooks/branch_delete.json.golden", obj: new(scm.BranchHook), }, + { + event: "System Hook", + before: "testdata/webhooks/branch_create.json", + after: "testdata/webhooks/branch_create.json.golden", + obj: new(scm.PushHook), + }, + { + event: "System Hook", + before: "testdata/webhooks/branch_delete.json", + after: "testdata/webhooks/branch_delete.json.golden", + obj: new(scm.BranchHook), + }, // tag hooks { event: "Tag Push Hook", @@ -51,6 +63,18 @@ func TestWebhooks(t *testing.T) { after: "testdata/webhooks/tag_delete.json.golden", obj: new(scm.TagHook), }, + { + event: "System Hook", + before: "testdata/webhooks/tag_create.json", + after: "testdata/webhooks/tag_create.json.golden", + obj: new(scm.PushHook), + }, + { + event: "System Hook", + before: "testdata/webhooks/tag_delete.json", + after: "testdata/webhooks/tag_delete.json.golden", + obj: new(scm.TagHook), + }, // push hooks { event: "Push Hook", @@ -58,6 +82,12 @@ func TestWebhooks(t *testing.T) { after: "testdata/webhooks/push.json.golden", obj: new(scm.PushHook), }, + { + event: "System Hook", + before: "testdata/webhooks/push.json", + after: "testdata/webhooks/push.json.golden", + obj: new(scm.PushHook), + }, // // issue hooks // { // event: "issues", @@ -79,6 +109,13 @@ func TestWebhooks(t *testing.T) { after: "testdata/webhooks/pull_request_create.json.golden", obj: new(scm.PullRequestHook), }, + { + event: "System Hook", + before: "testdata/webhooks/pull_request_create.json", + after: "testdata/webhooks/pull_request_create.json.golden", + obj: new(scm.PullRequestHook), + }, + // { // event: "Merge Request Hook", // before: "testdata/webhooks/pull_request_edited.json", @@ -115,6 +152,30 @@ func TestWebhooks(t *testing.T) { after: "testdata/webhooks/pull_request_merge.json.golden", obj: new(scm.PullRequestHook), }, + { + event: "System Hook", + before: "testdata/webhooks/pull_request_close.json", + after: "testdata/webhooks/pull_request_close.json.golden", + obj: new(scm.PullRequestHook), + }, + { + event: "System Hook", + before: "testdata/webhooks/pull_request_review_ready.json", + after: "testdata/webhooks/pull_request_review_ready.json.golden", + obj: new(scm.PullRequestHook), + }, + { + event: "System Hook", + before: "testdata/webhooks/pull_request_reopen.json", + after: "testdata/webhooks/pull_request_reopen.json.golden", + obj: new(scm.PullRequestHook), + }, + { + event: "System Hook", + before: "testdata/webhooks/pull_request_merge.json", + after: "testdata/webhooks/pull_request_merge.json.golden", + obj: new(scm.PullRequestHook), + }, // Note hook for Gitlab Merge Request comment { event: "Note Hook", @@ -122,6 +183,12 @@ func TestWebhooks(t *testing.T) { after: "testdata/webhooks/merge_request_comment_create.json.golden", obj: new(scm.IssueCommentHook), }, + { + event: "System Hook", + before: "testdata/webhooks/merge_request_comment_create.json", + after: "testdata/webhooks/merge_request_comment_create.json.golden", + obj: new(scm.IssueCommentHook), + }, } for _, test := range tests { From f42f711bde13c46156985153941f880386a598c8 Mon Sep 17 00:00:00 2001 From: atefehmohseni <57154674+atefehmohseni@users.noreply.github.com> Date: Mon, 18 Nov 2024 21:28:54 -0800 Subject: [PATCH 171/195] Update pr.go --- scm/driver/bitbucket/pr.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm/driver/bitbucket/pr.go b/scm/driver/bitbucket/pr.go index ead47a821..38610bf5e 100644 --- a/scm/driver/bitbucket/pr.go +++ b/scm/driver/bitbucket/pr.go @@ -193,7 +193,7 @@ func convertPullRequest(from *pr) *scm.PullRequest { Sha: from.Destination.Commit.Hash, }, Author: scm.User{ - Login: from.Author.Nickname, + Login: from.Author.UUID, Name: from.Author.DisplayName, Avatar: from.Author.Links.Avatar.Href, }, From ad49c0a6b9215301ac063978682a9e32752a724a Mon Sep 17 00:00:00 2001 From: atefehmohseni <57154674+atefehmohseni@users.noreply.github.com> Date: Mon, 18 Nov 2024 21:47:51 -0800 Subject: [PATCH 172/195] Update prs.json.golden --- scm/driver/bitbucket/testdata/prs.json.golden | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm/driver/bitbucket/testdata/prs.json.golden b/scm/driver/bitbucket/testdata/prs.json.golden index 29cafe903..99a5905f3 100644 --- a/scm/driver/bitbucket/testdata/prs.json.golden +++ b/scm/driver/bitbucket/testdata/prs.json.golden @@ -23,7 +23,7 @@ "Name": "Lachlan-Vass/ios-date-picker-component-duplicate-marc-1579222909688" }, "Author": { - "Login": "Lachlan", + "Login": "ef9d9075-f870-417f-b424-83adbc8efa54", "Name": "Lachlan Vass", "Avatar": "https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/5c7c7b1a0b79db7c3e33eca2/6b6b8178-0da0-4a37-b0dd-f8b5e3628eaa/128" }, From 494c7c7d222363cf025fe38c3b213aac98dba043 Mon Sep 17 00:00:00 2001 From: atefehmohseni <57154674+atefehmohseni@users.noreply.github.com> Date: Mon, 18 Nov 2024 21:48:08 -0800 Subject: [PATCH 173/195] Update pr.json.golden --- scm/driver/bitbucket/testdata/pr.json.golden | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm/driver/bitbucket/testdata/pr.json.golden b/scm/driver/bitbucket/testdata/pr.json.golden index 8132df37f..eb0f2c047 100644 --- a/scm/driver/bitbucket/testdata/pr.json.golden +++ b/scm/driver/bitbucket/testdata/pr.json.golden @@ -22,7 +22,7 @@ "Name": "Lachlan-Vass/ios-date-picker-component-duplicate-marc-1579222909688" }, "Author": { - "Login": "Lachlan", + "Login": "ef9d9075-f870-417f-b424-83adbc8efa54", "Name": "Lachlan Vass", "Avatar": "https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/5c7c7b1a0b79db7c3e33eca2/6b6b8178-0da0-4a37-b0dd-f8b5e3628eaa/128" }, From 2cb72e1be625c5d94790bb7eca362b68684782ee Mon Sep 17 00:00:00 2001 From: atefehmohseni <57154674+atefehmohseni@users.noreply.github.com> Date: Mon, 18 Nov 2024 21:52:57 -0800 Subject: [PATCH 174/195] Update pr.go --- scm/driver/bitbucket/pr.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm/driver/bitbucket/pr.go b/scm/driver/bitbucket/pr.go index 38610bf5e..4d435c192 100644 --- a/scm/driver/bitbucket/pr.go +++ b/scm/driver/bitbucket/pr.go @@ -193,7 +193,7 @@ func convertPullRequest(from *pr) *scm.PullRequest { Sha: from.Destination.Commit.Hash, }, Author: scm.User{ - Login: from.Author.UUID, + Login: from.Author.AccountID, Name: from.Author.DisplayName, Avatar: from.Author.Links.Avatar.Href, }, From 8f57b646812524037782314137052815b86aeb00 Mon Sep 17 00:00:00 2001 From: atefehmohseni <57154674+atefehmohseni@users.noreply.github.com> Date: Mon, 18 Nov 2024 21:55:43 -0800 Subject: [PATCH 175/195] Update pr.json.golden --- scm/driver/bitbucket/testdata/pr.json.golden | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm/driver/bitbucket/testdata/pr.json.golden b/scm/driver/bitbucket/testdata/pr.json.golden index eb0f2c047..541b7b4ca 100644 --- a/scm/driver/bitbucket/testdata/pr.json.golden +++ b/scm/driver/bitbucket/testdata/pr.json.golden @@ -22,7 +22,7 @@ "Name": "Lachlan-Vass/ios-date-picker-component-duplicate-marc-1579222909688" }, "Author": { - "Login": "ef9d9075-f870-417f-b424-83adbc8efa54", + "Login": "5c7c7b1a0b79db7c3e33eca2", "Name": "Lachlan Vass", "Avatar": "https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/5c7c7b1a0b79db7c3e33eca2/6b6b8178-0da0-4a37-b0dd-f8b5e3628eaa/128" }, From 44d28c751c4e838ee99b0a5a7be7a289334742f9 Mon Sep 17 00:00:00 2001 From: atefehmohseni <57154674+atefehmohseni@users.noreply.github.com> Date: Mon, 18 Nov 2024 21:56:34 -0800 Subject: [PATCH 176/195] Update prs.json.golden --- scm/driver/bitbucket/testdata/prs.json.golden | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm/driver/bitbucket/testdata/prs.json.golden b/scm/driver/bitbucket/testdata/prs.json.golden index 99a5905f3..993b68bef 100644 --- a/scm/driver/bitbucket/testdata/prs.json.golden +++ b/scm/driver/bitbucket/testdata/prs.json.golden @@ -23,7 +23,7 @@ "Name": "Lachlan-Vass/ios-date-picker-component-duplicate-marc-1579222909688" }, "Author": { - "Login": "ef9d9075-f870-417f-b424-83adbc8efa54", + "Login": "5c7c7b1a0b79db7c3e33eca2", "Name": "Lachlan Vass", "Avatar": "https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/5c7c7b1a0b79db7c3e33eca2/6b6b8178-0da0-4a37-b0dd-f8b5e3628eaa/128" }, From a394f0d2cd7ba0bc4cad45d2c7277f974e2a08a5 Mon Sep 17 00:00:00 2001 From: atefehmohseni <57154674+atefehmohseni@users.noreply.github.com> Date: Tue, 19 Nov 2024 07:53:40 -0800 Subject: [PATCH 177/195] Update pr.go --- scm/driver/bitbucket/pr.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm/driver/bitbucket/pr.go b/scm/driver/bitbucket/pr.go index 4d435c192..54f0b8b18 100644 --- a/scm/driver/bitbucket/pr.go +++ b/scm/driver/bitbucket/pr.go @@ -193,7 +193,7 @@ func convertPullRequest(from *pr) *scm.PullRequest { Sha: from.Destination.Commit.Hash, }, Author: scm.User{ - Login: from.Author.AccountID, + ID: from.Author.AccountID, Name: from.Author.DisplayName, Avatar: from.Author.Links.Avatar.Href, }, From de8ab9207236ee5ef0f3fbd46029b7ecf2008741 Mon Sep 17 00:00:00 2001 From: atefehmohseni <57154674+atefehmohseni@users.noreply.github.com> Date: Tue, 19 Nov 2024 07:54:44 -0800 Subject: [PATCH 178/195] Update pr.json.golden --- scm/driver/bitbucket/testdata/pr.json.golden | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm/driver/bitbucket/testdata/pr.json.golden b/scm/driver/bitbucket/testdata/pr.json.golden index 541b7b4ca..1ed8a643f 100644 --- a/scm/driver/bitbucket/testdata/pr.json.golden +++ b/scm/driver/bitbucket/testdata/pr.json.golden @@ -22,7 +22,7 @@ "Name": "Lachlan-Vass/ios-date-picker-component-duplicate-marc-1579222909688" }, "Author": { - "Login": "5c7c7b1a0b79db7c3e33eca2", + "ID": "5c7c7b1a0b79db7c3e33eca2", "Name": "Lachlan Vass", "Avatar": "https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/5c7c7b1a0b79db7c3e33eca2/6b6b8178-0da0-4a37-b0dd-f8b5e3628eaa/128" }, From 587bff37744f17d407e77508d38831260289aee0 Mon Sep 17 00:00:00 2001 From: atefehmohseni <57154674+atefehmohseni@users.noreply.github.com> Date: Tue, 19 Nov 2024 07:54:56 -0800 Subject: [PATCH 179/195] Update prs.json.golden --- scm/driver/bitbucket/testdata/prs.json.golden | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm/driver/bitbucket/testdata/prs.json.golden b/scm/driver/bitbucket/testdata/prs.json.golden index 993b68bef..90a246041 100644 --- a/scm/driver/bitbucket/testdata/prs.json.golden +++ b/scm/driver/bitbucket/testdata/prs.json.golden @@ -23,7 +23,7 @@ "Name": "Lachlan-Vass/ios-date-picker-component-duplicate-marc-1579222909688" }, "Author": { - "Login": "5c7c7b1a0b79db7c3e33eca2", + "ID": "5c7c7b1a0b79db7c3e33eca2", "Name": "Lachlan Vass", "Avatar": "https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/5c7c7b1a0b79db7c3e33eca2/6b6b8178-0da0-4a37-b0dd-f8b5e3628eaa/128" }, From df651244d043b16a27f42fa401e127c4697b1dd6 Mon Sep 17 00:00:00 2001 From: atefehmohseni <57154674+atefehmohseni@users.noreply.github.com> Date: Tue, 19 Nov 2024 12:24:12 -0800 Subject: [PATCH 180/195] gofmt --- scm/driver/bitbucket/pr.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm/driver/bitbucket/pr.go b/scm/driver/bitbucket/pr.go index 54f0b8b18..c0282f714 100644 --- a/scm/driver/bitbucket/pr.go +++ b/scm/driver/bitbucket/pr.go @@ -193,7 +193,7 @@ func convertPullRequest(from *pr) *scm.PullRequest { Sha: from.Destination.Commit.Hash, }, Author: scm.User{ - ID: from.Author.AccountID, + ID: from.Author.AccountID, Name: from.Author.DisplayName, Avatar: from.Author.Links.Avatar.Href, }, From d5ed63c1a5888b1378412d5d95c24c866e4bb47c Mon Sep 17 00:00:00 2001 From: Olivier Vernin Date: Thu, 21 Nov 2024 19:21:08 +0100 Subject: [PATCH 181/195] fix: pass gitlab mergerequest param via json body (#322) Signed-off-by: Olivier Vernin --- scm/driver/gitlab/pr.go | 23 ++++++++++++++++------- scm/driver/gitlab/pr_test.go | 4 ---- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/scm/driver/gitlab/pr.go b/scm/driver/gitlab/pr.go index b8f67719a..bb63590a6 100644 --- a/scm/driver/gitlab/pr.go +++ b/scm/driver/gitlab/pr.go @@ -60,14 +60,23 @@ func (s *pullService) ListCommits(ctx context.Context, repo string, number int, } func (s *pullService) Create(ctx context.Context, repo string, input *scm.PullRequestInput) (*scm.PullRequest, *scm.Response, error) { - in := url.Values{} - in.Set("title", input.Title) - in.Set("description", input.Body) - in.Set("source_branch", input.Source) - in.Set("target_branch", input.Target) - path := fmt.Sprintf("api/v4/projects/%s/merge_requests?%s", encode(repo), in.Encode()) + // https://docs.gitlab.com/ee/api/merge_requests.html#create-mr + in := struct { + Title string `json:"title"` + Description string `json:"description"` + SourceBranch string `json:"source_branch"` + TargetBranch string `json:"target_branch"` + }{ + Title: input.Title, + Description: input.Body, + SourceBranch: input.Source, + TargetBranch: input.Target, + } + + path := fmt.Sprintf("api/v4/projects/%s/merge_requests", encode(repo)) + out := new(pr) - res, err := s.client.do(ctx, "POST", path, nil, out) + res, err := s.client.do(ctx, "POST", path, in, out) return convertPullRequest(out), res, err } diff --git a/scm/driver/gitlab/pr_test.go b/scm/driver/gitlab/pr_test.go index fe35f1e8d..c36ab067e 100644 --- a/scm/driver/gitlab/pr_test.go +++ b/scm/driver/gitlab/pr_test.go @@ -162,10 +162,6 @@ func TestPullCreate(t *testing.T) { gock.New("https://gitlab.com"). Post("/api/v4/projects/diaspora/diaspora/merge_requests"). - MatchParam("title", input.Title). - MatchParam("description", input.Body). - MatchParam("source_branch", input.Source). - MatchParam("target_branch", input.Target). Reply(201). Type("application/json"). SetHeaders(mockHeaders). From 31d79c45a9cab727607b88cf8e893c39462e3978 Mon Sep 17 00:00:00 2001 From: Karan Saraswat Date: Mon, 2 Dec 2024 17:19:12 +0530 Subject: [PATCH 182/195] feat: [PIPE-23808]: integrate author details with the harness commits API --- scm/content.go | 4 +- scm/driver/harness/content.go | 196 +++++++++++++++++----------------- 2 files changed, 101 insertions(+), 99 deletions(-) diff --git a/scm/content.go b/scm/content.go index 4f5e4a0e9..2d5cb6fde 100644 --- a/scm/content.go +++ b/scm/content.go @@ -40,13 +40,13 @@ type ( // Find returns the repository file content by path. Find(ctx context.Context, repo, path, ref string) (*Content, *Response, error) - // Create creates a new repositroy file. + // Create creates a new repository file. Create(ctx context.Context, repo, path string, params *ContentParams) (*Response, error) // Update updates a repository file. Update(ctx context.Context, repo, path string, params *ContentParams) (*Response, error) - // Delete deletes a reository file. + // Delete deletes a repository file. Delete(ctx context.Context, repo, path string, params *ContentParams) (*Response, error) // List returns a list of contents in a repository directory by path. It is diff --git a/scm/driver/harness/content.go b/scm/driver/harness/content.go index 40dd24d6c..16159cb53 100644 --- a/scm/driver/harness/content.go +++ b/scm/driver/harness/content.go @@ -55,6 +55,10 @@ func (s *contentService) Create(ctx context.Context, repo, path string, params * Title: params.Message, Actions: []action{a}, BypassRules: true, + Author: identity{ + Name: params.Signature.Name, + Email: params.Signature.Email, + }, } res, err := s.client.do(ctx, "POST", endpoint, in, nil) @@ -81,6 +85,10 @@ func (s *contentService) Update(ctx context.Context, repo, path string, params * Title: params.Message, Actions: []action{a}, BypassRules: true, + Author: identity{ + Name: params.Signature.Name, + Email: params.Signature.Email, + }, } res, err := s.client.do(ctx, "POST", endpoint, in, nil) @@ -105,6 +113,10 @@ func (s *contentService) Delete(ctx context.Context, repo, path string, params * Title: params.Message, Actions: []action{a}, BypassRules: true, + Author: identity{ + Name: params.Signature.Name, + Email: params.Signature.Email, + }, } res, err := s.client.do(ctx, "POST", endpoint, in, nil) @@ -123,109 +135,99 @@ func (s *contentService) List(ctx context.Context, repo, path, ref string, _ scm return convertContentInfoList(out.Content.Entries), res, err } -type editFile struct { - Actions []action `json:"actions"` - Branch string `json:"branch"` - Message string `json:"message"` - NewBranch string `json:"new_branch"` - Title string `json:"title"` +type ( + identity struct { + Name string `json:"name"` + Email string `json:"email"` + } - BypassRules bool `json:"bypass_rules"` -} + editFile struct { + Actions []action `json:"actions"` + Author identity `json:"author"` + Branch string `json:"branch"` + Message string `json:"message"` + NewBranch string `json:"new_branch"` + Title string `json:"title"` -type action struct { - Action string `json:"action"` - Encoding string `json:"encoding"` - Path string `json:"path"` - Payload string `json:"payload"` - Sha string `json:"sha"` -} + BypassRules bool `json:"bypass_rules"` + } -type fileContent struct { - Type string `json:"type"` - Sha string `json:"sha"` - Name string `json:"name"` - Path string `json:"path"` - LatestCommit struct { - Sha string `json:"sha"` - Title string `json:"title"` - Message string `json:"message"` - Author struct { - Identity struct { - Name string `json:"name"` - Email string `json:"email"` - } `json:"identity"` - When time.Time `json:"when"` - } `json:"author"` - Committer struct { - Identity struct { - Name string `json:"name"` - Email string `json:"email"` - } `json:"identity"` - When time.Time `json:"when"` - } `json:"committer"` - } `json:"latest_commit"` - Content struct { + action struct { + Action string `json:"action"` Encoding string `json:"encoding"` - Data string `json:"data"` - Size int `json:"size"` - } `json:"content"` -} + Path string `json:"path"` + Payload string `json:"payload"` + Sha string `json:"sha"` + } -type contentList struct { - Type string `json:"type"` - Sha string `json:"sha"` - Name string `json:"name"` - Path string `json:"path"` - LatestCommit struct { - Sha string `json:"sha"` - Title string `json:"title"` - Message string `json:"message"` - Author struct { - Identity struct { - Name string `json:"name"` - Email string `json:"email"` - } `json:"identity"` - When time.Time `json:"when"` - } `json:"author"` - Committer struct { - Identity struct { - Name string `json:"name"` - Email string `json:"email"` - } `json:"identity"` - When time.Time `json:"when"` - } `json:"committer"` - } `json:"latest_commit"` - Content struct { - Entries []fileEntry `json:"entries"` - } `json:"content"` -} + fileContent struct { + Type string `json:"type"` + Sha string `json:"sha"` + Name string `json:"name"` + Path string `json:"path"` + LatestCommit struct { + Sha string `json:"sha"` + Title string `json:"title"` + Message string `json:"message"` + Author struct { + Identity identity `json:"identity"` + When time.Time `json:"when"` + } `json:"author"` + Committer struct { + Identity identity `json:"identity"` + When time.Time `json:"when"` + } `json:"committer"` + } `json:"latest_commit"` + Content struct { + Encoding string `json:"encoding"` + Data string `json:"data"` + Size int `json:"size"` + } `json:"content"` + } -type fileEntry struct { - Type string `json:"type"` - Sha string `json:"sha"` - Name string `json:"name"` - Path string `json:"path"` - LatestCommit struct { - Sha string `json:"sha"` - Title string `json:"title"` - Message string `json:"message"` - Author struct { - Identity struct { - Name string `json:"name"` - Email string `json:"email"` - } `json:"identity"` - When time.Time `json:"when"` - } `json:"author"` - Committer struct { - Identity struct { - Name string `json:"name"` - Email string `json:"email"` - } `json:"identity"` - When time.Time `json:"when"` - } `json:"committer"` - } `json:"latest_commit"` -} + contentList struct { + Type string `json:"type"` + Sha string `json:"sha"` + Name string `json:"name"` + Path string `json:"path"` + LatestCommit struct { + Sha string `json:"sha"` + Title string `json:"title"` + Message string `json:"message"` + Author struct { + Identity identity `json:"identity"` + When time.Time `json:"when"` + } `json:"author"` + Committer struct { + Identity identity `json:"identity"` + When time.Time `json:"when"` + } `json:"committer"` + } `json:"latest_commit"` + Content struct { + Entries []fileEntry `json:"entries"` + } `json:"content"` + } + + fileEntry struct { + Type string `json:"type"` + Sha string `json:"sha"` + Name string `json:"name"` + Path string `json:"path"` + LatestCommit struct { + Sha string `json:"sha"` + Title string `json:"title"` + Message string `json:"message"` + Author struct { + Identity identity `json:"identity"` + When time.Time `json:"when"` + } `json:"author"` + Committer struct { + Identity identity `json:"identity"` + When time.Time `json:"when"` + } `json:"committer"` + } `json:"latest_commit"` + } +) func convertContentInfoList(from []fileEntry) []*scm.ContentInfo { to := []*scm.ContentInfo{} From 2826df1267c7b149c346a0dfd9f187f31e0f2dbb Mon Sep 17 00:00:00 2001 From: raghavharness Date: Wed, 19 Feb 2025 13:11:51 +0530 Subject: [PATCH 183/195] change ref to query escape --- scm/driver/azure/content.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scm/driver/azure/content.go b/scm/driver/azure/content.go index b300049f6..c5a8fbf35 100644 --- a/scm/driver/azure/content.go +++ b/scm/driver/azure/content.go @@ -126,8 +126,9 @@ func (s *contentService) List(ctx context.Context, repo, path, ref string, _ scm if s.client.project == "" { return nil, nil, ProjectRequiredError() } + urlEncodedRef := url.QueryEscape(ref) endpoint := fmt.Sprintf("%s/%s/_apis/git/repositories/%s/items?scopePath=%s&recursionLevel=Full&$format=json", s.client.owner, s.client.project, repo, path) - endpoint += generateURIFromRef(ref) + endpoint += generateURIFromRef(urlEncodedRef) out := new(contentList) res, err := s.client.do(ctx, "GET", endpoint, nil, &out) return convertContentInfoList(out.Value), res, err From 9308066f6bd640f4f561d973ee5ce94dd78e6f82 Mon Sep 17 00:00:00 2001 From: raghavharness Date: Wed, 19 Feb 2025 13:18:02 +0530 Subject: [PATCH 184/195] change ref to query escape --- scm/driver/azure/content.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm/driver/azure/content.go b/scm/driver/azure/content.go index c5a8fbf35..eea1d7484 100644 --- a/scm/driver/azure/content.go +++ b/scm/driver/azure/content.go @@ -209,7 +209,7 @@ func generateURIFromRef(ref string) (uri string) { if len(ref) == 40 { return fmt.Sprintf("&versionDescriptor.versionType=commit&versionDescriptor.version=%s", ref) } else { - return fmt.Sprintf("&versionDescriptor.versionType=branch&versionDescriptor.version=%s", ref) + return fmt.Sprintf("&versionDescriptor.versionType=tag&versionDescriptor.version=%s", ref) } } return "" From feb699bb82a8155de07883e3cf14b4203157721e Mon Sep 17 00:00:00 2001 From: raghavharness Date: Wed, 19 Feb 2025 14:29:40 +0530 Subject: [PATCH 185/195] add tag support for content list api azure --- scm/driver/azure/content.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/scm/driver/azure/content.go b/scm/driver/azure/content.go index eea1d7484..a31258d8a 100644 --- a/scm/driver/azure/content.go +++ b/scm/driver/azure/content.go @@ -9,6 +9,7 @@ import ( "encoding/base64" "fmt" "net/url" + "strings" "github.com/drone/go-scm/scm" ) @@ -126,9 +127,8 @@ func (s *contentService) List(ctx context.Context, repo, path, ref string, _ scm if s.client.project == "" { return nil, nil, ProjectRequiredError() } - urlEncodedRef := url.QueryEscape(ref) endpoint := fmt.Sprintf("%s/%s/_apis/git/repositories/%s/items?scopePath=%s&recursionLevel=Full&$format=json", s.client.owner, s.client.project, repo, path) - endpoint += generateURIFromRef(urlEncodedRef) + endpoint += generateURIFromRef(ref) out := new(contentList) res, err := s.client.do(ctx, "GET", endpoint, nil, &out) return convertContentInfoList(out.Value), res, err @@ -208,8 +208,10 @@ func generateURIFromRef(ref string) (uri string) { if ref != "" { if len(ref) == 40 { return fmt.Sprintf("&versionDescriptor.versionType=commit&versionDescriptor.version=%s", ref) + } else if strings.HasPrefix(ref, "refs/tags/") { + return fmt.Sprintf("&versionDescriptor.versionType=tag&versionDescriptor.version=%s", scm.TrimRef(ref)) } else { - return fmt.Sprintf("&versionDescriptor.versionType=tag&versionDescriptor.version=%s", ref) + return fmt.Sprintf("&versionDescriptor.versionType=branch&versionDescriptor.version=%s", ref) } } return "" From a3630387aae897f0fd30a5d4b664f96136b345c9 Mon Sep 17 00:00:00 2001 From: raghavharness Date: Wed, 19 Feb 2025 15:49:01 +0530 Subject: [PATCH 186/195] add tag support for content list api azure --- scm/driver/azure/content.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/scm/driver/azure/content.go b/scm/driver/azure/content.go index a31258d8a..37b6ed50e 100644 --- a/scm/driver/azure/content.go +++ b/scm/driver/azure/content.go @@ -208,10 +208,8 @@ func generateURIFromRef(ref string) (uri string) { if ref != "" { if len(ref) == 40 { return fmt.Sprintf("&versionDescriptor.versionType=commit&versionDescriptor.version=%s", ref) - } else if strings.HasPrefix(ref, "refs/tags/") { - return fmt.Sprintf("&versionDescriptor.versionType=tag&versionDescriptor.version=%s", scm.TrimRef(ref)) } else { - return fmt.Sprintf("&versionDescriptor.versionType=branch&versionDescriptor.version=%s", ref) + return fmt.Sprintf("&versionDescriptor.versionType=tag&versionDescriptor.version=%s", ref) } } return "" From d6b76712a5f0a20b893d8a137d9ee3512739ec91 Mon Sep 17 00:00:00 2001 From: raghavharness Date: Wed, 19 Feb 2025 16:34:26 +0530 Subject: [PATCH 187/195] add tag support for content list api azure --- scm/driver/azure/content.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm/driver/azure/content.go b/scm/driver/azure/content.go index 37b6ed50e..8c5cd3e9f 100644 --- a/scm/driver/azure/content.go +++ b/scm/driver/azure/content.go @@ -9,7 +9,7 @@ import ( "encoding/base64" "fmt" "net/url" - "strings" + // "strings" "github.com/drone/go-scm/scm" ) From 6a6fa108a993f8b8ed4f89ecd3cd7a4b537296ad Mon Sep 17 00:00:00 2001 From: raghavharness Date: Wed, 19 Feb 2025 16:41:00 +0530 Subject: [PATCH 188/195] add tag support for content list api azure --- scm/driver/azure/content.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scm/driver/azure/content.go b/scm/driver/azure/content.go index 8c5cd3e9f..a31258d8a 100644 --- a/scm/driver/azure/content.go +++ b/scm/driver/azure/content.go @@ -9,7 +9,7 @@ import ( "encoding/base64" "fmt" "net/url" - // "strings" + "strings" "github.com/drone/go-scm/scm" ) @@ -208,8 +208,10 @@ func generateURIFromRef(ref string) (uri string) { if ref != "" { if len(ref) == 40 { return fmt.Sprintf("&versionDescriptor.versionType=commit&versionDescriptor.version=%s", ref) + } else if strings.HasPrefix(ref, "refs/tags/") { + return fmt.Sprintf("&versionDescriptor.versionType=tag&versionDescriptor.version=%s", scm.TrimRef(ref)) } else { - return fmt.Sprintf("&versionDescriptor.versionType=tag&versionDescriptor.version=%s", ref) + return fmt.Sprintf("&versionDescriptor.versionType=branch&versionDescriptor.version=%s", ref) } } return "" From e91781e589c84eb5c5f683ef3d607bf4c994725b Mon Sep 17 00:00:00 2001 From: Shivam Negi Date: Thu, 10 Apr 2025 15:43:01 +0530 Subject: [PATCH 189/195] feat: [PIPE-25660]: Handling for pipeline hook (#330) * feat: [PIPE-25660]: Handling for pipeline hook * feat: [PIPE-25660]: Added the parse for Gitlab pipeline event * feat: [PIPE-25660]: Added the parse for Gitlab pipeline event * feat: [PIPE-25660]: Added the parse for Gitlab pipeline event * feat: [PIPE-25660]: Support for pipeline hook event * feat: [PIPE-25660]: Support for pipeline hook event * feat: [PIPE-25660]: Support for pipeline hook event * feat: [PIPE-25660]: Support for pipeline hook event * feat: [PIPE-25660]: Support for pipeline hook event * feat: [PIPE-25660]: Support for pipeline hook event * feat: [PIPE-25660]: Support for pipeline hook event * feat: [PIPE-25660]: Support for pipeline hook event * feat: [PIPE-25660]: Support for pipeline hook event * feat: [PIPE-25660]: Support for pipeline hook event * feat: [PIPE-25660]: Support for pipeline hook event * feat: [PIPE-25660]: Support for pipeline hook event * feat: [PIPE-25660]: Support for pipeline hook event * feat: [PIPE-25660]: Support for pipeline hook event * feat: [PIPE-25660]: Support for pipeline hook event * feat: [PIPE-25660]: Support for pipeline hook event * feat: [PIPE-25660]: Support for pipeline hook event --- scm/const.go | 62 +++ .../webhooks/pipeline_hook_created.json | 175 ++++++++ .../pipeline_hook_created.json.golden | 39 ++ .../webhooks/pipeline_hook_update.json | 175 ++++++++ .../webhooks/pipeline_hook_update.json.golden | 39 ++ scm/driver/bitbucket/webhook.go | 149 +++++++ scm/driver/bitbucket/webhook_test.go | 14 + .../testdata/webhooks/pipeline_hook.json | 389 ++++++++++++++++++ .../webhooks/pipeline_hook.json.golden | 50 +++ scm/driver/github/webhook.go | 132 ++++++ scm/driver/github/webhook_test.go | 9 +- scm/driver/gitlab/repo.go | 3 + .../testdata/webhooks/pipeline_hook.json | 115 ++++++ .../webhooks/pipeline_hook.json.golden | 50 +++ scm/driver/gitlab/webhook.go | 192 ++++++++- scm/driver/gitlab/webhook_test.go | 6 + scm/git.go | 9 + scm/repo.go | 1 + scm/util.go | 17 + scm/webhook.go | 10 + 20 files changed, 1632 insertions(+), 4 deletions(-) create mode 100644 scm/driver/bitbucket/testdata/webhooks/pipeline_hook_created.json create mode 100644 scm/driver/bitbucket/testdata/webhooks/pipeline_hook_created.json.golden create mode 100644 scm/driver/bitbucket/testdata/webhooks/pipeline_hook_update.json create mode 100644 scm/driver/bitbucket/testdata/webhooks/pipeline_hook_update.json.golden create mode 100644 scm/driver/github/testdata/webhooks/pipeline_hook.json create mode 100644 scm/driver/github/testdata/webhooks/pipeline_hook.json.golden create mode 100644 scm/driver/gitlab/testdata/webhooks/pipeline_hook.json create mode 100644 scm/driver/gitlab/testdata/webhooks/pipeline_hook.json.golden diff --git a/scm/const.go b/scm/const.go index 73fa7a9e6..1a62d5e98 100644 --- a/scm/const.go +++ b/scm/const.go @@ -283,4 +283,66 @@ func (v Visibility) String() (s string) { } } +// Status defines an enum for execution status +type ExecutionStatus int + +const ( + StatusUnknown ExecutionStatus = iota + StatusPending + StatusRunning + StatusSuccess + StatusFailed + StatusCanceled +) + +// String returns the string representation of ExecutionStatus. +func (k ExecutionStatus) String() string { + switch k { + case StatusSuccess: + return "success" + case StatusPending: + return "pending" + case StatusRunning: + return "running" + case StatusFailed: + return "failed" + case StatusCanceled: + return "canceled" + case StatusUnknown: + return "Unknown" + default: + return "unsupported" + } +} + +// MarshalJSON returns the JSON-encoded Action. +func (k ExecutionStatus) MarshalJSON() ([]byte, error) { + return json.Marshal(k.String()) +} + +// UnmarshalJSON unmarshales the JSON-encoded ExecutionStatus. +func (k *ExecutionStatus) UnmarshalJSON(data []byte) error { + var s string + if err := json.Unmarshal(data, &s); err != nil { + return err + } + switch s { + case StatusSuccess.String(): + *k = StatusSuccess + case StatusPending.String(): + *k = StatusPending + case StatusPending.String(): + *k = StatusPending + case StatusRunning.String(): + *k = StatusRunning + case StatusFailed.String(): + *k = StatusFailed + case StatusCanceled.String(): + *k = StatusCanceled + default: + *k = StatusUnknown + } + return nil +} + const SearchTimeFormat = "2006-01-02T15:04:05Z" diff --git a/scm/driver/bitbucket/testdata/webhooks/pipeline_hook_created.json b/scm/driver/bitbucket/testdata/webhooks/pipeline_hook_created.json new file mode 100644 index 000000000..02c506c67 --- /dev/null +++ b/scm/driver/bitbucket/testdata/webhooks/pipeline_hook_created.json @@ -0,0 +1,175 @@ +{ + "repository": { + "type": "repository", + "full_name": "automationtestharness/testrepo", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/automationtestharness/testrepo" + }, + "html": { + "href": "https://bitbucket.org/automationtestharness/testrepo" + }, + "avatar": { + "href": "https://bytebucket.org/ravatar/%7B2b922c6d-3824-4e91-a7be-90c8b8392f84%7D?ts=default" + } + }, + "name": "testRepo", + "scm": "git", + "website": null, + "owner": { + "display_name": "Automationtestharness", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/workspaces/%7B612f7b18-b167-4bff-8ee9-d43570117ff1%7D" + }, + "avatar": { + "href": "https://bitbucket.org/account/automationtestharness/avatar/" + }, + "html": { + "href": "https://bitbucket.org/%7B612f7b18-b167-4bff-8ee9-d43570117ff1%7D/" + } + }, + "type": "team", + "uuid": "{612f7b18-b167-4bff-8ee9-d43570117ff1}", + "username": "automationtestharness" + }, + "workspace": { + "type": "workspace", + "uuid": "{612f7b18-b167-4bff-8ee9-d43570117ff1}", + "name": "Automationtestharness", + "slug": "automationtestharness", + "links": { + "avatar": { + "href": "https://bitbucket.org/workspaces/automationtestharness/avatar/?ts=1740994558" + }, + "html": { + "href": "https://bitbucket.org/automationtestharness/" + }, + "self": { + "href": "https://api.bitbucket.org/2.0/workspaces/automationtestharness" + } + } + }, + "is_private": true, + "project": { + "type": "project", + "key": "TEST", + "uuid": "{af6d7f47-6ce6-48b6-9beb-d5ad6b674ba0}", + "name": "test", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/workspaces/automationtestharness/projects/TEST" + }, + "html": { + "href": "https://bitbucket.org/automationtestharness/workspace/projects/TEST" + }, + "avatar": { + "href": "https://bitbucket.org/automationtestharness/workspace/projects/TEST/avatar/32?ts=1738907820" + } + } + }, + "uuid": "{2b922c6d-3824-4e91-a7be-90c8b8392f84}", + "parent": null + }, + "actor": { + "display_name": "Automationtestharness", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/workspaces/%7B612f7b18-b167-4bff-8ee9-d43570117ff1%7D" + }, + "avatar": { + "href": "https://bitbucket.org/account/automationtestharness/avatar/" + }, + "html": { + "href": "https://bitbucket.org/%7B612f7b18-b167-4bff-8ee9-d43570117ff1%7D/" + } + }, + "type": "team", + "uuid": "{612f7b18-b167-4bff-8ee9-d43570117ff1}", + "username": "automationtestharness" + }, + "commit_status": { + "key": "3343801", + "type": "build", + "state": "INPROGRESS", + "name": "Pipeline #4 for main", + "refname": "main", + "commit": { + "type": "commit", + "hash": "bdf6fac0519ffd1562461eb82e018ff62efffbc9", + "date": "2025-03-24T08:48:15+00:00", + "author": { + "type": "author", + "raw": "Shivam Negi ", + "user": { + "display_name": "Shivam Negi", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/users/%7Bce7d5dfc-83c9-4878-beaf-7b91610e104a%7D" + }, + "avatar": { + "href": "https://secure.gravatar.com/avatar/39b64ab2df0f61fcce00db05f94c600b?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FSN-2.png" + }, + "html": { + "href": "https://bitbucket.org/%7Bce7d5dfc-83c9-4878-beaf-7b91610e104a%7D/" + } + }, + "type": "user", + "uuid": "{ce7d5dfc-83c9-4878-beaf-7b91610e104a}", + "account_id": "601ba1bdb7bda90068ed5d1b", + "nickname": "Shivam Negi" + } + }, + "message": "Merged in Shivam-Negi/testyaml-edited-online-with-bitbucket-1742806076994 (pull request #13)\n\ntest.yaml edited online with Bitbucket\n", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/automationtestharness/testrepo/commit/bdf6fac0519ffd1562461eb82e018ff62efffbc9" + }, + "html": { + "href": "https://bitbucket.org/automationtestharness/testrepo/commits/bdf6fac0519ffd1562461eb82e018ff62efffbc9" + }, + "diff": { + "href": "https://api.bitbucket.org/2.0/repositories/automationtestharness/testrepo/diff/bdf6fac0519ffd1562461eb82e018ff62efffbc9" + }, + "approve": { + "href": "https://api.bitbucket.org/2.0/repositories/automationtestharness/testrepo/commit/bdf6fac0519ffd1562461eb82e018ff62efffbc9/approve" + }, + "comments": { + "href": "https://api.bitbucket.org/2.0/repositories/automationtestharness/testrepo/commit/bdf6fac0519ffd1562461eb82e018ff62efffbc9/comments" + }, + "statuses": { + "href": "https://api.bitbucket.org/2.0/repositories/automationtestharness/testrepo/commit/bdf6fac0519ffd1562461eb82e018ff62efffbc9/statuses" + } + } + }, + "url": "https://bitbucket.org/automationtestharness/testrepo/addon/pipelines/home#!/results/4", + "repository": { + "type": "repository", + "full_name": "automationtestharness/testrepo", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/automationtestharness/testrepo" + }, + "html": { + "href": "https://bitbucket.org/automationtestharness/testrepo" + }, + "avatar": { + "href": "https://bytebucket.org/ravatar/%7B2b922c6d-3824-4e91-a7be-90c8b8392f84%7D?ts=default" + } + }, + "name": "testRepo", + "uuid": "{2b922c6d-3824-4e91-a7be-90c8b8392f84}" + }, + "description": "", + "created_on": "2025-03-24T08:48:56.572438+00:00", + "updated_on": "2025-03-24T08:48:56.572450+00:00", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/automationtestharness/testrepo/commit/bdf6fac0519ffd1562461eb82e018ff62efffbc9/statuses/build/3343801" + }, + "commit": { + "href": "https://api.bitbucket.org/2.0/repositories/automationtestharness/testrepo/commit/bdf6fac0519ffd1562461eb82e018ff62efffbc9" + } + } + } + } \ No newline at end of file diff --git a/scm/driver/bitbucket/testdata/webhooks/pipeline_hook_created.json.golden b/scm/driver/bitbucket/testdata/webhooks/pipeline_hook_created.json.golden new file mode 100644 index 000000000..b0e6c2a38 --- /dev/null +++ b/scm/driver/bitbucket/testdata/webhooks/pipeline_hook_created.json.golden @@ -0,0 +1,39 @@ +{ + "Repo": { + "ID": "{2b922c6d-3824-4e91-a7be-90c8b8392f84}", + "Namespace": "automationtestharness", + "Name": "testrepo", + "Clone": "https://bitbucket.org/automationtestharness/testrepo", + "CloneSSH": "", + "Branch": "main", + "Private": true + }, + "Commit": { + "Sha": "bdf6fac0519ffd1562461eb82e018ff62efffbc9", + "Message": "Merged in Shivam-Negi/testyaml-edited-online-with-bitbucket-1742806076994 (pull request #13)\n\ntest.yaml edited online with Bitbucket\n", + "Author": { + "Name": "Shivam Negi", + "Email": "shivamnegi94@gmail.com", + "Avatar": "https://secure.gravatar.com/avatar/39b64ab2df0f61fcce00db05f94c600b?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FSN-2.png" + }, + "Committer": { + "Name": "Shivam Negi", + "Email": "shivamnegi94@gmail.com", + "Avatar": "https://secure.gravatar.com/avatar/39b64ab2df0f61fcce00db05f94c600b?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FSN-2.png" + }, + "Link": "https://bitbucket.org/automationtestharness/testrepo/commits/bdf6fac0519ffd1562461eb82e018ff62efffbc9" + }, + "Execution": { + "Number": 4, + "Status": "running", + "Created": "2025-03-24T08:48:56.572438+00:00", + "URL": "https://bitbucket.org/automationtestharness/testrepo/addon/pipelines/home#!/results/4" + }, + "Sender": { + "Login": "automationtestharness", + "Name": "Automationtestharness", + "Email": "", + "Avatar": "https://bitbucket.org/account/automationtestharness/avatar/", + "ID": "{612f7b18-b167-4bff-8ee9-d43570117ff1}" + } +} diff --git a/scm/driver/bitbucket/testdata/webhooks/pipeline_hook_update.json b/scm/driver/bitbucket/testdata/webhooks/pipeline_hook_update.json new file mode 100644 index 000000000..10655dd05 --- /dev/null +++ b/scm/driver/bitbucket/testdata/webhooks/pipeline_hook_update.json @@ -0,0 +1,175 @@ +{ + "repository": { + "type": "repository", + "full_name": "automationtestharness/testrepo", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/automationtestharness/testrepo" + }, + "html": { + "href": "https://bitbucket.org/automationtestharness/testrepo" + }, + "avatar": { + "href": "https://bytebucket.org/ravatar/%7B2b922c6d-3824-4e91-a7be-90c8b8392f84%7D?ts=default" + } + }, + "name": "testRepo", + "scm": "git", + "website": null, + "owner": { + "display_name": "Automationtestharness", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/workspaces/%7B612f7b18-b167-4bff-8ee9-d43570117ff1%7D" + }, + "avatar": { + "href": "https://bitbucket.org/account/automationtestharness/avatar/" + }, + "html": { + "href": "https://bitbucket.org/%7B612f7b18-b167-4bff-8ee9-d43570117ff1%7D/" + } + }, + "type": "team", + "uuid": "{612f7b18-b167-4bff-8ee9-d43570117ff1}", + "username": "automationtestharness" + }, + "workspace": { + "type": "workspace", + "uuid": "{612f7b18-b167-4bff-8ee9-d43570117ff1}", + "name": "Automationtestharness", + "slug": "automationtestharness", + "links": { + "avatar": { + "href": "https://bitbucket.org/workspaces/automationtestharness/avatar/?ts=1740994558" + }, + "html": { + "href": "https://bitbucket.org/automationtestharness/" + }, + "self": { + "href": "https://api.bitbucket.org/2.0/workspaces/automationtestharness" + } + } + }, + "is_private": true, + "project": { + "type": "project", + "key": "TEST", + "uuid": "{af6d7f47-6ce6-48b6-9beb-d5ad6b674ba0}", + "name": "test", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/workspaces/automationtestharness/projects/TEST" + }, + "html": { + "href": "https://bitbucket.org/automationtestharness/workspace/projects/TEST" + }, + "avatar": { + "href": "https://bitbucket.org/automationtestharness/workspace/projects/TEST/avatar/32?ts=1738907820" + } + } + }, + "uuid": "{2b922c6d-3824-4e91-a7be-90c8b8392f84}", + "parent": null + }, + "actor": { + "display_name": "Automationtestharness", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/workspaces/%7B612f7b18-b167-4bff-8ee9-d43570117ff1%7D" + }, + "avatar": { + "href": "https://bitbucket.org/account/automationtestharness/avatar/" + }, + "html": { + "href": "https://bitbucket.org/%7B612f7b18-b167-4bff-8ee9-d43570117ff1%7D/" + } + }, + "type": "team", + "uuid": "{612f7b18-b167-4bff-8ee9-d43570117ff1}", + "username": "automationtestharness" + }, + "commit_status": { + "key": "3343801", + "type": "build", + "state": "SUCCESSFUL", + "name": "Pipeline #4 for main", + "refname": "main", + "commit": { + "type": "commit", + "hash": "bdf6fac0519ffd1562461eb82e018ff62efffbc9", + "date": "2025-03-24T08:48:15+00:00", + "author": { + "type": "author", + "raw": "Shivam Negi ", + "user": { + "display_name": "Shivam Negi", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/users/%7Bce7d5dfc-83c9-4878-beaf-7b91610e104a%7D" + }, + "avatar": { + "href": "https://secure.gravatar.com/avatar/39b64ab2df0f61fcce00db05f94c600b?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FSN-2.png" + }, + "html": { + "href": "https://bitbucket.org/%7Bce7d5dfc-83c9-4878-beaf-7b91610e104a%7D/" + } + }, + "type": "user", + "uuid": "{ce7d5dfc-83c9-4878-beaf-7b91610e104a}", + "account_id": "601ba1bdb7bda90068ed5d1b", + "nickname": "Shivam Negi" + } + }, + "message": "Merged in Shivam-Negi/testyaml-edited-online-with-bitbucket-1742806076994 (pull request #13)\n\ntest.yaml edited online with Bitbucket\n", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/automationtestharness/testrepo/commit/bdf6fac0519ffd1562461eb82e018ff62efffbc9" + }, + "html": { + "href": "https://bitbucket.org/automationtestharness/testrepo/commits/bdf6fac0519ffd1562461eb82e018ff62efffbc9" + }, + "diff": { + "href": "https://api.bitbucket.org/2.0/repositories/automationtestharness/testrepo/diff/bdf6fac0519ffd1562461eb82e018ff62efffbc9" + }, + "approve": { + "href": "https://api.bitbucket.org/2.0/repositories/automationtestharness/testrepo/commit/bdf6fac0519ffd1562461eb82e018ff62efffbc9/approve" + }, + "comments": { + "href": "https://api.bitbucket.org/2.0/repositories/automationtestharness/testrepo/commit/bdf6fac0519ffd1562461eb82e018ff62efffbc9/comments" + }, + "statuses": { + "href": "https://api.bitbucket.org/2.0/repositories/automationtestharness/testrepo/commit/bdf6fac0519ffd1562461eb82e018ff62efffbc9/statuses" + } + } + }, + "url": "https://bitbucket.org/automationtestharness/testrepo/addon/pipelines/home#!/results/4", + "repository": { + "type": "repository", + "full_name": "automationtestharness/testrepo", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/automationtestharness/testrepo" + }, + "html": { + "href": "https://bitbucket.org/automationtestharness/testrepo" + }, + "avatar": { + "href": "https://bytebucket.org/ravatar/%7B2b922c6d-3824-4e91-a7be-90c8b8392f84%7D?ts=default" + } + }, + "name": "testRepo", + "uuid": "{2b922c6d-3824-4e91-a7be-90c8b8392f84}" + }, + "description": "", + "created_on": "2025-03-24T08:48:56.572438+00:00", + "updated_on": "2025-03-24T08:49:42.838984+00:00", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/automationtestharness/testrepo/commit/bdf6fac0519ffd1562461eb82e018ff62efffbc9/statuses/build/3343801" + }, + "commit": { + "href": "https://api.bitbucket.org/2.0/repositories/automationtestharness/testrepo/commit/bdf6fac0519ffd1562461eb82e018ff62efffbc9" + } + } + } + } \ No newline at end of file diff --git a/scm/driver/bitbucket/testdata/webhooks/pipeline_hook_update.json.golden b/scm/driver/bitbucket/testdata/webhooks/pipeline_hook_update.json.golden new file mode 100644 index 000000000..1b0b7623f --- /dev/null +++ b/scm/driver/bitbucket/testdata/webhooks/pipeline_hook_update.json.golden @@ -0,0 +1,39 @@ +{ + "Repo": { + "ID": "{2b922c6d-3824-4e91-a7be-90c8b8392f84}", + "Namespace": "automationtestharness", + "Name": "testrepo", + "Clone": "https://bitbucket.org/automationtestharness/testrepo", + "CloneSSH": "", + "Branch": "main", + "Private": true + }, + "Commit": { + "Sha": "bdf6fac0519ffd1562461eb82e018ff62efffbc9", + "Message": "Merged in Shivam-Negi/testyaml-edited-online-with-bitbucket-1742806076994 (pull request #13)\n\ntest.yaml edited online with Bitbucket\n", + "Author": { + "Name": "Shivam Negi", + "Email": "shivamnegi94@gmail.com", + "Avatar": "https://secure.gravatar.com/avatar/39b64ab2df0f61fcce00db05f94c600b?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FSN-2.png" + }, + "Committer": { + "Name": "Shivam Negi", + "Email": "shivamnegi94@gmail.com", + "Avatar": "https://secure.gravatar.com/avatar/39b64ab2df0f61fcce00db05f94c600b?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FSN-2.png" + }, + "Link": "https://bitbucket.org/automationtestharness/testrepo/commits/bdf6fac0519ffd1562461eb82e018ff62efffbc9" + }, + "Execution": { + "Number": 4, + "Status": "success", + "Created": "2025-03-24T08:48:56.572438+00:00", + "URL": "https://bitbucket.org/automationtestharness/testrepo/addon/pipelines/home#!/results/4" + }, + "Sender": { + "Login": "automationtestharness", + "Name": "Automationtestharness", + "Email": "", + "Avatar": "https://bitbucket.org/account/automationtestharness/avatar/", + "ID": "{612f7b18-b167-4bff-8ee9-d43570117ff1}" + } +} diff --git a/scm/driver/bitbucket/webhook.go b/scm/driver/bitbucket/webhook.go index d254bba54..3b1836220 100644 --- a/scm/driver/bitbucket/webhook.go +++ b/scm/driver/bitbucket/webhook.go @@ -11,6 +11,8 @@ import ( "io" "io/ioutil" "net/http" + "regexp" + "strconv" "time" "github.com/drone/go-scm/scm" @@ -70,6 +72,8 @@ func (s *webhookService) Parse(req *http.Request, fn scm.SecretFunc) (scm.Webhoo if hook != nil { hook.(*scm.IssueCommentHook).Action = scm.ActionDelete } + case "repo:commit_status_updated", "repo:commit_status_created": + hook, err = s.parsePipelineHook(data) } if err != nil { return nil, err @@ -138,6 +142,15 @@ func (s *webhookService) parsePullRequestHook(data []byte) (*scm.PullRequestHook } } +func (s *webhookService) parsePipelineHook(data []byte) (*scm.PipelineHook, error) { + dst := new(pipelineHook) + err := json.Unmarshal(data, dst) + if err != nil { + return nil, err + } + return convertBitbucketHook(dst), err +} + // // native data structures // @@ -598,6 +611,84 @@ type ( Repository prCommentHookRepo `json:"repository"` Actor prCommentHookUser `json:"actor"` } + + pipelineHook struct { + Repository webhookRepository `json:"repository"` + Actor actor `json:"actor"` + CommitStatus struct { + Key string `json:"key"` + Type string `json:"type"` + State string `json:"state"` + Name string `json:"name"` + RefName string `json:"refname"` + Commit struct { + Type string `json:"type"` + Hash string `json:"hash"` + Date time.Time `json:"date"` + Author author `json:"author"` + Message string `json:"message"` + Links struct { + Self href `json:"self"` + HTML href `json:"html"` + Avatar href `json:"avatar"` + } `json:"links"` + } `json:"commit"` + URL string `json:"url"` + Repository info `json:"repository"` + Description string `json:"description"` + CreatedOn time.Time `json:"created_on"` + UpdatedOn time.Time `json:"updated_on"` + Links struct { + Self href `json:"self"` + Commit href `json:"commit"` + } `json:"links"` + } `json:"commit_status"` + } + + href struct { + Href string `json:"href"` + } + + actor struct { + DisplayName string `json:"display_name"` + Links struct { + Self href `json:"self"` + HTML href `json:"html"` + Avatar href `json:"avatar"` + } `json:"links"` + Type string `json:"type"` + UUID string `json:"uuid"` + Username string `json:"username"` + } + + author struct { + Type string `json:"type"` + Raw string `json:"raw"` + User struct { + DisplayName string `json:"display_name"` + Links struct { + Self href `json:"self"` + HTML href `json:"html"` + Avatar href `json:"avatar"` + } `json:"links"` + Type string `json:"type"` + UUID string `json:"uuid"` + AccountID string `json:"account_id"` + Nickname string `json:"nickname"` + } `json:"user"` + } + + info struct { + Type string `json:"type"` + FullName string `json:"full_name"` + Links struct { + Self href `json:"self"` + HTML href `json:"html"` + Avatar href `json:"avatar"` + } `json:"links"` + Name string `json:"name"` + UUID string `json:"uuid"` + } ) // @@ -902,3 +993,61 @@ func convertPrCommentHook(src *prCommentHook) *scm.IssueCommentHook { } return &dst } + +func convertBitbucketHook(src *pipelineHook) *scm.PipelineHook { + if src.CommitStatus.Type == "" || src.CommitStatus.Type != "build" { + return nil + } + namespace, name := scm.Split(src.Repository.FullName) + + return &scm.PipelineHook{ + Repo: scm.Repository{ + ID: src.Repository.UUID, + Namespace: namespace, + Name: name, + Clone: src.Repository.Links.HTML.Href, // Assuming HTML link as Clone URL + Branch: src.CommitStatus.RefName, + Private: src.Repository.IsPrivate, + }, + Commit: scm.Commit{ + Sha: src.CommitStatus.Commit.Hash, + Message: src.CommitStatus.Commit.Message, + Author: scm.Signature{ + Name: src.CommitStatus.Commit.Author.User.DisplayName, + Email: extractEmail(src.CommitStatus.Commit.Author.Raw), + Avatar: src.CommitStatus.Commit.Author.User.Links.Avatar.Href, + }, + Committer: scm.Signature{ + Name: src.CommitStatus.Commit.Author.User.DisplayName, + Email: extractEmail(src.CommitStatus.Commit.Author.Raw), + Avatar: src.CommitStatus.Commit.Author.User.Links.Avatar.Href, + }, + Link: src.CommitStatus.Commit.Links.HTML.Href, + }, + Execution: scm.Execution{ + Number: extractExecutionId(src.CommitStatus.URL), + Status: scm.ConvertExecutionStatus(src.CommitStatus.State), + Created: src.CommitStatus.CreatedOn, + URL: src.CommitStatus.URL, + }, + Sender: scm.User{ + Login: src.Actor.Username, + Name: src.Actor.DisplayName, + Avatar: src.Actor.Links.Avatar.Href, + ID: src.Actor.UUID, + }, + PullRequest: scm.PullRequest{}, + } +} + +func extractExecutionId(url string) int { + re := regexp.MustCompile(`/results/(\d+)`) + match := re.FindStringSubmatch(url) + if len(match) > 1 { + id, err := strconv.Atoi(match[1]) + if err == nil { + return id + } + } + return -1 +} diff --git a/scm/driver/bitbucket/webhook_test.go b/scm/driver/bitbucket/webhook_test.go index e72e096ff..71f2b7e89 100644 --- a/scm/driver/bitbucket/webhook_test.go +++ b/scm/driver/bitbucket/webhook_test.go @@ -146,6 +146,20 @@ func TestWebhooks(t *testing.T) { after: "testdata/webhooks/pr_comment_deleted.json.golden", obj: new(scm.IssueCommentHook), }, + { + sig: "71295b197fa25f4356d2fb9965df3f2379d903d7", + event: "repo:commit_status_created", + before: "testdata/webhooks/pipeline_hook_created.json", + after: "testdata/webhooks/pipeline_hook_created.json.golden", + obj: new(scm.PipelineHook), + }, + { + sig: "71295b197fa25f4356d2fb9965df3f2379d903d7", + event: "repo:commit_status_updated", + before: "testdata/webhooks/pipeline_hook_update.json", + after: "testdata/webhooks/pipeline_hook_update.json.golden", + obj: new(scm.PipelineHook), + }, } for _, test := range tests { diff --git a/scm/driver/github/testdata/webhooks/pipeline_hook.json b/scm/driver/github/testdata/webhooks/pipeline_hook.json new file mode 100644 index 000000000..3a7fd0c92 --- /dev/null +++ b/scm/driver/github/testdata/webhooks/pipeline_hook.json @@ -0,0 +1,389 @@ +{ + "action": "in_progress", + "workflow_run": { + "id": 14030131450, + "name": "CI", + "node_id": "WFR_kwLOE_pLVc8AAAADRELQ-g", + "head_branch": "shivamnegi94-patch-27", + "head_sha": "f4229db4b70a8dadeb687f5ccce5fd327c04461a", + "path": ".github/workflows/blank.yml", + "display_title": "Update NewSre_v1.yaml", + "run_number": 2, + "event": "pull_request", + "status": "completed", + "conclusion": "success", + "workflow_id": 151617408, + "check_suite_id": 36111489428, + "check_suite_node_id": "CS_kwDOE_pLVc8AAAAIaGmZlA", + "url": "https://api.github.com/repos/shivamnegi94/testrepo/actions/runs/14030131450", + "html_url": "https://github.com/shivamnegi94/testrepo/actions/runs/14030131450", + "pull_requests": [ + { + "url": "https://api.github.com/repos/shivamnegi94/testrepo/pulls/164", + "id": 2412967773, + "number": 164, + "head": { + "ref": "shivamnegi94-patch-27", + "sha": "f4229db4b70a8dadeb687f5ccce5fd327c04461a", + "repo": { + "id": 335170389, + "url": "https://api.github.com/repos/shivamnegi94/testrepo", + "name": "testrepo" + } + }, + "base": { + "ref": "main", + "sha": "ded75dda298abfbf9f1900092e92b43f23bdd6d2", + "repo": { + "id": 335170389, + "url": "https://api.github.com/repos/shivamnegi94/testrepo", + "name": "testrepo" + } + } + } + ], + "created_at": "2025-03-24T08:03:42Z", + "updated_at": "2025-03-24T08:03:46Z", + "actor": { + "login": "shivamnegi94", + "id": 58415634, + "node_id": "MDQ6VXNlcjU4NDE1NjM0", + "avatar_url": "https://avatars.githubusercontent.com/u/58415634?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/shivamnegi94", + "html_url": "https://github.com/shivamnegi94", + "followers_url": "https://api.github.com/users/shivamnegi94/followers", + "following_url": "https://api.github.com/users/shivamnegi94/following{/other_user}", + "gists_url": "https://api.github.com/users/shivamnegi94/gists{/gist_id}", + "starred_url": "https://api.github.com/users/shivamnegi94/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/shivamnegi94/subscriptions", + "organizations_url": "https://api.github.com/users/shivamnegi94/orgs", + "repos_url": "https://api.github.com/users/shivamnegi94/repos", + "events_url": "https://api.github.com/users/shivamnegi94/events{/privacy}", + "received_events_url": "https://api.github.com/users/shivamnegi94/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "run_attempt": 1, + "referenced_workflows": [ + + ], + "run_started_at": "2025-03-24T08:03:42Z", + "triggering_actor": { + "login": "shivamnegi94", + "id": 58415634, + "node_id": "MDQ6VXNlcjU4NDE1NjM0", + "avatar_url": "https://avatars.githubusercontent.com/u/58415634?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/shivamnegi94", + "html_url": "https://github.com/shivamnegi94", + "followers_url": "https://api.github.com/users/shivamnegi94/followers", + "following_url": "https://api.github.com/users/shivamnegi94/following{/other_user}", + "gists_url": "https://api.github.com/users/shivamnegi94/gists{/gist_id}", + "starred_url": "https://api.github.com/users/shivamnegi94/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/shivamnegi94/subscriptions", + "organizations_url": "https://api.github.com/users/shivamnegi94/orgs", + "repos_url": "https://api.github.com/users/shivamnegi94/repos", + "events_url": "https://api.github.com/users/shivamnegi94/events{/privacy}", + "received_events_url": "https://api.github.com/users/shivamnegi94/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "jobs_url": "https://api.github.com/repos/shivamnegi94/testrepo/actions/runs/14030131450/jobs", + "logs_url": "https://api.github.com/repos/shivamnegi94/testrepo/actions/runs/14030131450/logs", + "check_suite_url": "https://api.github.com/repos/shivamnegi94/testrepo/check-suites/36111489428", + "artifacts_url": "https://api.github.com/repos/shivamnegi94/testrepo/actions/runs/14030131450/artifacts", + "cancel_url": "https://api.github.com/repos/shivamnegi94/testrepo/actions/runs/14030131450/cancel", + "rerun_url": "https://api.github.com/repos/shivamnegi94/testrepo/actions/runs/14030131450/rerun", + "previous_attempt_url": null, + "workflow_url": "https://api.github.com/repos/shivamnegi94/testrepo/actions/workflows/151617408", + "head_commit": { + "id": "f4229db4b70a8dadeb687f5ccce5fd327c04461a", + "tree_id": "36698bb567243f3d104f398e3b6e1a339570d3dc", + "message": "Update NewSre_v1.yaml", + "timestamp": "2025-03-24T08:03:33Z", + "author": { + "name": "Shivam Negi", + "email": "shivam.negi@harness.io" + }, + "committer": { + "name": "GitHub", + "email": "noreply@github.com" + } + }, + "repository": { + "id": 335170389, + "node_id": "MDEwOlJlcG9zaXRvcnkzMzUxNzAzODk=", + "name": "testrepo", + "full_name": "shivamnegi94/testrepo", + "private": false, + "owner": { + "login": "shivamnegi94", + "id": 58415634, + "node_id": "MDQ6VXNlcjU4NDE1NjM0", + "avatar_url": "https://avatars.githubusercontent.com/u/58415634?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/shivamnegi94", + "html_url": "https://github.com/shivamnegi94", + "followers_url": "https://api.github.com/users/shivamnegi94/followers", + "following_url": "https://api.github.com/users/shivamnegi94/following{/other_user}", + "gists_url": "https://api.github.com/users/shivamnegi94/gists{/gist_id}", + "starred_url": "https://api.github.com/users/shivamnegi94/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/shivamnegi94/subscriptions", + "organizations_url": "https://api.github.com/users/shivamnegi94/orgs", + "repos_url": "https://api.github.com/users/shivamnegi94/repos", + "events_url": "https://api.github.com/users/shivamnegi94/events{/privacy}", + "received_events_url": "https://api.github.com/users/shivamnegi94/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "html_url": "https://github.com/shivamnegi94/testrepo", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/shivamnegi94/testrepo", + "forks_url": "https://api.github.com/repos/shivamnegi94/testrepo/forks", + "keys_url": "https://api.github.com/repos/shivamnegi94/testrepo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/shivamnegi94/testrepo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/shivamnegi94/testrepo/teams", + "hooks_url": "https://api.github.com/repos/shivamnegi94/testrepo/hooks", + "issue_events_url": "https://api.github.com/repos/shivamnegi94/testrepo/issues/events{/number}", + "events_url": "https://api.github.com/repos/shivamnegi94/testrepo/events", + "assignees_url": "https://api.github.com/repos/shivamnegi94/testrepo/assignees{/user}", + "branches_url": "https://api.github.com/repos/shivamnegi94/testrepo/branches{/branch}", + "tags_url": "https://api.github.com/repos/shivamnegi94/testrepo/tags", + "blobs_url": "https://api.github.com/repos/shivamnegi94/testrepo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/shivamnegi94/testrepo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/shivamnegi94/testrepo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/shivamnegi94/testrepo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/shivamnegi94/testrepo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/shivamnegi94/testrepo/languages", + "stargazers_url": "https://api.github.com/repos/shivamnegi94/testrepo/stargazers", + "contributors_url": "https://api.github.com/repos/shivamnegi94/testrepo/contributors", + "subscribers_url": "https://api.github.com/repos/shivamnegi94/testrepo/subscribers", + "subscription_url": "https://api.github.com/repos/shivamnegi94/testrepo/subscription", + "commits_url": "https://api.github.com/repos/shivamnegi94/testrepo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/shivamnegi94/testrepo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/shivamnegi94/testrepo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/shivamnegi94/testrepo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/shivamnegi94/testrepo/contents/{+path}", + "compare_url": "https://api.github.com/repos/shivamnegi94/testrepo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/shivamnegi94/testrepo/merges", + "archive_url": "https://api.github.com/repos/shivamnegi94/testrepo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/shivamnegi94/testrepo/downloads", + "issues_url": "https://api.github.com/repos/shivamnegi94/testrepo/issues{/number}", + "pulls_url": "https://api.github.com/repos/shivamnegi94/testrepo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/shivamnegi94/testrepo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/shivamnegi94/testrepo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/shivamnegi94/testrepo/labels{/name}", + "releases_url": "https://api.github.com/repos/shivamnegi94/testrepo/releases{/id}", + "deployments_url": "https://api.github.com/repos/shivamnegi94/testrepo/deployments" + }, + "head_repository": { + "id": 335170389, + "node_id": "MDEwOlJlcG9zaXRvcnkzMzUxNzAzODk=", + "name": "testrepo", + "full_name": "shivamnegi94/testrepo", + "private": false, + "owner": { + "login": "shivamnegi94", + "id": 58415634, + "node_id": "MDQ6VXNlcjU4NDE1NjM0", + "avatar_url": "https://avatars.githubusercontent.com/u/58415634?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/shivamnegi94", + "html_url": "https://github.com/shivamnegi94", + "followers_url": "https://api.github.com/users/shivamnegi94/followers", + "following_url": "https://api.github.com/users/shivamnegi94/following{/other_user}", + "gists_url": "https://api.github.com/users/shivamnegi94/gists{/gist_id}", + "starred_url": "https://api.github.com/users/shivamnegi94/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/shivamnegi94/subscriptions", + "organizations_url": "https://api.github.com/users/shivamnegi94/orgs", + "repos_url": "https://api.github.com/users/shivamnegi94/repos", + "events_url": "https://api.github.com/users/shivamnegi94/events{/privacy}", + "received_events_url": "https://api.github.com/users/shivamnegi94/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "html_url": "https://github.com/shivamnegi94/testrepo", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/shivamnegi94/testrepo", + "forks_url": "https://api.github.com/repos/shivamnegi94/testrepo/forks", + "keys_url": "https://api.github.com/repos/shivamnegi94/testrepo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/shivamnegi94/testrepo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/shivamnegi94/testrepo/teams", + "hooks_url": "https://api.github.com/repos/shivamnegi94/testrepo/hooks", + "issue_events_url": "https://api.github.com/repos/shivamnegi94/testrepo/issues/events{/number}", + "events_url": "https://api.github.com/repos/shivamnegi94/testrepo/events", + "assignees_url": "https://api.github.com/repos/shivamnegi94/testrepo/assignees{/user}", + "branches_url": "https://api.github.com/repos/shivamnegi94/testrepo/branches{/branch}", + "tags_url": "https://api.github.com/repos/shivamnegi94/testrepo/tags", + "blobs_url": "https://api.github.com/repos/shivamnegi94/testrepo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/shivamnegi94/testrepo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/shivamnegi94/testrepo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/shivamnegi94/testrepo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/shivamnegi94/testrepo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/shivamnegi94/testrepo/languages", + "stargazers_url": "https://api.github.com/repos/shivamnegi94/testrepo/stargazers", + "contributors_url": "https://api.github.com/repos/shivamnegi94/testrepo/contributors", + "subscribers_url": "https://api.github.com/repos/shivamnegi94/testrepo/subscribers", + "subscription_url": "https://api.github.com/repos/shivamnegi94/testrepo/subscription", + "commits_url": "https://api.github.com/repos/shivamnegi94/testrepo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/shivamnegi94/testrepo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/shivamnegi94/testrepo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/shivamnegi94/testrepo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/shivamnegi94/testrepo/contents/{+path}", + "compare_url": "https://api.github.com/repos/shivamnegi94/testrepo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/shivamnegi94/testrepo/merges", + "archive_url": "https://api.github.com/repos/shivamnegi94/testrepo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/shivamnegi94/testrepo/downloads", + "issues_url": "https://api.github.com/repos/shivamnegi94/testrepo/issues{/number}", + "pulls_url": "https://api.github.com/repos/shivamnegi94/testrepo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/shivamnegi94/testrepo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/shivamnegi94/testrepo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/shivamnegi94/testrepo/labels{/name}", + "releases_url": "https://api.github.com/repos/shivamnegi94/testrepo/releases{/id}", + "deployments_url": "https://api.github.com/repos/shivamnegi94/testrepo/deployments" + } + }, + "workflow": { + "id": 151617408, + "node_id": "W_kwDOE_pLVc4JCX-A", + "name": "CI", + "path": ".github/workflows/blank.yml", + "state": "active", + "created_at": "2025-03-24T08:01:34.000Z", + "updated_at": "2025-03-24T08:01:34.000Z", + "url": "https://api.github.com/repos/shivamnegi94/testrepo/actions/workflows/151617408", + "html_url": "https://github.com/shivamnegi94/testrepo/blob/main/.github/workflows/blank.yml", + "badge_url": "https://github.com/shivamnegi94/testrepo/workflows/CI/badge.svg" + }, + "repository": { + "id": 335170389, + "node_id": "MDEwOlJlcG9zaXRvcnkzMzUxNzAzODk=", + "name": "testrepo", + "full_name": "shivamnegi94/testrepo", + "private": false, + "owner": { + "login": "shivamnegi94", + "id": 58415634, + "node_id": "MDQ6VXNlcjU4NDE1NjM0", + "avatar_url": "https://avatars.githubusercontent.com/u/58415634?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/shivamnegi94", + "html_url": "https://github.com/shivamnegi94", + "followers_url": "https://api.github.com/users/shivamnegi94/followers", + "following_url": "https://api.github.com/users/shivamnegi94/following{/other_user}", + "gists_url": "https://api.github.com/users/shivamnegi94/gists{/gist_id}", + "starred_url": "https://api.github.com/users/shivamnegi94/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/shivamnegi94/subscriptions", + "organizations_url": "https://api.github.com/users/shivamnegi94/orgs", + "repos_url": "https://api.github.com/users/shivamnegi94/repos", + "events_url": "https://api.github.com/users/shivamnegi94/events{/privacy}", + "received_events_url": "https://api.github.com/users/shivamnegi94/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "html_url": "https://github.com/shivamnegi94/testrepo", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/shivamnegi94/testrepo", + "forks_url": "https://api.github.com/repos/shivamnegi94/testrepo/forks", + "keys_url": "https://api.github.com/repos/shivamnegi94/testrepo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/shivamnegi94/testrepo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/shivamnegi94/testrepo/teams", + "hooks_url": "https://api.github.com/repos/shivamnegi94/testrepo/hooks", + "issue_events_url": "https://api.github.com/repos/shivamnegi94/testrepo/issues/events{/number}", + "events_url": "https://api.github.com/repos/shivamnegi94/testrepo/events", + "assignees_url": "https://api.github.com/repos/shivamnegi94/testrepo/assignees{/user}", + "branches_url": "https://api.github.com/repos/shivamnegi94/testrepo/branches{/branch}", + "tags_url": "https://api.github.com/repos/shivamnegi94/testrepo/tags", + "blobs_url": "https://api.github.com/repos/shivamnegi94/testrepo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/shivamnegi94/testrepo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/shivamnegi94/testrepo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/shivamnegi94/testrepo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/shivamnegi94/testrepo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/shivamnegi94/testrepo/languages", + "stargazers_url": "https://api.github.com/repos/shivamnegi94/testrepo/stargazers", + "contributors_url": "https://api.github.com/repos/shivamnegi94/testrepo/contributors", + "subscribers_url": "https://api.github.com/repos/shivamnegi94/testrepo/subscribers", + "subscription_url": "https://api.github.com/repos/shivamnegi94/testrepo/subscription", + "commits_url": "https://api.github.com/repos/shivamnegi94/testrepo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/shivamnegi94/testrepo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/shivamnegi94/testrepo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/shivamnegi94/testrepo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/shivamnegi94/testrepo/contents/{+path}", + "compare_url": "https://api.github.com/repos/shivamnegi94/testrepo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/shivamnegi94/testrepo/merges", + "archive_url": "https://api.github.com/repos/shivamnegi94/testrepo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/shivamnegi94/testrepo/downloads", + "issues_url": "https://api.github.com/repos/shivamnegi94/testrepo/issues{/number}", + "pulls_url": "https://api.github.com/repos/shivamnegi94/testrepo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/shivamnegi94/testrepo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/shivamnegi94/testrepo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/shivamnegi94/testrepo/labels{/name}", + "releases_url": "https://api.github.com/repos/shivamnegi94/testrepo/releases{/id}", + "deployments_url": "https://api.github.com/repos/shivamnegi94/testrepo/deployments", + "created_at": "2021-02-02T04:41:22Z", + "updated_at": "2025-03-24T08:01:37Z", + "pushed_at": "2025-03-24T08:03:33Z", + "git_url": "git://github.com/shivamnegi94/testrepo.git", + "ssh_url": "git@github.com:shivamnegi94/testrepo.git", + "clone_url": "https://github.com/shivamnegi94/testrepo.git", + "svn_url": "https://github.com/shivamnegi94/testrepo", + "homepage": null, + "size": 209, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "has_discussions": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 56, + "license": null, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [ + + ], + "visibility": "public", + "forks": 0, + "open_issues": 56, + "watchers": 0, + "default_branch": "main" + }, + "sender": { + "login": "shivamnegi94", + "id": 58415634, + "node_id": "MDQ6VXNlcjU4NDE1NjM0", + "avatar_url": "https://avatars.githubusercontent.com/u/58415634?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/shivamnegi94", + "html_url": "https://github.com/shivamnegi94", + "followers_url": "https://api.github.com/users/shivamnegi94/followers", + "following_url": "https://api.github.com/users/shivamnegi94/following{/other_user}", + "gists_url": "https://api.github.com/users/shivamnegi94/gists{/gist_id}", + "starred_url": "https://api.github.com/users/shivamnegi94/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/shivamnegi94/subscriptions", + "organizations_url": "https://api.github.com/users/shivamnegi94/orgs", + "repos_url": "https://api.github.com/users/shivamnegi94/repos", + "events_url": "https://api.github.com/users/shivamnegi94/events{/privacy}", + "received_events_url": "https://api.github.com/users/shivamnegi94/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + } +} \ No newline at end of file diff --git a/scm/driver/github/testdata/webhooks/pipeline_hook.json.golden b/scm/driver/github/testdata/webhooks/pipeline_hook.json.golden new file mode 100644 index 000000000..b56869de0 --- /dev/null +++ b/scm/driver/github/testdata/webhooks/pipeline_hook.json.golden @@ -0,0 +1,50 @@ +{ + "Repo": { + "ID": "335170389", + "Namespace": "shivamnegi94", + "Name": "testrepo", + "Clone": "https://github.com/shivamnegi94/testrepo.git", + "CloneSSH": "git@github.com:shivamnegi94/testrepo.git", + "Link": "https://github.com/shivamnegi94/testrepo", + "Branch": "main", + "Created": "2021-02-02T04:41:22Z", + "Updated": "2025-03-24T08:01:37Z", + "Private": false, + "Visibility": 1, + "Perm": {} + }, + "Commit": { + "Sha": "f4229db4b70a8dadeb687f5ccce5fd327c04461a", + "Message": "Update NewSre_v1.yaml", + "Author": { + "Name": "Shivam Negi", + "Email": "shivam.negi@harness.io" + }, + "Committer": { + "Name": "GitHub", + "Email": "noreply@github.com" + } + }, + "Execution": { + "Number": 2, + "Status": "success", + "Created": "2025-03-24T08:03:42Z", + "URL": "https://api.github.com/repos/shivamnegi94/testrepo/actions/runs/14030131450" + }, + "Sender": { + "Login": "shivamnegi94", + "Avatar": "https://avatars.githubusercontent.com/u/58415634?v=4" + }, + "PullRequest": { + "Number": 164, + "Sha": "f4229db4b70a8dadeb687f5ccce5fd327c04461a", + "Ref": "shivamnegi94-patch-27", + "Source": "shivamnegi94-patch-27", + "Target": "main", + "Link": "https://api.github.com/repos/shivamnegi94/testrepo/pulls/164", + "Created": "2025-03-24T08:03:42Z", + "Draft": false, + "Closed": false, + "Merged": false + } +} diff --git a/scm/driver/github/webhook.go b/scm/driver/github/webhook.go index 2fbdae938..8f0b3571a 100644 --- a/scm/driver/github/webhook.go +++ b/scm/driver/github/webhook.go @@ -48,6 +48,8 @@ func (s *webhookService) Parse(req *http.Request, fn scm.SecretFunc) (scm.Webhoo hook, err = s.parseIssueCommentHook(data) case "release": hook, err = s.parseReleaseHook(data) + case "workflow_run": + hook, err = s.parsePipelineHook(data) default: return nil, scm.ErrUnknownEvent } @@ -182,6 +184,62 @@ func (s *webhookService) parsePullRequestHook(data []byte) (scm.Webhook, error) return dst, nil } +func (s *webhookService) parsePipelineHook(data []byte) (scm.Webhook, error) { + src := new(pipelineHook) + err := json.Unmarshal(data, src) + if err != nil { + return nil, err + } + dst, err := convertPipelineHook(src), nil + return dst, nil +} + +func convertPipelineHook(src *pipelineHook) *scm.PipelineHook { + pr := scm.PullRequest{} + if len(src.WorkflowRun.PullRequests) > 0 { + pr = scm.PullRequest{ + Number: src.WorkflowRun.PullRequests[0].Number, + Sha: src.WorkflowRun.PullRequests[0].Head.SHA, + Ref: src.WorkflowRun.PullRequests[0].Head.Ref, + Source: src.WorkflowRun.PullRequests[0].Head.Ref, + Target: src.WorkflowRun.PullRequests[0].Base.Ref, + Link: src.WorkflowRun.PullRequests[0].URL, + Created: src.WorkflowRun.CreatedAt, + } + } + + var execution_status string + if src.WorkflowRun.Status == "completed" { + execution_status = src.WorkflowRun.Conclusion.String + } else { + execution_status = src.WorkflowRun.Status + } + + return &scm.PipelineHook{ + Repo: *convertRepository(&src.Repository), + Commit: scm.Commit{ + Sha: src.WorkflowRun.HeadCommit.ID, + Message: src.WorkflowRun.HeadCommit.Message, + Author: scm.Signature{ + Name: src.WorkflowRun.HeadCommit.Author.Name, + Email: src.WorkflowRun.HeadCommit.Author.Email, + }, + Committer: scm.Signature{ + Name: src.WorkflowRun.HeadCommit.Committer.Name, + Email: src.WorkflowRun.HeadCommit.Committer.Email, + }, + }, + Execution: scm.Execution{ + Number: int(src.WorkflowRun.RunNumber), + Status: scm.ConvertExecutionStatus(execution_status), + Created: src.WorkflowRun.CreatedAt, + URL: src.WorkflowRun.URL, + }, + Sender: *convertUser(&src.Sender), + PullRequest: pr, + } +} + func (s *webhookService) parseReleaseHook(data []byte) (scm.Webhook, error) { src := new(releaseHook) err := json.Unmarshal(data, src) @@ -352,6 +410,80 @@ type ( Repository repository `json:"repository"` Sender user `json:"sender"` } + + pipelineHook struct { + Action string `json:"action"` + Sender user + WorkflowRun struct { + ID int64 `json:"id"` + Name string `json:"name"` + NodeID string `json:"node_id"` + HeadBranch string `json:"head_branch"` + HeadSHA string `json:"head_sha"` + Path string `json:"path"` + DisplayTitle string `json:"display_title"` + RunNumber int `json:"run_number"` + Event string `json:"event"` + Status string `json:"status"` + Conclusion null.String `json:"conclusion"` + WorkflowID int64 `json:"workflow_id"` + CheckSuiteID int64 `json:"check_suite_id"` + CheckSuiteNodeID string `json:"check_suite_node_id"` + URL string `json:"url"` + HtmlURL string `json:"html_url"` + PullRequests []struct { + URL string `json:"url"` + ID int64 `json:"id"` + Number int `json:"number"` + Head gitRef `json:"head"` + Base gitRef `json:"base"` + } `json:"pull_requests"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + Actor owner `json:"actor"` + RunAttempt int `json:"run_attempt"` + RunStartedAt time.Time `json:"run_started_at"` + TriggeringActor owner `json:"triggering_actor"` + JobsURL string `json:"jobs_url"` + LogsURL string `json:"logs_url"` + CheckSuiteURL string `json:"check_suite_url"` + ArtifactsURL string `json:"artifacts_url"` + CancelURL string `json:"cancel_url"` + RerunURL string `json:"rerun_url"` + PreviousAttemptURL null.String `json:"previous_attempt_url"` + WorkflowURL string `json:"workflow_url"` + HeadCommit struct { + ID string `json:"id"` + TreeID string `json:"tree_id"` + Message string `json:"message"` + Timestamp time.Time `json:"timestamp"` + Author author `json:"author"` + Committer author `json:"committer"` + } `json:"head_commit"` + } `json:"workflow_run"` + Repository repository `json:"repository"` + } + + gitRef struct { + Ref string `json:"ref"` + SHA string `json:"sha"` + Repo repository `json:"repo"` + } + + owner struct { + Login string `json:"login"` + ID int64 `json:"id"` + NodeID string `json:"node_id"` + AvatarURL string `json:"avatar_url"` + HTMLURL string `json:"html_url"` + Type string `json:"type"` + SiteAdmin bool `json:"site_admin"` + } + + author struct { + Name string `json:"name"` + Email string `json:"email"` + } ) // diff --git a/scm/driver/github/webhook_test.go b/scm/driver/github/webhook_test.go index f7c63c3fd..f30804fa3 100644 --- a/scm/driver/github/webhook_test.go +++ b/scm/driver/github/webhook_test.go @@ -25,9 +25,8 @@ func TestWebhooks(t *testing.T) { after string obj interface{} }{ - // // push events - // + // push hooks { event: "push", @@ -236,6 +235,12 @@ func TestWebhooks(t *testing.T) { after: "testdata/webhooks/release_released.json.golden", obj: new(scm.ReleaseHook), }, + { + event: "workflow_run", + before: "testdata/webhooks/pipeline_hook.json", + after: "testdata/webhooks/pipeline_hook.json.golden", + obj: new(scm.PipelineHook), + }, } for _, test := range tests { diff --git a/scm/driver/gitlab/repo.go b/scm/driver/gitlab/repo.go index 9a44bc3bc..7a041a8fb 100644 --- a/scm/driver/gitlab/repo.go +++ b/scm/driver/gitlab/repo.go @@ -151,6 +151,9 @@ func (s *repositoryService) CreateHook(ctx context.Context, repo string, input * if input.Events.Tag { params.Set("tag_push_events", "true") } + if input.Events.Pipeline { + params.Set("pipeline_events", "true") + } path := fmt.Sprintf("api/v4/projects/%s/hooks?%s", encode(repo), params.Encode()) out := new(hook) diff --git a/scm/driver/gitlab/testdata/webhooks/pipeline_hook.json b/scm/driver/gitlab/testdata/webhooks/pipeline_hook.json new file mode 100644 index 000000000..6deec0b0e --- /dev/null +++ b/scm/driver/gitlab/testdata/webhooks/pipeline_hook.json @@ -0,0 +1,115 @@ +{ + "object_kind": "pipeline", + "object_attributes":{ + "id": 31, + "iid": 3, + "name": "Pipeline for branch: master", + "ref": "master", + "tag": false, + "sha": "bcbb5ec396a2c0f828686f14fac9b80b780504f2", + "before_sha": "bcbb5ec396a2c0f828686f14fac9b80b780504f2", + "source": "merge_request_event", + "status": "success", + "stages":[ + "build", + "test", + "deploy" + ], + "created_at": "2016-08-12 15:23:28 UTC", + "finished_at": "2016-08-12 15:26:29 UTC", + "duration": 63, + "variables": [ + { + "key": "NESTOR_PROD_ENVIRONMENT", + "value": "us-west-1" + } + ], + "url": "http://example.com/gitlab-org/gitlab-test/-/pipelines/31" + }, + "merge_request": { + "id": 371997275, + "iid": 15, + "title": "Edit test.txt", + "source_branch": "shivamnegi94-main-patch-62619", + "source_project_id": 27743392, + "target_branch": "main", + "target_project_id": 27743392, + "state": "opened", + "merge_status": "can_be_merged", + "detailed_merge_status": "mergeable", + "url": "https://gitlab.com/shivamnegi94/test/-/merge_requests/15" + }, + "user":{ + "id": 1, + "name": "Administrator", + "username": "root", + "avatar_url": "http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon", + "email": "user_email@gitlab.com" + }, + "project":{ + "id": 1, + "name": "Gitlab Test", + "description": "Atque in sunt eos similique dolores voluptatem.", + "web_url": "http://192.168.64.1:3005/gitlab-org/gitlab-test", + "avatar_url": null, + "git_ssh_url": "git@192.168.64.1:gitlab-org/gitlab-test.git", + "git_http_url": "http://192.168.64.1:3005/gitlab-org/gitlab-test.git", + "namespace": "Gitlab Org", + "visibility_level": 20, + "path_with_namespace": "gitlab-org/gitlab-test", + "default_branch": "master" + }, + "commit":{ + "id": "bcbb5ec396a2c0f828686f14fac9b80b780504f2", + "message": "test\n", + "timestamp": "2016-08-12T17:23:21+02:00", + "url": "http://example.com/gitlab-org/gitlab-test/commit/bcbb5ec396a2c0f828686f14fac9b80b780504f2", + "author":{ + "name": "User", + "email": "user@gitlab.com" + } + }, + "source_pipeline":{ + "project":{ + "id": 41, + "web_url": "https://gitlab.example.com/gitlab-org/upstream-project", + "path_with_namespace": "gitlab-org/upstream-project" + }, + "pipeline_id": 30, + "job_id": 3401 + }, + "builds":[ + { + "id": 380, + "stage": "deploy", + "name": "production", + "status": "skipped", + "created_at": "2016-08-12 15:23:28 UTC", + "started_at": null, + "finished_at": null, + "duration": null, + "queued_duration": null, + "failure_reason": null, + "when": "manual", + "manual": true, + "allow_failure": false, + "user":{ + "id": 1, + "name": "Administrator", + "username": "root", + "avatar_url": "http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon", + "email": "admin@example.com" + }, + "runner": null, + "artifacts_file":{ + "filename": null, + "size": null + }, + "environment": { + "name": "production", + "action": "start", + "deployment_tier": "production" + } + } + ] +} \ No newline at end of file diff --git a/scm/driver/gitlab/testdata/webhooks/pipeline_hook.json.golden b/scm/driver/gitlab/testdata/webhooks/pipeline_hook.json.golden new file mode 100644 index 000000000..8e70f4b6b --- /dev/null +++ b/scm/driver/gitlab/testdata/webhooks/pipeline_hook.json.golden @@ -0,0 +1,50 @@ +{ + "repo": { + "id": "1", + "namespace": "gitlab-org", + "name": "gitlab-test", + "clone": "http://192.168.64.1:3005/gitlab-org/gitlab-test.git", + "cloneSSH": "git@192.168.64.1:gitlab-org/gitlab-test.git", + "link": "http://192.168.64.1:3005/gitlab-org/gitlab-test", + "branch": "master", + "private": false + }, + "commit": { + "sha": "bcbb5ec396a2c0f828686f14fac9b80b780504f2", + "message": "test\n", + "author": { + "name": "User", + "email": "user@gitlab.com" + }, + "committer": { + "name": "User", + "email": "user@gitlab.com" + }, + "link": "http://example.com/gitlab-org/gitlab-test/commit/bcbb5ec396a2c0f828686f14fac9b80b780504f2" + }, + "Execution": { + "Number": 31, + "status": "success", + "Created": "2016-08-12T15:23:28Z", + "URL": "http://example.com/gitlab-org/gitlab-test/-/pipelines/31" + }, + "sender": { + "login": "root", + "name": "Administrator", + "email": "user_email@gitlab.com", + "avatar": "http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80&d=identicon" + }, + "PullRequest": { + "Number": 371997275, + "Title": "Edit test.txt", + "Sha": "bcbb5ec396a2c0f828686f14fac9b80b780504f2", + "Ref": "master", + "Source": "shivamnegi94-main-patch-62619", + "Target": "main", + "Link": "https://gitlab.com/shivamnegi94/test/-/merge_requests/15", + "Created": "2016-08-12T15:23:28Z", + "Draft": false, + "Closed": false, + "Merged": false + } +} diff --git a/scm/driver/gitlab/webhook.go b/scm/driver/gitlab/webhook.go index c70569471..c76f33f79 100644 --- a/scm/driver/gitlab/webhook.go +++ b/scm/driver/gitlab/webhook.go @@ -41,6 +41,8 @@ func (s *webhookService) Parse(req *http.Request, fn scm.SecretFunc) (scm.Webhoo hook, err = parseIssueCommentHook(data) case "System Hook": hook, err = parseSystemHook(data) + case "Pipeline Hook": + return parsePipelineHook(data) default: return nil, scm.ErrUnknownEvent } @@ -98,6 +100,16 @@ func parseIssueCommentHook(data []byte) (scm.Webhook, error) { return dst, nil } +func parsePipelineHook(data []byte) (scm.Webhook, error) { + src := new(pipelineHook) + err := json.Unmarshal(data, src) + if err != nil { + return nil, err + } + dst, err := convertPipelineHook(src), nil + return dst, nil +} + func parsePushHook(data []byte) (scm.Webhook, error) { src := new(pushHook) err := json.Unmarshal(data, src) @@ -385,8 +397,6 @@ func convertPullRequestHook(src *pullRequestHook) *scm.PullRequestHook { Draft: src.ObjectAttributes.WorkInProgress, Closed: src.ObjectAttributes.State != "opened", Merged: src.ObjectAttributes.State == "merged", - // Created : src.ObjectAttributes.CreatedAt, - // Updated : src.ObjectAttributes.UpdatedAt, // 2017-12-10 17:01:11 UTC Author: scm.User{ Login: src.User.Username, Name: src.User.Name, @@ -420,6 +430,57 @@ func parseTimeString(timeString string) time.Time { return t } +func convertPipelineHook(src *pipelineHook) *scm.PipelineHook { + namespace, name := scm.Split(src.Project.PathWithNamespace) + return &scm.PipelineHook{ + Repo: scm.Repository{ + ID: strconv.Itoa(src.Project.ID), + Namespace: namespace, + Name: name, + Clone: src.Project.GitHTTPURL, + CloneSSH: src.Project.GitSSHURL, + Link: src.Project.WebURL, + Branch: src.Project.DefaultBranch, + Private: false, + }, + Commit: scm.Commit{ + Sha: src.ObjectAttributes.SHA, + Message: src.Commit.Message, + Author: scm.Signature{ + Name: src.Commit.Author.Name, + Email: src.Commit.Author.Email, + }, + Committer: scm.Signature{ + Name: src.Commit.Author.Name, + Email: src.Commit.Author.Email, + }, + Link: src.Commit.URL, + }, + Execution: scm.Execution{ + Number: src.ObjectAttributes.ID, + Status: scm.ConvertExecutionStatus(src.ObjectAttributes.Status), + Created: parseTimeString(src.ObjectAttributes.CreatedAt), + URL: src.ObjectAttributes.URL, + }, + Sender: scm.User{ + Login: src.User.Username, + Name: src.User.Name, + Email: src.User.Email, + Avatar: src.User.AvatarURL, + }, + PullRequest: scm.PullRequest{ + Number: src.MergeRequest.ID, + Title: src.MergeRequest.Title, + Sha: src.ObjectAttributes.SHA, + Ref: src.ObjectAttributes.Ref, + Source: src.MergeRequest.SourceBranch, + Target: src.MergeRequest.TargetBranch, + Link: src.MergeRequest.URL, + Created: parseTimeString(src.ObjectAttributes.CreatedAt), + }, + } +} + type ( // Generic struct to detect event type event struct { @@ -904,4 +965,131 @@ type ( Homepage string `json:"homepage"` } `json:"repository"` } + + pipelineHook struct { + ObjectKind string `json:"object_kind"` + ObjectAttributes struct { + ID int `json:"id"` + IID int `json:"iid"` + Name string `json:"name"` + Ref string `json:"ref"` + Tag bool `json:"tag"` + SHA string `json:"sha"` + BeforeSHA string `json:"before_sha"` + Source string `json:"source"` + Status string `json:"status"` + Stages []string `json:"stages"` + CreatedAt string `json:"created_at"` + FinishedAt string `json:"finished_at"` + Duration int `json:"duration"` + Variables []variable `json:"variables"` + URL string `json:"url"` + } `json:"object_attributes"` + MergeRequest struct { + ID int `json:"id"` + IID int `json:"iid"` + Title string `json:"title"` + SourceBranch string `json:"source_branch"` + SourceProjectID int `json:"source_project_id"` + TargetBranch string `json:"target_branch"` + TargetProjectID int `json:"target_project_id"` + State string `json:"state"` + MergeStatus string `json:"merge_status"` + DetailedMergeStatus string `json:"detailed_merge_status"` + URL string `json:"url"` + } `json:"merge_request"` + User struct { + ID int `json:"id"` + Name string `json:"name"` + Username string `json:"username"` + AvatarURL string `json:"avatar_url"` + Email string `json:"email"` + } `json:"user"` + Project struct { + ID int `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + WebURL string `json:"web_url"` + AvatarURL null.String `json:"avatar_url"` + GitSSHURL string `json:"git_ssh_url"` + GitHTTPURL string `json:"git_http_url"` + Namespace string `json:"namespace"` + VisibilityLevel int `json:"visibility_level"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + } `json:"project"` + Commit struct { + ID string `json:"id"` + Message string `json:"message"` + Timestamp string `json:"timestamp"` + URL string `json:"url"` + Author author `json:"author"` + } `json:"commit"` + SourcePipeline struct { + Project struct { + ID int `json:"id"` + WebURL string `json:"web_url"` + PathWithNamespace string `json:"path_with_namespace"` + } `json:"project"` + PipelineID int `json:"pipeline_id"` + JobID int `json:"job_id"` + } `json:"source_pipeline"` + Builds []build `json:"builds"` + } + + variable struct { + Key string `json:"key"` + Value string `json:"value"` + } + + author struct { + Name string `json:"name"` + Email string `json:"email"` + } + + build struct { + ID int `json:"id"` + Stage string `json:"stage"` + Name string `json:"name"` + Status string `json:"status"` + CreatedAt string `json:"created_at"` + StartedAt null.String `json:"started_at"` + FinishedAt null.String `json:"finished_at"` + Duration float64 `json:"duration"` + QueuedDuration float64 `json:"queued_duration"` + FailureReason null.String `json:"failure_reason"` + When string `json:"when"` + Manual bool `json:"manual"` + AllowFailure bool `json:"allow_failure"` + User struct { + ID int `json:"id"` + Name string `json:"name"` + Username string `json:"username"` + AvatarURL string `json:"avatar_url"` + Email string `json:"email"` + } `json:"user"` + Runner runner `json:"runner"` + ArtifactsFile artifacts `json:"artifacts_file"` + Environment environment `json:"environment"` + } + + runner struct { + ID int `json:"id"` + Description string `json:"description"` + Active bool `json:"active"` + RunnerType string `json:"runner_type"` + IsShared bool `json:"is_shared"` + Tags []string `json:"tags"` + } + + artifacts struct { + Filename null.String `json:"filename"` + Size null.Int `json:"size"` + } + + environment struct { + Name string `json:"name"` + Action string `json:"action"` + DeploymentTier string `json:"deployment_tier"` + } ) diff --git a/scm/driver/gitlab/webhook_test.go b/scm/driver/gitlab/webhook_test.go index 16041c67d..e238a615c 100644 --- a/scm/driver/gitlab/webhook_test.go +++ b/scm/driver/gitlab/webhook_test.go @@ -189,6 +189,12 @@ func TestWebhooks(t *testing.T) { after: "testdata/webhooks/merge_request_comment_create.json.golden", obj: new(scm.IssueCommentHook), }, + { + event: "Pipeline Hook", + before: "testdata/webhooks/pipeline_hook.json", + after: "testdata/webhooks/pipeline_hook.json.golden", + obj: new(scm.PipelineHook), + }, } for _, test := range tests { diff --git a/scm/git.go b/scm/git.go index 5f0d9892a..afcc9e1e9 100644 --- a/scm/git.go +++ b/scm/git.go @@ -56,6 +56,15 @@ type ( Avatar string } + // Pipeline Execution details + Execution struct { + Number int + Status ExecutionStatus + Created time.Time + Updated time.Time + URL string + } + // GitService provides access to git resources. GitService interface { // CreateBranch creates a git branch by name given a sha. diff --git a/scm/repo.go b/scm/repo.go index 8ec383c37..5fe699427 100644 --- a/scm/repo.go +++ b/scm/repo.go @@ -65,6 +65,7 @@ type ( Deployment bool Issue bool IssueComment bool + Pipeline bool PullRequest bool PullRequestComment bool Push bool diff --git a/scm/util.go b/scm/util.go index 6aa496834..4e72f524f 100644 --- a/scm/util.go +++ b/scm/util.go @@ -103,6 +103,23 @@ func ConvertVisibility(from string) Visibility { } } +func ConvertExecutionStatus(from string) ExecutionStatus { + switch from { + case "running", "in_progress", "INPROGRESS": + return StatusRunning + case "success", "completed", "SUCCESSFUL": + return StatusSuccess + case "Failed", "failure", "FAILED": + return StatusFailed + case "Canceled", "cancelled", "STOPPED": + return StatusCanceled + case "pending", "queued": + return StatusPending + default: + return StatusUnknown + } +} + func ConvertPrivate(from string) bool { switch from { case "public", "": diff --git a/scm/webhook.go b/scm/webhook.go index f6875f6f2..ffe4791cd 100644 --- a/scm/webhook.go +++ b/scm/webhook.go @@ -37,6 +37,15 @@ type ( Commits []Commit } + // PipelineHook + PipelineHook struct { + Commit Commit + Execution Execution + PullRequest PullRequest + Repo Repository + Sender User + } + // BranchHook represents a branch or tag event, // eg create and delete github event types. BranchHook struct { @@ -150,3 +159,4 @@ func (h *PullRequestHook) Repository() Repository { return h.Repo } func (h *PullRequestCommentHook) Repository() Repository { return h.Repo } func (h *ReviewCommentHook) Repository() Repository { return h.Repo } func (h *ReleaseHook) Repository() Repository { return h.Repo } +func (h *PipelineHook) Repository() Repository { return h.Repo } From 2a616abf6e05440722da99347a51e043398fd49f Mon Sep 17 00:00:00 2001 From: Abhinav Singh Date: Tue, 22 Apr 2025 20:55:50 -0700 Subject: [PATCH 190/195] feat: add new field of commit link for HC webhooks (#331) --- scm/driver/harness/webhook.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scm/driver/harness/webhook.go b/scm/driver/harness/webhook.go index 33be360b4..c4b7173e0 100644 --- a/scm/driver/harness/webhook.go +++ b/scm/driver/harness/webhook.go @@ -172,6 +172,7 @@ type ( hookCommit struct { Sha string `json:"sha"` Message string `json:"message"` + URL string `json:"url"` Author struct { Identity struct { Name string `json:"name"` @@ -272,6 +273,7 @@ func convertHookCommit(c hookCommit) scm.Commit { Name: c.Committer.Identity.Name, Email: c.Committer.Identity.Email, }, + Link: c.URL, } } From ecd9254d1d864e74c348bfa8625c63701aa0f691 Mon Sep 17 00:00:00 2001 From: "OP (oppenheimer)" <21008429+Ompragash@users.noreply.github.com> Date: Wed, 23 Apr 2025 09:33:03 +0530 Subject: [PATCH 191/195] feat: Rename .drone.yml to .drone.yml.bak (#335) --- .drone.yml => .drone.yml.bak | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .drone.yml => .drone.yml.bak (100%) diff --git a/.drone.yml b/.drone.yml.bak similarity index 100% rename from .drone.yml rename to .drone.yml.bak From a515870a3931d01562ab61723891462134a3277f Mon Sep 17 00:00:00 2001 From: Abhinav Singh Date: Thu, 1 May 2025 12:55:57 -0700 Subject: [PATCH 192/195] feat: new hc webhook fields (#337) * feat: new hc webhook fields * feat: new hc webhook fields --- .../webhooks/pull_request_branch_updated.json | 1 + .../pull_request_branch_updated.json.golden | 10 +++++ .../webhooks/pull_request_closed.json | 1 + .../webhooks/pull_request_closed.json.golden | 10 +++++ .../pull_request_comment_created.json | 43 ++++++++++++++++++- .../pull_request_comment_created.json.golden | 12 +++++- .../webhooks/pull_request_merged.json | 1 + .../webhooks/pull_request_merged.json.golden | 10 +++++ .../webhooks/pull_request_opened.json | 1 + .../webhooks/pull_request_opened.json.golden | 10 +++++ .../webhooks/pull_request_reopened.json | 1 + .../pull_request_reopened.json.golden | 10 +++++ scm/driver/harness/webhook.go | 14 ++++++ 13 files changed, 122 insertions(+), 2 deletions(-) diff --git a/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json b/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json index 8a88fc594..dec4c06f6 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json +++ b/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json @@ -26,6 +26,7 @@ "target_repo_id": 13, "target_branch": "main", "merge_strategy": null, + "merge_base_sha": "5473eebbc0ce1d08981c955161b07a7989566b7b", "author": { "id": 8, "uid": "0osgWsTZRsSZ8RWfjLRkEg", diff --git a/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json.golden b/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json.golden index 2b4f2a643..0cc22af45 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json.golden +++ b/scm/driver/harness/testdata/webhooks/pull_request_branch_updated.json.golden @@ -33,6 +33,16 @@ "Created": "2023-02-02T18:21:25.38-08:00", "Updated": "2023-02-02T18:21:25.38-08:00" }, + "Base": { + "Name": "main", + "Path": "refs/heads/main", + "Sha": "5473eebbc0ce1d08981c955161b07a7989566b7b" + }, + "Head": { + "Name": "b", + "Path": "refs/heads/b", + "Sha": "f74f3d2a88d1b7cb19ff3bf069aa423763d341ef" + }, "Created": "0001-01-01T00:00:00Z", "Updated": "0001-01-01T00:00:00Z" }, diff --git a/scm/driver/harness/testdata/webhooks/pull_request_closed.json b/scm/driver/harness/testdata/webhooks/pull_request_closed.json index 4f47de5fa..4039bc208 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_closed.json +++ b/scm/driver/harness/testdata/webhooks/pull_request_closed.json @@ -25,6 +25,7 @@ "source_branch": "asdxsa", "target_repo_id": 22, "target_branch": "main", + "merge_base_sha": "5473eebbc0ce1d08981c955161b07a7989566b7b", "author": { "id": 3, "uid": "admin", diff --git a/scm/driver/harness/testdata/webhooks/pull_request_closed.json.golden b/scm/driver/harness/testdata/webhooks/pull_request_closed.json.golden index 8b5fc2143..bfd493649 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_closed.json.golden +++ b/scm/driver/harness/testdata/webhooks/pull_request_closed.json.golden @@ -33,6 +33,16 @@ "Created": "2023-10-03T16:50:21.613+05:30", "Updated": "2023-10-03T16:50:21.613+05:30" }, + "Base": { + "Name": "main", + "Path": "refs/heads/main", + "Sha": "5473eebbc0ce1d08981c955161b07a7989566b7b" + }, + "Head": { + "Name": "asdxsa", + "Path": "refs/heads/asdxsa", + "Sha": "27822dd2ec788f924c97b0b194c5bfd906f2e574" + }, "Created": "0001-01-01T00:00:00Z", "Updated": "0001-01-01T00:00:00Z" }, diff --git a/scm/driver/harness/testdata/webhooks/pull_request_comment_created.json b/scm/driver/harness/testdata/webhooks/pull_request_comment_created.json index 52ae75598..cc69241e8 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_comment_created.json +++ b/scm/driver/harness/testdata/webhooks/pull_request_comment_created.json @@ -26,6 +26,7 @@ "target_repo_id": 18, "target_branch": "main", "merge_strategy": null, + "merge_base_sha": "5473eebbc0ce1d08981c955161b07a7989566b7b", "author": { "id": 8, "uid": "0osgWsTZRsSZ8RWfjLRkEg", @@ -57,8 +58,48 @@ "git_url": "http://localhost:3000/git/asd/demo.git" } }, + "sha": "f74f3d2a88d1b7cb19ff3bf069aa423763d341ef", + "commit": { + "sha": "f74f3d2a88d1b7cb19ff3bf069aa423763d341ef", + "message": "updated b2", + "author": { + "identity": { + "name": "Admin", + "email": "admin@harness.io" + }, + "when": "2023-02-01T13:28:55-08:00" + }, + "committer": { + "identity": { + "name": "Admin", + "email": "admin@harness.io" + }, + "when": "2023-02-01T13:28:55-08:00" + } + }, + "head_commit": { + "sha": "f74f3d2a88d1b7cb19ff3bf069aa423763d341ef", + "message": "updated b2", + "author": { + "identity": { + "name": "Admin", + "email": "admin@harness.io" + }, + "when": "2023-02-01T13:28:55-08:00" + }, + "committer": { + "identity": { + "name": "Admin", + "email": "admin@harness.io" + }, + "when": "2023-02-01T13:28:55-08:00" + } + }, "comment": { "id": 1, - "text": "pr comment" + "text": "pr comment", + "created": 1745471063621, + "updated": 1745471063621, + "kind": "comment" } } \ No newline at end of file diff --git a/scm/driver/harness/testdata/webhooks/pull_request_comment_created.json.golden b/scm/driver/harness/testdata/webhooks/pull_request_comment_created.json.golden index cb96e2634..a10e6efb6 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_comment_created.json.golden +++ b/scm/driver/harness/testdata/webhooks/pull_request_comment_created.json.golden @@ -15,7 +15,7 @@ "Number": 2, "Title": "Update test.txt", "Body": "", - "Sha": "", + "Sha": "f74f3d2a88d1b7cb19ff3bf069aa423763d341ef", "Ref": "refs/heads/pr2", "Source": "pr2", "Target": "main", @@ -32,6 +32,16 @@ "Created": "2023-02-02T18:21:25.38-08:00", "Updated": "2023-02-02T18:21:25.38-08:00" }, + "Base": { + "Name": "main", + "Path": "refs/heads/main", + "Sha": "5473eebbc0ce1d08981c955161b07a7989566b7b" + }, + "Head": { + "Name": "pr2", + "Path": "refs/heads/pr2", + "Sha": "f74f3d2a88d1b7cb19ff3bf069aa423763d341ef" + }, "Created": "0001-01-01T00:00:00Z", "Updated": "0001-01-01T00:00:00Z" }, diff --git a/scm/driver/harness/testdata/webhooks/pull_request_merged.json b/scm/driver/harness/testdata/webhooks/pull_request_merged.json index f8cd669b8..dac50c97f 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_merged.json +++ b/scm/driver/harness/testdata/webhooks/pull_request_merged.json @@ -26,6 +26,7 @@ "target_repo_id": 22, "target_branch": "main", "merge_strategy": "squash", + "merge_base_sha": "5473eebbc0ce1d08981c955161b07a7989566b7b", "author": { "id": 3, "uid": "admin", diff --git a/scm/driver/harness/testdata/webhooks/pull_request_merged.json.golden b/scm/driver/harness/testdata/webhooks/pull_request_merged.json.golden index 3bef4116c..7237cea0d 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_merged.json.golden +++ b/scm/driver/harness/testdata/webhooks/pull_request_merged.json.golden @@ -33,6 +33,16 @@ "Created": "2023-10-03T16:50:21.613+05:30", "Updated": "2023-10-03T16:50:21.613+05:30" }, + "Base": { + "Name": "main", + "Path": "refs/heads/main", + "Sha": "5473eebbc0ce1d08981c955161b07a7989566b7b" + }, + "Head": { + "Name": "xas", + "Path": "refs/heads/xas", + "Sha": "4ec41187008f77222a60dfa21cdbd980f6490443" + }, "Created": "0001-01-01T00:00:00Z", "Updated": "0001-01-01T00:00:00Z" }, diff --git a/scm/driver/harness/testdata/webhooks/pull_request_opened.json b/scm/driver/harness/testdata/webhooks/pull_request_opened.json index 7c1715f19..bfafcef5a 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_opened.json +++ b/scm/driver/harness/testdata/webhooks/pull_request_opened.json @@ -26,6 +26,7 @@ "target_repo_id": 13, "target_branch": "main", "merge_strategy": null, + "merge_base_sha": "5473eebbc0ce1d08981c955161b07a7989566b7b", "author": { "id": 8, "uid": "0osgWsTZRsSZ8RWfjLRkEg", diff --git a/scm/driver/harness/testdata/webhooks/pull_request_opened.json.golden b/scm/driver/harness/testdata/webhooks/pull_request_opened.json.golden index 9ea430e3d..a1fe53904 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_opened.json.golden +++ b/scm/driver/harness/testdata/webhooks/pull_request_opened.json.golden @@ -33,6 +33,16 @@ "Created": "2023-02-02T18:21:25.38-08:00", "Updated": "2023-02-02T18:21:25.38-08:00" }, + "Base": { + "Name": "main", + "Path": "refs/heads/main", + "Sha": "5473eebbc0ce1d08981c955161b07a7989566b7b" + }, + "Head": { + "Name": "b", + "Path": "refs/heads/b", + "Sha": "d74b1ebfe520ac01b209dd9085f005884cc9f4cd" + }, "Created": "0001-01-01T00:00:00Z", "Updated": "0001-01-01T00:00:00Z" }, diff --git a/scm/driver/harness/testdata/webhooks/pull_request_reopened.json b/scm/driver/harness/testdata/webhooks/pull_request_reopened.json index a7408779f..3915d0b45 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_reopened.json +++ b/scm/driver/harness/testdata/webhooks/pull_request_reopened.json @@ -26,6 +26,7 @@ "target_repo_id": 13, "target_branch": "main", "merge_strategy": null, + "merge_base_sha": "5473eebbc0ce1d08981c955161b07a7989566b7b", "author": { "id": 8, "uid": "0osgWsTZRsSZ8RWfjLRkEg", diff --git a/scm/driver/harness/testdata/webhooks/pull_request_reopened.json.golden b/scm/driver/harness/testdata/webhooks/pull_request_reopened.json.golden index 32bc95964..3c00c475c 100644 --- a/scm/driver/harness/testdata/webhooks/pull_request_reopened.json.golden +++ b/scm/driver/harness/testdata/webhooks/pull_request_reopened.json.golden @@ -33,6 +33,16 @@ "Created": "2023-02-02T18:21:25.38-08:00", "Updated": "2023-02-02T18:21:25.38-08:00" }, + "Base": { + "Name": "main", + "Path": "refs/heads/main", + "Sha": "5473eebbc0ce1d08981c955161b07a7989566b7b" + }, + "Head": { + "Name": "b", + "Path": "refs/heads/b", + "Sha": "f74f3d2a88d1b7cb19ff3bf069aa423763d341ef" + }, "Created": "0001-01-01T00:00:00Z", "Updated": "0001-01-01T00:00:00Z" }, diff --git a/scm/driver/harness/webhook.go b/scm/driver/harness/webhook.go index c4b7173e0..cb79b71fa 100644 --- a/scm/driver/harness/webhook.go +++ b/scm/driver/harness/webhook.go @@ -141,10 +141,12 @@ type ( State string `json:"state"` IsDraft bool `json:"is_draft"` Title string `json:"title"` + Description string `json:"description"` SourceRepoID int `json:"source_repo_id"` SourceBranch string `json:"source_branch"` TargetRepoID int `json:"target_repo_id"` TargetBranch string `json:"target_branch"` + MergeBaseSHA string `json:"merge_base_sha"` MergeStrategy interface{} `json:"merge_strategy"` Author principal `json:"author"` PrURL string `json:"pr_url"` @@ -356,15 +358,27 @@ func convertPullReq(pr pullReq, ref ref, commit hookCommit) scm.PullRequest { return scm.PullRequest{ Number: pr.Number, Title: pr.Title, + Body: pr.Description, Closed: pr.State != "open", Source: pr.SourceBranch, Target: pr.TargetBranch, Merged: pr.State == "merged", Fork: "fork", Link: pr.PrURL, + Draft: pr.IsDraft, Sha: commit.Sha, Ref: ref.Name, Author: convertUser(pr.Author), + Head: scm.Reference{ + Name: pr.SourceBranch, + Path: scm.ExpandRef(pr.SourceBranch, "refs/heads"), + Sha: commit.Sha, + }, + Base: scm.Reference{ + Name: pr.TargetBranch, + Path: scm.ExpandRef(pr.TargetBranch, "refs/heads"), + Sha: pr.MergeBaseSHA, + }, } } From 3a9d633508021fc1fef42db7bf25cd6e41d53009 Mon Sep 17 00:00:00 2001 From: Nasser Gonzalez Gonzalez Date: Fri, 11 Jul 2025 17:57:23 +0100 Subject: [PATCH 193/195] feat: Add ListTags to Azure (#338) * feat: Add ListTags to Azure * feat: Add ListTags to Azure. Add linting suggestions --- scm/driver/azure/git.go | 48 +++++++++++++++++- scm/driver/azure/git_test.go | 59 ++++++++++++++++++++++ scm/driver/azure/testdata/tags.json | 41 +++++++++++++++ scm/driver/azure/testdata/tags.json.golden | 12 +++++ 4 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 scm/driver/azure/testdata/tags.json create mode 100644 scm/driver/azure/testdata/tags.json.golden diff --git a/scm/driver/azure/git.go b/scm/driver/azure/git.go index af6656c13..dae86f58b 100644 --- a/scm/driver/azure/git.go +++ b/scm/driver/azure/git.go @@ -94,7 +94,18 @@ func (s *gitService) ListCommits(ctx context.Context, repo string, opts scm.Comm } func (s *gitService) ListTags(ctx context.Context, repo string, opts scm.ListOptions) ([]*scm.Reference, *scm.Response, error) { - return nil, nil, scm.ErrNotSupported + if s.client.project == "" { + return nil, nil, ProjectRequiredError() + } + endpoint := fmt.Sprintf("%s/%s/_apis/git/repositories/%s/refs?", s.client.owner, s.client.project, repo) + // add tags + endpoint += fmt.Sprintf("filter=tags/") + // add target + endpoint += fmt.Sprintf("&api-version=7.1-preview.1") + out := new(tags) + res, err := s.client.do(ctx, "GET", endpoint, nil, &out) + + return convertTags(out.Value), res, err } func (s *gitService) ListChanges(ctx context.Context, repo, ref string, _ scm.ListOptions) ([]*scm.Change, *scm.Response, error) { @@ -202,6 +213,29 @@ type compare struct { TargetCommit string `json:"targetCommit"` } +type tags struct { + Value []*tag `json:"value"` + Count int `json:"count"` +} +type tag struct { + Name string `json:"name"` + ObjectID string `json:"objectId"` + Creator struct { + DisplayName string `json:"displayName"` + URL string `json:"url"` + Links struct { + Avatar struct { + Href string `json:"href"` + } `json:"avatar"` + } `json:"_links"` + ID string `json:"id"` + UniqueName string `json:"uniqueName"` + ImageURL string `json:"imageUrl"` + Descriptor string `json:"descriptor"` + } `json:"creator"` + URL string `json:"url"` +} + func convertBranchList(from []*branch) []*scm.Reference { to := []*scm.Reference{} for _, v := range from { @@ -269,3 +303,15 @@ func convertChange(from *file) *scm.Change { return returnVal } + +func convertTags(from []*tag) []*scm.Reference { + var to []*scm.Reference + for _, v := range from { + to = append(to, &scm.Reference{ + Name: scm.TrimRef(v.Name), + Path: scm.ExpandRef(v.Name, "refs/tags/"), + Sha: v.ObjectID, + }) + } + return to +} diff --git a/scm/driver/azure/git_test.go b/scm/driver/azure/git_test.go index f150dc38e..4f79b78eb 100644 --- a/scm/driver/azure/git_test.go +++ b/scm/driver/azure/git_test.go @@ -175,3 +175,62 @@ func TestGitCompareChanges(t *testing.T) { } } + +func TestGitListTags(t *testing.T) { + defer gock.Off() + + gock.New("https:/dev.azure.com/"). + Get("/ORG/PROJ/_apis/git/repositories/REPOID/"). + Reply(200). + Type("application/json"). + File("testdata/tags.json") + + client := NewDefault("ORG", "PROJ") + got, _, err := client.Git.ListTags(context.Background(), "REPOID", scm.ListOptions{}) + if err != nil { + t.Error(err) + return + } + + want := []*scm.Reference{} + raw, _ := ioutil.ReadFile("testdata/tags.json.golden") + _ = json.Unmarshal(raw, &want) + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } +} + +func TestConvertTags(t *testing.T) { + from := []*tag{ + { + Name: "refs/tags/v1.0.0", + ObjectID: "23d9c1d0d6c41f1c8e08ab98a6a79c2d5ada649d", + }, + { + Name: "refs/tags/v1.1.0", + ObjectID: "8a9db19b5e19613c18e9059d7b9fa5d6d6a3785f", + }, + } + + got := convertTags(from) + + want := []*scm.Reference{ + { + Name: "v1.0.0", + Path: "refs/tags/v1.0.0", + Sha: "23d9c1d0d6c41f1c8e08ab98a6a79c2d5ada649d", + }, + { + Name: "v1.1.0", + Path: "refs/tags/v1.1.0", + Sha: "8a9db19b5e19613c18e9059d7b9fa5d6d6a3785f", + }, + } + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } +} diff --git a/scm/driver/azure/testdata/tags.json b/scm/driver/azure/testdata/tags.json new file mode 100644 index 000000000..090690921 --- /dev/null +++ b/scm/driver/azure/testdata/tags.json @@ -0,0 +1,41 @@ +{ + "value": [ + { + "name": "refs/tags/v1.0.0", + "objectId": "23d9c1d0d6c41f1c8e08ab98a6a79c2d5ada649d", + "creator": { + "displayName": "Test User", + "url": "https://dev.azure.com/fabrikam/_apis/Identities/d6245f20-2af8-44f4-9451-8107cb2767db", + "_links": { + "avatar": { + "href": "https://dev.azure.com/fabrikam/_apis/GraphProfile/MemberAvatars/aad.YTYyNDVmMjAtMmFmOC00NGY0LTk0NTEtODEwN2NiMjc2N2Ri" + } + }, + "id": "d6245f20-2af8-44f4-9451-8107cb2767db", + "uniqueName": "test@example.com", + "imageUrl": "https://dev.azure.com/fabrikam/_api/_common/identityImage?id=d6245f20-2af8-44f4-9451-8107cb2767db", + "descriptor": "aad.YTYyNDVmMjAtMmFmOC00NGY0LTk0NTEtODEwN2NiMjc2N2Ri" + }, + "url": "https://dev.azure.com/fabrikam/DefaultCollection/_apis/git/repositories/278d5cd2-584d-4b63-824a-2ba458937249/refs/tags/v1.0.0" + }, + { + "name": "refs/tags/v1.1.0", + "objectId": "8a9db19b5e19613c18e9059d7b9fa5d6d6a3785f", + "creator": { + "displayName": "Test User", + "url": "https://dev.azure.com/fabrikam/_apis/Identities/d6245f20-2af8-44f4-9451-8107cb2767db", + "_links": { + "avatar": { + "href": "https://dev.azure.com/fabrikam/_apis/GraphProfile/MemberAvatars/aad.YTYyNDVmMjAtMmFmOC00NGY0LTk0NTEtODEwN2NiMjc2N2Ri" + } + }, + "id": "d6245f20-2af8-44f4-9451-8107cb2767db", + "uniqueName": "test@example.com", + "imageUrl": "https://dev.azure.com/fabrikam/_api/_common/identityImage?id=d6245f20-2af8-44f4-9451-8107cb2767db", + "descriptor": "aad.YTYyNDVmMjAtMmFmOC00NGY0LTk0NTEtODEwN2NiMjc2N2Ri" + }, + "url": "https://dev.azure.com/fabrikam/DefaultCollection/_apis/git/repositories/278d5cd2-584d-4b63-824a-2ba458937249/refs/tags/v1.1.0" + } + ], + "count": 2 +} diff --git a/scm/driver/azure/testdata/tags.json.golden b/scm/driver/azure/testdata/tags.json.golden new file mode 100644 index 000000000..28ef8bbf3 --- /dev/null +++ b/scm/driver/azure/testdata/tags.json.golden @@ -0,0 +1,12 @@ +[ + { + "Name": "v1.0.0", + "Path": "refs/tags/v1.0.0", + "Sha": "23d9c1d0d6c41f1c8e08ab98a6a79c2d5ada649d" + }, + { + "Name": "v1.1.0", + "Path": "refs/tags/v1.1.0", + "Sha": "8a9db19b5e19613c18e9059d7b9fa5d6d6a3785f" + } +] From 761a455f9874ad7ffe1bca4b9c2b308a3bd9730d Mon Sep 17 00:00:00 2001 From: rcchopra Date: Sun, 20 Jul 2025 23:16:23 +0530 Subject: [PATCH 194/195] added algorithm in place --- scm/driver/azure/repo.go | 12 ------------ scm/driver/bitbucket/user.go | 15 +++++++-------- scm/driver/harness/org.go | 4 ++++ scm/driver/harness/repo.go | 7 +++++++ 4 files changed, 18 insertions(+), 20 deletions(-) diff --git a/scm/driver/azure/repo.go b/scm/driver/azure/repo.go index b2d4c15f7..0e815ae7c 100644 --- a/scm/driver/azure/repo.go +++ b/scm/driver/azure/repo.go @@ -24,8 +24,6 @@ func (s *RepositoryService) Find(ctx context.Context, repo string) (*scm.Reposit // 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) @@ -79,14 +77,6 @@ func (s *RepositoryService) ListRepoLanguages(context.Context, string) (map[stri return nil, nil, scm.ErrNotSupported } -func (s *RepositoryService) List2(ctx context.Context, orgSlug string, opts scm.ListOptions) ([]*scm.Repository, *scm.Response, error) { - return nil, nil, scm.ErrNotSupported -} - -func (s *RepositoryService) ListRepoLanguages(context.Context, string) (map[string]float64, *scm.Response, error) { - return nil, nil, scm.ErrNotSupported -} - // ListHooks returns a list or repository hooks. 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 @@ -113,8 +103,6 @@ func (s *RepositoryService) CreateHook(ctx context.Context, repo string, input * // 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) diff --git a/scm/driver/bitbucket/user.go b/scm/driver/bitbucket/user.go index beda0f021..718811fb8 100644 --- a/scm/driver/bitbucket/user.go +++ b/scm/driver/bitbucket/user.go @@ -6,7 +6,6 @@ package bitbucket import ( "context" - "errors" "fmt" "github.com/drone/go-scm/scm" @@ -30,9 +29,9 @@ func (s *userService) FindLogin(ctx context.Context, login string) (*scm.User, * } func (s *userService) FindEmail(ctx context.Context) (string, *scm.Response, error) { - out := new(emails) - res, err := s.client.do(ctx, "GET", "2.0/user/emails", nil, &out) - return convertEmailList(out), res, err + out := new(emails) + res, err := s.client.do(ctx, "GET", "2.0/user/emails", nil, &out) + return convertEmailList(out), res, err } func (s *userService) ListEmail(context.Context, scm.ListOptions) ([]*scm.Email, *scm.Response, error) { @@ -42,7 +41,7 @@ func (s *userService) ListEmail(context.Context, scm.ListOptions) ([]*scm.Email, func convertEmailList(from *emails) string { for _, v := range from.Values { if v.IsPrimary == true { - return v.Email + return v.Email } } return "" @@ -66,12 +65,12 @@ type user struct { } type email struct { - Email string `json:"email"` - IsPrimary bool `json:"is_primary"` + Email string `json:"email"` + IsPrimary bool `json:"is_primary"` } type emails struct { - Values []*email `json:"values"` + Values []*email `json:"values"` } func convertUser(from *user) *scm.User { diff --git a/scm/driver/harness/org.go b/scm/driver/harness/org.go index 28239d8d6..718aa77dd 100644 --- a/scm/driver/harness/org.go +++ b/scm/driver/harness/org.go @@ -28,6 +28,10 @@ func (s *organizationService) List(ctx context.Context, opts scm.ListOptions) ([ } +func (s *organizationService) ListMemberships(ctx context.Context, orgNameList []string, username string, opts scm.ListOptions) ([]*scm.Membership, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + // // native data structures // diff --git a/scm/driver/harness/repo.go b/scm/driver/harness/repo.go index 82f095d21..2ef3ceca6 100644 --- a/scm/driver/harness/repo.go +++ b/scm/driver/harness/repo.go @@ -108,6 +108,13 @@ func (s *repositoryService) CreateHook(ctx context.Context, repo string, input * return convertHook(out), res, err } +func (s *repositoryService) List2(ctx context.Context, orgSlug string, opts scm.ListOptions) ([]*scm.Repository, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} +func (s *repositoryService) ListRepoLanguages(context.Context, string) (map[string]float64, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + func (s *repositoryService) CreateStatus(ctx context.Context, repo string, ref string, input *scm.StatusInput) (*scm.Status, *scm.Response, error) { return nil, nil, scm.ErrNotSupported } From b50f244950b30cc3d55d1c11a5af262baed371cf Mon Sep 17 00:00:00 2001 From: rcchopra Date: Sun, 20 Jul 2025 23:44:25 +0530 Subject: [PATCH 195/195] ut's fix --- scm/driver/gitlab/pr.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scm/driver/gitlab/pr.go b/scm/driver/gitlab/pr.go index 0ec61e3b4..f161cf28b 100644 --- a/scm/driver/gitlab/pr.go +++ b/scm/driver/gitlab/pr.go @@ -181,7 +181,12 @@ func convertPullRequest(from *pr) *scm.PullRequest { Updated: from.Updated, Labels: labels, Base: scm.Reference{ - Sha: from.DiffRefs.BaseSha, + Name: from.TargetBranch, + Sha: from.DiffRefs.BaseSha, + }, + Head: scm.Reference{ + Name: from.SourceBranch, + Sha: from.DiffRefs.HeadSha, }, } }