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
}