in cli/azd/internal/cmd/deploy.go [172:327]
func (da *DeployAction) Run(ctx context.Context) (*actions.ActionResult, error) {
targetServiceName := da.flags.serviceName
if len(da.args) == 1 {
targetServiceName = da.args[0]
}
serviceNameWarningCheck(da.console, da.flags.serviceName, "deploy")
if da.env.GetSubscriptionId() == "" {
return nil, errors.New(
"infrastructure has not been provisioned. Run `azd provision`",
)
}
targetServiceName, err := getTargetServiceName(
ctx,
da.projectManager,
da.importManager,
da.projectConfig,
string(project.ServiceEventDeploy),
targetServiceName,
da.flags.All,
)
if err != nil {
return nil, err
}
if da.flags.All && da.flags.fromPackage != "" {
return nil, errors.New(
"'--from-package' cannot be specified when '--all' is set. Specify a specific service by passing a <service>")
}
if targetServiceName == "" && da.flags.fromPackage != "" {
return nil, errors.New(
//nolint:lll
"'--from-package' cannot be specified when deploying all services. Specify a specific service by passing a <service>",
)
}
if err := da.projectManager.Initialize(ctx, da.projectConfig); err != nil {
return nil, err
}
if err := da.projectManager.EnsureServiceTargetTools(ctx, da.projectConfig, func(svc *project.ServiceConfig) bool {
return targetServiceName == "" || svc.Name == targetServiceName
}); err != nil {
return nil, err
}
// Command title
da.console.MessageUxItem(ctx, &ux.MessageTitle{
Title: "Deploying services (azd deploy)",
})
startTime := time.Now()
deployResults := map[string]*project.ServiceDeployResult{}
stableServices, err := da.importManager.ServiceStable(ctx, da.projectConfig)
if err != nil {
return nil, err
}
for _, svc := range stableServices {
stepMessage := fmt.Sprintf("Deploying service %s", svc.Name)
da.console.ShowSpinner(ctx, stepMessage, input.Step)
// Skip this service if both cases are true:
// 1. The user specified a service name
// 2. This service is not the one the user specified
if targetServiceName != "" && targetServiceName != svc.Name {
da.console.StopSpinner(ctx, stepMessage, input.StepSkipped)
continue
}
if alphaFeatureId, isAlphaFeature := alpha.IsFeatureKey(string(svc.Host)); isAlphaFeature {
// alpha feature on/off detection for host is done during initialization.
// This is just for displaying the warning during deployment.
da.console.WarnForFeature(ctx, alphaFeatureId)
}
var packageResult *project.ServicePackageResult
if da.flags.fromPackage != "" {
// --from-package set, skip packaging
packageResult = &project.ServicePackageResult{
PackagePath: da.flags.fromPackage,
}
} else {
// --from-package not set, package the application
packageResult, err = async.RunWithProgress(
func(packageProgress project.ServiceProgress) {
progressMessage := fmt.Sprintf("Deploying service %s (%s)", svc.Name, packageProgress.Message)
da.console.ShowSpinner(ctx, progressMessage, input.Step)
},
func(progress *async.Progress[project.ServiceProgress]) (*project.ServicePackageResult, error) {
return da.serviceManager.Package(ctx, svc, nil, progress, nil)
},
)
// do not stop progress here as next step is to deploy
if err != nil {
da.console.StopSpinner(ctx, stepMessage, input.StepFailed)
return nil, err
}
}
deployResult, err := async.RunWithProgress(
func(deployProgress project.ServiceProgress) {
progressMessage := fmt.Sprintf("Deploying service %s (%s)", svc.Name, deployProgress.Message)
da.console.ShowSpinner(ctx, progressMessage, input.Step)
},
func(progress *async.Progress[project.ServiceProgress]) (*project.ServiceDeployResult, error) {
return da.serviceManager.Deploy(ctx, svc, packageResult, progress)
},
)
da.console.StopSpinner(ctx, stepMessage, input.GetStepResultFormat(err))
if err != nil {
return nil, err
}
deployResults[svc.Name] = deployResult
// report deploy outputs
da.console.MessageUxItem(ctx, deployResult)
}
aspireDashboardUrl := apphost.AspireDashboardUrl(ctx, da.env, da.alphaFeatureManager)
if aspireDashboardUrl != nil {
da.console.MessageUxItem(ctx, aspireDashboardUrl)
}
if da.formatter.Kind() == output.JsonFormat {
deployResult := DeploymentResult{
Timestamp: time.Now(),
Services: deployResults,
}
if fmtErr := da.formatter.Format(deployResult, da.writer, nil); fmtErr != nil {
return nil, fmt.Errorf("deploy result could not be displayed: %w", fmtErr)
}
}
return &actions.ActionResult{
Message: &actions.ResultMessage{
Header: fmt.Sprintf("Your application was deployed to Azure in %s.", ux.DurationAsText(since(startTime))),
FollowUp: getResourceGroupFollowUp(ctx,
da.formatter,
da.portalUrlBase,
da.projectConfig,
da.resourceManager,
da.env,
false,
),
},
}, nil
}