func()

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
}