diff --git a/bitbucket/projects_repos_commits.go b/bitbucket/projects_repos_commits.go index f39be3e..0a29a29 100644 --- a/bitbucket/projects_repos_commits.go +++ b/bitbucket/projects_repos_commits.go @@ -60,6 +60,61 @@ type CommitList struct { Commits []*Commit `json:"values"` } +type BuildStatus struct { + Key string `json:"key"` + State BuildStatusState `json:"state"` + URL string `json:"url"` + BuildNumber string `json:"buildNumber,omitempty"` + Description string `json:"description,omitempty"` + Duration uint64 `json:"duration,omitempty"` + Ref string `json:"ref,omitempty"` + TestResult *BuildStatusTestResult `json:"testResults,omitempty"` +} + +type BuildStatusTestResult struct { + Failed uint32 `json:"failed"` + Skipped uint32 `json:"skipped"` + Successful uint32 `json:"successful"` +} + +type BuildStatusState string + +const ( + BuildStatusStateCancelled BuildStatusState = "CANCELLED" + BuildStatusStateFailed BuildStatusState = "FAILED" + BuildStatusStateInProgress BuildStatusState = "INPROGRESS" + BuildStatusStateSuccessful BuildStatusState = "SUCCESSFUL" + BuildStatusStateUnknown BuildStatusState = "UNKNOWN" +) + +type Change struct { + ContentId string `json:"contentId"` + Path ChangePath `json:"path"` + Executable bool `json:"executable"` + Unchanged int `json:"percentUnchanged"` + Type ChangeType `json:"type"` + NodeType ChangeNodeType `json:"nodeType"` + Properties map[string]string `json:"properties"` +} + +type ChangePath struct { + Components []string `json:"components"` + Parent string `json:"parent"` + Name string `json:"name"` + Extension string `json:"extension"` + Title string `json:"toString"` +} + +type ChangeType string + +type ChangeNodeType string + +type ChangeList struct { + ListResponse + + Changes []*Change `json:"values"` +} + func (s *ProjectsService) SearchCommits(ctx context.Context, projectKey, repositorySlug string, opts *CommitSearchOptions) ([]*Commit, *Response, error) { p := fmt.Sprintf("projects/%s/repos/%s/commits", projectKey, repositorySlug) var l CommitList @@ -79,3 +134,28 @@ func (s *ProjectsService) GetCommit(ctx context.Context, projectKey, repositoryS } return &c, resp, nil } + +func (s *ProjectsService) CreateBuildStatus(ctx context.Context, projectKey, repositorySlug, commitId string, status *BuildStatus) (*Response, error) { + p := fmt.Sprintf("projects/%s/repos/%s/commits/%s/builds", projectKey, repositorySlug, commitId) + req, err := s.client.NewRequest("POST", projectsApiName, p, status) + if err != nil { + return nil, err + } + + var r Repository + resp, err := s.client.Do(ctx, req, &r) + if err != nil { + return resp, err + } + return resp, nil +} + +func (s *ProjectsService) ListChanges(ctx context.Context, projectKey, repositorySlug, commitId string, opts *ListOptions) ([]*Change, *Response, error) { + p := fmt.Sprintf("projects/%s/repos/%s/commits/%s/changes", projectKey, repositorySlug, commitId) + var l ChangeList + resp, err := s.client.GetPaged(ctx, projectsApiName, p, &l, opts) + if err != nil { + return nil, resp, err + } + return l.Changes, resp, nil +} diff --git a/bitbucket/projects_repos_commits_builds.go b/bitbucket/projects_repos_commits_builds.go deleted file mode 100644 index 616c6ef..0000000 --- a/bitbucket/projects_repos_commits_builds.go +++ /dev/null @@ -1,48 +0,0 @@ -package bitbucket - -import ( - "context" - "fmt" -) - -type BuildStatus struct { - Key string `json:"key"` - State BuildStatusState `json:"state"` - URL string `json:"url"` - BuildNumber string `json:"buildNumber,omitempty"` - Description string `json:"description,omitempty"` - Duration uint64 `json:"duration,omitempty"` - Ref string `json:"ref,omitempty"` - TestResult *BuildStatusTestResult `json:"testResults,omitempty"` -} - -type BuildStatusTestResult struct { - Failed uint32 `json:"failed"` - Skipped uint32 `json:"skipped"` - Successful uint32 `json:"successful"` -} - -type BuildStatusState string - -const ( - BuildStatusStateCancelled BuildStatusState = "CANCELLED" - BuildStatusStateFailed BuildStatusState = "FAILED" - BuildStatusStateInProgress BuildStatusState = "INPROGRESS" - BuildStatusStateSuccessful BuildStatusState = "SUCCESSFUL" - BuildStatusStateUnknown BuildStatusState = "UNKNOWN" -) - -func (s *ProjectsService) CreateBuildStatus(ctx context.Context, projectKey, repositorySlug, commitId string, status *BuildStatus) (*Response, error) { - p := fmt.Sprintf("projects/%s/repos/%s/commits/%s/builds", projectKey, repositorySlug, commitId) - req, err := s.client.NewRequest("POST", projectsApiName, p, status) - if err != nil { - return nil, err - } - - var r Repository - resp, err := s.client.Do(ctx, req, &r) - if err != nil { - return resp, err - } - return resp, nil -} diff --git a/bitbucket/projects_repos_commits_builds_test.go b/bitbucket/projects_repos_commits_builds_test.go deleted file mode 100644 index e3b4d96..0000000 --- a/bitbucket/projects_repos_commits_builds_test.go +++ /dev/null @@ -1,35 +0,0 @@ -package bitbucket - -import ( - "context" - "io" - "net/http" - "net/http/httptest" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestCreateBuildStatus(t *testing.T) { - server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { - assert.Equal(t, "POST", req.Method) - b, _ := io.ReadAll(req.Body) - assert.Equal(t, "{\"key\":\"BUILD-ID\",\"state\":\"INPROGRESS\",\"url\":\"https://ci.domain.com/builds/BUILD-ID\",\"buildNumber\":\"number\",\"duration\":10000,\"ref\":\"refs/head\"}\n", string(b)) - assert.Equal(t, "/api/latest/projects/PRJ/repos/repo/commits/commit/builds", req.URL.Path) - rw.Write([]byte(getWebhookResponse)) - })) - defer server.Close() - - client, _ := NewClient(server.URL, nil) - ctx := context.Background() - in := &BuildStatus{ - Key: "BUILD-ID", - State: BuildStatusStateInProgress, - URL: "https://ci.domain.com/builds/BUILD-ID", - BuildNumber: "number", - Duration: 10000, - Ref: "refs/head", - } - _, err := client.Projects.CreateBuildStatus(ctx, "PRJ", "repo", "commit", in) - assert.NoError(t, err) -} diff --git a/bitbucket/projects_repos_commits_test.go b/bitbucket/projects_repos_commits_test.go index 9d90ee5..bd03785 100644 --- a/bitbucket/projects_repos_commits_test.go +++ b/bitbucket/projects_repos_commits_test.go @@ -2,6 +2,7 @@ package bitbucket import ( "context" + "io" "net/http" "net/http/httptest" "testing" @@ -47,6 +48,48 @@ func TestGetCommit(t *testing.T) { } +func TestCreateBuildStatus(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + assert.Equal(t, "POST", req.Method) + b, _ := io.ReadAll(req.Body) + assert.Equal(t, "{\"key\":\"BUILD-ID\",\"state\":\"INPROGRESS\",\"url\":\"https://ci.domain.com/builds/BUILD-ID\",\"buildNumber\":\"number\",\"duration\":10000,\"ref\":\"refs/head\"}\n", string(b)) + assert.Equal(t, "/api/latest/projects/PRJ/repos/repo/commits/commit/builds", req.URL.Path) + rw.Write([]byte(getWebhookResponse)) + })) + defer server.Close() + + client, _ := NewClient(server.URL, nil) + ctx := context.Background() + in := &BuildStatus{ + Key: "BUILD-ID", + State: BuildStatusStateInProgress, + URL: "https://ci.domain.com/builds/BUILD-ID", + BuildNumber: "number", + Duration: 10000, + Ref: "refs/head", + } + _, err := client.Projects.CreateBuildStatus(ctx, "PRJ", "repo", "commit", in) + assert.NoError(t, err) +} + +func TestListChanges(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + assert.Equal(t, "GET", req.Method) + assert.Equal(t, "/api/latest/projects/KEY/repos/repo/commits/00a2f8656ec89118e65588ff3ac18328db35f6bc/changes", req.URL.Path) + + rw.Write([]byte(listChangesResponse)) + })) + defer server.Close() + + client, _ := NewClient(server.URL, nil) + ctx := context.Background() + commits, resp, err := client.Projects.ListChanges(ctx, "KEY", "repo", "00a2f8656ec89118e65588ff3ac18328db35f6bc", &ListOptions{}) + assert.NoError(t, err) + assert.Len(t, commits, 1) + assert.True(t, resp.LastPage) + assert.Equal(t, "clusters/netic-internal/prod1/releases/k8s-inventory-collector/secrets.yaml", commits[0].Path.Title) +} + const searchCommitsResponse = `{ "values": [ { @@ -168,3 +211,49 @@ const getCommitResponse = `{ } ] }` + +const listChangesResponse = `{ + "fromHash": null, + "toHash": "00a2f8656ec89118e65588ff3ac18328db35f6bc", + "properties": {}, + "values": [ + { + "contentId": "1c602c0799d6d852a07affd0ac06b4ce8548d6f0", + "fromContentId": "e00a3bef11aec0b71858ebbd07d3158c3ef8e142", + "path": { + "components": [ + "clusters", + "netic-internal", + "prod1", + "releases", + "k8s-inventory-collector", + "secrets.yaml" + ], + "parent": "clusters/netic-internal/prod1/releases/k8s-inventory-collector", + "name": "secrets.yaml", + "extension": "yaml", + "toString": "clusters/netic-internal/prod1/releases/k8s-inventory-collector/secrets.yaml" + }, + "executable": false, + "percentUnchanged": -1, + "type": "MODIFY", + "nodeType": "FILE", + "srcExecutable": false, + "links": { + "self": [ + { + "href": "https://git.domain.com/projects/KUB/repos/kubernetes-config/commits/00a2f8656ec89118e65588ff3ac18328db35f6bc#clusters/netic-internal/prod1/releases/k8s-inventory-collector/secrets.yaml" + } + ] + }, + "properties": { + "gitChangeType": "MODIFY" + } + } + ], + "size": 1, + "isLastPage": true, + "start": 0, + "limit": 25, + "nextPageStart": null + }`