Skip to content

Support best effort deployment history mode - #7169

Open
shreyas-goenka wants to merge 1 commit into
mainfrom
shreyas-goenka_data/shreyas/history-best-effort-default
Open

shreyas-goenka wants to merge 1 commit into
mainfrom
shreyas-goenka_data/shreyas/history-best-effort-default

Conversation

@shreyas-goenka

@shreyas-goenka shreyas-goenka commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

When experimental.deployment_history: true or DATABRICKS_BUNDLE_DEPLOYMENT_HISTORY=true are set use the best effort deployment history mode instead of treating DMS as SOT.

@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Commit: 83de54779 | Workflow run

Regression test report

Selected 20 changed tests (limit=20, 3 not selected)

21 tests: regression=19 unreleased=0 coverage=2 failing=0

test branch main (c6bb214) latest (v1.22.1)
TestAccept/bundle/deploy/readplan/lineage-mismatch/DMS= ✅ ✅ ✅
TestAccept/bundle/deploy/readplan/lineage-mismatch/DMS=true ✅ ❌ ❌
TestAccept/bundle/dms/bind-unbind-unsupported/DMS=true ✅ ❌ ❌
TestAccept/bundle/dms/declined-deploy/DMS=true ✅ ❌ ❌
TestAccept/bundle/dms/depends-on/DMS=true ✅ ❌ ❌
TestAccept/bundle/dms/deployment-metadata-change/DMS=true ✅ ❌ ❌
TestAccept/bundle/dms/empty-grants/DMS=true ✅ ❌ ❌
TestAccept/bundle/dms/existing-state/DMS= ✅ ❌ ❌
TestAccept/bundle/dms/failed-delete/DMS=true ✅ ❌ ❌
TestAccept/bundle/dms/failed-recreate/DMS=true ✅ ❌ ❌
TestAccept/bundle/dms/failed-update-permissions/DMS=true ✅ ❌ ❌
TestAccept/bundle/dms/mismatch-before-read/DMS=true ✅ ❌ ❌
TestAccept/bundle/dms/multiple-resources/DMS=true ✅ ❌ ❌
TestAccept/bundle/dms/no-drift/DMS=true ✅ ❌ ❌
TestAccept/bundle/dms/no-resources/DMS=true ✅ ❌ ❌
TestAccept/bundle/dms/operation-upload-fails-once/DMS=true ✅ ❌ ❌
TestAccept/bundle/dms/plan-without-dms/DMS= ✅ ✅ ✅
TestAccept/bundle/dms/record-failure/DMS=true ✅ ❌ ❌
TestAccept/bundle/dms/stale-local-state/DMS= ✅ ❌ ❌
TestAccept/bundle/dms/state-features/DMS=true ✅ ❌ ❌
TestAccept/bundle/dms/version-never-created/DMS=true ✅ ❌ ❌
TestAccept/bundle/deploy/readplan/lineage-mismatch/DMS=true: branch ✅ | main (c6bb214) ❌ | latest (v1.22.1) ❌

main (c6bb214):

acceptance_test.go:1311: 
        	Error Trace:	/home/runner/work/cli/cli/libs/testdiff/testdiff.go:22
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1311
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1081
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:659
        	Error:      	Not equal: 
        	            	expected: "\n>>> musterr [CLI] bundle deploy --plan plan.json\nWarn: Plan was created with CLI version 0.0.0-test but current version is [CLI_VERSION]\nError: plan lineage \"different-lineage\" does not match state lineage \"\"; the state may have been modified by another process\n\n"
        	            	actual  : "\n>>> musterr [CLI] bundle deploy --plan plan.json\nWarn: Plan was created with CLI version 0.0.0-test but current version is [CLI_VERSION]\nError: this plan was created for a different set of state features than the target now has; run 'bundle plan' again\n\n"
        	            	
        	            	Diff:
        	            	--- Expected
        	            	+++ Actual
        	            	@@ -3,3 +3,3 @@
        	            	 Warn: Plan was created with CLI version 0.0.0-test but current version is [CLI_VERSION]
        	            	-Error: plan lineage "different-lineage" does not match state lineage ""; the state may have been modified by another process
        	            	+Error: this plan was created for a different set of state features than the target now has; run 'bundle plan' again
        	            	 
        	Test:       	TestAccept/bundle/deploy/readplan/lineage-mismatch/DMS=true
        	Messages:   	bundle/deploy/readplan/lineage-mismatch/output.txt vs /tmp/TestAcceptbundledeployreadplanlineage-mismatchDMS=true1927392701/002/output.txt

latest (v1.22.1): same output as main (c6bb214)

TestAccept/bundle/dms/bind-unbind-unsupported/DMS=true: branch ✅ | main (c6bb214) ❌ | latest (v1.22.1) ❌

main (c6bb214):

acceptance_test.go:1311: 
        	Error Trace:	/home/runner/work/cli/cli/libs/testdiff/testdiff.go:22
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1311
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1081
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:659
        	Error:      	Not equal: 
        	            	expected: "\n=== bind is refused while recording deployment history\n>>> musterr [CLI] bundle deployment bind foo [JOB_ID]\nError: bind is not supported for a bundle target that records deployment history\n\n\n=== Unbind is allowed for file-backed history state\n>>> [CLI] bundle deploy\nUploading bundle files to /Workspace/Users/[USERNAME]/.bundle/dms-bind-unbind-[UNIQUE_NAME]/default/files...\nCreated jobs.foo\nFiles: 2 uploaded, 0 deleted\nResources: 1 created, 0 changed, 0 deleted, 0 unchanged\n\n>>> [CLI] bundle deployment unbind foo\n\n>>> jq {features, state} .databricks/bundle/default/resources.json\n{\n  \"features\": null,\n  \"state\": {}\n}\n"
        	            	actual  : "\n=== bind is refused while recording deployment history\n>>> musterr [CLI] bundle deployment bind foo [JOB_ID]\nError: bind is not supported for a bundle target that records deployment history\n\n\n=== Unbind is allowed for file-backed history state\n>>> [CLI] bundle deploy\nUploading bundle files to /Workspace/Users/[USERNAME]/.bundle/dms-bind-unbind-[UNIQUE_NAME]/default/files...\nCreated jobs.foo\nFiles: 2 uploaded, 0 deleted\nResources: 1 created, 0 changed, 0 deleted, 0 unchanged\n\n>>> [CLI] bundle deployment unbind foo\nError: unbind is not supported for a bundle target that records deployment history\n\n\nExit code: 1\n"
        	            	
        	            	Diff:
        	            	--- Expected
        	            	+++ Actual
        	            	@@ -14,8 +14,6 @@
        	            	 >>> [CLI] bundle deployment unbind foo
        	            	+Error: unbind is not supported for a bundle target that records deployment history
        	            	 
        	            	->>> jq {features, state} .databricks/bundle/default/resources.json
        	            	-{
        	            	-  "features": null,
        	            	-  "state": {}
        	            	-}
        	            	 
        	            	+Exit code: 1
        	            	+
        	Test:       	TestAccept/bundle/dms/bind-unbind-unsupported/DMS=true
        	Messages:   	bundle/dms/bind-unbind-unsupported/output.txt vs /tmp/TestAcceptbundledmsbind-unbind-unsupportedDMS=true369601024/002/output.txt

latest (v1.22.1):

