Skip to content

Skip shadow deployment history when the deployment read fails - #7335

Draft
pietern wants to merge 2 commits into
mainfrom
pietern/f04-7169-dms-read-failure
Draft

pietern wants to merge 2 commits into
mainfrom
pietern/f04-7169-dms-read-failure

Conversation

@pietern

@pietern pietern commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Changes

In deployment-history shadow mode, if reading the existing deployment from DMS fails, the CLI warned and continued with no deployment ID, so deploy and destroy treated the bundle as a first deploy and called CreateDeployment again: history went to a new deployment, jobs were stamped with the new ID, and destroy created and then deleted a fresh record.

Now a read failure of unknown cause (403, 5xx, unparseable last_version_id, failed workspace lookup) skips history for that run, which matches the documented shadow-mode contract that history errors only warn:

  • A 404 from GetDeployment (node present, record missing) still takes the existing "no deployment yet" path, which re-registers it.
  • When the node lookup succeeded, the known deployment ID is still stamped on jobs and pipelines, so bundle plan doesn't show a spurious update.
  • The skip is folded into RecordsHistory(), so telemetry and the deploy/destroy gates see it; a failed delete still fails the apply, as in a normal shadow run.
  • A destroy whose read failed warns that the DMS record is kept.
  • No behavior change when DMS is the primary store.

Open questions: when even the workspace lookup fails, jobs lose their deployment stamp for that run (fall back to resource state, or fail?); a skipped destroy leaves the DMS record orphaned; telemetry reports deployment_history_enabled=false for a skipped run.

Why

Bug in the best-effort (shadow) deployment history mode added in #7169. The mode is experimental and has no changelog entry, so this PR doesn't add one; happy to add one if we think opted-in users should hear about it.

