Skip to content

Commit

Permalink
Merge pull request drone#77 from jstrachan/stuff
Browse files Browse the repository at this point in the history
fix: add support for a Deployments API
  • Loading branch information
jenkins-x-bot committed Feb 24, 2020
2 parents 010ed53 + 7f82160 commit 0cf22c7
Show file tree
Hide file tree
Showing 21 changed files with 941 additions and 4 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# go-scm

[![Documentation](https://godoc.org/github.com/jenkins-x/go-scm?status.svg)](https://pkg.go.dev/mod/github.com/jenkins-x/go-scm)
[![Go Report Card](https://goreportcard.com/badge/github.com/jenkins-x/go-scm)](https://goreportcard.com/report/github.com/jenkins-x/go-scm)


A small library with minimal depenencies for working with Webhooks, Commits, Issues, Pull Requests, Comments, Reviews, Teams and more on multiple git provider:

* [GitHub](https://github.com/jenkins-x/go-scm/blob/master/scm/driver/github/github.go#L46)
Expand Down
5 changes: 3 additions & 2 deletions scm/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,17 +94,18 @@ type (

// Services used for communicating with the API.
Driver Driver
Apps AppService
Contents ContentService
Deployments DeploymentService
Git GitService
GraphQL GraphQLService
Organizations OrganizationService
Issues IssueService
PullRequests PullRequestService
Repositories RepositoryService
Reviews ReviewService
Users UserService
Webhooks WebhookService
GraphQL GraphQLService
Apps AppService

// DumpResponse optionally specifies a function to
// dump the the response body for debugging purposes.
Expand Down
93 changes: 93 additions & 0 deletions scm/deploy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package scm

import (
"context"
"time"
)

type (
// Deployment represents a request to deploy a version/ref/sha in some environment
Deployment struct {
ID string
Namespace string
Name string
Link string
Sha string
Ref string
FullName string
Description string
OriginalEnvironment string
Environment string
RepositoryLink string
StatusLink string
Author *User
Created time.Time
Updated time.Time
TransientEnvironment bool
ProductionEnvironment bool
}

// DeploymentInput the input to create a new deployment
DeploymentInput struct {
Ref string
Task string
Payload string
Environment string
Description string
RequiredContexts []string
AutoMerge bool
TransientEnvironment bool
ProductionEnvironment bool
}

// DeploymentStatus represents the status of a deployment
DeploymentStatus struct {
ID string
State string
Author *User
Description string
Environment string
DeploymentLink string
EnvironmentLink string
LogLink string
RepositoryLink string
TargetLink string
Created time.Time
Updated time.Time
}

// DeploymentStatusInput the input to creating a status of a deployment
DeploymentStatusInput struct {
State string
TargetLink string
LogLink string
Description string
Environment string
EnvironmentLink string
AutoInactive bool
}

// DeploymentService a service for working with deployments and deployment services
DeploymentService interface {
// Find find a deployment by id.
Find(ctx context.Context, repoFullName string, deploymentID string) (*Deployment, *Response, error)

// List returns a list of deployments.
List(ctx context.Context, repoFullName string, opts ListOptions) ([]*Deployment, *Response, error)

// Create creates a new deployment.
Create(ctx context.Context, repoFullName string, deployment *DeploymentInput) (*Deployment, *Response, error)

// Delete deletes a deployment.
Delete(ctx context.Context, repoFullName string, deploymentID string) (*Response, error)

// FindStatus find a deployment status by id.
FindStatus(ctx context.Context, repoFullName string, deploymentID string, statusID string) (*DeploymentStatus, *Response, error)

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

// Create creates a new deployment.
CreateStatus(ctx context.Context, repoFullName string, deploymentID string, deployment *DeploymentStatusInput) (*DeploymentStatus, *Response, error)
}
)
5 changes: 4 additions & 1 deletion scm/driver/fake/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package fake

import (
"context"
"fmt"
"strings"
"time"

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

func (s *repositoryService) Create(ctx context.Context, input *scm.RepositoryInput) (*scm.Repository, *scm.Response, error) {
s.data.CreateRepositories = append(s.data.CreateRepositories, input)
fullName := scm.Join(input.Namespace, input.Name)
repo := &scm.Repository{
Namespace: input.Namespace,
Name: input.Name,
FullName: scm.Join(input.Namespace, input.Name),
FullName: fullName,
Link: fmt.Sprintf("https://fake.com/%s.git", fullName),
Created: time.Now(),
}
s.data.Repositories = append(s.data.Repositories, repo)
Expand Down
207 changes: 207 additions & 0 deletions scm/driver/github/deploy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
package github

import (
"context"
"fmt"
"strconv"
"strings"
"time"

"github.com/jenkins-x/go-scm/scm"
)

type deploymentService struct {
client *wrapper
}

type deployment struct {
Namespace string
Name string
FullName string
ID int `json:"id"`
Link string `json:"url"`
Sha string `json:"sha"`
Ref string `json:"ref"`
Description string `json:"description"`
OriginalEnvironment string `json:"original_environment"`
Environment string `json:"environment"`
RepositoryLink string `json:"repository_url"`
StatusLink string `json:"statuses_url"`
Author *user `json:"creator"`
Created time.Time `json:"created_at"`
Updated time.Time `json:"updated_at"`
TransientEnvironment bool `json:"transient_environment"`
ProductionEnvironment bool `json:"production_environment"`
}

type deploymentInput struct {
Ref string `json:"ref"`
Task string `json:"task"`
Payload string `json:"payload"`
Environment string `json:"environment"`
Description string `json:"description"`
RequiredContexts []string `json:"required_contexts"`
AutoMerge bool `json:"auto_merge"`
TransientEnvironment bool `json:"transient_environment"`
ProductionEnvironment bool `json:"production_environment"`
}

type deploymentStatus struct {
ID int `json:"id"`
State string `json:"state"`
Author *user `json:"creator"`
Description string `json:"description"`
Environment string `json:"environment"`
DeploymentLink string `json:"deployment_url"`
EnvironmentLink string `json:"environment_url"`
LogLink string `json:"log_url"`
RepositoryLink string `json:"repository_url"`
TargetLink string `json:"target_url"`
Created time.Time `json:"created_at"`
Updated time.Time `json:"updated_at"`
}

type deploymentStatusInput struct {
State string `json:"state"`
TargetLink string `json:"target_url"`
LogLink string `json:"log_url"`
Description string `json:"description"`
Environment string `json:"environment"`
EnvironmentLink string `json:"environment_url"`
AutoInactive bool `json:"auto_inactive"`
}

func (s *deploymentService) Find(ctx context.Context, repoFullName string, deploymentID string) (*scm.Deployment, *scm.Response, error) {
path := fmt.Sprintf("repos/%s/deployments/%s", repoFullName, deploymentID)
out := new(deployment)
res, err := s.client.do(ctx, "GET", path, nil, out)
return convertDeployment(out, repoFullName), res, err
}

func (s *deploymentService) List(ctx context.Context, repoFullName string, opts scm.ListOptions) ([]*scm.Deployment, *scm.Response, error) {
path := fmt.Sprintf("repos/%s/deployments?%s", repoFullName, encodeListOptions(opts))
out := []*deployment{}
res, err := s.client.do(ctx, "GET", path, nil, &out)
return convertDeploymentList(out, repoFullName), res, err
}

func (s *deploymentService) Create(ctx context.Context, repoFullName string, deploymentInput *scm.DeploymentInput) (*scm.Deployment, *scm.Response, error) {
path := fmt.Sprintf("repos/%s/deployments", repoFullName)
in := convertToDeploymentInput(deploymentInput)
out := new(deployment)
res, err := s.client.do(ctx, "POST", path, in, out)
return convertDeployment(out, repoFullName), res, err
}

func (s *deploymentService) Delete(ctx context.Context, repoFullName string, deploymentID string) (*scm.Response, error) {
path := fmt.Sprintf("repos/%s/deployments/%s", repoFullName, deploymentID)
return s.client.do(ctx, "DELETE", path, nil, nil)
}

func (s *deploymentService) FindStatus(ctx context.Context, repoFullName string, deploymentID string, statusID string) (*scm.DeploymentStatus, *scm.Response, error) {
path := fmt.Sprintf("repos/%s/deployments/%s/statuses/%s", repoFullName, deploymentID, statusID)
out := new(deploymentStatus)
res, err := s.client.do(ctx, "GET", path, nil, out)
return convertDeploymentStatus(out), res, err
}

func (s *deploymentService) ListStatus(ctx context.Context, repoFullName string, deploymentID string, opts scm.ListOptions) ([]*scm.DeploymentStatus, *scm.Response, error) {
path := fmt.Sprintf("repos/%s/deployments/%s/statuses?%s", repoFullName, deploymentID, encodeListOptions(opts))
out := []*deploymentStatus{}
res, err := s.client.do(ctx, "GET", path, nil, &out)
return convertDeploymentStatusList(out), res, err
}

func (s *deploymentService) CreateStatus(ctx context.Context, repoFullName string, deploymentID string, deploymentStatusInput *scm.DeploymentStatusInput) (*scm.DeploymentStatus, *scm.Response, error) {
path := fmt.Sprintf("repos/%s/deployments/%s/statuses", repoFullName, deploymentID)
in := convertToDeploymentStatusInput(deploymentStatusInput)
out := new(deploymentStatus)
res, err := s.client.do(ctx, "POST", path, in, out)
return convertDeploymentStatus(out), res, err
}

func convertDeploymentList(out []*deployment, fullName string) []*scm.Deployment {
answer := []*scm.Deployment{}
for _, o := range out {
answer = append(answer, convertDeployment(o, fullName))
}
return answer
}

func convertDeploymentStatusList(out []*deploymentStatus) []*scm.DeploymentStatus {
answer := []*scm.DeploymentStatus{}
for _, o := range out {
answer = append(answer, convertDeploymentStatus(o))
}
return answer

}

func convertToDeploymentInput(from *scm.DeploymentInput) *deploymentInput {
return &deploymentInput{
Ref: from.Ref,
Task: from.Task,
Payload: from.Payload,
Environment: from.Environment,
Description: from.Description,
RequiredContexts: from.RequiredContexts,
AutoMerge: from.AutoMerge,
TransientEnvironment: from.TransientEnvironment,
ProductionEnvironment: from.ProductionEnvironment,
}
}

func convertDeployment(from *deployment, fullName string) *scm.Deployment {
dst := &scm.Deployment{
ID: strconv.Itoa(from.ID),
Link: from.Link,
Sha: from.Sha,
Ref: from.Ref,
FullName: fullName,
Description: from.Description,
OriginalEnvironment: from.OriginalEnvironment,
Environment: from.Environment,
RepositoryLink: from.RepositoryLink,
StatusLink: from.StatusLink,
Author: convertUser(from.Author),
Created: from.Created,
Updated: from.Updated,
TransientEnvironment: from.TransientEnvironment,
ProductionEnvironment: from.ProductionEnvironment,
}
names := strings.Split(fullName, "/")
if len(names) > 1 {
dst.Namespace = names[0]
dst.Name = names[1]
}
return dst
}

func convertDeploymentStatus(from *deploymentStatus) *scm.DeploymentStatus {
return &scm.DeploymentStatus{
ID: strconv.Itoa(from.ID),
State: from.State,
Author: convertUser(from.Author),
Description: from.Description,
Environment: from.Environment,
DeploymentLink: from.DeploymentLink,
EnvironmentLink: from.EnvironmentLink,
LogLink: from.LogLink,
RepositoryLink: from.RepositoryLink,
TargetLink: from.TargetLink,
Created: from.Created,
Updated: from.Updated,
}
}

func convertToDeploymentStatusInput(from *scm.DeploymentStatusInput) *deploymentStatusInput {
return &deploymentStatusInput{
State: from.State,
TargetLink: from.TargetLink,
LogLink: from.LogLink,
Description: from.Description,
Environment: from.Environment,
EnvironmentLink: from.EnvironmentLink,
AutoInactive: from.AutoInactive,
}
}

0 comments on commit 0cf22c7

Please sign in to comment.