acceptance_test.go:1311: 
        	Error Trace:	/home/runner/work/cli/cli/libs/testdiff/testdiff.go:22
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1311
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1081
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:659
        	Error:      	Not equal: 
        	            	expected: "\n=== bind is refused while recording deployment history\n>>> musterr [CLI] bundle deployment bind foo [JOB_ID]\nError: bind is not supported for a bundle target that records deployment history\n\n\n=== Unbind is allowed for file-backed history state\n>>> [CLI] bundle deploy\nUploading bundle files to /Workspace/Users/[USERNAME]/.bundle/dms-bind-unbind-[UNIQUE_NAME]/default/files...\nCreated jobs.foo\nFiles: 2 uploaded, 0 deleted\nResources: 1 created, 0 changed, 0 deleted, 0 unchanged\n\n>>> [CLI] bundle deployment unbind foo\n\n>>> jq {features, state} .databricks/bundle/default/resources.json\n{\n  \"features\": null,\n  \"state\": {}\n}\n"
        	            	actual  : "\n=== bind is refused while recording deployment history\n>>> musterr [CLI] bundle deployment bind foo [JOB_ID]\nError: bind is not supported for a bundle target that records deployment history\n\n\n=== Unbind is allowed for file-backed history state\n>>> [CLI] bundle deploy\nUploading bundle files to /Workspace/Users/[USERNAME]/.bundle/dms-bind-unbind-[UNIQUE_NAME]/default/files...\nCreated jobs.foo\nFiles: 2 uploaded, 0 deleted\nResources: 1 created, 0 changed, 0 deleted, 0 unchanged\n\n>>> [CLI] bundle deployment unbind foo\nError: unbind is not supported for a bundle target that records deployment history\n\n\nExit code: 1\n"
        	            	
        	            	Diff:
        	            	--- Expected
        	            	+++ Actual
        	            	@@ -14,8 +14,6 @@
        	            	 >>> [CLI] bundle deployment unbind foo
        	            	+Error: unbind is not supported for a bundle target that records deployment history
        	            	 
        	            	->>> jq {features, state} .databricks/bundle/default/resources.json
        	            	-{
        	            	-  "features": null,
        	            	-  "state": {}
        	            	-}
        	            	 
        	            	+Exit code: 1
        	            	+
        	Test:       	TestAccept/bundle/dms/bind-unbind-unsupported/DMS=true
        	Messages:   	bundle/dms/bind-unbind-unsupported/output.txt vs /tmp/TestAcceptbundledmsbind-unbind-unsupportedDMS=true1606995040/002/output.txt
FAIL
TestAccept/bundle/dms/declined-deploy/DMS=true: branch ✅ | main (c6bb214) ❌ | latest (v1.22.1) ❌

main (c6bb214):

acceptance_test.go:1311: Diff:
        --- bundle/dms/declined-deploy/output.txt
        +++ /tmp/TestAcceptbundledmsdeclined-deployDMS=true4271646783/002/output.txt
        @@ -67,7 +67,7 @@
           "lineage": "[UUID]",
           "serial": 1,
           "features": {
        -    "deployment_history_best_effort": {}
        +    "deployment_history": {}
           }
         }
         
        @@ -81,8 +81,16 @@
         }
         {
           "method": "GET",
        +  "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/resources"
        +}
        +{
        +  "method": "GET",
           "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]"
         }
        +{
        +  "method": "GET",
        +  "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/resources"
        +}
         
         >>> print_state.py --no-dms
         {
        @@ -91,17 +97,9 @@
          "lineage": "[UUID]",
          "serial": 1,
          "features": {
        -  "deployment_history_best_effort": {}
        +  "deployment_history": {}
          },
        - "state": {
        -  "resources.schemas.foo": {
        -   "__id__": "main.dms_declined_deploy_schema_[UNIQUE_NAME]",
        -   "state": {
        -    "catalog_name": "main",
        -    "name": "dms_declined_deploy_schema_[UNIQUE_NAME]"
        -   }
        -  }
        - }
        + "state": {}
         }
         
         === A destructive change without --auto-approve is declined: this console cannot prompt
        @@ -124,6 +121,10 @@
           "method": "GET",
           "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]"
         }
        +{
        +  "method": "GET",
        +  "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/resources"
        +}
         
         === The recorded resources are unchanged by the decline: the schema is still at version 1
         >>> MSYS_NO_PATHCONV=1 [CLI] bundle-deployments list-resources deployments/[DEPLOYMENT_ID] -o json
        @@ -160,6 +161,10 @@
           "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]"
         }
         {
        +  "method": "GET",
        +  "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/resources"
        +}
        +{
           "method": "POST",
           "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions",
           "q": {
        
    acceptance_test.go:1118: 
        LOG.catalog: {
        LOG.catalog:   "catalog_type": "MANAGED_CATALOG",
        LOG.catalog:   "created_at": 1793025837886,
        LOG.catalog:   "created_by": "tester@databricks.com",
        LOG.catalog:   "full_name": "dms_other_45z5htc4vbaxnotq6igtji65gi",
        LOG.catalog:   "metastore_id": "7a071a69-800a-715a-7a07-1a69800a7240",
        LOG.catalog:   "name": "dms_other_45z5htc4vbaxnotq6igtji65gi",
        LOG.catalog:   "owner": "tester@databricks.com",
        LOG.catalog:   "updated_at": 1793025837886,
        LOG.catalog:   "updated_by": "tester@databricks.com"
        LOG.catalog: }

latest (v1.22.1):

acceptance_test.go:1311: Diff:
        --- bundle/dms/declined-deploy/output.txt
        +++ /tmp/TestAcceptbundledmsdeclined-deployDMS=true110004605/002/output.txt
        @@ -67,7 +67,7 @@
           "lineage": "[UUID]",
           "serial": 1,
           "features": {
        -    "deployment_history_best_effort": {}
        +    "deployment_history": {}
           }
         }
         
        @@ -81,8 +81,16 @@
         }
         {
           "method": "GET",
        +  "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/resources"
        +}
        +{
        +  "method": "GET",
           "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]"
         }
        +{
        +  "method": "GET",
        +  "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/resources"
        +}
         
         >>> print_state.py --no-dms
         {
        @@ -91,17 +97,9 @@
          "lineage": "[UUID]",
          "serial": 1,
          "features": {
        -  "deployment_history_best_effort": {}
        +  "deployment_history": {}
          },
        - "state": {
        -  "resources.schemas.foo": {
        -   "__id__": "main.dms_declined_deploy_schema_[UNIQUE_NAME]",
        -   "state": {
        -    "catalog_name": "main",
        -    "name": "dms_declined_deploy_schema_[UNIQUE_NAME]"
        -   }
        -  }
        - }
        + "state": {}
         }
         
         === A destructive change without --auto-approve is declined: this console cannot prompt
        @@ -124,6 +121,10 @@
           "method": "GET",
           "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]"
         }
        +{
        +  "method": "GET",
        +  "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/resources"
        +}
         
         === The recorded resources are unchanged by the decline: the schema is still at version 1
         >>> MSYS_NO_PATHCONV=1 [CLI] bundle-deployments list-resources deployments/[DEPLOYMENT_ID] -o json
        @@ -160,6 +161,10 @@
           "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]"
         }
         {
        +  "method": "GET",
        +  "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/resources"
        +}
        +{
           "method": "POST",
           "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions",
           "q": {
        
    acceptance_test.go:1118: 
        LOG.catalog: {
        LOG.catalog:   "catalog_type": "MANAGED_CATALOG",
        LOG.catalog:   "created_at": 1793025857607,
        LOG.catalog:   "created_by": "tester@databricks.com",
        LOG.catalog:   "full_name": "dms_other_z7hca2wz5zcpnay7mfleklisce",
        LOG.catalog:   "metastore_id": "7a071a6e-1783-8ea4-7a07-1a6e17838fa9",
        LOG.catalog:   "name": "dms_other_z7hca2wz5zcpnay7mfleklisce",
        LOG.catalog:   "owner": "tester@databricks.com",
        LOG.catalog:   "updated_at": 1793025857607,
        LOG.catalog:   "updated_by": "tester@databricks.com"
        LOG.catalog: }
TestAccept/bundle/dms/depends-on/DMS=true: branch ✅ | main (c6bb214) ❌ | latest (v1.22.1) ❌

main (c6bb214):

acceptance_test.go:1311: Diff:
        --- bundle/dms/depends-on/output.txt
        +++ /tmp/TestAcceptbundledmsdepends-onDMS=true3112763550/002/output.txt
        @@ -5,7 +5,7 @@
           "plan_version": [PLAN_VERSION],
           "cli_version": "[CLI_VERSION]",
           "features": {
        -    "deployment_history_best_effort": {}
        +    "deployment_history": {}
           }
         }
         
        @@ -61,7 +61,7 @@
           "lineage": "[UUID]",
           "serial": 1,
           "features": {
        -    "deployment_history_best_effort": {}
        +    "deployment_history": {}
           }
         }
         
        @@ -91,53 +91,9 @@
          "lineage": "[UUID]",
          "serial": 1,
          "features": {
        -  "deployment_history_best_effort": {}
        +  "deployment_history": {}
          },
        - "state": {
        -  "resources.jobs.child": {
        -   "__id__": "[CHILD_ID]",
        -   "state": {
        -    "deployment": {
        -     "deployment_id": "[DEPLOYMENT_ID]",
        -     "kind": "BUNDLE",
        -     "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-depends-on-[UNIQUE_NAME]/default/state/metadata.json",
        -     "version_id": "1"
        -    },
        -    "description": "depends on [PARENT_ID]",
        -    "edit_mode": "UI_LOCKED",
        -    "format": "MULTI_TASK",
        -    "max_concurrent_runs": 1,
        -    "name": "child",
        -    "queue": {
        -     "enabled": true
        -    }
        -   },
        -   "depends_on": [
        -    {
        -     "node": "resources.jobs.parent",
        -     "label": "${resources.jobs.parent.id}"
        -    }
        -   ]
        -  },
        -  "resources.jobs.parent": {
        -   "__id__": "[PARENT_ID]",
        -   "state": {
        -    "deployment": {
        -     "deployment_id": "[DEPLOYMENT_ID]",
        -     "kind": "BUNDLE",
        -     "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-depends-on-[UNIQUE_NAME]/default/state/metadata.json",
        -     "version_id": "1"
        -    },
        -    "edit_mode": "UI_LOCKED",
        -    "format": "MULTI_TASK",
        -    "max_concurrent_runs": 1,
        -    "name": "parent",
        -    "queue": {
        -     "enabled": true
        -    }
        -   }
        -  }
        - }
        + "state": {}
         }
         
         >>> [CLI] bundle destroy --auto-approve

