Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(pipeline): add pipeline ls cmd #1529

Merged
merged 3 commits into from
Oct 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ github.com/gobuffalo/logger v1.0.3 h1:YaXOTHNPCvkqqA7w05A4v0k2tCdpr+sgFlgINbQ6gq
github.com/gobuffalo/logger v1.0.3/go.mod h1:SoeejUwldiS7ZsyCBphOGURmWdwUFXs0J7TCjEhjKxM=
github.com/gobuffalo/packd v1.0.0 h1:6ERZvJHfe24rfFmA9OaoKBdC7+c9sydrytMg8SdFGBM=
github.com/gobuffalo/packd v1.0.0/go.mod h1:6VTc4htmJRFB7u1m/4LeMTWjFoYrUiBkU9Fdec9hrhI=
github.com/gobuffalo/packr v1.30.1 h1:hu1fuVR3fXEZR7rXNW3h8rqSML8EVAf6KNm0NKO/wKg=
github.com/gobuffalo/packr/v2 v2.8.0 h1:IULGd15bQL59ijXLxEvA5wlMxsmx/ZkQv9T282zNVIY=
github.com/gobuffalo/packr/v2 v2.8.0/go.mod h1:PDk2k3vGevNE3SwVyVRgQCCXETC9SaONCNSXT1Q8M1g=
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
Expand Down
23 changes: 22 additions & 1 deletion internal/pkg/aws/codepipeline/codepipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ func (s *Stage) HumanString() string {
return fmt.Sprintf(" %s\t%s\t%s\t%s\n", s.Name, s.Category, s.Provider, s.Details)
}

