Skip to content

Commit 0cf22c7

Browse files
Merge pull request drone#77 from jstrachan/stuff
fix: add support for a Deployments API
2 parents 010ed53 + 7f82160 commit 0cf22c7

21 files changed

+941
-4
lines changed

README.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# go-scm
22

3+
[![Documentation](https://godoc.org/github.com/jenkins-x/go-scm?status.svg)](https://pkg.go.dev/mod/github.com/jenkins-x/go-scm)
4+
[![Go Report Card](https://goreportcard.com/badge/github.com/jenkins-x/go-scm)](https://goreportcard.com/report/github.com/jenkins-x/go-scm)
5+
6+
37
A small library with minimal depenencies for working with Webhooks, Commits, Issues, Pull Requests, Comments, Reviews, Teams and more on multiple git provider:
48

59
* [GitHub](https://github.com/jenkins-x/go-scm/blob/master/scm/driver/github/github.go#L46)

scm/client.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -94,17 +94,18 @@ type (
9494

9595
// Services used for communicating with the API.
9696
Driver Driver
97+
Apps AppService
9798
Contents ContentService
99+
Deployments DeploymentService
98100
Git GitService
101+
GraphQL GraphQLService
99102
Organizations OrganizationService
100103
Issues IssueService
101104
PullRequests PullRequestService
102105
Repositories RepositoryService
103106
Reviews ReviewService
104107
Users UserService
105108
Webhooks WebhookService
106-
GraphQL GraphQLService
107-
Apps AppService
108109

109110
// DumpResponse optionally specifies a function to
110111
// dump the the response body for debugging purposes.

scm/deploy.go

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package scm
2+
3+
import (
4+
"context"
5+
"time"
6+
)
7+
8+
type (
9+
// Deployment represents a request to deploy a version/ref/sha in some environment
10+
Deployment struct {
11+
ID string
12+
Namespace string
13+
Name string
14+
Link string
15+
Sha string
16+
Ref string
17+
FullName string
18+
Description string
19+
OriginalEnvironment string
20+
Environment string
21+
RepositoryLink string
22+
StatusLink string
23+
Author *User
24+
Created time.Time
25+
Updated time.Time
26+
TransientEnvironment bool
27+
ProductionEnvironment bool
28+
}
29+
30+
// DeploymentInput the input to create a new deployment
31+
DeploymentInput struct {
32+
Ref string
33+
Task string
34+
Payload string
35+
Environment string
36+
Description string
37+
RequiredContexts []string
38+
AutoMerge bool
39+
TransientEnvironment bool
40+
ProductionEnvironment bool
41+
}
42+
43+
// DeploymentStatus represents the status of a deployment
44+
DeploymentStatus struct {
45+
ID string
46+
State string
47+
Author *User
48+
Description string
49+
Environment string
50+
DeploymentLink string
51+
EnvironmentLink string
52+
LogLink string
53+
RepositoryLink string
54+
TargetLink string
55+
Created time.Time
56+
Updated time.Time
57+
}
58+
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+
70+
// DeploymentService a service for working with deployments and deployment services
71+
DeploymentService interface {
72+
// Find find a deployment by id.
73+
Find(ctx context.Context, repoFullName string, deploymentID string) (*Deployment, *Response, error)
74+
75+
// List returns a list of deployments.
76+
List(ctx context.Context, repoFullName string, opts ListOptions) ([]*Deployment, *Response, error)
77+
78+
// Create creates a new deployment.
79+
Create(ctx context.Context, repoFullName string, deployment *DeploymentInput) (*Deployment, *Response, error)
80+
81+
// Delete deletes a deployment.
82+
Delete(ctx context.Context, repoFullName string, deploymentID string) (*Response, error)
83+
84+
// FindStatus find a deployment status by id.
85+
FindStatus(ctx context.Context, repoFullName string, deploymentID string, statusID string) (*DeploymentStatus, *Response, error)
86+
87+
// List returns a list of deployments.
88+
ListStatus(ctx context.Context, repoFullName string, deploymentID string, options ListOptions) ([]*DeploymentStatus, *Response, error)
89+
90+
// Create creates a new deployment.
91+
CreateStatus(ctx context.Context, repoFullName string, deploymentID string, deployment *DeploymentStatusInput) (*DeploymentStatus, *Response, error)
92+
}
93+
)

scm/driver/fake/repo.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package fake
22

33
import (
44
"context"
5+
"fmt"
56
"strings"
67
"time"
78

@@ -106,10 +107,12 @@ func (s *repositoryService) ListStatus(ctx context.Context, repo string, ref str
106107

107108
func (s *repositoryService) Create(ctx context.Context, input *scm.RepositoryInput) (*scm.Repository, *scm.Response, error) {
108109
s.data.CreateRepositories = append(s.data.CreateRepositories, input)
110+
fullName := scm.Join(input.Namespace, input.Name)
109111
repo := &scm.Repository{
110112
Namespace: input.Namespace,
111113
Name: input.Name,
112-
FullName: scm.Join(input.Namespace, input.Name),
114+
FullName: fullName,
115+
Link: fmt.Sprintf("https://fake.com/%s.git", fullName),
113116
Created: time.Now(),
114117
}
115118
s.data.Repositories = append(s.data.Repositories, repo)

scm/driver/github/deploy.go

+207
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
package github
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"strconv"
7+
"strings"
8+
"time"
9+
10+
"github.com/jenkins-x/go-scm/scm"
11+
)
12+
13+
type deploymentService struct {
14+
client *wrapper
15+
}
16+
17+
type deployment struct {
18+
Namespace string
19+
Name string
20+
FullName string
21+
ID int `json:"id"`
22+
Link string `json:"url"`
23+
Sha string `json:"sha"`
24+
Ref string `json:"ref"`
25+
Description string `json:"description"`
26+
OriginalEnvironment string `json:"original_environment"`
27+
Environment string `json:"environment"`
28+
RepositoryLink string `json:"repository_url"`
29+
StatusLink string `json:"statuses_url"`
30+
Author *user `json:"creator"`
31+
Created time.Time `json:"created_at"`
32+
Updated time.Time `json:"updated_at"`
33+
TransientEnvironment bool `json:"transient_environment"`
34+
ProductionEnvironment bool `json:"production_environment"`
35+
}
36+
37+
type deploymentInput struct {
38+
Ref string `json:"ref"`
39+
Task string `json:"task"`
40+
Payload string `json:"payload"`
41+
Environment string `json:"environment"`
42+
Description string `json:"description"`
43+
RequiredContexts []string `json:"required_contexts"`
44+
AutoMerge bool `json:"auto_merge"`
45+
TransientEnvironment bool `json:"transient_environment"`
46+
ProductionEnvironment bool `json:"production_environment"`
47+
}
48+
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+
74+
func (s *deploymentService) Find(ctx context.Context, repoFullName string, deploymentID string) (*scm.Deployment, *scm.Response, error) {
75+
path := fmt.Sprintf("repos/%s/deployments/%s", repoFullName, deploymentID)
76+
out := new(deployment)
77+
res, err := s.client.do(ctx, "GET", path, nil, out)
78+
return convertDeployment(out, repoFullName), res, err
79+
}
80+
81+
func (s *deploymentService) List(ctx context.Context, repoFullName string, opts scm.ListOptions) ([]*scm.Deployment, *scm.Response, error) {
82+
path := fmt.Sprintf("repos/%s/deployments?%s", repoFullName, encodeListOptions(opts))
83+
out := []*deployment{}
84+
res, err := s.client.do(ctx, "GET", path, nil, &out)
85+
return convertDeploymentList(out, repoFullName), res, err
86+
}
87+
88+
func (s *deploymentService) Create(ctx context.Context, repoFullName string, deploymentInput *scm.DeploymentInput) (*scm.Deployment, *scm.Response, error) {
89+
path := fmt.Sprintf("repos/%s/deployments", repoFullName)
90+
in := convertToDeploymentInput(deploymentInput)
91+
out := new(deployment)
92+
res, err := s.client.do(ctx, "POST", path, in, out)
93+
return convertDeployment(out, repoFullName), res, err
94+
}
95+
96+
func (s *deploymentService) Delete(ctx context.Context, repoFullName string, deploymentID string) (*scm.Response, error) {
97+
path := fmt.Sprintf("repos/%s/deployments/%s", repoFullName, deploymentID)
98+
return s.client.do(ctx, "DELETE", path, nil, nil)
99+
}
100+
101+
func (s *deploymentService) FindStatus(ctx context.Context, repoFullName string, deploymentID string, statusID string) (*scm.DeploymentStatus, *scm.Response, error) {
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
106+
}
107+
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
113+
}
114+
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
121+
}
122+
123+
func convertDeploymentList(out []*deployment, fullName string) []*scm.Deployment {
124+
answer := []*scm.Deployment{}
125+
for _, o := range out {
126+
answer = append(answer, convertDeployment(o, fullName))
127+
}
128+
return answer
129+
}
130+
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+
140+
func convertToDeploymentInput(from *scm.DeploymentInput) *deploymentInput {
141+
return &deploymentInput{
142+
Ref: from.Ref,
143+
Task: from.Task,
144+
Payload: from.Payload,
145+
Environment: from.Environment,
146+
Description: from.Description,
147+
RequiredContexts: from.RequiredContexts,
148+
AutoMerge: from.AutoMerge,
149+
TransientEnvironment: from.TransientEnvironment,
150+
ProductionEnvironment: from.ProductionEnvironment,
151+
}
152+
}
153+
154+
func convertDeployment(from *deployment, fullName string) *scm.Deployment {
155+
dst := &scm.Deployment{
156+
ID: strconv.Itoa(from.ID),
157+
Link: from.Link,
158+
Sha: from.Sha,
159+
Ref: from.Ref,
160+
FullName: fullName,
161+
Description: from.Description,
162+
OriginalEnvironment: from.OriginalEnvironment,
163+
Environment: from.Environment,
164+
RepositoryLink: from.RepositoryLink,
165+
StatusLink: from.StatusLink,
166+
Author: convertUser(from.Author),
167+
Created: from.Created,
168+
Updated: from.Updated,
169+
TransientEnvironment: from.TransientEnvironment,
170+
ProductionEnvironment: from.ProductionEnvironment,
171+
}
172+
names := strings.Split(fullName, "/")
173+
if len(names) > 1 {
174+
dst.Namespace = names[0]
175+
dst.Name = names[1]
176+
}
177+
return dst
178+
}
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+
}

0 commit comments

Comments
 (0)