latest (v1.22.1): same output as main (c6bb214)

TestAccept/bundle/dms/deployment-metadata-change/DMS=true: branch ✅ | main (c6bb214) ❌ | latest (v1.22.1) ❌

main (c6bb214):

acceptance_test.go:1311: Diff:
        --- bundle/dms/deployment-metadata-change/output.txt
        +++ /tmp/TestAcceptbundledmsdeployment-metadata-changeDMS=true4079591879/002/output.txt
        @@ -67,7 +67,7 @@
           "lineage": "[UUID]",
           "serial": 1,
           "features": {
        -    "deployment_history_best_effort": {}
        +    "deployment_history": {}
           }
         }
         
        @@ -126,9 +126,9 @@
           "plan_version": [PLAN_VERSION],
           "cli_version": "[CLI_VERSION]",
           "lineage": "[UUID]",
        -  "serial": 2,
        +  "serial": 1,
           "features": {
        -    "deployment_history_best_effort": {}
        +    "deployment_history": {}
           }
         }

latest (v1.22.1): same output as main (c6bb214)

TestAccept/bundle/dms/empty-grants/DMS=true: branch ✅ | main (c6bb214) ❌ | latest (v1.22.1) ❌

main (c6bb214):

acceptance_test.go:1311: Diff:
        --- bundle/dms/empty-grants/output.txt
        +++ /tmp/TestAcceptbundledmsempty-grantsDMS=true1185415390/002/output.txt
        @@ -138,7 +138,7 @@
           "lineage": "[UUID]",
           "serial": 2,
           "features": {
        -    "deployment_history_best_effort": {}
        +    "deployment_history": {}
           }
         }
         
        @@ -163,17 +163,9 @@
          "lineage": "[UUID]",
          "serial": 2,
          "features": {
        -  "deployment_history_best_effort": {}
        +  "deployment_history": {}
          },
        - "state": {
        -  "resources.schemas.foo": {
        -   "__id__": "main.dms_empty_grants_[UNIQUE_NAME]",
        -   "state": {
        -    "catalog_name": "main",
        -    "name": "dms_empty_grants_[UNIQUE_NAME]"
        -   }
        -  }
        - }
        + "state": {}
         }
         
         >>> [CLI] bundle destroy --auto-approve

latest (v1.22.1): same output as main (c6bb214)

TestAccept/bundle/dms/existing-state/DMS=: branch ✅ | main (c6bb214) ❌ | latest (v1.22.1) ❌

main (c6bb214):

acceptance_test.go:1311: Diff:
        --- bundle/dms/existing-state/output.txt
        +++ /tmp/TestAcceptbundledmsexisting-stateDMS=2798636066/002/output.txt
        @@ -73,6 +73,6 @@
         {
           "state_version": 3,
           "features": {
        -    "deployment_history_best_effort": {}
        +    "deployment_history": {}
           }
         }

latest (v1.22.1): same output as main (c6bb214)

TestAccept/bundle/dms/failed-delete/DMS=true: branch ✅ | main (c6bb214) ❌ | latest (v1.22.1) ❌

main (c6bb214):

acceptance_test.go:1311: Diff:
        --- bundle/dms/failed-delete/output.txt
        +++ /tmp/TestAcceptbundledmsfailed-deleteDMS=true389811713/002/output.txt
        @@ -67,7 +67,7 @@
           "lineage": "[UUID]",
           "serial": 1,
           "features": {
        -    "deployment_history_best_effort": {}
        +    "deployment_history": {}
           }
         }
         
        @@ -92,28 +92,9 @@
          "lineage": "[UUID]",
          "serial": 1,
          "features": {
        -  "deployment_history_best_effort": {}
        +  "deployment_history": {}
          },
        - "state": {
        -  "resources.jobs.stuck": {
        -   "__id__": "[STUCK_ID]",
        -   "state": {
        -    "deployment": {
        -     "deployment_id": "[DEPLOYMENT_ID]",
        -     "kind": "BUNDLE",
        -     "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-failed-delete-[UNIQUE_NAME]/default/state/metadata.json",
        -     "version_id": "1"
        -    },
        -    "edit_mode": "UI_LOCKED",
        -    "format": "MULTI_TASK",
        -    "max_concurrent_runs": 1,
        -    "name": "stuck",
        -    "queue": {
        -     "enabled": true
        -    }
        -   }
        -  }
        - }
        + "state": {}
         }
         
         === A resource that fails to delete is recorded as a failed operation carrying the error, so the history says why rather than showing the resource gone
        @@ -203,28 +183,9 @@
          "lineage": "[UUID]",
          "serial": 2,
          "features": {
        -  "deployment_history_best_effort": {}
        +  "deployment_history": {}
          },
        - "state": {
        -  "resources.jobs.stuck": {
        -   "__id__": "[STUCK_ID]",
        -   "state": {
        -    "deployment": {
        -     "deployment_id": "[DEPLOYMENT_ID]",
        -     "kind": "BUNDLE",
        -     "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-failed-delete-[UNIQUE_NAME]/default/state/metadata.json",
        -     "version_id": "1"
        -    },
        -    "edit_mode": "UI_LOCKED",
        -    "format": "MULTI_TASK",
        -    "max_concurrent_runs": 1,
        -    "name": "stuck",
        -    "queue": {
        -     "enabled": true
        -    }
        -   }
        -  }
        - }
        + "state": {}
         }
         
         === The remote checkpoint stays at serial 1 while DMS advances to version 2

latest (v1.22.1): same output as main (c6bb214)

TestAccept/bundle/dms/failed-recreate/DMS=true: branch ✅ | main (c6bb214) ❌ | latest (v1.22.1) ❌

main (c6bb214):

acceptance_test.go:1311: Diff:
        --- bundle/dms/failed-recreate/output.txt
        +++ /tmp/TestAcceptbundledmsfailed-recreateDMS=true98414897/002/output.txt
        @@ -67,7 +67,7 @@
           "lineage": "[UUID]",
           "serial": 1,
           "features": {
        -    "deployment_history_best_effort": {}
        +    "deployment_history": {}
           }
         }
         
        @@ -92,18 +92,9 @@
          "lineage": "[UUID]",
          "serial": 1,
          "features": {
        -  "deployment_history_best_effort": {}
        +  "deployment_history": {}
          },
        - "state": {
        -  "resources.schemas.foo": {
        -   "__id__": "main.dms_failed_recreate_schema_[UNIQUE_NAME]",
        -   "state": {
        -    "catalog_name": "main",
        -    "comment": "v1",
        -    "name": "dms_failed_recreate_schema_[UNIQUE_NAME]"
        -   }
        -  }
        - }
        + "state": {}
         }
         
         === A recreate deletes and then fails to create. The delete went through, so the resource really is gone: the failed operation clears its state (self-contained, not assuming the delete's own write reached the service), rather than describing the resource as it was before the deploy
        @@ -188,7 +178,7 @@
          "lineage": "[UUID]",
          "serial": 2,
          "features": {
        -  "deployment_history_best_effort": {}
        +  "deployment_history": {}
          },
          "state": {}
         }
        
    acceptance_test.go:1118: 
        LOG.catalog: {
        LOG.catalog:   "catalog_type": "MANAGED_CATALOG",
        LOG.catalog:   "created_at": 1793025832586,
        LOG.catalog:   "created_by": "tester@databricks.com",
        LOG.catalog:   "full_name": "dms_other_xsaw64zatrbjncjgql26p2hznu",
        LOG.catalog:   "metastore_id": "7a071a68-4420-84aa-7a07-1a6844208587",
        LOG.catalog:   "name": "dms_other_xsaw64zatrbjncjgql26p2hznu",
        LOG.catalog:   "owner": "tester@databricks.com",
        LOG.catalog:   "updated_at": 1793025832586,
        LOG.catalog:   "updated_by": "tester@databricks.com"
        LOG.catalog: }
    acceptance_test.go:1118: 
        LOG.plan_final: create schemas.foo
        LOG.plan_final: 
        LOG.plan_final: Plan: 1 to add, 0 to change, 0 to delete, 0 unchanged

