Skip to content

Commit 5f88460

Browse files
committed
fix: add support for deployment status API with tests
1 parent fe4b569 commit 5f88460

9 files changed

+372
-24
lines changed

scm/deploy.go

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ type (
4444
DeploymentStatus struct {
4545
ID string
4646
State string
47-
Author User
47+
Author *User
4848
Description string
4949
Environment string
5050
DeploymentLink string
@@ -56,6 +56,17 @@ type (
5656
Updated time.Time
5757
}
5858

59+
// DeploymentStatusInput the input to creating a status of a deployment
60+
DeploymentStatusInput struct {
61+
State string
62+
TargetLink string
63+
LogLink string
64+
Description string
65+
Environment string
66+
EnvironmentLink string
67+
AutoInactive bool
68+
}
69+
5970
// DeploymentService a service for working with deployments and deployment services
6071
DeploymentService interface {
6172
// Find find a deployment by id.
@@ -74,15 +85,9 @@ type (
7485
FindStatus(ctx context.Context, repoFullName string, deploymentID string, statusID string) (*DeploymentStatus, *Response, error)
7586

7687
// List returns a list of deployments.
77-
ListStatus(ctx context.Context, repoFullName string, options ListOptions) ([]*DeploymentStatus, *Response, error)
88+
ListStatus(ctx context.Context, repoFullName string, deploymentID string, options ListOptions) ([]*DeploymentStatus, *Response, error)
7889

7990
// Create creates a new deployment.
80-
CreateStatus(ctx context.Context, repoFullName string, deployment *DeploymentStatus) (*DeploymentStatus, *Response, error)
81-
82-
// Update updates a deployment.
83-
UpdateStatus(ctx context.Context, repoFullName string, deployment *DeploymentStatus) (*DeploymentStatus, *Response, error)
84-
85-
// Delete deletes a deployment.
86-
DeleteStatus(ctx context.Context, repoFullName string, deploymentID string, statusID string) (*Response, error)
91+
CreateStatus(ctx context.Context, repoFullName string, deploymentID string, deployment *DeploymentStatusInput) (*DeploymentStatus, *Response, error)
8792
}
8893
)

scm/driver/github/deploy.go

Lines changed: 81 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,33 @@ type deploymentInput struct {
4646
ProductionEnvironment bool `json:"production_environment"`
4747
}
4848

49+
type deploymentStatus struct {
50+
ID int `json:"id"`
51+
State string `json:"state"`
52+
Author *user `json:"creator"`
53+
Description string `json:"description"`
54+
Environment string `json:"environment"`
55+
DeploymentLink string `json:"deployment_url"`
56+
EnvironmentLink string `json:"environment_url"`
57+
LogLink string `json:"log_url"`
58+
RepositoryLink string `json:"repository_url"`
59+
TargetLink string `json:"target_url"`
60+
Created time.Time `json:"created_at"`
61+
Updated time.Time `json:"updated_at"`
62+
}
63+
64+
type deploymentStatusInput struct {
65+
State string `json:"state"`
66+
TargetLink string `json:"target_url"`
67+
LogLink string `json:"log_url"`
68+
Description string `json:"description"`
69+
Environment string `json:"environment"`
70+
EnvironmentLink string `json:"environment_url"`
71+
AutoInactive bool `json:"auto_inactive"`
72+
}
73+
4974
func (s *deploymentService) Find(ctx context.Context, repoFullName string, deploymentID string) (*scm.Deployment, *scm.Response, error) {
50-
path := fmt.Sprintf("repos/%s/deployments/%s?", repoFullName, deploymentID)
75+
path := fmt.Sprintf("repos/%s/deployments/%s", repoFullName, deploymentID)
5176
out := new(deployment)
5277
res, err := s.client.do(ctx, "GET", path, nil, out)
5378
return convertDeployment(out, repoFullName), res, err
@@ -69,27 +94,30 @@ func (s *deploymentService) Create(ctx context.Context, repoFullName string, dep
6994
}
7095

7196
func (s *deploymentService) Delete(ctx context.Context, repoFullName string, deploymentID string) (*scm.Response, error) {
72-
panic("implement me")
97+
path := fmt.Sprintf("repos/%s/deployments/%s", repoFullName, deploymentID)
98+
return s.client.do(ctx, "DELETE", path, nil, nil)
7399
}
74100

75101
func (s *deploymentService) FindStatus(ctx context.Context, repoFullName string, deploymentID string, statusID string) (*scm.DeploymentStatus, *scm.Response, error) {
76-
panic("implement me")
77-
}
78-
79-
func (s *deploymentService) ListStatus(ctx context.Context, repoFullName string, options scm.ListOptions) ([]*scm.DeploymentStatus, *scm.Response, error) {
80-
panic("implement me")
81-
}
82-
83-
func (s *deploymentService) CreateStatus(ctx context.Context, repoFullName string, deployment *scm.DeploymentStatus) (*scm.DeploymentStatus, *scm.Response, error) {
84-
panic("implement me")
102+
path := fmt.Sprintf("repos/%s/deployments/%s/statuses/%s", repoFullName, deploymentID, statusID)
103+
out := new(deploymentStatus)
104+
res, err := s.client.do(ctx, "GET", path, nil, out)
105+
return convertDeploymentStatus(out), res, err
85106
}
86107

87-
func (s *deploymentService) UpdateStatus(ctx context.Context, repoFullName string, deployment *scm.DeploymentStatus) (*scm.DeploymentStatus, *scm.Response, error) {
88-
panic("implement me")
108+
func (s *deploymentService) ListStatus(ctx context.Context, repoFullName string, deploymentID string, opts scm.ListOptions) ([]*scm.DeploymentStatus, *scm.Response, error) {
109+
path := fmt.Sprintf("repos/%s/deployments/%s/statuses?%s", repoFullName, deploymentID, encodeListOptions(opts))
110+
out := []*deploymentStatus{}
111+
res, err := s.client.do(ctx, "GET", path, nil, &out)
112+
return convertDeploymentStatusList(out), res, err
89113
}
90114

91-
func (s *deploymentService) DeleteStatus(ctx context.Context, repoFullName string, deploymentID string, statusID string) (*scm.Response, error) {
92-
panic("implement me")
115+
func (s *deploymentService) CreateStatus(ctx context.Context, repoFullName string, deploymentID string, deploymentStatusInput *scm.DeploymentStatusInput) (*scm.DeploymentStatus, *scm.Response, error) {
116+
path := fmt.Sprintf("repos/%s/deployments/%s/statuses", repoFullName, deploymentID)
117+
in := convertToDeploymentStatusInput(deploymentStatusInput)
118+
out := new(deploymentStatus)
119+
res, err := s.client.do(ctx, "POST", path, in, out)
120+
return convertDeploymentStatus(out), res, err
93121
}
94122

95123
func convertDeploymentList(out []*deployment, fullName string) []*scm.Deployment {
@@ -100,6 +128,15 @@ func convertDeploymentList(out []*deployment, fullName string) []*scm.Deployment
100128
return answer
101129
}
102130

131+
func convertDeploymentStatusList(out []*deploymentStatus) []*scm.DeploymentStatus {
132+
answer := []*scm.DeploymentStatus{}
133+
for _, o := range out {
134+
answer = append(answer, convertDeploymentStatus(o))
135+
}
136+
return answer
137+
138+
}
139+
103140
func convertToDeploymentInput(from *scm.DeploymentInput) *deploymentInput {
104141
return &deploymentInput{
105142
Ref: from.Ref,
@@ -139,3 +176,32 @@ func convertDeployment(from *deployment, fullName string) *scm.Deployment {
139176
}
140177
return dst
141178
}
179+
180+
func convertDeploymentStatus(from *deploymentStatus) *scm.DeploymentStatus {
181+
return &scm.DeploymentStatus{
182+
ID: strconv.Itoa(from.ID),
183+
State: from.State,
184+
Author: convertUser(from.Author),
185+
Description: from.Description,
186+
Environment: from.Environment,
187+
DeploymentLink: from.DeploymentLink,
188+
EnvironmentLink: from.EnvironmentLink,
189+
LogLink: from.LogLink,
190+
RepositoryLink: from.RepositoryLink,
191+
TargetLink: from.TargetLink,
192+
Created: from.Created,
193+
Updated: from.Updated,
194+
}
195+
}
196+
197+
func convertToDeploymentStatusInput(from *scm.DeploymentStatusInput) *deploymentStatusInput {
198+
return &deploymentStatusInput{
199+
State: from.State,
200+
TargetLink: from.TargetLink,
201+
LogLink: from.LogLink,
202+
Description: from.Description,
203+
Environment: from.Environment,
204+
EnvironmentLink: from.EnvironmentLink,
205+
AutoInactive: from.AutoInactive,
206+
}
207+
}

scm/driver/github/deploy_test.go

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,108 @@ func TestDeploymentCreate(t *testing.T) {
137137
t.Run("Rate", testRate(res))
138138
}
139139

140+
func TestDeploymentStatusList(t *testing.T) {
141+
defer gock.Off()
142+
143+
gock.New("https://api.github.com").
144+
Get("/repos/octocat/example/deployments/1/statuses").
145+
MatchParam("page", "1").
146+
MatchParam("per_page", "30").
147+
Reply(200).
148+
Type("application/json").
149+
SetHeaders(mockHeaders).
150+
SetHeaders(mockPageHeaders).
151+
File("testdata/deploy_statuses.json")
152+
153+
client := NewDefault()
154+
got, res, err := client.Deployments.ListStatus(context.Background(), "octocat/example", "1", scm.ListOptions{Page: 1, Size: 30})
155+
if err != nil {
156+
t.Error(err)
157+
return
158+
}
159+
160+
want := []*scm.DeploymentStatus{}
161+
raw, _ := ioutil.ReadFile("testdata/deploy_statuses.json.golden")
162+
json.Unmarshal(raw, &want)
163+
164+
if diff := cmp.Diff(got, want); diff != "" {
165+
t.Errorf("Unexpected Results")
166+
t.Log(diff)
167+
168+
logGot(t, got)
169+
}
170+
171+
t.Run("Request", testRequest(res))
172+
t.Run("Rate", testRate(res))
173+
t.Run("Page", testPage(res))
174+
}
175+
176+
func TestDeploymentStatusFind(t *testing.T) {
177+
defer gock.Off()
178+
179+
gock.New("https://api.github.com").
180+
Get("/repos/octocat/example/deployments/1/statuses/1").
181+
Reply(200).
182+
Type("application/json").
183+
SetHeaders(mockHeaders).
184+
File("testdata/deploy_status.json")
185+
186+
client := NewDefault()
187+
got, res, err := client.Deployments.FindStatus(context.Background(), "octocat/example", "1", "1")
188+
if err != nil {
189+
t.Error(err)
190+
return
191+
}
192+
193+
want := new(scm.DeploymentStatus)
194+
raw, _ := ioutil.ReadFile("testdata/deploy_status.json.golden")
195+
json.Unmarshal(raw, want)
196+
197+
if diff := cmp.Diff(got, want); diff != "" {
198+
t.Errorf("Unexpected Results")
199+
t.Log(diff)
200+
201+
logGot(t, got)
202+
}
203+
204+
t.Run("Request", testRequest(res))
205+
t.Run("Rate", testRate(res))
206+
}
207+
208+
func TestDeploymentStatusCreate(t *testing.T) {
209+
defer gock.Off()
210+
211+
gock.New("https://api.github.com").
212+
Post("repos/octocat/example/deployments/1/statuses").
213+
Reply(201).
214+
Type("application/json").
215+
SetHeaders(mockHeaders).
216+
File("testdata/deploy_status_create.json")
217+
218+
in := &scm.DeploymentStatusInput{}
219+
220+
client := NewDefault()
221+
got, res, err := client.Deployments.CreateStatus(context.Background(), "octocat/example", "1", in)
222+
if err != nil {
223+
t.Error(err)
224+
return
225+
}
226+
227+
want := new(scm.DeploymentStatus)
228+
raw, _ := ioutil.ReadFile("testdata/deploy_status_create.json.golden")
229+
json.Unmarshal(raw, want)
230+
231+
if diff := cmp.Diff(got, want); diff != "" {
232+
t.Errorf("Unexpected Results")
233+
t.Log(diff)
234+
235+
logGot(t, got)
236+
}
237+
238+
t.Run("Request", testRequest(res))
239+
t.Run("Rate", testRate(res))
240+
}
241+
140242
func logGot(t *testing.T, got interface{}) {
141243
data, _ := json.Marshal(got)
142244
t.Log("got JSON:")
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"url": "https://api.github.com/repos/octocat/example/deployments/42/statuses/1",
3+
"id": 1,
4+
"node_id": "MDE2OkRlcGxveW1lbnRTdGF0dXMx",
5+
"state": "success",
6+
"creator": {
7+
"login": "octocat",
8+
"id": 1,
9+
"node_id": "MDQ6VXNlcjE=",
10+
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
11+
"gravatar_id": "",
12+
"url": "https://api.github.com/users/octocat",
13+
"html_url": "https://github.com/octocat",
14+
"followers_url": "https://api.github.com/users/octocat/followers",
15+
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
16+
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
17+
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
18+
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
19+
"organizations_url": "https://api.github.com/users/octocat/orgs",
20+
"repos_url": "https://api.github.com/users/octocat/repos",
21+
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
22+
"received_events_url": "https://api.github.com/users/octocat/received_events",
23+
"type": "User",
24+
"site_admin": false
25+
},
26+
"description": "Deployment finished successfully.",
27+
"environment": "production",
28+
"target_url": "https://example.com/deployment/42/output",
29+
"created_at": "2012-07-20T01:19:13Z",
30+
"updated_at": "2012-07-20T01:19:13Z",
31+
"deployment_url": "https://api.github.com/repos/octocat/example/deployments/42",
32+
"repository_url": "https://api.github.com/repos/octocat/example",
33+
"environment_url": "",
34+
"log_url": "https://example.com/deployment/42/output"
35+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"ID": "1",
3+
"State": "success",
4+
"Author": {
5+
"Login": "octocat",
6+
"Name": "",
7+
"Email": "",
8+
"Avatar": "https://github.com/images/error/octocat_happy.gif",
9+
"Link": "https://github.com/octocat",
10+
"Created": "0001-01-01T00:00:00Z",
11+
"Updated": "0001-01-01T00:00:00Z"
12+
},
13+
"Description": "Deployment finished successfully.",
14+
"Environment": "production",
15+
"DeploymentLink": "https://api.github.com/repos/octocat/example/deployments/42",
16+
"EnvironmentLink": "",
17+
"LogLink": "https://example.com/deployment/42/output",
18+
"RepositoryLink": "https://api.github.com/repos/octocat/example",
19+
"TargetLink": "https://example.com/deployment/42/output",
20+
"Created": "2012-07-20T01:19:13Z",
21+
"Updated": "2012-07-20T01:19:13Z"
22+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"url": "https://api.github.com/repos/octocat/example/deployments/42/statuses/1",
3+
"id": 1,
4+
"node_id": "MDE2OkRlcGxveW1lbnRTdGF0dXMx",
5+
"state": "success",
6+
"creator": {
7+
"login": "octocat",
8+
"id": 1,
9+
"node_id": "MDQ6VXNlcjE=",
10+
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
11+
"gravatar_id": "",
12+
"url": "https://api.github.com/users/octocat",
13+
"html_url": "https://github.com/octocat",
14+
"followers_url": "https://api.github.com/users/octocat/followers",
15+
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
16+
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
17+
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
18+
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
19+
"organizations_url": "https://api.github.com/users/octocat/orgs",
20+
"repos_url": "https://api.github.com/users/octocat/repos",
21+
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
22+
"received_events_url": "https://api.github.com/users/octocat/received_events",
23+
"type": "User",
24+
"site_admin": false
25+
},
26+
"description": "Deployment finished successfully.",
27+
"environment": "production",
28+
"target_url": "https://example.com/deployment/42/output",
29+
"created_at": "2012-07-20T01:19:13Z",
30+
"updated_at": "2012-07-20T01:19:13Z",
31+
"deployment_url": "https://api.github.com/repos/octocat/example/deployments/42",
32+
"repository_url": "https://api.github.com/repos/octocat/example",
33+
"environment_url": "",
34+
"log_url": "https://example.com/deployment/42/output"
35+
}

0 commit comments

Comments
 (0)