diff --git a/acceptance/bundle/help/bundle-validate/output.txt b/acceptance/bundle/help/bundle-validate/output.txt index e2dff4e36e..dbb15761b3 100644 --- a/acceptance/bundle/help/bundle-validate/output.txt +++ b/acceptance/bundle/help/bundle-validate/output.txt @@ -5,6 +5,7 @@ Validate bundle configuration for errors, warnings and recommendations. Run validate before deploy to catch configuration issues early: databricks bundle validate # Validate default target databricks bundle validate --target prod # Validate specific target + databricks bundle validate --strict # Fail on warnings Validation checks the configuration syntax and schema, permissions etc. @@ -14,7 +15,8 @@ Usage: databricks bundle validate [flags] Flags: - -h, --help help for validate + -h, --help help for validate + --strict Treat warnings as errors Global Flags: --debug enable debug logging diff --git a/acceptance/bundle/validate/strict/databricks.yml b/acceptance/bundle/validate/strict/databricks.yml new file mode 100644 index 0000000000..ae9d3e86b4 --- /dev/null +++ b/acceptance/bundle/validate/strict/databricks.yml @@ -0,0 +1,17 @@ +bundle: + name: test-bundle + +variables: + my_variable: + type: INVALID_TYPE + default: "value" + +targets: + foo: + default: true + + bar: + artifacts: + my_artifact: + type: INVALID_TYPE + build: "echo 'hello'" diff --git a/acceptance/bundle/validate/strict/out.test.toml b/acceptance/bundle/validate/strict/out.test.toml new file mode 100644 index 0000000000..d560f1de04 --- /dev/null +++ b/acceptance/bundle/validate/strict/out.test.toml @@ -0,0 +1,5 @@ +Local = true +Cloud = false + +[EnvMatrix] + DATABRICKS_BUNDLE_ENGINE = ["terraform", "direct"] diff --git a/acceptance/bundle/validate/strict/output.txt b/acceptance/bundle/validate/strict/output.txt new file mode 100644 index 0000000000..ca25c721f5 --- /dev/null +++ b/acceptance/bundle/validate/strict/output.txt @@ -0,0 +1,49 @@ + +>>> [CLI] bundle validate +Warning: invalid value "INVALID_TYPE" for enum field. Valid values are [complex] + at variables.my_variable.type + in databricks.yml:6:11 + +Name: test-bundle +Target: foo +Workspace: + User: [USERNAME] + Path: /Workspace/Users/[USERNAME]/.bundle/test-bundle/foo + +Found 1 warning + +>>> [CLI] bundle validate --strict +Warning: invalid value "INVALID_TYPE" for enum field. Valid values are [complex] + at variables.my_variable.type + in databricks.yml:6:11 + +Name: test-bundle +Target: foo +Workspace: + User: [USERNAME] + Path: /Workspace/Users/[USERNAME]/.bundle/test-bundle/foo + +Found 1 warning +Error: 1 warning was found. Warnings are not allowed in strict mode + +Exit code: 1 + +>>> [CLI] bundle validate --strict -t bar +Warning: invalid value "INVALID_TYPE" for enum field. Valid values are [complex] + at variables.my_variable.type + in databricks.yml:6:11 + +Warning: invalid value "INVALID_TYPE" for enum field. Valid values are [whl jar] + at artifacts.my_artifact.type + in databricks.yml:16:15 + +Name: test-bundle +Target: bar +Workspace: + User: [USERNAME] + Path: /Workspace/Users/[USERNAME]/.bundle/test-bundle/bar + +Found 2 warnings +Error: 2 warnings were found. Warnings are not allowed in strict mode + +Exit code: 1 diff --git a/acceptance/bundle/validate/strict/script b/acceptance/bundle/validate/strict/script new file mode 100644 index 0000000000..737a7a84e0 --- /dev/null +++ b/acceptance/bundle/validate/strict/script @@ -0,0 +1,7 @@ +# Without --strict, warnings don't cause exit code 1 +trace $CLI bundle validate + +# With --strict, warnings cause exit code 1 +errcode trace $CLI bundle validate --strict + +errcode trace $CLI bundle validate --strict -t bar diff --git a/cmd/bundle/validate.go b/cmd/bundle/validate.go index 1d13cbe490..3eccffde8f 100644 --- a/cmd/bundle/validate.go +++ b/cmd/bundle/validate.go @@ -2,6 +2,7 @@ package bundle import ( "encoding/json" + "fmt" "github.com/databricks/cli/bundle" "github.com/databricks/cli/bundle/render" @@ -35,6 +36,7 @@ func newValidateCommand() *cobra.Command { Run validate before deploy to catch configuration issues early: databricks bundle validate # Validate default target databricks bundle validate --target prod # Validate specific target + databricks bundle validate --strict # Fail on warnings Validation checks the configuration syntax and schema, permissions etc. @@ -43,8 +45,10 @@ Please run this command before deploying to ensure configuration quality.`, } var includeLocations bool + var strict bool cmd.Flags().BoolVar(&includeLocations, "include-locations", false, "Include location information in the output") cmd.Flags().MarkHidden("include-locations") + cmd.Flags().BoolVar(&strict, "strict", false, "Treat warnings as errors") cmd.RunE = func(cmd *cobra.Command, args []string) error { b, err := utils.ProcessBundle(cmd, utils.ProcessOptions{ @@ -74,6 +78,18 @@ Please run this command before deploying to ensure configuration quality.`, } } + // In strict mode, treat warnings as errors. + numWarnings := logdiag.NumWarnings(ctx) + if err == nil && strict && numWarnings > 0 { + prefix := "" + if numWarnings == 1 { + prefix = fmt.Sprintf("1 warning was found") + } else { + prefix = fmt.Sprintf("%d warnings were found", numWarnings) + } + return fmt.Errorf("%s. Warnings are not allowed in strict mode", prefix) + } + return err } diff --git a/libs/logdiag/logdiag.go b/libs/logdiag/logdiag.go index d830e4dfbe..75c9e5c188 100644 --- a/libs/logdiag/logdiag.go +++ b/libs/logdiag/logdiag.go @@ -77,6 +77,14 @@ func HasError(ctx context.Context) bool { return val.Errors > 0 } +func NumWarnings(ctx context.Context) int { + val := read(ctx) + val.mu.Lock() + defer val.mu.Unlock() + + return val.Warnings +} + func SetSeverity(ctx context.Context, target diag.Severity) { val := read(ctx) val.mu.Lock()