latest (v1.22.1):

acceptance_test.go:1311: Diff:
        --- bundle/dms/failed-recreate/output.txt
        +++ /tmp/TestAcceptbundledmsfailed-recreateDMS=true2582671346/002/output.txt
        @@ -67,7 +67,7 @@
           "lineage": "[UUID]",
           "serial": 1,
           "features": {
        -    "deployment_history_best_effort": {}
        +    "deployment_history": {}
           }
         }
         
        @@ -92,18 +92,9 @@
          "lineage": "[UUID]",
          "serial": 1,
          "features": {
        -  "deployment_history_best_effort": {}
        +  "deployment_history": {}
          },
        - "state": {
        -  "resources.schemas.foo": {
        -   "__id__": "main.dms_failed_recreate_schema_[UNIQUE_NAME]",
        -   "state": {
        -    "catalog_name": "main",
        -    "comment": "v1",
        -    "name": "dms_failed_recreate_schema_[UNIQUE_NAME]"
        -   }
        -  }
        - }
        + "state": {}
         }
         
         === A recreate deletes and then fails to create. The delete went through, so the resource really is gone: the failed operation clears its state (self-contained, not assuming the delete's own write reached the service), rather than describing the resource as it was before the deploy
        @@ -188,7 +178,7 @@
          "lineage": "[UUID]",
          "serial": 2,
          "features": {
        -  "deployment_history_best_effort": {}
        +  "deployment_history": {}
          },
          "state": {}
         }
        
    acceptance_test.go:1118: 
        LOG.catalog: {
        LOG.catalog:   "catalog_type": "MANAGED_CATALOG",
        LOG.catalog:   "created_at": 1793025854783,
        LOG.catalog:   "created_by": "tester@databricks.com",
        LOG.catalog:   "full_name": "dms_other_x4tpweya7jafpcpahcppzwed7q",
        LOG.catalog:   "metastore_id": "7a071a6d-6f2c-c2fd-7a07-1a6d6f2cc3f7",
        LOG.catalog:   "name": "dms_other_x4tpweya7jafpcpahcppzwed7q",
        LOG.catalog:   "owner": "tester@databricks.com",
        LOG.catalog:   "updated_at": 1793025854783,
        LOG.catalog:   "updated_by": "tester@databricks.com"
        LOG.catalog: }
    acceptance_test.go:1118: 
        LOG.plan_final: create schemas.foo
        LOG.plan_final: 
        LOG.plan_final: Plan: 1 to add, 0 to change, 0 to delete, 0 unchanged
TestAccept/bundle/dms/failed-update-permissions/DMS=true: branch ✅ | main (c6bb214) ❌ | latest (v1.22.1) ❌

main (c6bb214):

acceptance_test.go:1311: Diff:
        --- bundle/dms/failed-update-permissions/output.txt
        +++ /tmp/TestAcceptbundledmsfailed-update-permissionsDMS=true3475847843/002/output.txt
        @@ -15,7 +15,7 @@
           "lineage": "[UUID]",
           "serial": 1,
           "features": {
        -    "deployment_history_best_effort": {}
        +    "deployment_history": {}
           }
         }
         
        @@ -45,50 +45,9 @@
          "lineage": "[UUID]",
          "serial": 1,
          "features": {
        -  "deployment_history_best_effort": {}
        +  "deployment_history": {}
          },
        - "state": {
        -  "resources.jobs.foo": {
        -   "__id__": "[FOO_ID]",
        -   "state": {
        -    "deployment": {
        -     "deployment_id": "[DEPLOYMENT_ID]",
        -     "kind": "BUNDLE",
        -     "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-failed-update-permissions-[UNIQUE_NAME]/default/state/metadata.json",
        -     "version_id": "1"
        -    },
        -    "edit_mode": "UI_LOCKED",
        -    "format": "MULTI_TASK",
        -    "max_concurrent_runs": 1,
        -    "name": "foo",
        -    "queue": {
        -     "enabled": true
        -    }
        -   }
        -  },
        -  "resources.jobs.foo.permissions": {
        -   "__id__": "/jobs/[FOO_ID]",
        -   "state": {
        -    "object_id": "/jobs/[FOO_ID]",
        -    "__embed__": [
        -     {
        -      "level": "CAN_VIEW",
        -      "user_name": "viewer@example.com"
        -     },
        -     {
        -      "level": "IS_OWNER",
        -      "user_name": "[USERNAME]"
        -     }
        -    ]
        -   },
        -   "depends_on": [
        -    {
        -     "node": "resources.jobs.foo",
        -     "label": "${resources.jobs.foo.id}"
        -    }
        -   ]
        -  }
        - }
        + "state": {}
         }
         
         === A permissions update that fails records the failure with the permissions it still has. The resource ID here is a path rather than a number, and the state is the embedded permission list, so this covers a shape the resource tests do not
        @@ -141,50 +99,9 @@
          "lineage": "[UUID]",
          "serial": 2,
          "features": {
        -  "deployment_history_best_effort": {}
        +  "deployment_history": {}
          },
        - "state": {
        -  "resources.jobs.foo": {
        -   "__id__": "[FOO_ID]",
        -   "state": {
        -    "deployment": {
        -     "deployment_id": "[DEPLOYMENT_ID]",
        -     "kind": "BUNDLE",
        -     "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-failed-update-permissions-[UNIQUE_NAME]/default/state/metadata.json",
        -     "version_id": "1"
        -    },
        -    "edit_mode": "UI_LOCKED",
        -    "format": "MULTI_TASK",
        -    "max_concurrent_runs": 1,
        -    "name": "foo",
        -    "queue": {
        -     "enabled": true
        -    }
        -   }
        -  },
        -  "resources.jobs.foo.permissions": {
        -   "__id__": "/jobs/[FOO_ID]",
        -   "state": {
        -    "object_id": "/jobs/[FOO_ID]",
        -    "__embed__": [
        -     {
        -      "level": "CAN_VIEW",
        -      "user_name": "viewer@example.com"
        -     },
        -     {
        -      "level": "IS_OWNER",
        -      "user_name": "[USERNAME]"
        -     }
        -    ]
        -   },
        -   "depends_on": [
        -    {
        -     "node": "resources.jobs.foo",
        -     "label": "${resources.jobs.foo.id}"
        -    }
        -   ]
        -  }
        - }
        + "state": {}
         }
         
         >>> print_requests.py --dms //api/2.0/bundle --oneline

latest (v1.22.1): same output as main (c6bb214)

TestAccept/bundle/dms/mismatch-before-read/DMS=true: branch ✅ | main (c6bb214) ❌ | latest (v1.22.1) ❌

main (c6bb214):

