in internal/pkg/cli/deploy.go [436:520]
func (o *deployOpts) Run() error {
if err := o.askNames(); err != nil {
return err
}
if err := o.askEnv(); err != nil {
return err
}
if err := o.checkEnvExists(); err != nil {
return err
}
if err := o.maybeInitEnv(); err != nil {
return err
}
if err := o.maybeDeployEnv(); err != nil {
return err
}
deploymentOrderGroups, err := o.getDeploymentOrder()
if err != nil {
return err
}
cmds := make([][]workloadCommand, len(deploymentOrderGroups))
// Do all our asking before executing deploy commands.
// Also initialize workloads that need initialization (if they're specified by name and un-initialized,
// it means the customer probably wants to init them).
log.Infoln("Checking for all required information. We may ask you some questions.")
for order, deploymentGroup := range deploymentOrderGroups {
for _, workload := range deploymentGroup {
// 1. Decide whether the current workload needs initialization.
if err := o.maybeInitWkld(workload); err != nil {
return err
}
// 2. Set up workload command.
deployCmd, err := o.loadWkldCmd(workload)
if err != nil {
return err
}
cmds[order] = append(cmds[order], workloadCommand{
name: workload,
actionCommand: deployCmd,
})
// 3. Ask() and Validate() for required info.
if err := deployCmd.Ask(); err != nil {
return fmt.Errorf("ask %s deploy: %w", o.wlType, err)
}
if err := deployCmd.Validate(); err != nil {
return fmt.Errorf("validate %s deploy: %w", o.wlType, err)
}
}
}
if count := getTotalNumberOfWorkloads(cmds); count > 1 {
logDeploymentOrderInfo(cmds, count)
}
for g, deploymentGroup := range cmds {
// TODO parallelize this. Steps involve:
// 1. Modify the cmd to optionally disable progress tracker
// 2. Modify labeledSyncBuffer so it can display a spinner.
// 3. Wrap Execute() in a goroutine with ErrorGroup and context
for i, cmd := range deploymentGroup {
if err := cmd.Execute(); err != nil {
var errNoInfraChanges *errNoInfrastructureChanges
if !errors.As(err, &errNoInfraChanges) {
return fmt.Errorf("execute deployment %d of %d in group %d: %w", i+1, len(deploymentGroup), g+1, err)
}
// Don't run recommended actions if there is an infra error. It's possible for RecommendActions to panic
// when it returns an error (the actionRecommender return is nil in error cases and the struct member
// is never set.
continue
}
if err := cmd.RecommendActions(); err != nil {
return err
}
}
}
return nil
}