diff --git a/bundle/bundle.go b/bundle/bundle.go index 85625568..26065ab4 100644 --- a/bundle/bundle.go +++ b/bundle/bundle.go @@ -81,6 +81,9 @@ type Bundle struct { // files AutoApprove bool + // if true, the deploy changes are presented, but not applied + DryRun bool + // Tagging is used to normalize tag keys and values. // The implementation depends on the cloud being targeted. Tagging tags.Cloud diff --git a/bundle/phases/deploy.go b/bundle/phases/deploy.go index cb0ecf75..7fd231d3 100644 --- a/bundle/phases/deploy.go +++ b/bundle/phases/deploy.go @@ -115,6 +115,15 @@ properties such as the 'catalog' or 'storage' are changed:` return true, nil } + if b.DryRun { + cmdio.LogString(ctx, "Following changes would be deployed:") + _, err := tf.ShowPlanFile(ctx, b.Plan.Path) + if err != nil { + return false, err + } + return false, nil + } + if !cmdio.IsPromptSupported(ctx) { return false, fmt.Errorf("the deployment requires destructive actions, but current console does not support prompting. Please specify --auto-approve if you would like to skip prompts and proceed") } diff --git a/cmd/bundle/deploy.go b/cmd/bundle/deploy.go index f1c85cb3..1dc523dc 100644 --- a/cmd/bundle/deploy.go +++ b/cmd/bundle/deploy.go @@ -26,6 +26,7 @@ func newDeployCommand() *cobra.Command { var failOnActiveRuns bool var clusterId string var autoApprove bool + var dryRyn bool var verbose bool cmd.Flags().BoolVar(&force, "force", false, "Force-override Git branch validation.") cmd.Flags().BoolVar(&forceLock, "force-lock", false, "Force acquisition of deployment lock.") @@ -33,6 +34,7 @@ func newDeployCommand() *cobra.Command { cmd.Flags().StringVar(&clusterId, "compute-id", "", "Override cluster in the deployment with the given compute ID.") cmd.Flags().StringVarP(&clusterId, "cluster-id", "c", "", "Override cluster in the deployment with the given cluster ID.") cmd.Flags().BoolVar(&autoApprove, "auto-approve", false, "Skip interactive approvals that might be required for deployment.") + cmd.Flags().BoolVar(&dryRyn, "dry-run", false, "Present changes that would be deployed without applying.") cmd.Flags().MarkDeprecated("compute-id", "use --cluster-id instead") cmd.Flags().BoolVar(&verbose, "verbose", false, "Enable verbose output.") // Verbose flag currently only affects file sync output, it's used by the vscode extension @@ -47,6 +49,7 @@ func newDeployCommand() *cobra.Command { b.Config.Bundle.Force = force b.Config.Bundle.Deployment.Lock.Force = forceLock b.AutoApprove = autoApprove + b.DryRun = dryRyn if cmd.Flag("compute-id").Changed { b.Config.Bundle.ClusterId = clusterId diff --git a/internal/bundle/deploy_test.go b/internal/bundle/deploy_test.go index 88543585..e1eff60d 100644 --- a/internal/bundle/deploy_test.go +++ b/internal/bundle/deploy_test.go @@ -127,6 +127,34 @@ func TestAccBundleDeployUcSchemaFailsWithoutAutoApprove(t *testing.T) { assert.Contains(t, stdout.String(), "the deployment requires destructive actions, but current console does not support prompting. Please specify --auto-approve if you would like to skip prompts and proceed") } +func TestAccBundleDeployUcSchemaDryRun(t *testing.T) { + ctx, wt := acc.UcWorkspaceTest(t) + w := wt.W + + uniqueId := uuid.New().String() + schemaName := "test-schema-" + uniqueId + catalogName := "main" + + bundleRoot := setupUcSchemaBundle(t, ctx, w, uniqueId) + + // Remove the UC schema from the resource configuration. + err := os.Remove(filepath.Join(bundleRoot, "schema.yml")) + require.NoError(t, err) + + // Redeploy the bundle + t.Setenv("BUNDLE_ROOT", bundleRoot) + t.Setenv("TERM", "dumb") + c := internal.NewCobraTestRunnerWithContext(t, ctx, "bundle", "deploy", "--dry0run") + stdout, _, err := c.Run() + + // Assert the schema is deleted + _, err = w.Schemas.GetByFullName(ctx, strings.Join([]string{catalogName, schemaName}, ".")) + apiErr := &apierr.APIError{} + assert.Contains(t, stdout.String(), "Following changes would be deployed:") + assert.True(t, errors.As(err, &apiErr)) + assert.Equal(t, "SCHEMA_DOES_NOT_EXIST", apiErr.ErrorCode) +} + func TestAccBundlePipelineDeleteWithoutAutoApprove(t *testing.T) { ctx, wt := acc.WorkspaceTest(t) w := wt.W @@ -236,7 +264,7 @@ func TestAccDeployBasicBundleLogs(t *testing.T) { stdout, stderr := blackBoxRun(t, root, "bundle", "deploy") assert.Equal(t, strings.Join([]string{ - fmt.Sprintf("Uploading bundle files to /Workspace/Users/%s/.bundle/%s/files...", currentUser.UserName, uniqueId), + fmt.Sprintf("Uploading bundle files to /Users/%s/.bundle/%s/files...", currentUser.UserName, uniqueId), "Deploying resources...", "Updating deployment state...", "Deployment complete!\n",