acceptance_test.go:1311: 
        	Error Trace:	/home/runner/work/cli/cli/libs/testdiff/testdiff.go:22
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1311
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:1081
        	            				/home/runner/work/cli/cli/acceptance/acceptance_test.go:659
        	Error:      	Not equal: 
        	            	expected: "\n>>> [CLI] bundle deploy\nUploading bundle files to /Workspace/Users/[USERNAME]/.bundle/dms-mismatch-before-read-[UNIQUE_NAME]/default/files...\nCreated jobs.foo\nFiles: 2 uploaded, 0 deleted\nResources: 1 created, 0 changed, 0 deleted, 0 unchanged\n\n>>> fault.py GET /api/2.0/bundle/deployments/* 500 0 1\n\n>>> env DATABRICKS_BUNDLE_DEPLOYMENT_HISTORY=false [CLI] bundle plan\nupdate jobs.foo\n\nPlan: 0 to add, 1 to change, 0 to delete, 0 unchanged\n\n>>> env DATABRICKS_BUNDLE_DEPLOYMENT_HISTORY=false [CLI] bundle deploy\nUploading bundle files to /Workspace/Users/[USERNAME]/.bundle/dms-mismatch-before-read-[UNIQUE_NAME]/default/files...\nUpdated jobs.foo\nFiles: 1 uploaded, 0 deleted\nResources: 0 created, 1 changed, 0 deleted, 0 unchanged\n\n>>> jq .features // {} .databricks/bundle/default/resources.json\n{}\n"
        	            	actual  : "\n>>> [CLI] bundle deploy\nUploading bundle files to /Workspace/Users/[USERNAME]/.bundle/dms-mismatch-before-read-[UNIQUE_NAME]/default/files...\nCreated jobs.foo\nFiles: 2 uploaded, 0 deleted\nResources: 1 created, 0 changed, 0 deleted, 0 unchanged\n\n>>> fault.py GET /api/2.0/bundle/deployments/* 500 0 1\n\n>>> env DATABRICKS_BUNDLE_DEPLOYMENT_HISTORY=false [CLI] bundle plan\nError: deployment history setting (false) does not match the existing state (true)\n\nUpdate experimental.deployment_history to match the existing deployment, or run \"databricks bundle destroy\" to start over\n\n\nExit code: 1\n"
        	            	
        	            	Diff:
        	            	--- Expected
        	            	+++ Actual
        	            	@@ -10,14 +10,8 @@
        	            	 >>> env DATABRICKS_BUNDLE_DEPLOYMENT_HISTORY=false [CLI] bundle plan
        	            	-update jobs.foo
        	            	+Error: deployment history setting (false) does not match the existing state (true)
        	            	 
        	            	-Plan: 0 to add, 1 to change, 0 to delete, 0 unchanged
        	            	+Update experimental.deployment_history to match the existing deployment, or run "databricks bundle destroy" to start over
        	            	 
        	            	->>> env DATABRICKS_BUNDLE_DEPLOYMENT_HISTORY=false [CLI] bundle deploy
        	            	-Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/dms-mismatch-before-read-[UNIQUE_NAME]/default/files...
        	            	-Updated jobs.foo
        	            	-Files: 1 uploaded, 0 deleted
        	            	-Resources: 0 created, 1 changed, 0 deleted, 0 unchanged
        	            	 
        	            	->>> jq .features // {} .databricks/bundle/default/resources.json
        	            	-{}
        	            	+Exit code: 1
        	            	 
        	Test:       	TestAccept/bundle/dms/mismatch-before-read/DMS=true
        	Messages:   	bundle/dms/mismatch-before-read/output.txt vs /tmp/TestAcceptbundledmsmismatch-before-readDMS=true1843914717/002/output.txt

latest (v1.22.1): same output as main (c6bb214)

TestAccept/bundle/dms/multiple-resources/DMS=true: branch ✅ | main (c6bb214) ❌ | latest (v1.22.1) ❌

main (c6bb214):

