Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions acceptance/bundle/null/map-key/databricks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
bundle:
name: test-bundle

run_as:
user_name: base-user

variables:
foo:
default: base-value
description: a variable

resources:
jobs:
my_job:
name: my job
description: base description

targets:
dev-run-as:
# Complex: null on a struct-typed field at the top level of a target override.
# The base run_as value survives merge. When null-merge semantics change this
# field should become absent.
run_as:

dev-job-field:
# Scalar: null on a string field inside a resource. Normalization drops it
# and emits a warning; the base description survives merge.
resources:
jobs:
my_job:
description:

dev-variable:
# MapKey: null on a value in the variables map (map[string]*TargetVariable).
# The null overrides the variable entry; currently survives as null.
variables:
foo:

dev-resource:
# Resource: null on an entire resource entry. The job is completely nulled.
resources:
jobs:
my_job:
3 changes: 3 additions & 0 deletions acceptance/bundle/null/map-key/out.test.toml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

81 changes: 81 additions & 0 deletions acceptance/bundle/null/map-key/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@

>>> [CLI] bundle validate -o json -t dev-run-as
Warning: expected a string value, found null
at targets.dev-job-field.resources.jobs.my_job.description
in databricks.yml:31:23

{
"run_as": {
"user_name": "base-user"
}
}

>>> [CLI] bundle validate -o json -t dev-job-field
Warning: expected a string value, found null
at targets.dev-job-field.resources.jobs.my_job.description
in databricks.yml:31:23

{
"description": "base description"
}

>>> [CLI] bundle validate -o json -t dev-variable
Warning: expected a string value, found null
at targets.dev-job-field.resources.jobs.my_job.description
in databricks.yml:31:23

{
"variables": {
"foo": {
"default": "base-value",
"description": "a variable",
"value": "base-value"
}
}
}

>>> [CLI] bundle validate -o json -t dev-resource
Warning: expected a string value, found null
at targets.dev-job-field.resources.jobs.my_job.description
in databricks.yml:31:23

{
"resources": {
"jobs": {
"my_job": {
"deployment": {
"kind": "BUNDLE",
"metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/test-bundle/dev-resource/state/metadata.json"
},
"description": "base description",
"edit_mode": "UI_LOCKED",
"format": "MULTI_TASK",
"max_concurrent_runs": 1,
"name": "my job",
"queue": {
"enabled": true
},
"run_as": {
"user_name": "base-user"
}
}
}
}
}

>>> [CLI] bundle deploy -t dev-run-as
Warning: expected a string value, found null
at targets.dev-job-field.resources.jobs.my_job.description
in databricks.yml:31:23

Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/dev-run-as/files...
Deploying resources...
Updating deployment state...
Deployment complete!

>>> print_telemetry_bool_values
null-in-targets true
null-in-targets-complex true
null-in-targets-key true
null-in-targets-resource true
null-in-targets-scalar true
9 changes: 9 additions & 0 deletions acceptance/bundle/null/map-key/script
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
trace $CLI bundle validate -o json -t dev-run-as | jq '{run_as: .run_as}'
trace $CLI bundle validate -o json -t dev-job-field | jq '{description: .resources.jobs.my_job.description}'
trace $CLI bundle validate -o json -t dev-variable | jq '{variables: {foo: .variables.foo}}'
trace $CLI bundle validate -o json -t dev-resource | jq '{resources: {jobs: .resources.jobs}}'

trace $CLI bundle deploy -t dev-run-as
trace print_telemetry_bool_values | grep null-in-targets

rm -f out.requests.txt
17 changes: 17 additions & 0 deletions acceptance/bundle/null/null-from-include/databricks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
bundle:
name: test-bundle

include:
- override.yml

workspace:
root_path: /Workspace/Users/base-root

targets:
dev:
default: true

resources:
jobs:
my_job:
name: my job
3 changes: 3 additions & 0 deletions acceptance/bundle/null/null-from-include/out.test.toml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 25 additions & 0 deletions acceptance/bundle/null/null-from-include/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

>>> [CLI] bundle validate -o json -t dev
Warning: expected a string value, found null
at targets.dev.workspace.root_path
in override.yml:6:17

{
"workspace": {
"root_path": "/Workspace/Users/base-root"
}
}

>>> [CLI] bundle deploy -t dev
Warning: expected a string value, found null
at targets.dev.workspace.root_path
in override.yml:6:17

Uploading bundle files to /Workspace/Users/base-root/files...
Deploying resources...
Updating deployment state...
Deployment complete!

>>> print_telemetry_bool_values
null-in-targets true
null-in-targets-scalar true
6 changes: 6 additions & 0 deletions acceptance/bundle/null/null-from-include/override.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
targets:
dev:
# Null in an included file under targets: NullInTargets should be true
# even though the null comes from an included file, not the root config.
workspace:
root_path:
6 changes: 6 additions & 0 deletions acceptance/bundle/null/null-from-include/script
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
trace $CLI bundle validate -o json -t dev | jq '{workspace: {root_path: .workspace.root_path}}'

trace $CLI bundle deploy -t dev
trace print_telemetry_bool_values | grep null-in-targets

rm -f out.requests.txt
27 changes: 27 additions & 0 deletions acceptance/bundle/null/scalar-field/databricks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
bundle:
name: test-bundle

workspace:
root_path: /Workspace/Users/base-root

targets:
dev-null:
workspace:
# YAML null: normalization drops the null, so the base root_path survives
# in the merged config. When null-merge semantics change, this field should
# become absent (reverting to the default ~/.bundle/... path).
root_path:

