From e9d9eee03a62b5066c4a97b36805ab2dc0f1d28d Mon Sep 17 00:00:00 2001 From: Alyssa Gorbaneva Date: Thu, 10 Jul 2025 18:28:54 -0700 Subject: [PATCH 1/3] update deploy.go and add new flag --- cmd/pipelines/deploy.go | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/cmd/pipelines/deploy.go b/cmd/pipelines/deploy.go index 0ebdf04bae..1a83e8b30d 100644 --- a/cmd/pipelines/deploy.go +++ b/cmd/pipelines/deploy.go @@ -3,6 +3,7 @@ package pipelines import ( "context" + "time" "github.com/databricks/cli/bundle" "github.com/databricks/cli/bundle/config/validate" @@ -11,6 +12,7 @@ import ( "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/logdiag" "github.com/databricks/cli/libs/sync" + "github.com/databricks/cli/libs/telemetry/protos" "github.com/spf13/cobra" ) @@ -22,9 +24,11 @@ func deployCommand() *cobra.Command { } var forceLock bool + var failOnActiveRuns bool var autoApprove bool var verbose bool cmd.Flags().BoolVar(&forceLock, "force-lock", false, "Force acquisition of deployment lock.") + cmd.Flags().BoolVar(&failOnActiveRuns, "fail-on-active-runs", false, "Fail if there are running pipelines in the deployment.") cmd.Flags().BoolVar(&autoApprove, "auto-approve", false, "Skip interactive approvals that might be required for deployment.") cmd.Flags().BoolVar(&verbose, "verbose", false, "Enable verbose output.") // Verbose flag currently only affects file sync output, it's used by the vscode extension @@ -33,15 +37,19 @@ func deployCommand() *cobra.Command { cmd.RunE = func(cmd *cobra.Command, args []string) error { ctx := logdiag.InitContext(cmd.Context()) cmd.SetContext(ctx) - b := utils.ConfigureBundleWithVariables(cmd) - if logdiag.HasError(ctx) { + b := utils.ConfigureBundleWithVariables(cmd) + if b == nil || logdiag.HasError(ctx) { return root.ErrAlreadyPrinted } bundle.ApplyFuncContext(ctx, b, func(context.Context, *bundle.Bundle) { b.Config.Bundle.Deployment.Lock.Force = forceLock b.AutoApprove = autoApprove + + if cmd.Flag("fail-on-active-runs").Changed { + b.Config.Bundle.Deployment.FailOnActiveRuns = failOnActiveRuns + } }) var outputHandler sync.OutputHandler @@ -51,25 +59,45 @@ func deployCommand() *cobra.Command { } } + t0 := time.Now() phases.Initialize(ctx, b) + b.Metrics.ExecutionTimes = append(b.Metrics.ExecutionTimes, protos.IntMapEntry{ + Key: "phases.Initialize", + Value: time.Since(t0).Milliseconds(), + }) if logdiag.HasError(ctx) { return root.ErrAlreadyPrinted } + t1 := time.Now() bundle.ApplyContext(ctx, b, validate.FastValidate()) + b.Metrics.ExecutionTimes = append(b.Metrics.ExecutionTimes, protos.IntMapEntry{ + Key: "validate.FastValidate", + Value: time.Since(t1).Milliseconds(), + }) if logdiag.HasError(ctx) { return root.ErrAlreadyPrinted } + t2 := time.Now() phases.Build(ctx, b) + b.Metrics.ExecutionTimes = append(b.Metrics.ExecutionTimes, protos.IntMapEntry{ + Key: "phases.Build", + Value: time.Since(t2).Milliseconds(), + }) if logdiag.HasError(ctx) { return root.ErrAlreadyPrinted } + t3 := time.Now() phases.Deploy(ctx, b, outputHandler) + b.Metrics.ExecutionTimes = append(b.Metrics.ExecutionTimes, protos.IntMapEntry{ + Key: "phases.Deploy", + Value: time.Since(t3).Milliseconds(), + }) if logdiag.HasError(ctx) { return root.ErrAlreadyPrinted From 570489121734335a23d05d805f05a8b59ac2d19a Mon Sep 17 00:00:00 2001 From: Alyssa Gorbaneva Date: Fri, 11 Jul 2025 07:02:12 -0700 Subject: [PATCH 2/3] reverted deploy.go metrics --- cmd/bundle/deploy.go | 2 ++ cmd/pipelines/deploy.go | 23 +---------------------- 2 files changed, 3 insertions(+), 22 deletions(-) diff --git a/cmd/bundle/deploy.go b/cmd/bundle/deploy.go index 8ce265927c..a65f8a3e86 100644 --- a/cmd/bundle/deploy.go +++ b/cmd/bundle/deploy.go @@ -1,3 +1,5 @@ +// Copied to cmd/pipelines/deploy.go and adapted for pipelines use. +// Consider if changes made here should be made to the pipelines counterpart as well. package bundle import ( diff --git a/cmd/pipelines/deploy.go b/cmd/pipelines/deploy.go index 1a83e8b30d..f508fa8fc6 100644 --- a/cmd/pipelines/deploy.go +++ b/cmd/pipelines/deploy.go @@ -1,9 +1,9 @@ // Copied from cmd/bundle/deploy.go and adapted for pipelines use. +// Consider if changes made here should be made to the bundle counterpart as well. package pipelines import ( "context" - "time" "github.com/databricks/cli/bundle" "github.com/databricks/cli/bundle/config/validate" @@ -12,7 +12,6 @@ import ( "github.com/databricks/cli/cmd/root" "github.com/databricks/cli/libs/logdiag" "github.com/databricks/cli/libs/sync" - "github.com/databricks/cli/libs/telemetry/protos" "github.com/spf13/cobra" ) @@ -59,45 +58,25 @@ func deployCommand() *cobra.Command { } } - t0 := time.Now() phases.Initialize(ctx, b) - b.Metrics.ExecutionTimes = append(b.Metrics.ExecutionTimes, protos.IntMapEntry{ - Key: "phases.Initialize", - Value: time.Since(t0).Milliseconds(), - }) if logdiag.HasError(ctx) { return root.ErrAlreadyPrinted } - t1 := time.Now() bundle.ApplyContext(ctx, b, validate.FastValidate()) - b.Metrics.ExecutionTimes = append(b.Metrics.ExecutionTimes, protos.IntMapEntry{ - Key: "validate.FastValidate", - Value: time.Since(t1).Milliseconds(), - }) if logdiag.HasError(ctx) { return root.ErrAlreadyPrinted } - t2 := time.Now() phases.Build(ctx, b) - b.Metrics.ExecutionTimes = append(b.Metrics.ExecutionTimes, protos.IntMapEntry{ - Key: "phases.Build", - Value: time.Since(t2).Milliseconds(), - }) if logdiag.HasError(ctx) { return root.ErrAlreadyPrinted } - t3 := time.Now() phases.Deploy(ctx, b, outputHandler) - b.Metrics.ExecutionTimes = append(b.Metrics.ExecutionTimes, protos.IntMapEntry{ - Key: "phases.Deploy", - Value: time.Since(t3).Milliseconds(), - }) if logdiag.HasError(ctx) { return root.ErrAlreadyPrinted From 00f022fb6df9a7cd942dfc451ba038176c181de1 Mon Sep 17 00:00:00 2001 From: Alyssa Gorbaneva Date: Fri, 11 Jul 2025 08:41:57 -0700 Subject: [PATCH 3/3] acceptance test for pipelines --- .../deploy/fail-on-active-runs/databricks.yml | 6 ++++++ .../deploy/fail-on-active-runs/out.test.toml | 5 +++++ .../deploy/fail-on-active-runs/output.txt | 12 ++++++++++++ .../pipelines/deploy/fail-on-active-runs/script | 4 ++++ .../pipelines/deploy/fail-on-active-runs/test.toml | 14 ++++++++++++++ 5 files changed, 41 insertions(+) create mode 100644 acceptance/pipelines/deploy/fail-on-active-runs/databricks.yml create mode 100644 acceptance/pipelines/deploy/fail-on-active-runs/out.test.toml create mode 100644 acceptance/pipelines/deploy/fail-on-active-runs/output.txt create mode 100644 acceptance/pipelines/deploy/fail-on-active-runs/script create mode 100644 acceptance/pipelines/deploy/fail-on-active-runs/test.toml diff --git a/acceptance/pipelines/deploy/fail-on-active-runs/databricks.yml b/acceptance/pipelines/deploy/fail-on-active-runs/databricks.yml new file mode 100644 index 0000000000..854a1d112f --- /dev/null +++ b/acceptance/pipelines/deploy/fail-on-active-runs/databricks.yml @@ -0,0 +1,6 @@ +bundle: + name: pipeline-fail-on-active-runs +resources: + pipelines: + my_pipeline: + name: pipeline-fail-on-active-runs diff --git a/acceptance/pipelines/deploy/fail-on-active-runs/out.test.toml b/acceptance/pipelines/deploy/fail-on-active-runs/out.test.toml new file mode 100644 index 0000000000..387f29e8bb --- /dev/null +++ b/acceptance/pipelines/deploy/fail-on-active-runs/out.test.toml @@ -0,0 +1,5 @@ +Local = true +Cloud = false + +[EnvMatrix] + DATABRICKS_CLI_DEPLOYMENT = ["terraform"] diff --git a/acceptance/pipelines/deploy/fail-on-active-runs/output.txt b/acceptance/pipelines/deploy/fail-on-active-runs/output.txt new file mode 100644 index 0000000000..800306447c --- /dev/null +++ b/acceptance/pipelines/deploy/fail-on-active-runs/output.txt @@ -0,0 +1,12 @@ + +>>> [PIPELINES] deploy +Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/pipeline-fail-on-active-runs/default/files... +Deploying resources... +Updating deployment state... +Deployment complete! + +>>> errcode [PIPELINES] deploy --fail-on-active-runs +Error: pipeline [UUID] is running + + +Exit code: 1 diff --git a/acceptance/pipelines/deploy/fail-on-active-runs/script b/acceptance/pipelines/deploy/fail-on-active-runs/script new file mode 100644 index 0000000000..3894cb7d7a --- /dev/null +++ b/acceptance/pipelines/deploy/fail-on-active-runs/script @@ -0,0 +1,4 @@ +trace $PIPELINES deploy + +# We deploy the bundle again to check that the deploy is failing if the job is running +trace errcode $PIPELINES deploy --fail-on-active-runs diff --git a/acceptance/pipelines/deploy/fail-on-active-runs/test.toml b/acceptance/pipelines/deploy/fail-on-active-runs/test.toml new file mode 100644 index 0000000000..bf36891b04 --- /dev/null +++ b/acceptance/pipelines/deploy/fail-on-active-runs/test.toml @@ -0,0 +1,14 @@ +# Deploy relies on terraform.CheckRunningResource() +EnvMatrix.DATABRICKS_CLI_DEPLOYMENT = ["terraform"] + +# Cycling between states not implemented yet +# spec to avoid "pipeline spec is nil" error + +[[Server]] +Pattern = "GET /api/2.0/pipelines/{pipeline_id}" +Response.Body = ''' +{ + "state": "RUNNING", + "spec": {} +} +'''