diff --git a/cli/azd/.vscode/cspell-azd-dictionary.txt b/cli/azd/.vscode/cspell-azd-dictionary.txt index ec26a8a1c1f..24dcab93eaa 100644 --- a/cli/azd/.vscode/cspell-azd-dictionary.txt +++ b/cli/azd/.vscode/cspell-azd-dictionary.txt @@ -10,6 +10,7 @@ azdtempl azdtest azsdk AZURECLI +azurestaticapps azureutil byts containerapp @@ -35,6 +36,7 @@ omitempty osutil pflag pyapp +keychain restoreapp rzip sstore diff --git a/cli/azd/CHANGELOG.md b/cli/azd/CHANGELOG.md index ffeaed1d44b..13f716f7723 100644 --- a/cli/azd/CHANGELOG.md +++ b/cli/azd/CHANGELOG.md @@ -6,6 +6,8 @@ - Fixed an issue where passing `--help` to `azd` would result in an error message being printed to standard error before the help was printed. - [[#71]](https://github.com/Azure/azure-dev/issues/71) Fixed detection for disabled GitHub actions on new created repos. +- [[#70]](https://github.com/Azure/azure-dev/issues/70) Ensure SWA app is in READY state after deployment completes +- [[#53]](https://github.com/Azure/azure-dev/issues/53) SWA app is deployed to incorrect environment ## 0.1.0-beta.1 (2022-07-11) diff --git a/cli/azd/pkg/project/service_target_staticwebapp.go b/cli/azd/pkg/project/service_target_staticwebapp.go index e226dcbde54..8122430ff75 100644 --- a/cli/azd/pkg/project/service_target_staticwebapp.go +++ b/cli/azd/pkg/project/service_target_staticwebapp.go @@ -8,12 +8,17 @@ import ( "fmt" "log" "strings" + "time" "github.com/azure/azure-dev/cli/azd/pkg/azure" "github.com/azure/azure-dev/cli/azd/pkg/environment" "github.com/azure/azure-dev/cli/azd/pkg/tools" ) +// TODO: Enhance for multi-environment support +// https://github.com/Azure/azure-dev/issues/1152 +const DefaultStaticWebAppEnvironmentName = "default" + type staticWebAppTarget struct { config *ServiceConfig env *environment.Environment @@ -31,25 +36,34 @@ func (at *staticWebAppTarget) Deploy(ctx context.Context, azdCtx *environment.Az at.config.OutputPath = "build" } - staticWebAppEnvironmentName := at.env.GetEnvName() - if strings.TrimSpace(staticWebAppEnvironmentName) == "" { - staticWebAppEnvironmentName = "production" - } - - log.Printf("Logging into SWA CLI: TenantId: %s, SubscriptionId: %s, ResourceGroup: %s, ResourceName: %s", at.env.GetTenantId(), at.env.GetSubscriptionId(), at.scope.ResourceGroupName(), at.scope.ResourceName()) - - // Login to get the app deployment token - progress <- "Generating deployment tokens" - if err := at.swa.Login(ctx, at.env.GetTenantId(), at.env.GetSubscriptionId(), at.scope.ResourceGroupName(), at.scope.ResourceName()); err != nil { - return ServiceDeploymentResult{}, fmt.Errorf("Failed deploying static web app: %w", err) + // Get the static webapp deployment token + progress <- "Retrieving deployment token" + deploymentToken, err := at.cli.GetStaticWebAppApiKey(ctx, at.env.GetSubscriptionId(), at.scope.ResourceGroupName(), at.scope.ResourceName()) + if err != nil { + return ServiceDeploymentResult{}, fmt.Errorf("failed retrieving static web app deployment token: %w", err) } // SWA performs a zip & deploy of the specified output folder and publishes it to the configured environment - log.Printf("Deploying SWA app: TenantId: %s, SubscriptionId: %s, ResourceGroup: %s, ResourceName: %s", at.env.GetTenantId(), at.env.GetSubscriptionId(), at.scope.ResourceGroupName(), at.scope.ResourceName()) progress <- "Publishing deployment artifacts" - res, err := at.swa.Deploy(ctx, at.env.GetTenantId(), at.env.GetSubscriptionId(), at.scope.ResourceGroupName(), at.scope.ResourceName(), at.config.RelativePath, at.config.OutputPath, staticWebAppEnvironmentName) + res, err := at.swa.Deploy(ctx, + at.config.Project.Path, + at.env.GetTenantId(), + at.env.GetSubscriptionId(), + at.scope.ResourceGroupName(), + at.scope.ResourceName(), + at.config.RelativePath, + at.config.OutputPath, + DefaultStaticWebAppEnvironmentName, + deploymentToken) + + log.Println(res) + if err != nil { - return ServiceDeploymentResult{}, fmt.Errorf("Failed deploying static web app: %w", err) + return ServiceDeploymentResult{}, fmt.Errorf("failed deploying static web app: %w", err) + } + + if err := at.verifyDeployment(ctx, progress); err != nil { + return ServiceDeploymentResult{}, err } progress <- "Fetching endpoints for static web app" @@ -71,11 +85,41 @@ func (at *staticWebAppTarget) Deploy(ctx context.Context, azdCtx *environment.Az func (at *staticWebAppTarget) Endpoints(ctx context.Context) ([]string, error) { // TODO: Enhance for multi-environment support // https://github.com/Azure/azure-dev/issues/1152 - if props, err := at.cli.GetStaticWebAppProperties(ctx, at.env.GetSubscriptionId(), at.scope.ResourceGroupName(), at.scope.ResourceName()); err != nil { + envProps, err := at.cli.GetStaticWebAppEnvironmentProperties(ctx, at.env.GetSubscriptionId(), at.scope.ResourceGroupName(), at.scope.ResourceName(), DefaultStaticWebAppEnvironmentName) + if err != nil { return nil, fmt.Errorf("fetching service properties: %w", err) - } else { - return []string{fmt.Sprintf("https://%s/", props.DefaultHostname)}, nil } + + return []string{fmt.Sprintf("https://%s/", envProps.Hostname)}, nil +} + +func (at *staticWebAppTarget) verifyDeployment(ctx context.Context, progress chan<- string) error { + verifyMsg := "Verifying deployment" + retries := 0 + const maxRetries = 10 + + for { + progress <- verifyMsg + envProps, err := at.cli.GetStaticWebAppEnvironmentProperties(ctx, at.env.GetSubscriptionId(), at.scope.ResourceGroupName(), at.scope.ResourceName(), DefaultStaticWebAppEnvironmentName) + if err != nil { + return fmt.Errorf("failed verifying static web app deployment: %w", err) + } + + if envProps.Status == "Ready" { + break + } + + retries++ + + if retries >= maxRetries { + return fmt.Errorf("failed verifying static web app deployment. Still in %s state", envProps.Status) + } + + verifyMsg += "." + time.Sleep(5 * time.Second) + } + + return nil } func NewStaticWebAppTarget(config *ServiceConfig, env *environment.Environment, scope *environment.DeploymentScope, azCli tools.AzCli, swaCli tools.SwaCli) ServiceTarget { diff --git a/cli/azd/pkg/tools/azcli.go b/cli/azd/pkg/tools/azcli.go index ea3a0778f89..f5b8e678370 100644 --- a/cli/azd/pkg/tools/azcli.go +++ b/cli/azd/pkg/tools/azcli.go @@ -11,6 +11,7 @@ import ( "io" "net/http" "regexp" + "strings" "time" azdinternal "github.com/azure/azure-dev/cli/azd/internal" @@ -77,6 +78,8 @@ type AzCli interface { GetAppServiceProperties(ctx context.Context, subscriptionId string, resourceGroupName string, applicationName string) (AzCliAppServiceProperties, error) GetContainerAppProperties(ctx context.Context, subscriptionId string, resourceGroupName string, applicationName string) (AzCliContainerAppProperties, error) GetStaticWebAppProperties(ctx context.Context, subscriptionID string, resourceGroup string, appName string) (AzCliStaticWebAppProperties, error) + GetStaticWebAppApiKey(ctx context.Context, subscriptionID string, resourceGroup string, appName string) (string, error) + GetStaticWebAppEnvironmentProperties(ctx context.Context, subscriptionID string, resourceGroup string, appName string, environmentName string) (AzCliStaticWebAppEnvironmentProperties, error) GetSignedInUserId(ctx context.Context) (string, error) @@ -209,6 +212,11 @@ type AzCliStaticWebAppProperties struct { DefaultHostname string `json:"defaultHostname"` } +type AzCliStaticWebAppEnvironmentProperties struct { + Hostname string `json:"hostname"` + Status string `json:"status"` +} + type AzCliLocation struct { // The human friendly name of the location (e.g. "West US 2") DisplayName string `json:"displayName"` @@ -538,6 +546,51 @@ func (cli *azCli) GetStaticWebAppProperties(ctx context.Context, subscriptionID return staticWebAppProperties, nil } +func (cli *azCli) GetStaticWebAppEnvironmentProperties(ctx context.Context, subscriptionID string, resourceGroup string, appName string, environmentName string) (AzCliStaticWebAppEnvironmentProperties, error) { + res, err := cli.runAzCommandWithArgs(context.Background(), executil.RunArgs{ + Args: []string{ + "staticwebapp", "environment", "show", + "--subscription", subscriptionID, + "--resource-group", resourceGroup, + "--name", appName, + "--environment", environmentName, + "--output", "json", + }, + EnrichError: true, + }) + + if err != nil { + return AzCliStaticWebAppEnvironmentProperties{}, fmt.Errorf("failed getting staticwebapp environment properties: %w", err) + } + + var environmentProperties AzCliStaticWebAppEnvironmentProperties + if err := json.Unmarshal([]byte(res.Stdout), &environmentProperties); err != nil { + return AzCliStaticWebAppEnvironmentProperties{}, fmt.Errorf("could not unmarshal output %s as an AzCliStaticWebAppEnvironmentProperties: %w", res.Stdout, err) + } + + return environmentProperties, nil +} + +func (cli *azCli) GetStaticWebAppApiKey(ctx context.Context, subscriptionID string, resourceGroup string, appName string) (string, error) { + res, err := cli.runAzCommandWithArgs(context.Background(), executil.RunArgs{ + Args: []string{ + "staticwebapp", "secrets", "list", + "--subscription", subscriptionID, + "--resource-group", resourceGroup, + "--name", appName, + "--query", "properties.apiKey", + "--output", "tsv", + }, + EnrichError: true, + }) + + if err != nil { + return "", fmt.Errorf("failed getting staticwebapp api key: %w", err) + } + + return strings.TrimSpace(res.Stdout), nil +} + func (cli *azCli) DeployToSubscription(ctx context.Context, subscriptionId string, deploymentName string, templateFile string, parametersFile string, location string) (AzCliDeploymentResult, error) { res, err := cli.runAzCommand(ctx, "deployment", "sub", "create", "--subscription", subscriptionId, "--name", deploymentName, "--location", location, "--template-file", templateFile, "--parameters", fmt.Sprintf("@%s", parametersFile), "--output", "json") if isNotLoggedInMessage(res.Stderr) { diff --git a/cli/azd/pkg/tools/azcli_staticwebapp_test.go b/cli/azd/pkg/tools/azcli_staticwebapp_test.go index e4247bac8bd..cb5428dde01 100644 --- a/cli/azd/pkg/tools/azcli_staticwebapp_test.go +++ b/cli/azd/pkg/tools/azcli_staticwebapp_test.go @@ -77,3 +77,139 @@ func Test_GetStaticWebAppProperties(t *testing.T) { require.EqualError(t, err, "failed getting staticwebapp properties: example error message") }) } + +func Test_GetStaticWebAppEnvironmentProperties(t *testing.T) { + tempAZCLI := NewAzCli(NewAzCliArgs{ + EnableDebug: false, + EnableTelemetry: true, + }) + azcli := tempAZCLI.(*azCli) + + ran := false + + t.Run("NoErrors", func(t *testing.T) { + azcli.runWithResultFn = func(ctx context.Context, args executil.RunArgs) (executil.RunResult, error) { + ran = true + + require.Equal(t, []string{ + "staticwebapp", "environment", "show", + "--subscription", "subID", + "--resource-group", "resourceGroupID", + "--name", "appName", + "--environment", "default", + "--output", "json", + }, args.Args) + + require.True(t, args.EnrichError, "errors are enriched") + + return executil.RunResult{ + Stdout: `{"hostname":"default-environment-name.azurestaticapps.net"}`, + Stderr: "stderr text", + // if the returned `error` is nil we don't return an error. The underlying 'exec' + // returns an error if the command returns a non-zero exit code so we don't actually + // need to check it. + ExitCode: 1, + }, nil + } + + props, err := azcli.GetStaticWebAppEnvironmentProperties(context.Background(), "subID", "resourceGroupID", "appName", "default") + require.NoError(t, err) + require.Equal(t, "default-environment-name.azurestaticapps.net", props.Hostname) + require.True(t, ran) + }) + + t.Run("Error", func(t *testing.T) { + azcli.runWithResultFn = func(ctx context.Context, args executil.RunArgs) (executil.RunResult, error) { + ran = true + + require.Equal(t, []string{ + "staticwebapp", "environment", "show", + "--subscription", "subID", + "--resource-group", "resourceGroupID", + "--name", "appName", + "--environment", "default", + "--output", "json", + }, args.Args) + + require.True(t, args.EnrichError, "errors are enriched") + return executil.RunResult{ + Stdout: "", + Stderr: "stderr text", + ExitCode: 1, + }, errors.New("example error message") + } + + props, err := azcli.GetStaticWebAppEnvironmentProperties(context.Background(), "subID", "resourceGroupID", "appName", "default") + require.Equal(t, AzCliStaticWebAppEnvironmentProperties{}, props) + require.True(t, ran) + require.EqualError(t, err, "failed getting staticwebapp environment properties: example error message") + }) +} + +func Test_GetStaticWebAppApiKey(t *testing.T) { + tempAZCLI := NewAzCli(NewAzCliArgs{ + EnableDebug: false, + EnableTelemetry: true, + }) + azcli := tempAZCLI.(*azCli) + + ran := false + + t.Run("NoErrors", func(t *testing.T) { + azcli.runWithResultFn = func(ctx context.Context, args executil.RunArgs) (executil.RunResult, error) { + ran = true + + require.Equal(t, []string{ + "staticwebapp", "secrets", "list", + "--subscription", "subID", + "--resource-group", "resourceGroupID", + "--name", "appName", + "--query", "properties.apiKey", + "--output", "tsv", + }, args.Args) + + require.True(t, args.EnrichError, "errors are enriched") + + return executil.RunResult{ + Stdout: "ABC123", + Stderr: "stderr text", + // if the returned `error` is nil we don't return an error. The underlying 'exec' + // returns an error if the command returns a non-zero exit code so we don't actually + // need to check it. + ExitCode: 1, + }, nil + } + + apiKey, err := azcli.GetStaticWebAppApiKey(context.Background(), "subID", "resourceGroupID", "appName") + require.NoError(t, err) + require.Equal(t, "ABC123", apiKey) + require.True(t, ran) + }) + + t.Run("Error", func(t *testing.T) { + azcli.runWithResultFn = func(ctx context.Context, args executil.RunArgs) (executil.RunResult, error) { + ran = true + + require.Equal(t, []string{ + "staticwebapp", "secrets", "list", + "--subscription", "subID", + "--resource-group", "resourceGroupID", + "--name", "appName", + "--query", "properties.apiKey", + "--output", "tsv", + }, args.Args) + + require.True(t, args.EnrichError, "errors are enriched") + return executil.RunResult{ + Stdout: "", + Stderr: "stderr text", + ExitCode: 1, + }, errors.New("example error message") + } + + apiKey, err := azcli.GetStaticWebAppApiKey(context.Background(), "subID", "resourceGroupID", "appName") + require.Equal(t, "", apiKey) + require.True(t, ran) + require.EqualError(t, err, "failed getting staticwebapp api key: example error message") + }) +} diff --git a/cli/azd/pkg/tools/swa.go b/cli/azd/pkg/tools/swa.go index 19b5b31c666..1e8d4d80506 100644 --- a/cli/azd/pkg/tools/swa.go +++ b/cli/azd/pkg/tools/swa.go @@ -6,6 +6,7 @@ package tools import ( "context" "fmt" + "log" "github.com/azure/azure-dev/cli/azd/pkg/executil" ) @@ -19,9 +20,8 @@ func NewSwaCli() SwaCli { type SwaCli interface { ExternalTool - Login(ctx context.Context, tenantId string, subscriptionId string, resourceGroup string, appName string) error - Build(ctx context.Context, appFolderPath string, outputRelativeFolderPath string) error - Deploy(ctx context.Context, tenantId string, subscriptionId string, resourceGroup string, appName string, appFolderPath string, outputRelativeFolderPath string, environment string) (string, error) + Build(ctx context.Context, cwd string, appFolderPath string, outputRelativeFolderPath string) error + Deploy(ctx context.Context, cwd string, tenantId string, subscriptionId string, resourceGroup string, appName string, appFolderPath string, outputRelativeFolderPath string, environment string, deploymentToken string) (string, error) } type swaCli struct { @@ -29,24 +29,10 @@ type swaCli struct { runWithResultFn func(ctx context.Context, args executil.RunArgs) (executil.RunResult, error) } -func (cli *swaCli) Login(ctx context.Context, tenantId string, subscriptionId string, resourceGroup string, appName string) error { - res, err := cli.executeCommand(ctx, ".", "login", - "--tenant-id", tenantId, - "--subscription-id", subscriptionId, - "--resource-group", resourceGroup, - "--app-name", appName) - - if err != nil { - return fmt.Errorf("swa login: %s: %w", res.String(), err) - } - - return nil -} - -func (cli *swaCli) Build(ctx context.Context, appFolderPath string, outputRelativeFolderPath string) error { +func (cli *swaCli) Build(ctx context.Context, cwd string, appFolderPath string, outputRelativeFolderPath string) error { res, err := cli.executeCommand(ctx, - appFolderPath, "build", - "--app-location", ".", + cwd, "build", + "--app-location", appFolderPath, "--output-location", outputRelativeFolderPath) if err != nil { @@ -56,22 +42,26 @@ func (cli *swaCli) Build(ctx context.Context, appFolderPath string, outputRelati return nil } -func (cli *swaCli) Deploy(ctx context.Context, tenantId string, subscriptionId string, resourceGroup string, appName string, appFolderPath string, outputRelativeFolderPath string, environment string) (string, error) { +func (cli *swaCli) Deploy(ctx context.Context, cwd string, tenantId string, subscriptionId string, resourceGroup string, appName string, appFolderPath string, outputRelativeFolderPath string, environment string, deploymentToken string) (string, error) { + log.Printf("SWA Deploy: TenantId: %s, SubscriptionId: %s, ResourceGroup: %s, ResourceName: %s, Environment: %s", tenantId, subscriptionId, resourceGroup, appName, environment) + res, err := cli.executeCommand(ctx, - appFolderPath, "deploy", + cwd, "deploy", "--tenant-id", tenantId, "--subscription-id", subscriptionId, "--resource-group", resourceGroup, "--app-name", appName, - "--app-location", ".", + "--app-location", appFolderPath, "--output-location", outputRelativeFolderPath, - "--env", environment) + "--env", environment, + "--no-use-keychain", + "--deployment-token", deploymentToken) if err != nil { return "", fmt.Errorf("swa deploy: %s: %w", res.String(), err) } - return res.Stdout, nil + return res.Stdout + res.Stderr, nil } func (cli *swaCli) CheckInstalled(_ context.Context) (bool, error) { @@ -91,8 +81,9 @@ func (cli *swaCli) executeCommand(ctx context.Context, cwd string, args ...strin finalArgs := append(defaultArgs, args...) return cli.runWithResultFn(ctx, executil.RunArgs{ - Cmd: "npx", - Args: finalArgs, - Cwd: cwd, + Cmd: "npx", + Args: finalArgs, + Cwd: cwd, + EnrichError: true, }) } diff --git a/cli/azd/pkg/tools/swa_test.go b/cli/azd/pkg/tools/swa_test.go index 2cda221dc21..eacb4e99919 100644 --- a/cli/azd/pkg/tools/swa_test.go +++ b/cli/azd/pkg/tools/swa_test.go @@ -12,66 +12,6 @@ import ( "github.com/stretchr/testify/require" ) -func Test_SwaLogin(t *testing.T) { - tempSwaCli := NewSwaCli() - swacli := tempSwaCli.(*swaCli) - - ran := false - - t.Run("NoErrors", func(t *testing.T) { - swacli.runWithResultFn = func(ctx context.Context, args executil.RunArgs) (executil.RunResult, error) { - ran = true - - require.Equal(t, []string{ - "-y", "@azure/static-web-apps-cli", - "login", - "--tenant-id", "tenantID", - "--subscription-id", "subscriptionID", - "--resource-group", "resourceGroupID", - "--app-name", "appName", - }, args.Args) - - return executil.RunResult{ - Stdout: "", - Stderr: "", - // if the returned `error` is nil we don't return an error. The underlying 'exec' - // returns an error if the command returns a non-zero exit code so we don't actually - // need to check it. - ExitCode: 1, - }, nil - } - - err := swacli.Login(context.Background(), "tenantID", "subscriptionID", "resourceGroupID", "appName") - require.NoError(t, err) - require.True(t, ran) - }) - - t.Run("Error", func(t *testing.T) { - swacli.runWithResultFn = func(ctx context.Context, args executil.RunArgs) (executil.RunResult, error) { - ran = true - - require.Equal(t, []string{ - "-y", "@azure/static-web-apps-cli", - "login", - "--tenant-id", "tenantID", - "--subscription-id", "subscriptionID", - "--resource-group", "resourceGroupID", - "--app-name", "appName", - }, args.Args) - - return executil.RunResult{ - Stdout: "stdout text", - Stderr: "stderr text", - ExitCode: 1, - }, errors.New("example error message") - } - - err := swacli.Login(context.Background(), "tenantID", "subscriptionID", "resourceGroupID", "appName") - require.True(t, ran) - require.EqualError(t, err, "swa login: exit code: 1, stdout: stdout text, stderr: stderr text: example error message") - }) -} - func Test_SwaBuild(t *testing.T) { tempSwaCli := NewSwaCli() swacli := tempSwaCli.(*swaCli) @@ -82,11 +22,11 @@ func Test_SwaBuild(t *testing.T) { swacli.runWithResultFn = func(ctx context.Context, args executil.RunArgs) (executil.RunResult, error) { ran = true - require.Equal(t, "./appFolderPath", args.Cwd) + require.Equal(t, "./projectPath", args.Cwd) require.Equal(t, []string{ "-y", "@azure/static-web-apps-cli", "build", - "--app-location", ".", + "--app-location", "service/path", "--output-location", "build", }, args.Args) @@ -100,7 +40,7 @@ func Test_SwaBuild(t *testing.T) { }, nil } - err := swacli.Build(context.Background(), "./appFolderPath", "build") + err := swacli.Build(context.Background(), "./projectPath", "service/path", "build") require.NoError(t, err) require.True(t, ran) }) @@ -109,11 +49,11 @@ func Test_SwaBuild(t *testing.T) { swacli.runWithResultFn = func(ctx context.Context, args executil.RunArgs) (executil.RunResult, error) { ran = true - require.Equal(t, "./appFolderPath", args.Cwd) + require.Equal(t, "./projectPath", args.Cwd) require.Equal(t, []string{ "-y", "@azure/static-web-apps-cli", "build", - "--app-location", ".", + "--app-location", "service/path", "--output-location", "build", }, args.Args) @@ -124,7 +64,7 @@ func Test_SwaBuild(t *testing.T) { }, errors.New("example error message") } - err := swacli.Build(context.Background(), "./appFolderPath", "build") + err := swacli.Build(context.Background(), "./projectPath", "service/path", "build") require.True(t, ran) require.EqualError(t, err, "swa build: exit code: 1, stdout: stdout text, stderr: stderr text: example error message") }) @@ -140,7 +80,7 @@ func Test_SwaDeploy(t *testing.T) { swacli.runWithResultFn = func(ctx context.Context, args executil.RunArgs) (executil.RunResult, error) { ran = true - require.Equal(t, "./appFolderPath", args.Cwd) + require.Equal(t, "./projectPath", args.Cwd) require.Equal(t, []string{ "-y", "@azure/static-web-apps-cli", "deploy", @@ -148,9 +88,11 @@ func Test_SwaDeploy(t *testing.T) { "--subscription-id", "subscriptionID", "--resource-group", "resourceGroupID", "--app-name", "appName", - "--app-location", ".", + "--app-location", "service/path", "--output-location", "build", - "--env", "production", + "--env", "default", + "--no-use-keychain", + "--deployment-token", "deploymentToken", }, args.Args) return executil.RunResult{ @@ -163,7 +105,7 @@ func Test_SwaDeploy(t *testing.T) { }, nil } - _, err := swacli.Deploy(context.Background(), "tenantID", "subscriptionID", "resourceGroupID", "appName", "./appFolderPath", "build", "production") + _, err := swacli.Deploy(context.Background(), "./projectPath", "tenantID", "subscriptionID", "resourceGroupID", "appName", "service/path", "build", "default", "deploymentToken") require.NoError(t, err) require.True(t, ran) }) @@ -172,7 +114,7 @@ func Test_SwaDeploy(t *testing.T) { swacli.runWithResultFn = func(ctx context.Context, args executil.RunArgs) (executil.RunResult, error) { ran = true - require.Equal(t, "./appFolderPath", args.Cwd) + require.Equal(t, "./projectPath", args.Cwd) require.Equal(t, []string{ "-y", "@azure/static-web-apps-cli", "deploy", @@ -180,9 +122,11 @@ func Test_SwaDeploy(t *testing.T) { "--subscription-id", "subscriptionID", "--resource-group", "resourceGroupID", "--app-name", "appName", - "--app-location", ".", + "--app-location", "service/path", "--output-location", "build", - "--env", "production", + "--env", "default", + "--no-use-keychain", + "--deployment-token", "deploymentToken", }, args.Args) return executil.RunResult{ @@ -192,7 +136,7 @@ func Test_SwaDeploy(t *testing.T) { }, errors.New("example error message") } - _, err := swacli.Deploy(context.Background(), "tenantID", "subscriptionID", "resourceGroupID", "appName", "./appFolderPath", "build", "production") + _, err := swacli.Deploy(context.Background(), "./projectPath", "tenantID", "subscriptionID", "resourceGroupID", "appName", "service/path", "build", "default", "deploymentToken") require.True(t, ran) require.EqualError(t, err, "swa deploy: exit code: 1, stdout: stdout text, stderr: stderr text: example error message") }) diff --git a/cli/azd/test/samples/funcapp/requirements.txt b/cli/azd/test/samples/funcapp/requirements.txt index 4dbffc6b68d..6bb1e59d0a8 100644 --- a/cli/azd/test/samples/funcapp/requirements.txt +++ b/cli/azd/test/samples/funcapp/requirements.txt @@ -1,3 +1,3 @@ -# Do not include azure-functions-worker as it may conflict with the Azure Functions platform - +# Do not include azure-functions-worker as it may conflict with the Azure Functions platform + azure-functions \ No newline at end of file