acceptance_test.go:1311: Diff:
        --- bundle/dms/multiple-resources/output.txt
        +++ /tmp/TestAcceptbundledmsmultiple-resourcesDMS=true1001452942/002/output.txt
        @@ -25,7 +25,7 @@
           "lineage": "[UUID]",
           "serial": 1,
           "features": {
        -    "deployment_history_best_effort": {}
        +    "deployment_history": {}
           }
         }
         
        @@ -70,100 +70,9 @@
          "lineage": "[UUID]",
          "serial": 1,
          "features": {
        -  "deployment_history_best_effort": {}
        +  "deployment_history": {}
          },
        - "state": {
        -  "resources.jobs.five": {
        -   "__id__": "[FIVE_ID]",
        -   "state": {
        -    "deployment": {
        -     "deployment_id": "[DEPLOYMENT_ID]",
        -     "kind": "BUNDLE",
        -     "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-multiple-resources-[UNIQUE_NAME]/default/state/metadata.json",
        -     "version_id": "1"
        -    },
        -    "edit_mode": "UI_LOCKED",
        -    "format": "MULTI_TASK",
        -    "max_concurrent_runs": 1,
        -    "name": "five",
        -    "queue": {
        -     "enabled": true
        -    }
        -   }
        -  },
        -  "resources.jobs.four": {
        -   "__id__": "[FOUR_ID]",
        -   "state": {
        -    "deployment": {
        -     "deployment_id": "[DEPLOYMENT_ID]",
        -     "kind": "BUNDLE",
        -     "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-multiple-resources-[UNIQUE_NAME]/default/state/metadata.json",
        -     "version_id": "1"
        -    },
        -    "edit_mode": "UI_LOCKED",
        -    "format": "MULTI_TASK",
        -    "max_concurrent_runs": 1,
        -    "name": "four",
        -    "queue": {
        -     "enabled": true
        -    }
        -   }
        -  },
        -  "resources.jobs.one": {
        -   "__id__": "[ONE_ID]",
        -   "state": {
        -    "deployment": {
        -     "deployment_id": "[DEPLOYMENT_ID]",
        -     "kind": "BUNDLE",
        -     "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-multiple-resources-[UNIQUE_NAME]/default/state/metadata.json",
        -     "version_id": "1"
        -    },
        -    "edit_mode": "UI_LOCKED",
        -    "format": "MULTI_TASK",
        -    "max_concurrent_runs": 1,
        -    "name": "one",
        -    "queue": {
        -     "enabled": true
        -    }
        -   }
        -  },
        -  "resources.jobs.three": {
        -   "__id__": "[THREE_ID]",
        -   "state": {
        -    "deployment": {
        -     "deployment_id": "[DEPLOYMENT_ID]",
        -     "kind": "BUNDLE",
        -     "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-multiple-resources-[UNIQUE_NAME]/default/state/metadata.json",
        -     "version_id": "1"
        -    },
        -    "edit_mode": "UI_LOCKED",
        -    "format": "MULTI_TASK",
        -    "max_concurrent_runs": 1,
        -    "name": "three",
        -    "queue": {
        -     "enabled": true
        -    }
        -   }
        -  },
        -  "resources.jobs.two": {
        -   "__id__": "[TWO_ID]",
        -   "state": {
        -    "deployment": {
        -     "deployment_id": "[DEPLOYMENT_ID]",
        -     "kind": "BUNDLE",
        -     "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-multiple-resources-[UNIQUE_NAME]/default/state/metadata.json",
        -     "version_id": "1"
        -    },
        -    "edit_mode": "UI_LOCKED",
        -    "format": "MULTI_TASK",
        -    "max_concurrent_runs": 1,
        -    "name": "two",
        -    "queue": {
        -     "enabled": true
        -    }
        -   }
        -  }
        - }
        + "state": {}
         }
         
         === Redeploy with no changes: nothing is applied, so no version is created at all - the deployment's version tracks state changes, like serial
        @@ -180,9 +88,9 @@
           "plan_version": [PLAN_VERSION],
           "cli_version": "[CLI_VERSION]",
           "lineage": "[UUID]",
        -  "serial": 2,
        +  "serial": 1,
           "features": {
        -    "deployment_history_best_effort": {}
        +    "deployment_history": {}
           }
         }
         
        @@ -225,100 +132,9 @@
          "state_version": 3,
          "cli_version": "[CLI_VERSION]",
          "lineage": "[UUID]",
        - "serial": 2,
        + "serial": 1,
          "features": {
        -  "deployment_history_best_effort": {}
        +  "deployment_history": {}
          },
        - "state": {
        -  "resources.jobs.five": {
        -   "__id__": "[FIVE_ID]",
        -   "state": {
        -    "deployment": {
        -     "deployment_id": "[DEPLOYMENT_ID]",
        -     "kind": "BUNDLE",
        -     "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-multiple-resources-[UNIQUE_NAME]/default/state/metadata.json",
        -     "version_id": "1"
        -    },
        -    "edit_mode": "UI_LOCKED",
        -    "format": "MULTI_TASK",
        -    "max_concurrent_runs": 1,
        -    "name": "five",
        -    "queue": {
        -     "enabled": true
        -    }
        -   }
        -  },
        -  "resources.jobs.four": {
        -   "__id__": "[FOUR_ID]",
        -   "state": {
        -    "deployment": {
        -     "deployment_id": "[DEPLOYMENT_ID]",
        -     "kind": "BUNDLE",
        -     "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-multiple-resources-[UNIQUE_NAME]/default/state/metadata.json",
        -     "version_id": "1"
        -    },
        -    "edit_mode": "UI_LOCKED",
        -    "format": "MULTI_TASK",
        -    "max_concurrent_runs": 1,
        -    "name": "four",
        -    "queue": {
        -     "enabled": true
        -    }
        -   }
        -  },
        -  "resources.jobs.one": {
        -   "__id__": "[ONE_ID]",
        -   "state": {
        -    "deployment": {
        -     "deployment_id": "[DEPLOYMENT_ID]",
        -     "kind": "BUNDLE",
        -     "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-multiple-resources-[UNIQUE_NAME]/default/state/metadata.json",
        -     "version_id": "1"
        -    },
        -    "edit_mode": "UI_LOCKED",
        -    "format": "MULTI_TASK",
        -    "max_concurrent_runs": 1,
        -    "name": "one",
        -    "queue": {
        -     "enabled": true
        -    }
        -   }
        -  },
        -  "resources.jobs.three": {
        -   "__id__": "[THREE_ID]",
        -   "state": {
        -    "deployment": {
        -     "deployment_id": "[DEPLOYMENT_ID]",
        -     "kind": "BUNDLE",
        -     "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-multiple-resources-[UNIQUE_NAME]/default/state/metadata.json",
        -     "version_id": "1"
... (33 more lines truncated, raise DATABRICKS_CLI_TEST_MAX_LOG to see more)

latest (v1.22.1):

acceptance_test.go:1311: Diff:
        --- bundle/dms/multiple-resources/output.txt
        +++ /tmp/TestAcceptbundledmsmultiple-resourcesDMS=true218626429/002/output.txt
        @@ -25,7 +25,7 @@
           "lineage": "[UUID]",
           "serial": 1,
           "features": {
        -    "deployment_history_best_effort": {}
        +    "deployment_history": {}
           }
         }
         
        @@ -70,100 +70,9 @@
          "lineage": "[UUID]",
          "serial": 1,
          "features": {
        -  "deployment_history_best_effort": {}
        +  "deployment_history": {}
          },
        - "state": {
        -  "resources.jobs.five": {
        -   "__id__": "[FIVE_ID]",
        -   "state": {
        -    "deployment": {
        -     "deployment_id": "[DEPLOYMENT_ID]",
        -     "kind": "BUNDLE",
        -     "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-multiple-resources-[UNIQUE_NAME]/default/state/metadata.json",
        -     "version_id": "1"
        -    },
        -    "edit_mode": "UI_LOCKED",
        -    "format": "MULTI_TASK",
        -    "max_concurrent_runs": 1,
        -    "name": "five",
        -    "queue": {
        -     "enabled": true
        -    }
        -   }
        -  },
        -  "resources.jobs.four": {
        -   "__id__": "[FOUR_ID]",
        -   "state": {
        -    "deployment": {
        -     "deployment_id": "[DEPLOYMENT_ID]",
        -     "kind": "BUNDLE",
        -     "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-multiple-resources-[UNIQUE_NAME]/default/state/metadata.json",
        -     "version_id": "1"
        -    },
        -    "edit_mode": "UI_LOCKED",
        -    "format": "MULTI_TASK",
        -    "max_concurrent_runs": 1,
        -    "name": "four",
        -    "queue": {
        -     "enabled": true
        -    }
        -   }
        -  },
        -  "resources.jobs.one": {
        -   "__id__": "[ONE_ID]",
        -   "state": {
        -    "deployment": {
        -     "deployment_id": "[DEPLOYMENT_ID]",
        -     "kind": "BUNDLE",
        -     "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-multiple-resources-[UNIQUE_NAME]/default/state/metadata.json",
        -     "version_id": "1"
        -    },
        -    "edit_mode": "UI_LOCKED",
        -    "format": "MULTI_TASK",
        -    "max_concurrent_runs": 1,
        -    "name": "one",
        -    "queue": {
        -     "enabled": true
        -    }
        -   }
        -  },
        -  "resources.jobs.three": {
        -   "__id__": "[THREE_ID]",
        -   "state": {
        -    "deployment": {
        -     "deployment_id": "[DEPLOYMENT_ID]",
        -     "kind": "BUNDLE",
        -     "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-multiple-resources-[UNIQUE_NAME]/default/state/metadata.json",
        -     "version_id": "1"
        -    },
        -    "edit_mode": "UI_LOCKED",
        -    "format": "MULTI_TASK",
        -    "max_concurrent_runs": 1,
        -    "name": "three",
        -    "queue": {
        -     "enabled": true
        -    }
        -   }
        -  },
        -  "resources.jobs.two": {
        -   "__id__": "[TWO_ID]",
        -   "state": {
        -    "deployment": {
        -     "deployment_id": "[DEPLOYMENT_ID]",
        -     "kind": "BUNDLE",
        -     "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-multiple-resources-[UNIQUE_NAME]/default/state/metadata.json",
        -     "version_id": "1"
        -    },
        -    "edit_mode": "UI_LOCKED",
        -    "format": "MULTI_TASK",
        -    "max_concurrent_runs": 1,
        -    "name": "two",
        -    "queue": {
        -     "enabled": true
        -    }
        -   }
        -  }
        - }
        + "state": {}
         }
         
         === Redeploy with no changes: nothing is applied, so no version is created at all - the deployment's version tracks state changes, like serial
        @@ -180,9 +88,9 @@
           "plan_version": [PLAN_VERSION],
           "cli_version": "[CLI_VERSION]",
           "lineage": "[UUID]",
        -  "serial": 2,
        +  "serial": 1,
           "features": {
        -    "deployment_history_best_effort": {}
        +    "deployment_history": {}
           }
         }
         
        @@ -225,100 +132,9 @@
          "state_version": 3,
          "cli_version": "[CLI_VERSION]",
          "lineage": "[UUID]",
        - "serial": 2,
        + "serial": 1,
          "features": {
        -  "deployment_history_best_effort": {}
        +  "deployment_history": {}
          },
        - "state": {
        -  "resources.jobs.five": {
        -   "__id__": "[FIVE_ID]",
        -   "state": {
        -    "deployment": {
        -     "deployment_id": "[DEPLOYMENT_ID]",
        -     "kind": "BUNDLE",
        -     "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-multiple-resources-[UNIQUE_NAME]/default/state/metadata.json",
        -     "version_id": "1"
        -    },
        -    "edit_mode": "UI_LOCKED",
        -    "format": "MULTI_TASK",
        -    "max_concurrent_runs": 1,
        -    "name": "five",
        -    "queue": {
        -     "enabled": true
        -    }
        -   }
        -  },
        -  "resources.jobs.four": {
        -   "__id__": "[FOUR_ID]",
        -   "state": {
        -    "deployment": {
        -     "deployment_id": "[DEPLOYMENT_ID]",
        -     "kind": "BUNDLE",
        -     "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-multiple-resources-[UNIQUE_NAME]/default/state/metadata.json",
        -     "version_id": "1"
        -    },
        -    "edit_mode": "UI_LOCKED",
        -    "format": "MULTI_TASK",
        -    "max_concurrent_runs": 1,
        -    "name": "four",
        -    "queue": {
        -     "enabled": true
        -    }
        -   }
        -  },
        -  "resources.jobs.one": {
        -   "__id__": "[ONE_ID]",
        -   "state": {
        -    "deployment": {
        -     "deployment_id": "[DEPLOYMENT_ID]",
        -     "kind": "BUNDLE",
        -     "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-multiple-resources-[UNIQUE_NAME]/default/state/metadata.json",
        -     "version_id": "1"
        -    },
        -    "edit_mode": "UI_LOCKED",
        -    "format": "MULTI_TASK",
        -    "max_concurrent_runs": 1,
        -    "name": "one",
        -    "queue": {
        -     "enabled": true
        -    }
        -   }
        -  },
        -  "resources.jobs.three": {
        -   "__id__": "[THREE_ID]",
        -   "state": {
        -    "deployment": {
        -     "deployment_id": "[DEPLOYMENT_ID]",
        -     "kind": "BUNDLE",
        -     "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-multiple-resources-[UNIQUE_NAME]/default/state/metadata.json",
        -     "version_id": "1"
... (31 more lines truncated, raise DATABRICKS_CLI_TEST_MAX_LOG to see more)
TestAccept/bundle/dms/no-drift/DMS=true: branch ✅ | main (c6bb214) ❌ | latest (v1.22.1) ❌

main (c6bb214):

acceptance_test.go:1311: Diff:
        --- bundle/dms/no-drift/output.txt
        +++ /tmp/TestAcceptbundledmsno-driftDMS=true2673245955/002/output.txt
        @@ -35,7 +35,7 @@
           "lineage": "[UUID]",
           "serial": 1,
           "features": {
        -    "deployment_history_best_effort": {}
        +    "deployment_history": {}
           }
         }
         
        @@ -50,52 +50,9 @@
          "lineage": "[UUID]",
          "serial": 1,
          "features": {
        -  "deployment_history_best_effort": {}
        +  "deployment_history": {}
          },
        - "state": {
        -  "resources.jobs.foo": {
        -   "__id__": "[FOO_ID]",
        -   "state": {
        -    "deployment": {
        -     "deployment_id": "[DEPLOYMENT_ID]",
        -     "kind": "BUNDLE",
        -     "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-no-drift-[UNIQUE_NAME]/default/state/metadata.json",
        -     "version_id": "1"
        -    },
        -    "edit_mode": "UI_LOCKED",
        -    "format": "MULTI_TASK",
        -    "max_concurrent_runs": 1,
        -    "name": "foo",
        -    "queue": {
        -     "enabled": true
        -    }
        -   }
        -  },
        -  "resources.pipelines.bar": {
        -   "__id__": "[BAR_ID]",
        -   "state": {
        -    "catalog": "main",
        -    "channel": "CURRENT",
        -    "deployment": {
        -     "deployment_id": "[DEPLOYMENT_ID]",
        -     "kind": "BUNDLE",
        -     "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-no-drift-[UNIQUE_NAME]/default/state/metadata.json",
        -     "version_id": "1"
        -    },
        -    "edition": "ADVANCED",
        -    "libraries": [
        -     {
        -      "file": {
        -       "path": "/Workspace/Users/[USERNAME]/.bundle/dms-no-drift-[UNIQUE_NAME]/default/files/transform.py"
        -      }
        -     }
        -    ],
        -    "name": "bar-[UNIQUE_NAME]",
        -    "schema": "default",
        -    "serverless": true
        -   }
        -  }
        - }
        + "state": {}
         }
         
         === Plan without touching anything: the deployment stamp must not show as drift
        @@ -224,7 +180,7 @@
           "lineage": "[UUID]",
           "serial": 2,
           "features": {
        -    "deployment_history_best_effort": {}
        +    "deployment_history": {}
           }
         }
         
        @@ -243,53 +199,9 @@
          "lineage": "[UUID]",
          "serial": 2,
          "features": {
        -  "deployment_history_best_effort": {}
        +  "deployment_history": {}
          },
        - "state": {
        -  "resources.jobs.foo": {
        -   "__id__": "[FOO_ID]",
        -   "state": {
        -    "deployment": {
        -     "deployment_id": "[DEPLOYMENT_ID]",
        -     "kind": "BUNDLE",
        -     "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-no-drift-[UNIQUE_NAME]/default/state/metadata.json",
        -     "version_id": "1"
        -    },
        -    "edit_mode": "UI_LOCKED",
        -    "format": "MULTI_TASK",
        -    "max_concurrent_runs": 1,
        -    "name": "foo",
        -    "queue": {
        -     "enabled": true
        -    }
        -   }
        -  },
        -  "resources.pipelines.bar": {
        -   "__id__": "[BAR_ID]",
        -   "state": {
        -    "catalog": "main",
        -    "channel": "CURRENT",
        -    "deployment": {
        -     "deployment_id": "[DEPLOYMENT_ID]",
        -     "kind": "BUNDLE",
        -     "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-no-drift-[UNIQUE_NAME]/default/state/metadata.json",
        -     "version_id": "2"
        -    },
        -    "development": true,
        -    "edition": "ADVANCED",
        -    "libraries": [
        -     {
        -      "file": {
        -       "path": "/Workspace/Users/[USERNAME]/.bundle/dms-no-drift-[UNIQUE_NAME]/default/files/transform.py"
        -      }
        -     }
        -    ],
        -    "name": "bar-[UNIQUE_NAME]",
        -    "schema": "default",
        -    "serverless": true
        -   }
        -  }
        - }
        + "state": {}
         }
         
         === Plan again: no residual drift, and the version stamps are ignored

latest (v1.22.1): same output as main (c6bb214)

TestAccept/bundle/dms/no-resources/DMS=true: branch ✅ | main (c6bb214) ❌ | latest (v1.22.1) ❌

main (c6bb214):

acceptance_test.go:1311: Diff:
        --- bundle/dms/no-resources/output.txt
        +++ /tmp/TestAcceptbundledmsno-resourcesDMS=true3484378012/002/output.txt
        @@ -35,9 +35,8 @@
           "plan_version": [PLAN_VERSION],
           "cli_version": "[CLI_VERSION]",
           "lineage": "[UUID]",
        -  "serial": 1,
           "features": {
        -    "deployment_history_best_effort": {}
        +    "deployment_history": {}
           }
         }
         
        @@ -54,9 +52,8 @@
          "state_version": 3,
          "cli_version": "[CLI_VERSION]",
          "lineage": "[UUID]",
        - "serial": 1,
          "features": {
        -  "deployment_history_best_effort": {}
        +  "deployment_history": {}
          },
          "state": {}
         }
        @@ -74,6 +70,10 @@
         }
         {
           "method": "GET",
        +  "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/resources"
        +}
        +{
        +  "method": "GET",
           "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]"
         }
         {
        @@ -82,8 +82,16 @@
         }
         {
           "method": "GET",
        +  "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/resources"
        +}
        +{
        +  "method": "GET",
           "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]"
         }
        +{
        +  "method": "GET",
        +  "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/resources"
        +}
         
         === The plan records the deployment_history feature
         >>> [CLI] bundle plan -o json
        @@ -91,9 +97,8 @@
           "plan_version": [PLAN_VERSION],
           "cli_version": "[CLI_VERSION]",
           "lineage": "[UUID]",
        -  "serial": 2,
           "features": {
        -    "deployment_history_best_effort": {}
        +    "deployment_history": {}
           }
         }
         
        @@ -110,9 +114,8 @@
          "state_version": 3,
          "cli_version": "[CLI_VERSION]",
          "lineage": "[UUID]",
        - "serial": 2,
          "features": {
        -  "deployment_history_best_effort": {}
        +  "deployment_history": {}
          },
          "state": {}
         }