Tests

  • New acceptance tests under acceptance/bundle/dms/read-failure/ (local only, faults injected with fault.py), one per scenario: deploy (403 on plan and deploy, the job's deployment stamp, and the resuming deploy), not-found (a half-created deployment recovers), failed-delete (a failed job delete still fails the deploy), and destroy (the record is kept). Each fails without the fix.
  • New unit test TestSkipHistoryKeepsShadowMarker.
  • go test ./cmd/bundle/utils/... ./bundle/direct/... ./bundle/phases/...; acceptance bundle/(dms|deploy|destroy|templates/deployment-history|migrate/auto/dms-migration|state|telemetry); task fmt-q/lint-q.

This pull request and its description were written by Isaac.

In deployment history shadow mode, a failed read of the recorded
deployment (workspace lookup, GetDeployment, or parsing last_version_id)
only warned and left the deployment ID empty. Deploy and destroy then
took the first-deploy path and called CreateDeployment again, recording
the run against a second deployment for the same bundle.

When the read fails for an unknown reason (403, 5xx, unparseable
last_version_id), skip history for this run through RecordsHistory, so
deploy, destroy and telemetry all see it while the shadow marker and WAL
mode stay unchanged. When the workspace lookup found the deployment, keep
stamping its id on jobs and pipelines so the skipped run does not update
them just to clear it. A node whose record is missing (404) is a
half-created deployment and keeps taking the first-deploy path, which
re-registers it. A destroy that skipped history warns that the record is
kept. A failed delete still fails the apply in a skipped run, as it does
when history is recorded.

DMS-primary state is unchanged: a read failure there already fails the
command.

Co-authored-by: Isaac <no-reply@databricks.com>
@github-actions github-actions Bot added the DABs DABs related issues label Nov 4, 2026
@github-actions

github-actions Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Commit: 5e155785f | Workflow run

Regression test report

Selected 4 changed tests (limit=20, 0 not selected)

4 tests: regression=4 unreleased=0 coverage=0 failing=0
test branch main (7adc80d) latest (v1.24.0)
TestAccept/bundle/dms/read-failure/deploy/DMS=true ✅ ❌ ❌
TestAccept/bundle/dms/read-failure/destroy/DMS=true ✅ ❌ ❌
TestAccept/bundle/dms/read-failure/failed-delete/DMS=true ✅ ❌ ❌
TestAccept/bundle/dms/read-failure/not-found/DMS=true ✅ ❌ ❌
TestAccept/bundle/dms/read-failure/deploy/DMS=true: branch ✅ | main (7adc80d) ❌ | latest (v1.24.0) ❌

main (7adc80d):

acceptance_test.go:1345: Diff:
        --- bundle/dms/read-failure/deploy/output.txt
        +++ /tmp/TestAcceptbundledmsread-failuredeployDMS=true1229253276/002/output.txt
        @@ -3,16 +3,18 @@
         >>> fault.py GET /api/2.0/bundle/deployments/* 403 0 1 PERMISSION_DENIED
         
         >>> [CLI] bundle plan
        -Warn: Could not read deployment history, not recording it for this run: Fault injected by test.
        -Plan: 0 to add, 0 to change, 0 to delete, 1 unchanged
        +Warn: Could not read deployment history: Fault injected by test.
        +update jobs.foo
         
        +Plan: 0 to add, 1 to change, 0 to delete, 0 unchanged
        +
         === Deploy with a failed read: no history is recorded, so no second deployment is created, and the job keeps its deployment id
         >>> update_file.py databricks.yml name: foo name: renamed
         
         >>> fault.py GET /api/2.0/bundle/deployments/* 403 0 1 PERMISSION_DENIED
         
         >>> [CLI] bundle deploy
        -Warn: Could not read deployment history, not recording it for this run: Fault injected by test.
        +Warn: Could not read deployment history: Fault injected by test.
         Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/files...
         Updated jobs.foo
         Files: 2 uploaded, 0 deleted
        @@ -20,10 +15,14 @@
         
         >>> print_requests.py --dms //api/2.0/bundle --get --oneline
         {"method": "GET", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]"}
        +{"method": "POST", "path": "/api/2.0/bundle/deployments", "body": {"display_name": "dms-read-failure-[UNIQUE_NAME]", "initial_parent_path": "/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/state", "target_name": "default", "workspace_info": {"file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/files", "root_path": "/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default"}}}
        +{"method": "POST", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions", "q": {"version_id": "2"}, "body": {"cli_version": "[CLI_VERSION]", "operations": [{"action_type": "OPERATION_ACTION_TYPE_UPDATE", "resource_key": "jobs.foo"}], "version_type": "VERSION_TYPE_DEPLOY"}}
        +{"method": "PATCH", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions/2/operations/jobs.foo", "q": {"update_mask": "state,error_message,resource_id,status"}, "body": {"error_message": "", "resource_id": "[FOO_ID]", "sequence_id": 0, "state": "{\"state\":{\"deployment\":{\"deployment_id\":\"4000000000000058\",\"kind\":\"BUNDLE\",\"metadata_file_path\":\"/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/state/metadata.json\"},\"edit_mode\":\"UI_LOCKED\",\"format\":\"MULTI_TASK\",\"max_concurrent_runs\":1,\"name\":\"renamed\",\"queue\":{\"enabled\":true}}}", "status": "OPERATION_STATUS_SUCCEEDED"}}
        +{"method": "POST", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions/2/complete", "body": {"completion_reason": "VERSION_COMPLETE_SUCCESS"}}
         
         >>> [CLI] jobs get [FOO_ID]
         {
        -  "deployment_id": "[DEPLOYMENT_ID]",
        +  "deployment_id": "4000000000000058",
           "kind": "BUNDLE",
           "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/state/metadata.json"
         }
        @@ -39,13 +35,13 @@
         
         >>> print_requests.py --dms //api/2.0/bundle --get --oneline
         {"method": "GET", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]"}
        -{"method": "POST", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions", "q": {"version_id": "3"}, "body": {"cli_version": "[CLI_VERSION]", "operations": [{"action_type": "OPERATION_ACTION_TYPE_UPDATE", "resource_key": "jobs.foo"}], "previous_version_id": "1", "version_type": "VERSION_TYPE_DEPLOY"}}
        -{"method": "PATCH", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions/3/operations/jobs.foo", "q": {"update_mask": "state,error_message,resource_id,status"}, "body": {"error_message": "", "resource_id": "[FOO_ID]", "sequence_id": 0, "state": "{\"state\":{\"deployment\":{\"deployment_id\":\"[DEPLOYMENT_ID]\",\"kind\":\"BUNDLE\",\"metadata_file_path\":\"/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/state/metadata.json\",\"version_id\":\"3\"},\"edit_mode\":\"UI_LOCKED\",\"format\":\"MULTI_TASK\",\"max_concurrent_runs\":1,\"name\":\"resumed\",\"queue\":{\"enabled\":true}}}", "status": "OPERATION_STATUS_SUCCEEDED"}}
        +{"method": "POST", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions", "q": {"version_id": "3"}, "body": {"cli_version": "[CLI_VERSION]", "operations": [{"action_type": "OPERATION_ACTION_TYPE_UPDATE", "resource_key": "jobs.foo"}], "previous_version_id": "2", "version_type": "VERSION_TYPE_DEPLOY"}}
        +{"method": "PATCH", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions/3/operations/jobs.foo", "q": {"update_mask": "state,error_message,resource_id,status"}, "body": {"error_message": "", "resource_id": "[FOO_ID]", "sequence_id": 0, "state": "{\"state\":{\"deployment\":{\"deployment_id\":\"4000000000000058\",\"kind\":\"BUNDLE\",\"metadata_file_path\":\"/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/state/metadata.json\",\"version_id\":\"3\"},\"edit_mode\":\"UI_LOCKED\",\"format\":\"MULTI_TASK\",\"max_concurrent_runs\":1,\"name\":\"resumed\",\"queue\":{\"enabled\":true}}}", "status": "OPERATION_STATUS_SUCCEEDED"}}
         {"method": "POST", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions/3/complete", "body": {"completion_reason": "VERSION_COMPLETE_SUCCESS"}}
         
         >>> [CLI] jobs get [FOO_ID]
         {
        -  "deployment_id": "[DEPLOYMENT_ID]",
        +  "deployment_id": "4000000000000058",
           "kind": "BUNDLE",
           "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/state/metadata.json",
           "version_id": "3"
        
    acceptance_test.go:1123: 
        LOG.setup: Uploading bundle files to /Workspace/Users/tester@databricks.com/.bundle/dms-read-failure-fdye2u45hfbapes6l2oc5u4oru/default/files...
        LOG.setup: Current Deployment Version: http://127.0.0.1:40995/deployments/4000000000000039?version=1
        LOG.setup: Created jobs.foo
        LOG.setup: Files: 3 uploaded, 0 deleted
        LOG.setup: Resources: 1 created, 0 changed, 0 deleted, 0 unchanged

latest (v1.24.0):

acceptance_test.go:1345: Diff:
        --- bundle/dms/read-failure/deploy/output.txt
        +++ /tmp/TestAcceptbundledmsread-failuredeployDMS=true2811324651/002/output.txt
        @@ -3,16 +3,18 @@
         >>> fault.py GET /api/2.0/bundle/deployments/* 403 0 1 PERMISSION_DENIED
         
         >>> [CLI] bundle plan
        -Warn: Could not read deployment history, not recording it for this run: Fault injected by test.
        -Plan: 0 to add, 0 to change, 0 to delete, 1 unchanged
        +Warn: Could not read deployment history: Fault injected by test.
        +update jobs.foo
         
        +Plan: 0 to add, 1 to change, 0 to delete, 0 unchanged
        +
         === Deploy with a failed read: no history is recorded, so no second deployment is created, and the job keeps its deployment id
         >>> update_file.py databricks.yml name: foo name: renamed
         
         >>> fault.py GET /api/2.0/bundle/deployments/* 403 0 1 PERMISSION_DENIED
         
         >>> [CLI] bundle deploy
        -Warn: Could not read deployment history, not recording it for this run: Fault injected by test.
        +Warn: Could not read deployment history: Fault injected by test.
         Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/files...
         Updated jobs.foo
         Files: 2 uploaded, 0 deleted
        @@ -20,10 +15,14 @@
         
         >>> print_requests.py --dms //api/2.0/bundle --get --oneline
         {"method": "GET", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]"}
        +{"method": "POST", "path": "/api/2.0/bundle/deployments", "body": {"display_name": "dms-read-failure-[UNIQUE_NAME]", "initial_parent_path": "/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/state", "target_name": "default", "workspace_info": {"file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/files", "root_path": "/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default"}}}
        +{"method": "POST", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions", "q": {"version_id": "2"}, "body": {"cli_version": "[CLI_VERSION]", "operations": [{"action_type": "OPERATION_ACTION_TYPE_UPDATE", "resource_key": "jobs.foo"}], "version_type": "VERSION_TYPE_DEPLOY"}}
        +{"method": "PATCH", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions/2/operations/jobs.foo", "q": {"update_mask": "state,error_message,resource_id,status"}, "body": {"error_message": "", "resource_id": "[FOO_ID]", "sequence_id": 0, "state": "{\"state\":{\"deployment\":{\"deployment_id\":\"4000000000000057\",\"kind\":\"BUNDLE\",\"metadata_file_path\":\"/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/state/metadata.json\"},\"edit_mode\":\"UI_LOCKED\",\"format\":\"MULTI_TASK\",\"max_concurrent_runs\":1,\"name\":\"renamed\",\"queue\":{\"enabled\":true}}}", "status": "OPERATION_STATUS_SUCCEEDED"}}
        +{"method": "POST", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions/2/complete", "body": {"completion_reason": "VERSION_COMPLETE_SUCCESS"}}
         
         >>> [CLI] jobs get [FOO_ID]
         {
        -  "deployment_id": "[DEPLOYMENT_ID]",
        +  "deployment_id": "4000000000000057",
           "kind": "BUNDLE",
           "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/state/metadata.json"
         }
        @@ -39,13 +35,13 @@
         
         >>> print_requests.py --dms //api/2.0/bundle --get --oneline
         {"method": "GET", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]"}
        -{"method": "POST", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions", "q": {"version_id": "3"}, "body": {"cli_version": "[CLI_VERSION]", "operations": [{"action_type": "OPERATION_ACTION_TYPE_UPDATE", "resource_key": "jobs.foo"}], "previous_version_id": "1", "version_type": "VERSION_TYPE_DEPLOY"}}
        -{"method": "PATCH", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions/3/operations/jobs.foo", "q": {"update_mask": "state,error_message,resource_id,status"}, "body": {"error_message": "", "resource_id": "[FOO_ID]", "sequence_id": 0, "state": "{\"state\":{\"deployment\":{\"deployment_id\":\"[DEPLOYMENT_ID]\",\"kind\":\"BUNDLE\",\"metadata_file_path\":\"/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/state/metadata.json\",\"version_id\":\"3\"},\"edit_mode\":\"UI_LOCKED\",\"format\":\"MULTI_TASK\",\"max_concurrent_runs\":1,\"name\":\"resumed\",\"queue\":{\"enabled\":true}}}", "status": "OPERATION_STATUS_SUCCEEDED"}}
        +{"method": "POST", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions", "q": {"version_id": "3"}, "body": {"cli_version": "[CLI_VERSION]", "operations": [{"action_type": "OPERATION_ACTION_TYPE_UPDATE", "resource_key": "jobs.foo"}], "previous_version_id": "2", "version_type": "VERSION_TYPE_DEPLOY"}}
        +{"method": "PATCH", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions/3/operations/jobs.foo", "q": {"update_mask": "state,error_message,resource_id,status"}, "body": {"error_message": "", "resource_id": "[FOO_ID]", "sequence_id": 0, "state": "{\"state\":{\"deployment\":{\"deployment_id\":\"4000000000000057\",\"kind\":\"BUNDLE\",\"metadata_file_path\":\"/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/state/metadata.json\",\"version_id\":\"3\"},\"edit_mode\":\"UI_LOCKED\",\"format\":\"MULTI_TASK\",\"max_concurrent_runs\":1,\"name\":\"resumed\",\"queue\":{\"enabled\":true}}}", "status": "OPERATION_STATUS_SUCCEEDED"}}
         {"method": "POST", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions/3/complete", "body": {"completion_reason": "VERSION_COMPLETE_SUCCESS"}}
         
         >>> [CLI] jobs get [FOO_ID]
         {
        -  "deployment_id": "[DEPLOYMENT_ID]",
        +  "deployment_id": "4000000000000057",
           "kind": "BUNDLE",
           "metadata_file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/state/metadata.json",
           "version_id": "3"
        
    acceptance_test.go:1123: 
        LOG.setup: Uploading bundle files to /Workspace/Users/tester@databricks.com/.bundle/dms-read-failure-igdpaormxvhbxk5qvjhqditkce/default/files...
        LOG.setup: Current Deployment Version: http://127.0.0.1:40485/deployments/4000000000000042?version=1
        LOG.setup: Created jobs.foo
        LOG.setup: Files: 3 uploaded, 0 deleted
        LOG.setup: Resources: 1 created, 0 changed, 0 deleted, 0 unchanged
TestAccept/bundle/dms/read-failure/destroy/DMS=true: branch ✅ | main (7adc80d) ❌ | latest (v1.24.0) ❌

main (7adc80d):

acceptance_test.go:1345: Diff:
        --- bundle/dms/read-failure/destroy/output.txt
        +++ /tmp/TestAcceptbundledmsread-failuredestroyDMS=true4163372755/002/output.txt
        @@ -3,17 +3,21 @@
         >>> fault.py GET /api/2.0/bundle/deployments/* 403 0 1 PERMISSION_DENIED
         
         >>> [CLI] bundle destroy --auto-approve
        -Warn: Could not read deployment history, not recording it for this run: Fault injected by test.
        +Warn: Could not read deployment history: Fault injected by test.
         The following resources will be deleted:
           delete resources.jobs.foo
         
         All files and directories at the following location will be deleted: /Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default
         
        -Warn: Keeping the deployment history record, if any: it could not be read, so this destroy does not delete it
         Destroy: 1 deleted
         
         >>> print_requests.py --dms //api/2.0/bundle --get --oneline
         {"method": "GET", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]"}
        +{"method": "POST", "path": "/api/2.0/bundle/deployments", "body": {"display_name": "dms-read-failure-[UNIQUE_NAME]", "initial_parent_path": "/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/state", "target_name": "default", "workspace_info": {"file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/files", "root_path": "/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default"}}}
        +{"method": "POST", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions", "q": {"version_id": "2"}, "body": {"cli_version": "[CLI_VERSION]", "operations": [{"action_type": "OPERATION_ACTION_TYPE_DELETE", "resource_key": "jobs.foo"}], "version_type": "VERSION_TYPE_DESTROY"}}
        +{"method": "PATCH", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions/2/operations/jobs.foo", "q": {"update_mask": "state,error_message,status"}, "body": {"error_message": "", "sequence_id": 0, "status": "OPERATION_STATUS_SUCCEEDED"}}
        +{"method": "POST", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions/2/complete", "body": {"completion_reason": "VERSION_COMPLETE_SUCCESS"}}
        +{"method": "DELETE", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]"}
         
         === The deployment record is kept
         >>> MSYS_NO_PATHCONV=1 [CLI] bundle-deployments get-deployment deployments/[DEPLOYMENT_ID] -o json
        
    acceptance_test.go:1123: 
        LOG.setup: Uploading bundle files to /Workspace/Users/tester@databricks.com/.bundle/dms-read-failure-zhneredaqrgbxj3a32d7ycppoi/default/files...
        LOG.setup: Current Deployment Version: http://127.0.0.1:38031/deployments/4000000000000108?version=1
        LOG.setup: Created jobs.foo
        LOG.setup: Files: 3 uploaded, 0 deleted
        LOG.setup: Resources: 1 created, 0 changed, 0 deleted, 0 unchanged

latest (v1.24.0):

acceptance_test.go:1345: Diff:
        --- bundle/dms/read-failure/destroy/output.txt
        +++ /tmp/TestAcceptbundledmsread-failuredestroyDMS=true2297917805/002/output.txt
        @@ -3,17 +3,21 @@
         >>> fault.py GET /api/2.0/bundle/deployments/* 403 0 1 PERMISSION_DENIED
         
         >>> [CLI] bundle destroy --auto-approve
        -Warn: Could not read deployment history, not recording it for this run: Fault injected by test.
        +Warn: Could not read deployment history: Fault injected by test.
         The following resources will be deleted:
           delete resources.jobs.foo
         
         All files and directories at the following location will be deleted: /Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default
         
        -Warn: Keeping the deployment history record, if any: it could not be read, so this destroy does not delete it
         Destroy: 1 deleted
         
         >>> print_requests.py --dms //api/2.0/bundle --get --oneline
         {"method": "GET", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]"}
        +{"method": "POST", "path": "/api/2.0/bundle/deployments", "body": {"display_name": "dms-read-failure-[UNIQUE_NAME]", "initial_parent_path": "/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/state", "target_name": "default", "workspace_info": {"file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/files", "root_path": "/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default"}}}
        +{"method": "POST", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions", "q": {"version_id": "2"}, "body": {"cli_version": "[CLI_VERSION]", "operations": [{"action_type": "OPERATION_ACTION_TYPE_DELETE", "resource_key": "jobs.foo"}], "version_type": "VERSION_TYPE_DESTROY"}}
        +{"method": "PATCH", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions/2/operations/jobs.foo", "q": {"update_mask": "state,error_message,status"}, "body": {"error_message": "", "sequence_id": 0, "status": "OPERATION_STATUS_SUCCEEDED"}}
        +{"method": "POST", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions/2/complete", "body": {"completion_reason": "VERSION_COMPLETE_SUCCESS"}}
        +{"method": "DELETE", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]"}
         
         === The deployment record is kept
         >>> MSYS_NO_PATHCONV=1 [CLI] bundle-deployments get-deployment deployments/[DEPLOYMENT_ID] -o json
        
    acceptance_test.go:1123: 
        LOG.setup: Uploading bundle files to /Workspace/Users/tester@databricks.com/.bundle/dms-read-failure-gi5offd6tbd4fa3zgyo3femore/default/files...
        LOG.setup: Current Deployment Version: http://127.0.0.1:43481/deployments/4000000000000079?version=1
        LOG.setup: Created jobs.foo
        LOG.setup: Files: 3 uploaded, 0 deleted
        LOG.setup: Resources: 1 created, 0 changed, 0 deleted, 0 unchanged
TestAccept/bundle/dms/read-failure/failed-delete/DMS=true: branch ✅ | main (7adc80d) ❌ | latest (v1.24.0) ❌

main (7adc80d):

acceptance_test.go:1345: Diff:
        --- bundle/dms/read-failure/failed-delete/output.txt
        +++ /tmp/TestAcceptbundledmsread-failurefailed-deleteDMS=true1608116887/002/output.txt
        @@ -7,7 +7,7 @@
         >>> fault.py POST /api/2.2/jobs/delete 400 0 1 INVALID_PARAMETER_VALUE
         
         >>> musterr [CLI] bundle deploy
        -Warn: Could not read deployment history, not recording it for this run: Fault injected by test.
        +Warn: Could not read deployment history: Fault injected by test.
         Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/files...
         Error: cannot delete resources.jobs.bar: deleting id=[BAR_ID]: Fault injected by test. (400 INVALID_PARAMETER_VALUE)
         
        @@ -16,10 +16,16 @@
         API error_code: INVALID_PARAMETER_VALUE
         API message: Fault injected by test.
         
        +Updated jobs.foo
         Files: 2 uploaded, 0 deleted
         
         >>> print_requests.py --dms //api/2.0/bundle --get --oneline
         {"method": "GET", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]"}
        +{"method": "POST", "path": "/api/2.0/bundle/deployments", "body": {"display_name": "dms-read-failure-[UNIQUE_NAME]", "initial_parent_path": "/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/state", "target_name": "default", "workspace_info": {"file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/files", "root_path": "/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default"}}}
        +{"method": "POST", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions", "q": {"version_id": "2"}, "body": {"cli_version": "[CLI_VERSION]", "operations": [{"action_type": "OPERATION_ACTION_TYPE_DELETE", "resource_key": "jobs.bar"}, {"action_type": "OPERATION_ACTION_TYPE_UPDATE", "resource_key": "jobs.foo"}], "version_type": "VERSION_TYPE_DEPLOY"}}
        +{"method": "PATCH", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions/2/operations/jobs.bar", "q": {"update_mask": "state,error_message,resource_id,status"}, "body": {"error_message": "deleting id=[BAR_ID]: Fault injected by test. (400 INVALID_PARAMETER_VALUE)", "resource_id": "[BAR_ID]", "sequence_id": 0, "state": "{\"state\":{\"deployment\":{\"deployment_id\":\"[DEPLOYMENT_ID]\",\"kind\":\"BUNDLE\",\"metadata_file_path\":\"/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/state/metadata.json\",\"version_id\":\"1\"},\"edit_mode\":\"UI_LOCKED\",\"format\":\"MULTI_TASK\",\"max_concurrent_runs\":1,\"name\":\"bar\",\"queue\":{\"enabled\":true}}}", "status": "OPERATION_STATUS_FAILED"}}
        +{"method": "PATCH", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions/2/operations/jobs.foo", "q": {"update_mask": "state,error_message,resource_id,status"}, "body": {"error_message": "", "resource_id": "8793870973222073613", "sequence_id": 0, "state": "{\"state\":{\"deployment\":{\"deployment_id\":\"4000000000000116\",\"kind\":\"BUNDLE\",\"metadata_file_path\":\"/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/state/metadata.json\"},\"edit_mode\":\"UI_LOCKED\",\"format\":\"MULTI_TASK\",\"max_concurrent_runs\":1,\"name\":\"foo\",\"queue\":{\"enabled\":true}}}", "status": "OPERATION_STATUS_SUCCEEDED"}}
        +{"method": "POST", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions/2/complete", "body": {"completion_reason": "VERSION_COMPLETE_FAILURE"}}
         
         >>> [CLI] jobs get [BAR_ID]
         "bar"
        
    acceptance_test.go:1123: 
        LOG.setup: Uploading bundle files to /Workspace/Users/tester@databricks.com/.bundle/dms-read-failure-qhof7o5pbnaxna7g6djvh4c3vy/default/files...
        LOG.setup: Current Deployment Version: http://127.0.0.1:43547/deployments/4000000000000080?version=1
        LOG.setup: Created jobs.bar
        LOG.setup: Created jobs.foo
        LOG.setup: Files: 3 uploaded, 0 deleted
        LOG.setup: Resources: 2 created, 0 changed, 0 deleted, 0 unchanged
FAIL

latest (v1.24.0):

acceptance_test.go:1345: Diff:
        --- bundle/dms/read-failure/failed-delete/output.txt
        +++ /tmp/TestAcceptbundledmsread-failurefailed-deleteDMS=true24013727/002/output.txt
        @@ -7,7 +7,7 @@
         >>> fault.py POST /api/2.2/jobs/delete 400 0 1 INVALID_PARAMETER_VALUE
         
         >>> musterr [CLI] bundle deploy
        -Warn: Could not read deployment history, not recording it for this run: Fault injected by test.
        +Warn: Could not read deployment history: Fault injected by test.
         Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/files...
         Error: cannot delete resources.jobs.bar: deleting id=[BAR_ID]: Fault injected by test. (400 INVALID_PARAMETER_VALUE)
         
        @@ -16,10 +16,16 @@
         API error_code: INVALID_PARAMETER_VALUE
         API message: Fault injected by test.
         
        +Updated jobs.foo
         Files: 2 uploaded, 0 deleted
         
         >>> print_requests.py --dms //api/2.0/bundle --get --oneline
         {"method": "GET", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]"}
        +{"method": "POST", "path": "/api/2.0/bundle/deployments", "body": {"display_name": "dms-read-failure-[UNIQUE_NAME]", "initial_parent_path": "/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/state", "target_name": "default", "workspace_info": {"file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/files", "root_path": "/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default"}}}
        +{"method": "POST", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions", "q": {"version_id": "2"}, "body": {"cli_version": "[CLI_VERSION]", "operations": [{"action_type": "OPERATION_ACTION_TYPE_DELETE", "resource_key": "jobs.bar"}, {"action_type": "OPERATION_ACTION_TYPE_UPDATE", "resource_key": "jobs.foo"}], "version_type": "VERSION_TYPE_DEPLOY"}}
        +{"method": "PATCH", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions/2/operations/jobs.bar", "q": {"update_mask": "state,error_message,resource_id,status"}, "body": {"error_message": "deleting id=[BAR_ID]: Fault injected by test. (400 INVALID_PARAMETER_VALUE)", "resource_id": "[BAR_ID]", "sequence_id": 0, "state": "{\"state\":{\"deployment\":{\"deployment_id\":\"[DEPLOYMENT_ID]\",\"kind\":\"BUNDLE\",\"metadata_file_path\":\"/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/state/metadata.json\",\"version_id\":\"1\"},\"edit_mode\":\"UI_LOCKED\",\"format\":\"MULTI_TASK\",\"max_concurrent_runs\":1,\"name\":\"bar\",\"queue\":{\"enabled\":true}}}", "status": "OPERATION_STATUS_FAILED"}}
        +{"method": "PATCH", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions/2/operations/jobs.foo", "q": {"update_mask": "state,error_message,resource_id,status"}, "body": {"error_message": "", "resource_id": "8793870977637415885", "sequence_id": 0, "state": "{\"state\":{\"deployment\":{\"deployment_id\":\"4000000000000050\",\"kind\":\"BUNDLE\",\"metadata_file_path\":\"/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/state/metadata.json\"},\"edit_mode\":\"UI_LOCKED\",\"format\":\"MULTI_TASK\",\"max_concurrent_runs\":1,\"name\":\"foo\",\"queue\":{\"enabled\":true}}}", "status": "OPERATION_STATUS_SUCCEEDED"}}
        +{"method": "POST", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]/versions/2/complete", "body": {"completion_reason": "VERSION_COMPLETE_FAILURE"}}
         
         >>> [CLI] jobs get [BAR_ID]
         "bar"
        
    acceptance_test.go:1123: 
        LOG.setup: Uploading bundle files to /Workspace/Users/tester@databricks.com/.bundle/dms-read-failure-l6npt673kvabbbakyruxbpe6i4/default/files...
        LOG.setup: Current Deployment Version: http://127.0.0.1:37641/deployments/4000000000000020?version=1
        LOG.setup: Created jobs.foo
        LOG.setup: Created jobs.bar
        LOG.setup: Files: 3 uploaded, 0 deleted
        LOG.setup: Resources: 2 created, 0 changed, 0 deleted, 0 unchanged
TestAccept/bundle/dms/read-failure/not-found/DMS=true: branch ✅ | main (7adc80d) ❌ | latest (v1.24.0) ❌

main (7adc80d):

acceptance_test.go:1345: Diff:
        --- bundle/dms/read-failure/not-found/output.txt
        +++ /tmp/TestAcceptbundledmsread-failurenot-foundDMS=true583382008/002/output.txt
        @@ -5,6 +5,7 @@
         >>> fault.py GET /api/2.0/bundle/deployments/* 404 0 1 NOT_FOUND
         
         >>> [CLI] bundle deploy
        +Warn: Could not read deployment history: Fault injected by test.
         Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/files...
         Updated jobs.foo
         Files: 2 uploaded, 0 deleted
        @@ -14,5 +15,5 @@
         {"method": "GET", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]"}
         {"method": "POST", "path": "/api/2.0/bundle/deployments", "body": {"display_name": "dms-read-failure-[UNIQUE_NAME]", "initial_parent_path": "/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/state", "target_name": "default", "workspace_info": {"file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/files", "root_path": "/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default"}}}
         {"method": "POST", "path": "/api/2.0/bundle/deployments/[NEW_DEPLOYMENT_ID]/versions", "q": {"version_id": "2"}, "body": {"cli_version": "[CLI_VERSION]", "operations": [{"action_type": "OPERATION_ACTION_TYPE_UPDATE", "resource_key": "jobs.foo"}], "version_type": "VERSION_TYPE_DEPLOY"}}
        -{"method": "PATCH", "path": "/api/2.0/bundle/deployments/[NEW_DEPLOYMENT_ID]/versions/2/operations/jobs.foo", "q": {"update_mask": "state,error_message,resource_id,status"}, "body": {"error_message": "", "resource_id": "[FOO_ID]", "sequence_id": 0, "state": "{\"state\":{\"deployment\":{\"deployment_id\":\"[NEW_DEPLOYMENT_ID]\",\"kind\":\"BUNDLE\",\"metadata_file_path\":\"/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/state/metadata.json\",\"version_id\":\"2\"},\"edit_mode\":\"UI_LOCKED\",\"format\":\"MULTI_TASK\",\"max_concurrent_runs\":1,\"name\":\"renamed\",\"queue\":{\"enabled\":true}}}", "status": "OPERATION_STATUS_SUCCEEDED"}}
        +{"method": "PATCH", "path": "/api/2.0/bundle/deployments/[NEW_DEPLOYMENT_ID]/versions/2/operations/jobs.foo", "q": {"update_mask": "state,error_message,resource_id,status"}, "body": {"error_message": "", "resource_id": "[FOO_ID]", "sequence_id": 0, "state": "{\"state\":{\"deployment\":{\"deployment_id\":\"[NEW_DEPLOYMENT_ID]\",\"kind\":\"BUNDLE\",\"metadata_file_path\":\"/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/state/metadata.json\"},\"edit_mode\":\"UI_LOCKED\",\"format\":\"MULTI_TASK\",\"max_concurrent_runs\":1,\"name\":\"renamed\",\"queue\":{\"enabled\":true}}}", "status": "OPERATION_STATUS_SUCCEEDED"}}
         {"method": "POST", "path": "/api/2.0/bundle/deployments/[NEW_DEPLOYMENT_ID]/versions/2/complete", "body": {"completion_reason": "VERSION_COMPLETE_SUCCESS"}}
        
    acceptance_test.go:1123: 
        LOG.setup: Uploading bundle files to /Workspace/Users/tester@databricks.com/.bundle/dms-read-failure-kn73gi4rpfbmdk7ly33kdtsjbe/default/files...
        LOG.setup: Current Deployment Version: http://127.0.0.1:33733/deployments/4000000000000040?version=1
        LOG.setup: Created jobs.foo
        LOG.setup: Files: 3 uploaded, 0 deleted
        LOG.setup: Resources: 1 created, 0 changed, 0 deleted, 0 unchanged

latest (v1.24.0):

acceptance_test.go:1345: Diff:
        --- bundle/dms/read-failure/not-found/output.txt
        +++ /tmp/TestAcceptbundledmsread-failurenot-foundDMS=true3222795512/002/output.txt
        @@ -5,6 +5,7 @@
         >>> fault.py GET /api/2.0/bundle/deployments/* 404 0 1 NOT_FOUND
         
         >>> [CLI] bundle deploy
        +Warn: Could not read deployment history: Fault injected by test.
         Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/files...
         Updated jobs.foo
         Files: 2 uploaded, 0 deleted
        @@ -14,5 +15,5 @@
         {"method": "GET", "path": "/api/2.0/bundle/deployments/[DEPLOYMENT_ID]"}
         {"method": "POST", "path": "/api/2.0/bundle/deployments", "body": {"display_name": "dms-read-failure-[UNIQUE_NAME]", "initial_parent_path": "/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/state", "target_name": "default", "workspace_info": {"file_path": "/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/files", "root_path": "/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default"}}}
         {"method": "POST", "path": "/api/2.0/bundle/deployments/[NEW_DEPLOYMENT_ID]/versions", "q": {"version_id": "2"}, "body": {"cli_version": "[CLI_VERSION]", "operations": [{"action_type": "OPERATION_ACTION_TYPE_UPDATE", "resource_key": "jobs.foo"}], "version_type": "VERSION_TYPE_DEPLOY"}}
        -{"method": "PATCH", "path": "/api/2.0/bundle/deployments/[NEW_DEPLOYMENT_ID]/versions/2/operations/jobs.foo", "q": {"update_mask": "state,error_message,resource_id,status"}, "body": {"error_message": "", "resource_id": "[FOO_ID]", "sequence_id": 0, "state": "{\"state\":{\"deployment\":{\"deployment_id\":\"[NEW_DEPLOYMENT_ID]\",\"kind\":\"BUNDLE\",\"metadata_file_path\":\"/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/state/metadata.json\",\"version_id\":\"2\"},\"edit_mode\":\"UI_LOCKED\",\"format\":\"MULTI_TASK\",\"max_concurrent_runs\":1,\"name\":\"renamed\",\"queue\":{\"enabled\":true}}}", "status": "OPERATION_STATUS_SUCCEEDED"}}
        +{"method": "PATCH", "path": "/api/2.0/bundle/deployments/[NEW_DEPLOYMENT_ID]/versions/2/operations/jobs.foo", "q": {"update_mask": "state,error_message,resource_id,status"}, "body": {"error_message": "", "resource_id": "[FOO_ID]", "sequence_id": 0, "state": "{\"state\":{\"deployment\":{\"deployment_id\":\"[NEW_DEPLOYMENT_ID]\",\"kind\":\"BUNDLE\",\"metadata_file_path\":\"/Workspace/Users/[USERNAME]/.bundle/dms-read-failure-[UNIQUE_NAME]/default/state/metadata.json\"},\"edit_mode\":\"UI_LOCKED\",\"format\":\"MULTI_TASK\",\"max_concurrent_runs\":1,\"name\":\"renamed\",\"queue\":{\"enabled\":true}}}", "status": "OPERATION_STATUS_SUCCEEDED"}}
         {"method": "POST", "path": "/api/2.0/bundle/deployments/[NEW_DEPLOYMENT_ID]/versions/2/complete", "body": {"completion_reason": "VERSION_COMPLETE_SUCCESS"}}
        
    acceptance_test.go:1123: 
        LOG.setup: Uploading bundle files to /Workspace/Users/tester@databricks.com/.bundle/dms-read-failure-wkxabcvmrjee7prvntrz3atfne/default/files...
        LOG.setup: Current Deployment Version: http://127.0.0.1:46265/deployments/4000000000000109?version=1
        LOG.setup: Created jobs.foo
        LOG.setup: Files: 3 uploaded, 0 deleted
        LOG.setup: Resources: 1 created, 0 changed, 0 deleted, 0 unchanged
FAIL

@eng-dev-ecosystem-bot

eng-dev-ecosystem-bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: 5e15578

Run: 42002176747

Env 🔄​flaky ✅​pass 🙈​skip Time
✅​ aws linux-2core-8gb 271 19 4:06
✅​ aws-windows-latest-4core-16gb 273 17 3:19
✅​ azure linux-2core-8gb 270 19 4:00
🔄​ azure-windows-latest-4core-16gb 1 271 17 3:37
✅​ gcp linux-2core-8gb 271 19 4:08
✅​ gcp-windows-latest-4core-16gb 273 17 3:21
Test Name azure-windows-latest-4core-16gb
🔄​ TestSyncIncrementalFileOverwritesFolder 🔄​f
Top 3 slowest tests (at least 2 minutes):
duration env testname
3:17 azure-windows-latest-4core-16gb TestAccept
3:14 gcp-windows-latest-4core-16gb TestAccept
3:12 aws-windows-latest-4core-16gb TestAccept

acceptance/bundle/dms/read-failure ran six steps in one script, each
depending on the state the previous one left, so it was hard to tell
which behavior a given output line pinned. Split it into four tests that
each start from their own recorded deployment (setup output goes to
LOG.setup and its requests are drained):

- deploy: plan and deploy with a failed read send only the GET, keep the
  job's deployment_id stamp, and the next deploy resumes on the same
  deployment.
- not-found: a 404 (half-created deployment) re-registers the deployment
  and records history.
- failed-delete: a failed job delete in a run with a failed read still
  fails the deploy and keeps the job in state.
- destroy: a destroy with a failed read records nothing and keeps the
  deployment record.

The shared setup and fault helpers live in read-failure/script.prepare,
and read-failure/test.toml keeps the tests local-only.

Co-authored-by: Isaac <no-reply@databricks.com>

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.

2 participants