From d654b8006e19af5325269325a45140ea4d1f6cbc Mon Sep 17 00:00:00 2001 From: Shreyas Goenka Date: Mon, 21 Sep 2026 15:15:40 +0000 Subject: [PATCH] bundle: report deployment history in deploy telemetry --- acceptance/bundle/dms/no-resources/output.txt | 3 +++ acceptance/bundle/dms/no-resources/script | 1 + acceptance/bundle/dms/script.prepare | 4 ++++ .../telemetry/deploy-app-lifecycle-started/output.txt | 4 ++++ acceptance/bundle/telemetry/deploy/out.telemetry.txt | 4 ++++ acceptance/script.prepare | 9 ++++----- bundle/metrics/metrics.go | 1 + bundle/phases/telemetry.go | 1 + 8 files changed, 22 insertions(+), 5 deletions(-) diff --git a/acceptance/bundle/dms/no-resources/output.txt b/acceptance/bundle/dms/no-resources/output.txt index b0167af933e..635506c6bc5 100644 --- a/acceptance/bundle/dms/no-resources/output.txt +++ b/acceptance/bundle/dms/no-resources/output.txt @@ -5,6 +5,9 @@ Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/dms-no-resources-[ Files: 3 uploaded, 0 deleted Resources: 0 created, 0 changed, 0 deleted, 0 unchanged +>>> deployment_history_telemetry +deployment_history_enabled true + >>> print_requests.py --dms //api/2.0/bundle --get { "method": "POST", diff --git a/acceptance/bundle/dms/no-resources/script b/acceptance/bundle/dms/no-resources/script index 7f9e9760b5d..247c1abcb3e 100644 --- a/acceptance/bundle/dms/no-resources/script +++ b/acceptance/bundle/dms/no-resources/script @@ -2,6 +2,7 @@ envsubst < databricks.yml.tmpl > databricks.yml title "First deploy of a bundle with no resources: the deployment is created, and its workspace node identifies it even though no resource state was written" trace $CLI bundle deploy +trace deployment_history_telemetry trace print_requests.py --dms //api/2.0/bundle --get trace MSYS_NO_PATHCONV=1 $CLI workspace get-status "/Workspace/Users/${CURRENT_USER_NAME}/.bundle/dms-no-resources-${UNIQUE_NAME}/default/state/resources.deployment.json" | jq '{object_type,path}' diff --git a/acceptance/bundle/dms/script.prepare b/acceptance/bundle/dms/script.prepare index fee2c01fd1b..c67f63ef8e0 100644 --- a/acceptance/bundle/dms/script.prepare +++ b/acceptance/bundle/dms/script.prepare @@ -7,3 +7,7 @@ dms_plan() { trace $CLI bundle plan "$@" -o json | jq 'del(.plan)' trace $CLI bundle plan "$@" } + +deployment_history_telemetry() { + jq -r 'select(.path? == "/telemetry-ext") | .body.protoLogs[] | fromjson | .entry.databricks_cli_log.bundle_deploy_event.experimental.bool_values[] | select(.key == "deployment_history_enabled") | "\(.key) \(.value)"' "$OUT_REQUESTS" +} diff --git a/acceptance/bundle/telemetry/deploy-app-lifecycle-started/output.txt b/acceptance/bundle/telemetry/deploy-app-lifecycle-started/output.txt index db642ef17c3..479203649de 100644 --- a/acceptance/bundle/telemetry/deploy-app-lifecycle-started/output.txt +++ b/acceptance/bundle/telemetry/deploy-app-lifecycle-started/output.txt @@ -89,6 +89,10 @@ Resources: 1 created, 0 changed, 0 deleted, 0 unchanged "key": "has_classic_interactive_compute", "value": false }, + { + "key": "deployment_history_enabled", + "value": false + }, { "key": "app_lifecycle_started", "value": true diff --git a/acceptance/bundle/telemetry/deploy/out.telemetry.txt b/acceptance/bundle/telemetry/deploy/out.telemetry.txt index ae01136c31b..626565b3d77 100644 --- a/acceptance/bundle/telemetry/deploy/out.telemetry.txt +++ b/acceptance/bundle/telemetry/deploy/out.telemetry.txt @@ -121,6 +121,10 @@ { "key": "has_classic_interactive_compute", "value": false + }, + { + "key": "deployment_history_enabled", + "value": false } ], "bundle_mode": "TYPE_UNSPECIFIED", diff --git a/acceptance/script.prepare b/acceptance/script.prepare index e4c6ea53f02..a53627b231d 100644 --- a/acceptance/script.prepare +++ b/acceptance/script.prepare @@ -121,12 +121,11 @@ nostamp() { env -u MSYS_NO_PATHCONV nostamp.py "$@" } -# The engine_terraform_* keys reflect the deployment engine opt-in; engine_terraform_env -# in particular mirrors $DATABRICKS_BUNDLE_ENGINE, which the acceptance matrix sets per -# variant, so it diverges across the matrix. Drop both here so this shared helper stays -# engine-agnostic; they are asserted per-engine in bundle/telemetry/deploy. +# The engine_terraform_* and deployment_history_enabled keys reflect matrix settings, so they +# legitimately diverge across variants. Drop them here so this shared helper stays +# matrix-agnostic; engine selection is asserted in bundle/telemetry/deploy. print_telemetry_bool_values() { - jq -r 'select(.path? == "/telemetry-ext") | (.body.protoLogs // [])[] | fromjson | ( (.entry // .) | (.databricks_cli_log.bundle_deploy_event.experimental.bool_values // []) ) | map("\(.key) \(.value)") | .[]' "$OUT_REQUESTS" | grep -v '^engine_terraform_' | sort + jq -r 'select(.path? == "/telemetry-ext") | (.body.protoLogs // [])[] | fromjson | ( (.entry // .) | (.databricks_cli_log.bundle_deploy_event.experimental.bool_values // []) ) | map("\(.key) \(.value)") | .[]' "$OUT_REQUESTS" | grep -Ev '^(engine_terraform_|deployment_history_enabled )' | sort } sethome() { diff --git a/bundle/metrics/metrics.go b/bundle/metrics/metrics.go index e5a50769ee9..27169e44a10 100644 --- a/bundle/metrics/metrics.go +++ b/bundle/metrics/metrics.go @@ -8,6 +8,7 @@ const ( PresetsNamePrefixIsSet = "presets_name_prefix_is_set" AppLifecycleStarted = "app_lifecycle_started" ClusterLifecycleStarted = "cluster_lifecycle_started" + DeploymentHistoryEnabled = "deployment_history_enabled" SqlWarehouseLifecycleStarted = "sql_warehouse_lifecycle_started" SelectUsed = "select_used" diff --git a/bundle/phases/telemetry.go b/bundle/phases/telemetry.go index e8b7617fc55..4b6d705eba9 100644 --- a/bundle/phases/telemetry.go +++ b/bundle/phases/telemetry.go @@ -198,6 +198,7 @@ func aiRuntimeTaskMetrics(jobs map[string]*resources.Job) (present, scheduled, m // LogDeployTelemetry logs a telemetry event for a bundle deploy command. func LogDeployTelemetry(ctx context.Context, b *bundle.Bundle, errMsg string) { errMsg = telemetry.ScrubErrorMessage(errMsg) + b.Metrics.SetBoolValue(metrics.DeploymentHistoryEnabled, b.DeploymentBundle.StateDB.IsDeploymentMetadataService()) resourcesCount := int64(0) _, err := dyn.MapByPattern(b.Config.Value(), dyn.NewPattern(dyn.Key("resources"), dyn.AnyKey(), dyn.AnyKey()), func(p dyn.Path, v dyn.Value) (dyn.Value, error) {