dev-empty:
workspace:
# Explicit empty string: not a null, so normalization keeps it.
# The empty string overrides the base, then DefineDefaultWorkspaceRoot
# re-fills it with the default ~/.bundle/... path (since the field is "").
# Empty string and YAML null currently produce the same final value via
# different paths; this is captured here to document both behaviors.
root_path: ""

resources:
jobs:
my_job:
name: my job
3 changes: 3 additions & 0 deletions acceptance/bundle/null/scalar-field/out.test.toml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 36 additions & 0 deletions acceptance/bundle/null/scalar-field/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@

>>> [CLI] bundle validate -o json -t dev-null
Warning: expected a string value, found null
at targets.dev-null.workspace.root_path
in databricks.yml:13:17

{
"workspace": {
"root_path": "/Workspace/Users/base-root"
}
}

>>> [CLI] bundle validate -o json -t dev-empty
Warning: expected a string value, found null
at targets.dev-null.workspace.root_path
in databricks.yml:13:17

{
"workspace": {
"root_path": "/Workspace/Users/base-root"
}
}

>>> [CLI] bundle deploy -t dev-null
Warning: expected a string value, found null
at targets.dev-null.workspace.root_path
in databricks.yml:13:17

Uploading bundle files to /Workspace/Users/base-root/files...
Deploying resources...
Updating deployment state...
Deployment complete!

>>> print_telemetry_bool_values
null-in-targets true
null-in-targets-scalar true
7 changes: 7 additions & 0 deletions acceptance/bundle/null/scalar-field/script
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
trace $CLI bundle validate -o json -t dev-null | jq '{workspace: {root_path: .workspace.root_path}}'
trace $CLI bundle validate -o json -t dev-empty | jq '{workspace: {root_path: .workspace.root_path}}'

trace $CLI bundle deploy -t dev-null
trace print_telemetry_bool_values | grep null-in-targets

rm -f out.requests.txt
5 changes: 5 additions & 0 deletions acceptance/bundle/null/test.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
EnvMatrix.DATABRICKS_BUNDLE_ENGINE = []
RecordRequests = true

[Env]
DATABRICKS_CACHE_ENABLED = "false"
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ Deployment complete!
>>> cat out.requests.txt
{
"bool_values": [
{
"key": "null-in-targets",
"value": false
},
{
"key": "local.cache.attempt",
"value": true
Expand Down
2 changes: 2 additions & 0 deletions acceptance/bundle/telemetry/deploy-compute-type/output.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ local.cache.attempt true
local.cache.attempt true
local.cache.hit true
local.cache.miss true
null-in-targets false
null-in-targets false
permissions_section_set false
permissions_section_set false
presets_name_prefix_is_set false
Expand Down
1 change: 1 addition & 0 deletions acceptance/bundle/telemetry/deploy-experimental/output.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ has_classic_job_compute false
has_serverless_compute false
local.cache.attempt true
local.cache.miss true
null-in-targets false
permissions_section_set false
presets_name_prefix_is_set false
python_wheel_wrapper_is_set false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ has_classic_job_compute false
has_serverless_compute false
local.cache.attempt true
local.cache.miss true
null-in-targets false
permissions_section_set false
presets_name_prefix_is_set true
python_wheel_wrapper_is_set false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ has_classic_job_compute false
has_serverless_compute false
local.cache.attempt true
local.cache.miss true
null-in-targets false
permissions_section_set false
presets_name_prefix_is_set true
python_wheel_wrapper_is_set false
Expand Down
2 changes: 2 additions & 0 deletions acceptance/bundle/telemetry/deploy-whl-artifacts/output.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ local.cache.attempt true
local.cache.attempt true
local.cache.hit true
local.cache.miss true
null-in-targets false
null-in-targets false
permissions_section_set false
permissions_section_set false
python_wheel_wrapper_is_set false
Expand Down
4 changes: 4 additions & 0 deletions acceptance/bundle/telemetry/deploy/out.telemetry.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@
"lookup_variable_count": 0,
"target_count": 1,
"bool_values": [
{
"key": "null-in-targets",
"value": false
},
{
"key": "local.cache.attempt",
"value": true
Expand Down
43 changes: 43 additions & 0 deletions bundle/config/mutator/collect_null_telemetry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package mutator

import (
"context"

"github.com/databricks/cli/bundle"
"github.com/databricks/cli/libs/diag"
)

// collectNullTelemetry records per-category flags for null values found anywhere
// under the "targets" section, as authored. The signal is computed at load time
// (before normalization drops nulls on scalar-typed fields) and accumulated across
// all included files; this mutator just surfaces it as telemetry.
type collectNullTelemetry struct{}

func CollectNullTelemetry() bundle.Mutator {
return &collectNullTelemetry{}
}

func (*collectNullTelemetry) Name() string {
return "CollectNullTelemetry"
}

func (*collectNullTelemetry) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagnostics {
info := b.Config.NullInTargets()
b.Metrics.SetBoolValue("null-in-targets", info.Any())
if info.Scalar {
b.Metrics.SetBoolValue("null-in-targets-scalar", true)
}
if info.Complex {
b.Metrics.SetBoolValue("null-in-targets-complex", true)
}
if info.MapKey {
b.Metrics.SetBoolValue("null-in-targets-key", true)
}
if info.ArrayIndex {
b.Metrics.SetBoolValue("null-in-targets-index", true)
}
if info.Resource {
b.Metrics.SetBoolValue("null-in-targets-resource", true)
}
return nil
}
Loading
Loading