func()

in internal/pkg/cli/job_deploy.go [165:283]


func (o *deployJobOpts) Execute() error {
	if !o.clientConfigured {
		if err := o.configureClients(); err != nil {
			return err
		}
	}
	if !o.allowWkldDowngrade {
		if err := validateWkldVersion(o.jobVersionGetter, o.name, o.templateVersion); err != nil {
			return err
		}
	}
	mft, interpolated, err := workloadManifest(&workloadManifestInput{
		name:         o.name,
		appName:      o.appName,
		envName:      o.envName,
		ws:           o.ws,
		interpolator: o.newInterpolator(o.appName, o.envName),
		unmarshal:    o.unmarshal,
		sess:         o.envSess,
	})
	if err != nil {
		return err
	}
	o.appliedDynamicMft = mft
	o.rawMft = interpolated
	if err := validateWorkloadManifestCompatibilityWithEnv(o.ws, o.envFeaturesDescriber, mft, o.envName); err != nil {
		return err
	}
	deployer, err := o.newJobDeployer()
	if err != nil {
		return err
	}
	serviceInRegion, err := deployer.IsServiceAvailableInRegion(o.targetEnv.Region)
	if err != nil {
		return fmt.Errorf("check if Scheduled Job(s) is available in region %s: %w", o.targetEnv.Region, err)
	}

	if !serviceInRegion {
		log.Warningf(`Scheduled Job might not be available in region %s; proceed with caution.
`, o.targetEnv.Region)
	}
	uploadOut, err := deployer.UploadArtifacts()
	if err != nil {
		return fmt.Errorf("upload deploy resources for job %s: %w", o.name, err)
	}
	if o.showDiff {
		output, err := deployer.GenerateCloudFormationTemplate(&deploy.GenerateCloudFormationTemplateInput{
			StackRuntimeConfiguration: deploy.StackRuntimeConfiguration{
				RootUserARN:        o.rootUserARN,
				Tags:               o.targetApp.Tags,
				EnvFileARNs:        uploadOut.EnvFileARNs,
				ImageDigests:       uploadOut.ImageDigests,
				AddonsURL:          uploadOut.AddonsURL,
				Version:            o.templateVersion,
				CustomResourceURLs: uploadOut.CustomResourceURLs,
			},
		})
		if err != nil {
			return fmt.Errorf("generate the template for job %q against environment %q: %w", o.name, o.envName, err)
		}
		if err := diff(deployer, output.Template, o.diffWriter); err != nil {
			var errHasDiff *errHasDiff
			if !errors.As(err, &errHasDiff) {
				return err
			}
		}
		contd, err := o.prompt.Confirm(continueDeploymentPrompt, "")
		if err != nil {
			return fmt.Errorf("ask whether to continue with the deployment: %w", err)
		}
		if !contd {
			return nil
		}
	}
	if _, err = deployer.DeployWorkload(&deploy.DeployWorkloadInput{
		StackRuntimeConfiguration: deploy.StackRuntimeConfiguration{
			ImageDigests:       uploadOut.ImageDigests,
			EnvFileARNs:        uploadOut.EnvFileARNs,
			AddonsURL:          uploadOut.AddonsURL,
			RootUserARN:        o.rootUserARN,
			Version:            o.templateVersion,
			Tags:               tags.Merge(o.targetApp.Tags, o.resourceTags),
			CustomResourceURLs: uploadOut.CustomResourceURLs,
		},
		Options: deploy.Options{
			DisableRollback: o.disableRollback,
			Detach:          o.detach,
		},
	}); err != nil {
		var errStackDeletedOnInterrupt *deploycfn.ErrStackDeletedOnInterrupt
		var errStackUpdateCanceledOnInterrupt *deploycfn.ErrStackUpdateCanceledOnInterrupt
		var errEmptyChangeSet *awscfn.ErrChangeSetEmpty
		if errors.As(err, &errStackDeletedOnInterrupt) {
			return nil
		}
		if errors.As(err, &errStackUpdateCanceledOnInterrupt) {
			log.Successf("Successfully rolled back service %s to the previous configuration.\n", color.HighlightUserInput(o.name))
			return nil
		}
		if o.disableRollback {
			stackName := stack.NameForWorkload(o.targetApp.Name, o.targetEnv.Name, o.name)
			rollbackCmd := fmt.Sprintf("aws cloudformation rollback-stack --stack-name %s --role-arn %s", stackName, o.targetEnv.ExecutionRoleARN)
			log.Infof(`It seems like you have disabled automatic stack rollback for this deployment. To debug, you can visit the AWS console to inspect the errors.
After fixing the deployment, you can:
1. Run %s to rollback the deployment.
2. Run %s to make a new deployment.
`, color.HighlightCode(rollbackCmd), color.HighlightCode("copilot job deploy"))
		}
		if errors.As(err, &errEmptyChangeSet) {
			return &errNoInfrastructureChanges{parentErr: err}
		}
		return fmt.Errorf("deploy job %s to environment %s: %w", o.name, o.envName, err)
	}
	if o.detach {
		return nil
	}
	log.Successf("Deployed %s.\n", color.HighlightUserInput(o.name))
	return nil
}