From 56e33ec4a5b0eb430b9cf0a98222f1a2a01d0c1a Mon Sep 17 00:00:00 2001 From: Austin Ely Date: Wed, 30 Aug 2023 16:08:02 -0400 Subject: [PATCH 1/6] chore: swap deployEnv to opt in when environment already exists --- internal/pkg/cli/deploy.go | 7 ------- internal/pkg/cli/deploy_test.go | 34 +++------------------------------ 2 files changed, 3 insertions(+), 38 deletions(-) diff --git a/internal/pkg/cli/deploy.go b/internal/pkg/cli/deploy.go index d91a288b33f..c48e73044f6 100644 --- a/internal/pkg/cli/deploy.go +++ b/internal/pkg/cli/deploy.go @@ -397,13 +397,6 @@ func (o *deployOpts) maybeDeployEnv() error { if !o.envExistsInWs { return nil } - if o.deployEnv == nil { - v, err := o.prompt.Confirm(fmt.Sprintf("Would you like to deploy the environment %q before deploying your workload?", o.envName), "", prompt.WithFinalMessage("Deploy environment:")) - if err != nil { - return fmt.Errorf("confirm env deployment: %w", err) - } - o.deployEnv = aws.Bool(v) - } if aws.BoolValue(o.deployEnv) { cmd, err := o.newDeployEnvCmd(o) diff --git a/internal/pkg/cli/deploy_test.go b/internal/pkg/cli/deploy_test.go index c73b643d093..76f79bbff19 100644 --- a/internal/pkg/cli/deploy_test.go +++ b/internal/pkg/cli/deploy_test.go @@ -945,51 +945,26 @@ func Test_deployOpts_maybeInitEnv(t *testing.T) { } func Test_deployOpts_maybeDeployEnv(t *testing.T) { - mockError := errors.New("some error") tests := map[string]struct { envExistsInWs bool deployEnv *bool - mockPrompt func(m *mocks.Mockprompter) mockDeployEnvCmd func(m *mocks.Mockcmd) wantErr string }{ "env does not exist in ws": { envExistsInWs: false, - mockPrompt: func(m *mocks.Mockprompter) {}, mockDeployEnvCmd: func(m *mocks.Mockcmd) {}, }, - "env exists; deploy false when prompted": { - envExistsInWs: true, - mockPrompt: func(m *mocks.Mockprompter) { - m.EXPECT().Confirm(gomock.Any(), gomock.Any(), gomock.Any()).Return(false, nil) - }, + "env exists in app, flag set false": { + envExistsInWs: true, + deployEnv: aws.Bool(false), mockDeployEnvCmd: func(m *mocks.Mockcmd) {}, }, - "env exists; deploy true when prompted": { - envExistsInWs: true, - mockPrompt: func(m *mocks.Mockprompter) { - m.EXPECT().Confirm(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil) - }, - mockDeployEnvCmd: func(m *mocks.Mockcmd) { - m.EXPECT().Validate().Return(nil) - m.EXPECT().Ask().Return(nil) - m.EXPECT().Execute().Return(nil) - }, - }, - "error selecting whether to deploy env": { - envExistsInWs: true, - mockPrompt: func(m *mocks.Mockprompter) { - m.EXPECT().Confirm(gomock.Any(), gomock.Any(), gomock.Any()).Return(false, mockError) - }, - mockDeployEnvCmd: func(m *mocks.Mockcmd) {}, - wantErr: "confirm env deployment: some error", - }, "env exists; deploy flag set": { envExistsInWs: true, deployEnv: aws.Bool(true), - mockPrompt: func(m *mocks.Mockprompter) {}, mockDeployEnvCmd: func(m *mocks.Mockcmd) { m.EXPECT().Validate().Return(nil) m.EXPECT().Ask().Return(nil) @@ -1002,10 +977,8 @@ func Test_deployOpts_maybeDeployEnv(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() - mockPrompt := mocks.NewMockprompter(ctrl) mockDeployEnvCmd := mocks.NewMockcmd(ctrl) - tc.mockPrompt(mockPrompt) tc.mockDeployEnvCmd(mockDeployEnvCmd) o := &deployOpts{ @@ -1017,7 +990,6 @@ func Test_deployOpts_maybeDeployEnv(t *testing.T) { deployEnv: tc.deployEnv, }, envExistsInWs: tc.envExistsInWs, - prompt: mockPrompt, newDeployEnvCmd: func(o *deployOpts) (cmd, error) { return mockDeployEnvCmd, nil }, From 170508677e672bb411b8ff177f8c76a8d8a92078 Mon Sep 17 00:00:00 2001 From: Austin Ely Date: Thu, 31 Aug 2023 12:50:17 -0400 Subject: [PATCH 2/6] chore: only prompt for env deploy confirmation when --env was specified --- internal/pkg/cli/deploy.go | 24 +++++++++++++++++++----- internal/pkg/cli/deploy_test.go | 31 ++++++++++++++++++++++++++++--- 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/internal/pkg/cli/deploy.go b/internal/pkg/cli/deploy.go index c48e73044f6..fae6c10f738 100644 --- a/internal/pkg/cli/deploy.go +++ b/internal/pkg/cli/deploy.go @@ -68,8 +68,9 @@ type deployOpts struct { wlType string // values for initialization logic - envExistsInApp bool - envExistsInWs bool + envExistsInApp bool + envExistsInWs bool + promptForEnvDeploy bool // Cached variables wsEnvironments []string @@ -94,6 +95,8 @@ func newDeployOpts(vars deployVars) (*deployOpts, error) { ws: ws, prompt: prompter, + promptForEnvDeploy: true, + newWorkloadAdder: func() wkldInitializerWithoutManifest { return &initialize.WorkloadInitializer{ Store: store, @@ -397,6 +400,13 @@ func (o *deployOpts) maybeDeployEnv() error { if !o.envExistsInWs { return nil } + if o.promptForEnvDeploy { + v, err := o.prompt.Confirm(fmt.Sprintf("Would you like to deploy the environment %q before deploying your workload?", o.envName), "", prompt.WithFinalMessage("Deploy environment:")) + if err != nil { + return fmt.Errorf("confirm env deployment: %w", err) + } + o.deployEnv = aws.Bool(v) + } if aws.BoolValue(o.deployEnv) { cmd, err := o.newDeployEnvCmd(o) @@ -454,14 +464,14 @@ func BuildDeployCmd() *cobra.Command { Long: "Deploy a Copilot job or service.", Example: ` Deploys a service named "frontend" to a "test" environment. - /code $ copilot deploy --name frontend --env test --deploy-env=false + /code $ copilot deploy --name frontend --env test Deploys a job named "mailer" with additional resource tags to a "prod" environment. - /code $ copilot deploy -n mailer -e prod --resource-tags source/revision=bb133e7,deployment/initiator=manual --deploy-env=false + /code $ copilot deploy -n mailer -e prod --resource-tags source/revision=bb133e7,deployment/initiator=manual Initializes and deploys an environment named "test" in us-west-2 under the "default" profile with local manifest, then deploys a service named "api" /code $ copilot deploy --init-env --deploy-env --env test --name api --profile default --region us-west-2 Initializes and deploys a service named "backend" to a "prod" environment. - /code $ copilot deploy --init-wkld --deploy-env=false --env prod --name backend`, + /code $ copilot deploy --init-wkld --env prod --name backend`, RunE: runCmdE(func(cmd *cobra.Command, args []string) error { opts, err := newDeployOpts(vars) @@ -490,6 +500,10 @@ func BuildDeployCmd() *cobra.Command { } } + if cmd.Flags().Changed(envFlag) || cmd.Flags().Changed(deployEnvFlag) { + opts.promptForEnvDeploy = false + } + if err := opts.Run(); err != nil { return err } diff --git a/internal/pkg/cli/deploy_test.go b/internal/pkg/cli/deploy_test.go index 76f79bbff19..eed564ca01f 100644 --- a/internal/pkg/cli/deploy_test.go +++ b/internal/pkg/cli/deploy_test.go @@ -946,31 +946,52 @@ func Test_deployOpts_maybeInitEnv(t *testing.T) { func Test_deployOpts_maybeDeployEnv(t *testing.T) { tests := map[string]struct { - envExistsInWs bool - deployEnv *bool + envExistsInWs bool + promptForEnvDeploy bool + deployEnv *bool mockDeployEnvCmd func(m *mocks.Mockcmd) + mockPrompter func(m *mocks.Mockprompter) wantErr string }{ "env does not exist in ws": { envExistsInWs: false, mockDeployEnvCmd: func(m *mocks.Mockcmd) {}, + mockPrompter: func(m *mocks.Mockprompter) {}, }, "env exists in app, flag set false": { envExistsInWs: true, deployEnv: aws.Bool(false), mockDeployEnvCmd: func(m *mocks.Mockcmd) {}, + mockPrompter: func(m *mocks.Mockprompter) {}, }, "env exists; deploy flag set": { envExistsInWs: true, deployEnv: aws.Bool(true), + mockPrompter: func(m *mocks.Mockprompter) {}, mockDeployEnvCmd: func(m *mocks.Mockcmd) { m.EXPECT().Validate().Return(nil) m.EXPECT().Ask().Return(nil) m.EXPECT().Execute().Return(nil) }, }, + "no env name specified, deployEnv flag unset": { + envExistsInWs: true, + promptForEnvDeploy: true, + deployEnv: nil, + mockDeployEnvCmd: func(m *mocks.Mockcmd) {}, + mockPrompter: func(m *mocks.Mockprompter) { + m.EXPECT().Confirm(gomock.Any(), "", gomock.Any()).Return(false, nil) + }, + }, + "no env name specified, deployEnv set": { + envExistsInWs: true, + promptForEnvDeploy: false, + deployEnv: aws.Bool(false), + mockDeployEnvCmd: func(m *mocks.Mockcmd) {}, + mockPrompter: func(m *mocks.Mockprompter) {}, + }, } for name, tc := range tests { t.Run(name, func(t *testing.T) { @@ -978,8 +999,10 @@ func Test_deployOpts_maybeDeployEnv(t *testing.T) { defer ctrl.Finish() mockDeployEnvCmd := mocks.NewMockcmd(ctrl) + mockPrompter := mocks.NewMockprompter(ctrl) tc.mockDeployEnvCmd(mockDeployEnvCmd) + tc.mockPrompter(mockPrompter) o := &deployOpts{ deployVars: deployVars{ @@ -989,10 +1012,12 @@ func Test_deployOpts_maybeDeployEnv(t *testing.T) { }, deployEnv: tc.deployEnv, }, - envExistsInWs: tc.envExistsInWs, + promptForEnvDeploy: tc.promptForEnvDeploy, + envExistsInWs: tc.envExistsInWs, newDeployEnvCmd: func(o *deployOpts) (cmd, error) { return mockDeployEnvCmd, nil }, + prompt: mockPrompter, } err := o.maybeDeployEnv() From 867079ab2305be463792ee354ce7d5c7fb9b78b0 Mon Sep 17 00:00:00 2001 From: Austin Ely Date: Thu, 31 Aug 2023 13:21:41 -0400 Subject: [PATCH 3/6] chore: update logic --- internal/pkg/cli/deploy.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/pkg/cli/deploy.go b/internal/pkg/cli/deploy.go index fae6c10f738..5576825936b 100644 --- a/internal/pkg/cli/deploy.go +++ b/internal/pkg/cli/deploy.go @@ -400,7 +400,8 @@ func (o *deployOpts) maybeDeployEnv() error { if !o.envExistsInWs { return nil } - if o.promptForEnvDeploy { + + if o.deployEnv == nil && !o.envExistsInApp { v, err := o.prompt.Confirm(fmt.Sprintf("Would you like to deploy the environment %q before deploying your workload?", o.envName), "", prompt.WithFinalMessage("Deploy environment:")) if err != nil { return fmt.Errorf("confirm env deployment: %w", err) From 2b5ba59b0051d418b30fbd68dffdae02a36bb447 Mon Sep 17 00:00:00 2001 From: Austin Ely Date: Thu, 31 Aug 2023 13:33:07 -0400 Subject: [PATCH 4/6] chore: update docs --- site/content/docs/commands/deploy.en.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/site/content/docs/commands/deploy.en.md b/site/content/docs/commands/deploy.en.md index 3f8d5748e62..c08894415f4 100644 --- a/site/content/docs/commands/deploy.en.md +++ b/site/content/docs/commands/deploy.en.md @@ -64,12 +64,12 @@ rollback of the stack via the AWS console or AWS CLI before the next deployment. ## Examples Deploys a service named "frontend" to a "test" environment. ```console -$ copilot deploy --name frontend --env test --deploy-env=false +$ copilot deploy --name frontend --env test ``` Deploys a job named "mailer" with additional resource tags to a "prod" environment. ```console -$ copilot deploy -n mailer -e prod --resource-tags source/revision=bb133e7,deployment/initiator=manual --deploy-env=false +$ copilot deploy -n mailer -e prod --resource-tags source/revision=bb133e7,deployment/initiator=manual ``` Initializes and deploys an environment named "test" in us-west-2 under the "default" profile with local manifest, From 29fe3d092a84f242d93813f05a9ee3d7d78c0237 Mon Sep 17 00:00:00 2001 From: Austin Ely Date: Thu, 31 Aug 2023 13:33:52 -0400 Subject: [PATCH 5/6] Revert "chore: update logic" This reverts commit 867079ab2305be463792ee354ce7d5c7fb9b78b0. --- internal/pkg/cli/deploy.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/internal/pkg/cli/deploy.go b/internal/pkg/cli/deploy.go index 5576825936b..fae6c10f738 100644 --- a/internal/pkg/cli/deploy.go +++ b/internal/pkg/cli/deploy.go @@ -400,8 +400,7 @@ func (o *deployOpts) maybeDeployEnv() error { if !o.envExistsInWs { return nil } - - if o.deployEnv == nil && !o.envExistsInApp { + if o.promptForEnvDeploy { v, err := o.prompt.Confirm(fmt.Sprintf("Would you like to deploy the environment %q before deploying your workload?", o.envName), "", prompt.WithFinalMessage("Deploy environment:")) if err != nil { return fmt.Errorf("confirm env deployment: %w", err) From 1a2dd3282f7a618417231c3537856335c55d6ca8 Mon Sep 17 00:00:00 2001 From: Austin Ely Date: Thu, 31 Aug 2023 13:34:02 -0400 Subject: [PATCH 6/6] Revert "chore: only prompt for env deploy confirmation when --env was specified" This reverts commit 170508677e672bb411b8ff177f8c76a8d8a92078. --- internal/pkg/cli/deploy.go | 24 +++++------------------- internal/pkg/cli/deploy_test.go | 31 +++---------------------------- 2 files changed, 8 insertions(+), 47 deletions(-) diff --git a/internal/pkg/cli/deploy.go b/internal/pkg/cli/deploy.go index fae6c10f738..c48e73044f6 100644 --- a/internal/pkg/cli/deploy.go +++ b/internal/pkg/cli/deploy.go @@ -68,9 +68,8 @@ type deployOpts struct { wlType string // values for initialization logic - envExistsInApp bool - envExistsInWs bool - promptForEnvDeploy bool + envExistsInApp bool + envExistsInWs bool // Cached variables wsEnvironments []string @@ -95,8 +94,6 @@ func newDeployOpts(vars deployVars) (*deployOpts, error) { ws: ws, prompt: prompter, - promptForEnvDeploy: true, - newWorkloadAdder: func() wkldInitializerWithoutManifest { return &initialize.WorkloadInitializer{ Store: store, @@ -400,13 +397,6 @@ func (o *deployOpts) maybeDeployEnv() error { if !o.envExistsInWs { return nil } - if o.promptForEnvDeploy { - v, err := o.prompt.Confirm(fmt.Sprintf("Would you like to deploy the environment %q before deploying your workload?", o.envName), "", prompt.WithFinalMessage("Deploy environment:")) - if err != nil { - return fmt.Errorf("confirm env deployment: %w", err) - } - o.deployEnv = aws.Bool(v) - } if aws.BoolValue(o.deployEnv) { cmd, err := o.newDeployEnvCmd(o) @@ -464,14 +454,14 @@ func BuildDeployCmd() *cobra.Command { Long: "Deploy a Copilot job or service.", Example: ` Deploys a service named "frontend" to a "test" environment. - /code $ copilot deploy --name frontend --env test + /code $ copilot deploy --name frontend --env test --deploy-env=false Deploys a job named "mailer" with additional resource tags to a "prod" environment. - /code $ copilot deploy -n mailer -e prod --resource-tags source/revision=bb133e7,deployment/initiator=manual + /code $ copilot deploy -n mailer -e prod --resource-tags source/revision=bb133e7,deployment/initiator=manual --deploy-env=false Initializes and deploys an environment named "test" in us-west-2 under the "default" profile with local manifest, then deploys a service named "api" /code $ copilot deploy --init-env --deploy-env --env test --name api --profile default --region us-west-2 Initializes and deploys a service named "backend" to a "prod" environment. - /code $ copilot deploy --init-wkld --env prod --name backend`, + /code $ copilot deploy --init-wkld --deploy-env=false --env prod --name backend`, RunE: runCmdE(func(cmd *cobra.Command, args []string) error { opts, err := newDeployOpts(vars) @@ -500,10 +490,6 @@ func BuildDeployCmd() *cobra.Command { } } - if cmd.Flags().Changed(envFlag) || cmd.Flags().Changed(deployEnvFlag) { - opts.promptForEnvDeploy = false - } - if err := opts.Run(); err != nil { return err } diff --git a/internal/pkg/cli/deploy_test.go b/internal/pkg/cli/deploy_test.go index eed564ca01f..76f79bbff19 100644 --- a/internal/pkg/cli/deploy_test.go +++ b/internal/pkg/cli/deploy_test.go @@ -946,52 +946,31 @@ func Test_deployOpts_maybeInitEnv(t *testing.T) { func Test_deployOpts_maybeDeployEnv(t *testing.T) { tests := map[string]struct { - envExistsInWs bool - promptForEnvDeploy bool - deployEnv *bool + envExistsInWs bool + deployEnv *bool mockDeployEnvCmd func(m *mocks.Mockcmd) - mockPrompter func(m *mocks.Mockprompter) wantErr string }{ "env does not exist in ws": { envExistsInWs: false, mockDeployEnvCmd: func(m *mocks.Mockcmd) {}, - mockPrompter: func(m *mocks.Mockprompter) {}, }, "env exists in app, flag set false": { envExistsInWs: true, deployEnv: aws.Bool(false), mockDeployEnvCmd: func(m *mocks.Mockcmd) {}, - mockPrompter: func(m *mocks.Mockprompter) {}, }, "env exists; deploy flag set": { envExistsInWs: true, deployEnv: aws.Bool(true), - mockPrompter: func(m *mocks.Mockprompter) {}, mockDeployEnvCmd: func(m *mocks.Mockcmd) { m.EXPECT().Validate().Return(nil) m.EXPECT().Ask().Return(nil) m.EXPECT().Execute().Return(nil) }, }, - "no env name specified, deployEnv flag unset": { - envExistsInWs: true, - promptForEnvDeploy: true, - deployEnv: nil, - mockDeployEnvCmd: func(m *mocks.Mockcmd) {}, - mockPrompter: func(m *mocks.Mockprompter) { - m.EXPECT().Confirm(gomock.Any(), "", gomock.Any()).Return(false, nil) - }, - }, - "no env name specified, deployEnv set": { - envExistsInWs: true, - promptForEnvDeploy: false, - deployEnv: aws.Bool(false), - mockDeployEnvCmd: func(m *mocks.Mockcmd) {}, - mockPrompter: func(m *mocks.Mockprompter) {}, - }, } for name, tc := range tests { t.Run(name, func(t *testing.T) { @@ -999,10 +978,8 @@ func Test_deployOpts_maybeDeployEnv(t *testing.T) { defer ctrl.Finish() mockDeployEnvCmd := mocks.NewMockcmd(ctrl) - mockPrompter := mocks.NewMockprompter(ctrl) tc.mockDeployEnvCmd(mockDeployEnvCmd) - tc.mockPrompter(mockPrompter) o := &deployOpts{ deployVars: deployVars{ @@ -1012,12 +989,10 @@ func Test_deployOpts_maybeDeployEnv(t *testing.T) { }, deployEnv: tc.deployEnv, }, - promptForEnvDeploy: tc.promptForEnvDeploy, - envExistsInWs: tc.envExistsInWs, + envExistsInWs: tc.envExistsInWs, newDeployEnvCmd: func(o *deployOpts) (cmd, error) { return mockDeployEnvCmd, nil }, - prompt: mockPrompter, } err := o.maybeDeployEnv()