latest (v1.22.1): same output as main (c6bb214)

5 more failure details omitted, see the full report in the run.

@eng-dev-ecosystem-bot

eng-dev-ecosystem-bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: 83de547

Run: 40341236532

Env 🔄​flaky ✅​pass 🙈​skip Time
🔄​ aws linux-2core-8gb 1 307 25 15:49
✅​ aws-windows-latest-4core-16gb 310 23 12:32
✅​ azure linux-2core-8gb 307 25 13:59
✅​ azure-windows-latest-4core-16gb 309 23 9:37
🔄​ gcp linux-2core-8gb 3 305 25 19:00
✅​ gcp-windows-latest-4core-16gb 310 23 12:42
Test Name aws linux-2core-8gb gcp linux-2core-8gb
🔄​ TestAccept ✅​p 🔄​f
🔄​ TestAccept/bundle/dms/multiple-resources ✅​p 🔄​f
🔄​ TestAccept/bundle/dms/multiple-resources/DMS=true ✅​p 🔄​f
🔄​ TestSyncNestedSpacePlusAndHashAreEscapedSync 🔄​f ✅​p
Top 33 slowest tests (at least 2 minutes):
duration env testname
6:23 gcp-windows-latest-4core-16gb TestAccept
5:42 aws-windows-latest-4core-16gb TestAccept
3:52 aws linux-2core-8gb TestAccept
3:48 aws-windows-latest-4core-16gb TestFilerWorkspaceFilesExtensionsStat
3:25 gcp-windows-latest-4core-16gb TestAccept/bundle/dms/stale-plan/DMS=true/READPLAN=1
3:21 aws-windows-latest-4core-16gb TestAccept/bundle/dms/stale-local-state/DMS=
3:16 azure-windows-latest-4core-16gb TestAccept/bundle/dms/existing-state/DMS=
3:09 aws-windows-latest-4core-16gb TestAccept/bundle/dms/stale-plan/DMS=true/READPLAN=1
3:09 aws-windows-latest-4core-16gb TestAccept/bundle/dms/state-features/DMS=true
2:59 azure-windows-latest-4core-16gb TestAccept
2:58 azure linux-2core-8gb TestAccept
2:55 gcp linux-2core-8gb TestFilerWorkspaceFilesExtensionsDelete
2:38 azure linux-2core-8gb TestWorkspaceFilesExtensions_ExportFormatIsPreserved/jupyter_r
2:37 aws-windows-latest-4core-16gb TestImportDirWithOverwriteFlag
2:29 aws-windows-latest-4core-16gb TestFilerRecursiveDelete/workspace_files_extensions
2:28 gcp-windows-latest-4core-16gb TestAccept/bundle/dms/no-drift/DMS=true
2:25 aws linux-2core-8gb TestAccept/bundle/dms/existing-state/DMS=
2:25 gcp-windows-latest-4core-16gb TestImportDirWithOverwriteFlag
2:23 gcp linux-2core-8gb TestAccept/bundle/dms/stale-plan/DMS=true/READPLAN=
2:21 azure-windows-latest-4core-16gb TestFilerWorkspaceFilesExtensionsReadDir
2:21 gcp linux-2core-8gb TestImportDirDoesNotOverwrite
2:18 azure linux-2core-8gb TestAccept/bundle/dms/deployment-metadata-change/DMS=true
2:16 gcp linux-2core-8gb TestAccept/bundle/dms/stale-local-state/DMS=
2:15 gcp-windows-latest-4core-16gb TestWorkspaceFilesExtensions_ExportFormatIsPreserved/source_sql
2:12 azure-windows-latest-4core-16gb TestFilerRecursiveDelete/workspace_files_extensions
2:08 gcp linux-2core-8gb TestAccept/bundle/dms/stale-plan/DMS=true/READPLAN=1
2:07 aws linux-2core-8gb TestFilerWorkspaceFilesExtensionsRead
2:07 gcp-windows-latest-4core-16gb TestSetupLocalServerlessProvision
2:05 aws-windows-latest-4core-16gb TestAccept/bundle/dms/existing-state/DMS=
2:03 gcp linux-2core-8gb TestAccept/bundle/dms/existing-state/DMS=
2:02 azure-windows-latest-4core-16gb TestAccept/bundle/dms/deployment-metadata-change/DMS=true
2:02 aws linux-2core-8gb TestFilerWorkspaceFilesExtensionsReadDir
2:01 aws linux-2core-8gb TestImportDir