// ListPipelineNamesByTags retrieves the names of all pipelines for a project.
// ListPipelineNamesByTags retrieves the names of all pipelines for an application.
func (c *CodePipeline) ListPipelineNamesByTags(tags map[string]string) ([]string, error) {
var pipelineNames []string
resources, err := c.rgClient.GetResourcesByTags(pipelineResourceType, tags)
Expand All @@ -210,6 +210,27 @@ func (c *CodePipeline) ListPipelineNamesByTags(tags map[string]string) ([]string
return pipelineNames, nil
}

// GetPipelineByTags retrieves all of pipelines for an application.
func (c *CodePipeline) GetPipelinesByTags(tags map[string]string) ([]*Pipeline, error) {
var pipelines []*Pipeline
resources, err := c.rgClient.GetResourcesByTags(pipelineResourceType, tags)
if err != nil {
return nil, err
}
for _, resource := range resources {
name, err := c.getPipelineName(resource.ARN)
if err != nil {
return nil, err
}
pipeline, err := c.GetPipeline(name)
if err != nil {
return nil, err
}
pipelines = append(pipelines, pipeline)
}
return pipelines, nil
}

func (c *CodePipeline) getPipelineName(resourceArn string) (string, error) {
parsedArn, err := arn.Parse(resourceArn)
if err != nil {
Expand Down
35 changes: 27 additions & 8 deletions internal/pkg/cli/app_show.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import (
"fmt"
"io"

"github.com/aws/copilot-cli/internal/pkg/aws/codepipeline"
"github.com/aws/copilot-cli/internal/pkg/aws/sessions"
"github.com/aws/copilot-cli/internal/pkg/config"
"github.com/aws/copilot-cli/internal/pkg/deploy"
"github.com/aws/copilot-cli/internal/pkg/term/prompt"
"github.com/aws/copilot-cli/internal/pkg/term/selector"

Expand All @@ -29,10 +32,11 @@ type showAppVars struct {
type showAppOpts struct {
showAppVars

prompt prompter
store store
w io.Writer
sel appSelector
prompt prompter
store store
w io.Writer
sel appSelector
pipelineSvc pipelineGetter
}

func newShowAppOpts(vars showAppVars) (*showAppOpts, error) {
Expand All @@ -41,13 +45,18 @@ func newShowAppOpts(vars showAppVars) (*showAppOpts, error) {
return nil, fmt.Errorf("new config store: %w", err)
}

defaultSession, err := sessions.NewProvider().Default()
if err != nil {
return nil, fmt.Errorf("default session: %w", err)
}
prompter := prompt.New()
return &showAppOpts{
showAppVars: vars,
store: store,
w: log.OutputWriter,
prompt: prompter,
sel: selector.NewSelect(prompter, store),
pipelineSvc: codepipeline.New(defaultSession),
}, nil
}

Expand Down Expand Up @@ -103,6 +112,15 @@ func (o *showAppOpts) description() (*describe.App, error) {
if err != nil {
return nil, fmt.Errorf("list services in application %s: %w", o.name, err)
}

pipelines, err := o.pipelineSvc.GetPipelinesByTags(map[string]string{
deploy.AppTagKey: o.name,
})

if err != nil {
return nil, fmt.Errorf("list pipelines in application %s: %w", o.name, err)
}

var trimmedEnvs []*config.Environment
for _, env := range envs {
trimmedEnvs = append(trimmedEnvs, &config.Environment{
Expand All @@ -120,10 +138,11 @@ func (o *showAppOpts) description() (*describe.App, error) {
})
}
return &describe.App{
Name: app.Name,
URI: app.Domain,
Envs: trimmedEnvs,
Services: trimmedSvcs,
Name: app.Name,
URI: app.Domain,
Envs: trimmedEnvs,
Services: trimmedSvcs,
Pipelines: pipelines,
}, nil
}

Expand Down
69 changes: 62 additions & 7 deletions internal/pkg/cli/app_show_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,18 @@ import (
"fmt"
"testing"

"github.com/aws/copilot-cli/internal/pkg/aws/codepipeline"
"github.com/aws/copilot-cli/internal/pkg/cli/mocks"
"github.com/aws/copilot-cli/internal/pkg/config"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/require"
)

type showAppMocks struct {
storeSvc *mocks.Mockstore
prompt *mocks.Mockprompter
sel *mocks.MockappSelector
storeSvc *mocks.Mockstore
prompt *mocks.Mockprompter
sel *mocks.MockappSelector
pipelineSvc *mocks.MockpipelineGetter
}

func TestShowAppOpts_Validate(t *testing.T) {
Expand Down Expand Up @@ -194,9 +196,15 @@ func TestShowAppOpts_Execute(t *testing.T) {
Prod: true,
},
}, nil)
m.pipelineSvc.EXPECT().
GetPipelinesByTags(gomock.Eq(map[string]string{"copilot-application": "my-app"})).
Return([]*codepipeline.Pipeline{
{Name: "pipeline1"},
{Name: "pipeline2"},
}, nil)
},

wantedContent: "{\"name\":\"my-app\",\"uri\":\"example.com\",\"environments\":[{\"app\":\"\",\"name\":\"test\",\"region\":\"us-west-2\",\"accountID\":\"123456789\",\"prod\":false,\"registryURL\":\"\",\"executionRoleARN\":\"\",\"managerRoleARN\":\"\"},{\"app\":\"\",\"name\":\"prod\",\"region\":\"us-west-1\",\"accountID\":\"123456789\",\"prod\":true,\"registryURL\":\"\",\"executionRoleARN\":\"\",\"managerRoleARN\":\"\"}],\"services\":[{\"app\":\"\",\"name\":\"my-svc\",\"type\":\"lb-web-svc\"}]}\n",
wantedContent: "{\"name\":\"my-app\",\"uri\":\"example.com\",\"environments\":[{\"app\":\"\",\"name\":\"test\",\"region\":\"us-west-2\",\"accountID\":\"123456789\",\"prod\":false,\"registryURL\":\"\",\"executionRoleARN\":\"\",\"managerRoleARN\":\"\"},{\"app\":\"\",\"name\":\"prod\",\"region\":\"us-west-1\",\"accountID\":\"123456789\",\"prod\":true,\"registryURL\":\"\",\"executionRoleARN\":\"\",\"managerRoleARN\":\"\"}],\"services\":[{\"app\":\"\",\"name\":\"my-svc\",\"type\":\"lb-web-svc\"}],\"pipelines\":[{\"name\":\"pipeline1\",\"region\":\"\",\"accountId\":\"\",\"stages\":null,\"createdAt\":\"0001-01-01T00:00:00Z\",\"updatedAt\":\"0001-01-01T00:00:00Z\"},{\"name\":\"pipeline2\",\"region\":\"\",\"accountId\":\"\",\"stages\":null,\"createdAt\":\"0001-01-01T00:00:00Z\",\"updatedAt\":\"0001-01-01T00:00:00Z\"}]}\n",
},
"correctly shows human output": {
setupMocks: func(m showAppMocks) {
Expand All @@ -222,6 +230,12 @@ func TestShowAppOpts_Execute(t *testing.T) {
Region: "us-west-1",
},
}, nil)
m.pipelineSvc.EXPECT().
GetPipelinesByTags(gomock.Eq(map[string]string{"copilot-application": "my-app"})).
Return([]*codepipeline.Pipeline{
{Name: "pipeline1"},
{Name: "pipeline2"},
}, nil)
},

wantedContent: `About
Expand All @@ -239,6 +253,12 @@ Services

Name Type
my-svc lb-web-svc

Pipelines

Name
pipeline1
pipeline2
`,
},
"returns error if fail to get application": {
Expand Down Expand Up @@ -286,6 +306,38 @@ Services

wantedError: fmt.Errorf("list services in application %s: %w", "my-app", testError),
},
"returns error if fail to list pipelines": {
shouldOutputJSON: false,

setupMocks: func(m showAppMocks) {
m.storeSvc.EXPECT().GetApplication("my-app").Return(&config.Application{
Name: "my-app",
Domain: "example.com",
}, nil)
m.storeSvc.EXPECT().ListEnvironments("my-app").Return([]*config.Environment{
{
Name: "test",
Region: "us-west-2",
AccountID: "123456789",
},
{
Name: "prod",
AccountID: "123456789",
Region: "us-west-1",
},
}, nil)
m.storeSvc.EXPECT().ListServices("my-app").Return([]*config.Workload{
{
Name: "my-svc",
Type: "lb-web-svc",
},
}, nil)
m.pipelineSvc.EXPECT().
GetPipelinesByTags(gomock.Eq(map[string]string{"copilot-application": "my-app"})).
Return(nil, testError)
},
wantedError: fmt.Errorf("list pipelines in application %s: %w", "my-app", testError),
},
}

for name, tc := range testCases {
Expand All @@ -295,9 +347,11 @@ Services

b := &bytes.Buffer{}
mockStoreReader := mocks.NewMockstore(ctrl)
mockPLSvc := mocks.NewMockpipelineGetter(ctrl)

mocks := showAppMocks{
storeSvc: mockStoreReader,
storeSvc: mockStoreReader,
pipelineSvc: mockPLSvc,
}
tc.setupMocks(mocks)

Expand All @@ -306,8 +360,9 @@ Services
shouldOutputJSON: tc.shouldOutputJSON,
name: testAppName,
},
store: mockStoreReader,
w: b,
store: mockStoreReader,
w: b,
pipelineSvc: mockPLSvc,
}

// WHEN
Expand Down
1 change: 1 addition & 0 deletions internal/pkg/cli/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@ type versionGetter interface {
type pipelineGetter interface {
GetPipeline(pipelineName string) (*codepipeline.Pipeline, error)
ListPipelineNamesByTags(tags map[string]string) ([]string, error)
GetPipelinesByTags(tags map[string]string) ([]*codepipeline.Pipeline, error)
}

type executor interface {
Expand Down
15 changes: 15 additions & 0 deletions internal/pkg/cli/mocks/mock_interfaces.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions internal/pkg/cli/pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Continuous delivery pipelines to release services.`,
cmd.AddCommand(buildPipelineDeleteCmd())
cmd.AddCommand(buildPipelineShowCmd())
cmd.AddCommand(buildPipelineStatusCmd())
cmd.AddCommand(buildPipelineListCmd())

cmd.SetUsageTemplate(template.Usage)
cmd.Annotations = map[string]string{
Expand Down
Loading