@shreyas-goenka shreyas-goenka changed the title Use enforced best-effort history for the YAML opt-in Use enforced best-effort deployment history for all opt-ins Oct 26, 2026
@shreyas-goenka
shreyas-goenka force-pushed the shreyas-goenka_data/shreyas/history-best-effort-default branch from 4017609 to 0b70621 Compare October 26, 2026 05:25
@shreyas-goenka shreyas-goenka changed the title Use enforced best-effort deployment history for all opt-ins Default deployment history to enforced file-backed recording Oct 26, 2026
@shreyas-goenka
shreyas-goenka force-pushed the shreyas-goenka_data/shreyas/history-best-effort-default branch 8 times, most recently from 0471b06 to 8542de3 Compare October 26, 2026 10:47

title "Deploy job foo and pipeline bar; both are recorded at version 1"
trace $CLI bundle deploy
replace_ids.py

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added because resources.json now contains the actual state, so we need to repl the IDs.

case WritingDMS:
return db.VersionID
case WritingFileWithHistory, WritingFileWithHistoryEnforced:
case ReadingFile, WritingFileWithHistory, WritingFileWithHistoryEnforced:

@shreyas-goenka shreyas-goenka Oct 26, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

planning happens before upgrade to write, so we need to use max here as well. Safe because db.VersionID is 0 by default.

Base automatically changed from shreyas-goenka_data/shreyas/statedb-modes to main October 26, 2026 10:54
@shreyas-goenka
shreyas-goenka force-pushed the shreyas-goenka_data/shreyas/history-best-effort-default branch from 8542de3 to f1e49cf Compare October 26, 2026 10:58
@github-actions github-actions Bot added the DABs DABs related issues label Oct 26, 2026
@shreyas-goenka
shreyas-goenka force-pushed the shreyas-goenka_data/shreyas/history-best-effort-default branch from f1e49cf to ed3ba2e Compare October 26, 2026 11:09
@shreyas-goenka shreyas-goenka changed the title Default deployment history to enforced file-backed recording Support best effort deployment history mode Oct 26, 2026
@shreyas-goenka
shreyas-goenka force-pushed the shreyas-goenka_data/shreyas/history-best-effort-default branch 2 times, most recently from 8692c4f to 8ca44ba Compare October 26, 2026 11:37
}
return enforceDeploymentHistorySetting(ctx, b, stateDesc, false)
stateDesc.Features = b.DeploymentBundle.StateDB.StateFeatures()
if err := enforceDeploymentHistorySetting(ctx, b, stateDesc, false); err != nil {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll remove this in a followup PR. Kept here to keep the diff minimal for this one.

@shreyas-goenka
shreyas-goenka force-pushed the shreyas-goenka_data/shreyas/history-best-effort-default branch from 8ca44ba to 49f895d Compare October 26, 2026 12:34
# The gate that refuses bind while recording deployment history is on the config, so it fires
# before any deploy. Create a real workspace job so bind gets past fetching the resource and
# reaches the gate, instead of failing because the resource does not exist.
title "bind is refused while recording deployment history"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With direct being source of truth, we can do bind now, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes absolutely. I just plan on addressing it in a followup PR to keep the scope narrow here.

bundle:
name: dms-bind-unbind-$UNIQUE_NAME
experimental:
deployment_history: true

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how is deployment_history set in this test? It is set somehow since bind outputs "Error: bind is not supported for a bundle target that records deployment history" but I don't see where. Env var somewhere?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test only runs for EnvMatrix.DMS = ["true"] so this bit was redundant.

"serial": 1,
"features": {
"deployment_history": {}
"deployment_history_best_effort": {}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need the feature anymore with direct being source of truth, right? Sure older clients will not write to DMS but that's defensible for beta. Advantage is that you can drop DMS without any back migration.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussed offline, we'll keep the state, but rename it to deployment_history_shadow in a followup PR.

update_file.py databricks.yml 'deployment_history: true' 'deployment_history: false'

# The configuration mismatch must be rejected before trying to read the deployment from DMS.
# Disabling file-backed history must not depend on DMS being available.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is file-backed history?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just our best effort history feature. We should be abel to disable this without talking to DMS or making any APIs calls.

@shreyas-goenka
shreyas-goenka force-pushed the shreyas-goenka_data/shreyas/history-best-effort-default branch from 49f895d to 91e0249 Compare October 26, 2026 13:01
Comment thread bundle/phases/bind.go
if b.Config.Experimental != nil {
configured = b.Config.Experimental.DeploymentHistory
}
if stateDesc.IsDMS() || bundleenv.RecordsDeploymentHistory(ctx, configured) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we'll remove this check all together in a followup, given DMS is no longer the source of truth.

@shreyas-goenka
shreyas-goenka force-pushed the shreyas-goenka_data/shreyas/history-best-effort-default branch 2 times, most recently from 8f9a4fa to bbd5aa4 Compare October 26, 2026 13:21
"plan": {},
"features": {
"deployment_history": {}
"deployment_history_best_effort": {}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll rename this in a followup.

@shreyas-goenka
shreyas-goenka force-pushed the shreyas-goenka_data/shreyas/history-best-effort-default branch 2 times, most recently from 7d6a9cf to de2849a Compare October 26, 2026 14:20

if stateDesc.Engine.IsDirect() && !opts.SkipEnforcingDeploymentHistorySetting {
if stateDesc.Engine.IsDirect() && !opts.Destroy {
if err := enforceDeploymentHistorySetting(ctx, b, stateDesc, opts.Deploy || opts.PreDeployChecks); err != nil {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this validation will be removed in a followup. Kept to keep the diff short.

@shreyas-goenka
shreyas-goenka force-pushed the shreyas-goenka_data/shreyas/history-best-effort-default branch from de2849a to 83de547 Compare October 26, 2026 14:36
@shreyas-goenka
shreyas-goenka marked this pull request as ready for review October 26, 2026 14:38
@shreyas-goenka
shreyas-goenka requested review from a team as code owners October 26, 2026 14:38

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

DABs DABs related issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants