From 5bb58d32a0ef83f1f50181bf060c990d0d115552 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Fri, 21 Aug 2026 18:13:57 +0200 Subject: [PATCH 1/5] Reproduce UpdateSchema "Nothing to update" on a comment set outside the bundle A schema without `comment` in the config becomes undeployable once someone sets a description on it in UC: the engine reads the remote comment, plans an update, and every field of the PATCH serializes away under omitempty. UC rejects the empty body with `400 INVALID_PARAMETER_VALUE / UpdateSchema Nothing to update`, which aborts the whole deploy. Add an acceptance test for it and make the fake workspace reject an empty UpdateSchema payload the way UC does, so the local run fails the same way the cloud one does. Co-authored-by: Isaac --- .../comment_out_of_band/databricks.yml.tmpl | 8 ++ .../drift/comment_out_of_band/out.test.toml | 3 + .../drift/comment_out_of_band/output.txt | 78 +++++++++++++++++++ .../schemas/drift/comment_out_of_band/script | 32 ++++++++ .../drift/comment_out_of_band/test.toml | 11 +++ libs/testserver/schemas.go | 33 ++++++++ 6 files changed, 165 insertions(+) create mode 100644 acceptance/bundle/resources/schemas/drift/comment_out_of_band/databricks.yml.tmpl create mode 100644 acceptance/bundle/resources/schemas/drift/comment_out_of_band/out.test.toml create mode 100644 acceptance/bundle/resources/schemas/drift/comment_out_of_band/output.txt create mode 100644 acceptance/bundle/resources/schemas/drift/comment_out_of_band/script create mode 100644 acceptance/bundle/resources/schemas/drift/comment_out_of_band/test.toml diff --git a/acceptance/bundle/resources/schemas/drift/comment_out_of_band/databricks.yml.tmpl b/acceptance/bundle/resources/schemas/drift/comment_out_of_band/databricks.yml.tmpl new file mode 100644 index 00000000000..e3283c6b3bf --- /dev/null +++ b/acceptance/bundle/resources/schemas/drift/comment_out_of_band/databricks.yml.tmpl @@ -0,0 +1,8 @@ +bundle: + name: test-bundle + +resources: + schemas: + schema1: + catalog_name: main + name: test-schema-$UNIQUE_NAME diff --git a/acceptance/bundle/resources/schemas/drift/comment_out_of_band/out.test.toml b/acceptance/bundle/resources/schemas/drift/comment_out_of_band/out.test.toml new file mode 100644 index 00000000000..8c52d40aa2d --- /dev/null +++ b/acceptance/bundle/resources/schemas/drift/comment_out_of_band/out.test.toml @@ -0,0 +1,3 @@ +Cloud = true +RequiresUnityCatalog = true +EnvMatrix.DATABRICKS_BUNDLE_ENGINE = ["direct"] diff --git a/acceptance/bundle/resources/schemas/drift/comment_out_of_band/output.txt b/acceptance/bundle/resources/schemas/drift/comment_out_of_band/output.txt new file mode 100644 index 00000000000..be6797d19ec --- /dev/null +++ b/acceptance/bundle/resources/schemas/drift/comment_out_of_band/output.txt @@ -0,0 +1,78 @@ + +=== Deploy a schema that does not declare a comment +>>> [CLI] bundle deploy +Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files... +Created schemas.schema1 +Files: 0 uploaded, 0 deleted +Resources: 1 created, 0 changed, 0 deleted, 0 unchanged + +=== Set the comment out of band, the way Catalog Explorer does +=== The remote comment is drift, so the plan updates the schema +>>> [CLI] bundle plan --output json +{ + "action": "update", + "remote": "set outside the bundle" +} + +=== Redeploy clears the comment +>>> errcode [CLI] bundle deploy +Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files... +Error: cannot update resources.schemas.schema1: updating id=main.test-schema-[UNIQUE_NAME]: UpdateSchema Nothing to update. (400 INVALID_PARAMETER_VALUE) + +Endpoint: PATCH [DATABRICKS_URL]/api/2.1/unity-catalog/schemas/main.test-schema-[UNIQUE_NAME] +HTTP Status: 400 Bad Request +API error_code: INVALID_PARAMETER_VALUE +API message: UpdateSchema Nothing to update. + +Files: 0 uploaded, 0 deleted + +Exit code: 1 + +=== The comment is gone +>>> [CLI] api get /api/2.1/unity-catalog/schemas/main.test-schema-[UNIQUE_NAME] +"set outside the bundle" + +=== Redeploy is a no-op +>>> errcode [CLI] bundle deploy +Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files... +Error: cannot update resources.schemas.schema1: updating id=main.test-schema-[UNIQUE_NAME]: UpdateSchema Nothing to update. (400 INVALID_PARAMETER_VALUE) + +Endpoint: PATCH [DATABRICKS_URL]/api/2.1/unity-catalog/schemas/main.test-schema-[UNIQUE_NAME] +HTTP Status: 400 Bad Request +API error_code: INVALID_PARAMETER_VALUE +API message: UpdateSchema Nothing to update. + +Files: 0 uploaded, 0 deleted + +Exit code: 1 + +>>> [CLI] bundle destroy --auto-approve +The following resources will be deleted: + delete resources.schemas.schema1 + +This action will result in the deletion of the following UC schemas. Any underlying data may be lost: + delete resources.schemas.schema1 + +All files and directories at the following location will be deleted: /Workspace/Users/[USERNAME]/.bundle/test-bundle/default + +Destroy: 1 deleted + +=== The UpdateSchema payloads the deploys sent +>>> print_requests.py --method PATCH //unity-catalog/schemas +{ + "method": "PATCH", + "path": "/api/2.1/unity-catalog/schemas/main.test-schema-[UNIQUE_NAME]", + "body": { + "comment": "set outside the bundle" + } +} +{ + "method": "PATCH", + "path": "/api/2.1/unity-catalog/schemas/main.test-schema-[UNIQUE_NAME]", + "body": {} +} +{ + "method": "PATCH", + "path": "/api/2.1/unity-catalog/schemas/main.test-schema-[UNIQUE_NAME]", + "body": {} +} diff --git a/acceptance/bundle/resources/schemas/drift/comment_out_of_band/script b/acceptance/bundle/resources/schemas/drift/comment_out_of_band/script new file mode 100644 index 00000000000..dac79d7d8d5 --- /dev/null +++ b/acceptance/bundle/resources/schemas/drift/comment_out_of_band/script @@ -0,0 +1,32 @@ +echo "*" > .gitignore +envsubst < databricks.yml.tmpl > databricks.yml + +SCHEMA="main.test-schema-${UNIQUE_NAME}" + +# print_requests.py consumes out.requests.txt, so it has to run after the last +# request the test makes, which is the destroy below. +cleanup() { + trace $CLI bundle destroy --auto-approve + + title "The UpdateSchema payloads the deploys sent" + trace print_requests.py --method PATCH //unity-catalog/schemas +} +trap cleanup EXIT + +title "Deploy a schema that does not declare a comment" +trace $CLI bundle deploy + +title "Set the comment out of band, the way Catalog Explorer does" +MSYS_NO_PATHCONV=1 $CLI api patch "/api/2.1/unity-catalog/schemas/$SCHEMA" --json '{"comment":"set outside the bundle"}' > /dev/null + +title "The remote comment is drift, so the plan updates the schema" +trace $CLI bundle plan --output json | jq '.plan[].changes.comment' + +title "Redeploy clears the comment" +trace errcode $CLI bundle deploy + +title "The comment is gone" +MSYS_NO_PATHCONV=1 trace $CLI api get "/api/2.1/unity-catalog/schemas/$SCHEMA" | jq '.comment' + +title "Redeploy is a no-op" +trace errcode $CLI bundle deploy diff --git a/acceptance/bundle/resources/schemas/drift/comment_out_of_band/test.toml b/acceptance/bundle/resources/schemas/drift/comment_out_of_band/test.toml new file mode 100644 index 00000000000..4f7503fc8e8 --- /dev/null +++ b/acceptance/bundle/resources/schemas/drift/comment_out_of_band/test.toml @@ -0,0 +1,11 @@ +Cloud = true +RequiresUnityCatalog = true + +# UpdateSchema payload construction is direct-engine-specific. +EnvMatrix.DATABRICKS_BUNDLE_ENGINE = ["direct"] + +Ignore = [ + ".databricks", + ".gitignore", + "databricks.yml", +] diff --git a/libs/testserver/schemas.go b/libs/testserver/schemas.go index 66d23a3011c..f685239a62f 100644 --- a/libs/testserver/schemas.go +++ b/libs/testserver/schemas.go @@ -80,6 +80,28 @@ func (s *FakeWorkspace) SchemasUpdate(req Request, name string) Response { } } + var fields map[string]json.RawMessage + + if err := json.Unmarshal(req.Body, &fields); err != nil { + return Response{ + Body: fmt.Sprintf("internal error: %s", err), + StatusCode: http.StatusInternalServerError, + } + } + + // UC rejects a PATCH that carries no field to update instead of treating it as a + // no-op. Verified against a real workspace: {} and {"comment": null} are rejected, + // while {"comment": ""} and {"custom_max_retention_hours": 0} are accepted. + if !hasFieldToUpdate(fields) { + return Response{ + StatusCode: http.StatusBadRequest, + Body: map[string]string{ + "error_code": "INVALID_PARAMETER_VALUE", + "message": "UpdateSchema Nothing to update.", + }, + } + } + var schemaUpdate catalog.SchemaInfo if err := json.Unmarshal(req.Body, &schemaUpdate); err != nil { @@ -106,3 +128,14 @@ func (s *FakeWorkspace) SchemasUpdate(req Request, name string) Response { Body: existing, } } + +// hasFieldToUpdate reports whether an update payload carries at least one field the +// backend can act on. A key set to null does not count. +func hasFieldToUpdate(fields map[string]json.RawMessage) bool { + for _, value := range fields { + if string(value) != "null" { + return true + } + } + return false +} From a48e6f5f418afe3c8e28254aeb371f9f356ed4dd Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Fri, 21 Aug 2026 18:16:12 +0200 Subject: [PATCH 2/5] Send comment explicitly on UpdateSchema so a cleared comment is not an empty PATCH Every UpdateSchema field is omitempty, so a schema whose config declares no comment produced an empty PATCH body once the comment was set out of band. UC answers that with `400 / UpdateSchema Nothing to update` rather than a no-op, which failed the whole deploy with no way out from the CLI. Force-send comment so the payload always carries a field and clearing a comment set outside the bundle actually happens. Co-authored-by: Isaac --- .../schema-comment-nothing-to-update.md | 1 + .../drift/comment_out_of_band/output.txt | 36 +++++-------------- .../schemas/drift/comment_out_of_band/script | 4 +-- bundle/direct/dresources/schema.go | 6 ++++ libs/testserver/schemas.go | 7 ++++ 5 files changed, 25 insertions(+), 29 deletions(-) create mode 100644 .nextchanges/bundles/schema-comment-nothing-to-update.md diff --git a/.nextchanges/bundles/schema-comment-nothing-to-update.md b/.nextchanges/bundles/schema-comment-nothing-to-update.md new file mode 100644 index 00000000000..01dc55eca9f --- /dev/null +++ b/.nextchanges/bundles/schema-comment-nothing-to-update.md @@ -0,0 +1 @@ +Fixed `bundle deploy` failing with `UpdateSchema Nothing to update` on the direct engine when a schema's comment was set outside the bundle. diff --git a/acceptance/bundle/resources/schemas/drift/comment_out_of_band/output.txt b/acceptance/bundle/resources/schemas/drift/comment_out_of_band/output.txt index be6797d19ec..f82449ce7a2 100644 --- a/acceptance/bundle/resources/schemas/drift/comment_out_of_band/output.txt +++ b/acceptance/bundle/resources/schemas/drift/comment_out_of_band/output.txt @@ -15,36 +15,21 @@ Resources: 1 created, 0 changed, 0 deleted, 0 unchanged } === Redeploy clears the comment ->>> errcode [CLI] bundle deploy +>>> [CLI] bundle deploy Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files... -Error: cannot update resources.schemas.schema1: updating id=main.test-schema-[UNIQUE_NAME]: UpdateSchema Nothing to update. (400 INVALID_PARAMETER_VALUE) - -Endpoint: PATCH [DATABRICKS_URL]/api/2.1/unity-catalog/schemas/main.test-schema-[UNIQUE_NAME] -HTTP Status: 400 Bad Request -API error_code: INVALID_PARAMETER_VALUE -API message: UpdateSchema Nothing to update. - +Updated schemas.schema1 Files: 0 uploaded, 0 deleted - -Exit code: 1 +Resources: 0 created, 1 changed, 0 deleted, 0 unchanged === The comment is gone >>> [CLI] api get /api/2.1/unity-catalog/schemas/main.test-schema-[UNIQUE_NAME] -"set outside the bundle" +"" === Redeploy is a no-op ->>> errcode [CLI] bundle deploy +>>> [CLI] bundle deploy Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files... -Error: cannot update resources.schemas.schema1: updating id=main.test-schema-[UNIQUE_NAME]: UpdateSchema Nothing to update. (400 INVALID_PARAMETER_VALUE) - -Endpoint: PATCH [DATABRICKS_URL]/api/2.1/unity-catalog/schemas/main.test-schema-[UNIQUE_NAME] -HTTP Status: 400 Bad Request -API error_code: INVALID_PARAMETER_VALUE -API message: UpdateSchema Nothing to update. - Files: 0 uploaded, 0 deleted - -Exit code: 1 +Resources: 0 created, 0 changed, 0 deleted, 1 unchanged >>> [CLI] bundle destroy --auto-approve The following resources will be deleted: @@ -69,10 +54,7 @@ Destroy: 1 deleted { "method": "PATCH", "path": "/api/2.1/unity-catalog/schemas/main.test-schema-[UNIQUE_NAME]", - "body": {} -} -{ - "method": "PATCH", - "path": "/api/2.1/unity-catalog/schemas/main.test-schema-[UNIQUE_NAME]", - "body": {} + "body": { + "comment": "" + } } diff --git a/acceptance/bundle/resources/schemas/drift/comment_out_of_band/script b/acceptance/bundle/resources/schemas/drift/comment_out_of_band/script index dac79d7d8d5..b5f23ec918e 100644 --- a/acceptance/bundle/resources/schemas/drift/comment_out_of_band/script +++ b/acceptance/bundle/resources/schemas/drift/comment_out_of_band/script @@ -23,10 +23,10 @@ title "The remote comment is drift, so the plan updates the schema" trace $CLI bundle plan --output json | jq '.plan[].changes.comment' title "Redeploy clears the comment" -trace errcode $CLI bundle deploy +trace $CLI bundle deploy title "The comment is gone" MSYS_NO_PATHCONV=1 trace $CLI api get "/api/2.1/unity-catalog/schemas/$SCHEMA" | jq '.comment' title "Redeploy is a no-op" -trace errcode $CLI bundle deploy +trace $CLI bundle deploy diff --git a/bundle/direct/dresources/schema.go b/bundle/direct/dresources/schema.go index 24c82ceb6a6..86b7f81762c 100644 --- a/bundle/direct/dresources/schema.go +++ b/bundle/direct/dresources/schema.go @@ -59,6 +59,12 @@ func (r *ResourceSchema) DoUpdate(ctx context.Context, id string, config *catalo ForceSendFields: utils.FilterFields[catalog.UpdateSchema](config.ForceSendFields, "EnablePredictiveOptimization", "NewName", "Owner"), } + // UC answers a PATCH that carries no field with "Nothing to update" (400) instead of + // treating it as a no-op, and omitempty drops every field the config leaves unset. + // Always sending comment keeps the payload non-empty and makes clearing a comment + // that was set outside the bundle explicit. + updateRequest.ForceSendFields = append(updateRequest.ForceSendFields, "Comment") + response, err := r.client.Schemas.Update(ctx, updateRequest) if err != nil { return nil, err diff --git a/libs/testserver/schemas.go b/libs/testserver/schemas.go index f685239a62f..f48c3e1596e 100644 --- a/libs/testserver/schemas.go +++ b/libs/testserver/schemas.go @@ -119,6 +119,13 @@ func (s *FakeWorkspace) SchemasUpdate(req Request, name string) Response { } } + // mergo skips zero values, so an explicit empty comment would leave the stored one in + // place. UC clears it, and comment is the only field its UpdateSchema can clear: an + // empty or null properties map is what it rejects as "nothing to update" above. + if _, ok := fields["comment"]; ok { + existing.Comment = schemaUpdate.Comment + } + existing.UpdatedAt = nowMilli() existing.UpdatedBy = s.CurrentUser().UserName From 216c5c3dba1a76384880c07b36c6adbc1f13014c Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Fri, 21 Aug 2026 18:22:26 +0200 Subject: [PATCH 3/5] Reword the testserver comment on clearing a schema comment Co-authored-by: Isaac --- libs/testserver/schemas.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/testserver/schemas.go b/libs/testserver/schemas.go index f48c3e1596e..7de58a8a2bf 100644 --- a/libs/testserver/schemas.go +++ b/libs/testserver/schemas.go @@ -120,8 +120,8 @@ func (s *FakeWorkspace) SchemasUpdate(req Request, name string) Response { } // mergo skips zero values, so an explicit empty comment would leave the stored one in - // place. UC clears it, and comment is the only field its UpdateSchema can clear: an - // empty or null properties map is what it rejects as "nothing to update" above. + // place. UC clears it instead. Comment is the only field UpdateSchema can clear at + // all: clearing properties needs an empty or null map, which the check above rejects. if _, ok := fields["comment"]; ok { existing.Comment = schemaUpdate.Comment } From c7e2bfbe13e5eff7d777e1fa598ecee216db6811 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Sat, 22 Aug 2026 09:06:34 +0200 Subject: [PATCH 4/5] Send comment explicitly on UpdateCatalog and UpdateVolume too Catalogs and volumes fail exactly like schemas did: their update payloads carry only fields the config may leave unset, so clearing a comment that was set out of band produced an empty PATCH and `400 / Nothing to update`. Verified against a real workspace for both. Force-send comment in all four update paths (catalogs and volumes each have a rename variant), moving the shared reason into forceSendComment, and teach the fake workspace to reject an empty payload and honour an explicit empty comment the way UC does. Co-authored-by: Isaac --- .../schema-comment-nothing-to-update.md | 2 +- .../comment_out_of_band/databricks.yml.tmpl | 7 ++ .../drift/comment_out_of_band/out.test.toml | 3 + .../drift/comment_out_of_band/output.txt | 57 ++++++++++++++++ .../catalogs/drift/comment_out_of_band/script | 32 +++++++++ .../drift/comment_out_of_band/test.toml | 11 +++ .../comment_out_of_band/databricks.yml.tmpl | 13 ++++ .../drift/comment_out_of_band/out.test.toml | 3 + .../drift/comment_out_of_band/output.txt | 68 +++++++++++++++++++ .../volumes/drift/comment_out_of_band/script | 32 +++++++++ .../drift/comment_out_of_band/test.toml | 11 +++ bundle/direct/dresources/catalog.go | 4 +- bundle/direct/dresources/schema.go | 8 +-- bundle/direct/dresources/util.go | 11 +++ bundle/direct/dresources/volume.go | 4 +- libs/testserver/catalogs.go | 13 +++- libs/testserver/fake_workspace.go | 32 +++++++++ libs/testserver/schemas.go | 34 +--------- libs/testserver/volumes.go | 12 +++- 19 files changed, 311 insertions(+), 46 deletions(-) create mode 100644 acceptance/bundle/resources/catalogs/drift/comment_out_of_band/databricks.yml.tmpl create mode 100644 acceptance/bundle/resources/catalogs/drift/comment_out_of_band/out.test.toml create mode 100644 acceptance/bundle/resources/catalogs/drift/comment_out_of_band/output.txt create mode 100644 acceptance/bundle/resources/catalogs/drift/comment_out_of_band/script create mode 100644 acceptance/bundle/resources/catalogs/drift/comment_out_of_band/test.toml create mode 100644 acceptance/bundle/resources/volumes/drift/comment_out_of_band/databricks.yml.tmpl create mode 100644 acceptance/bundle/resources/volumes/drift/comment_out_of_band/out.test.toml create mode 100644 acceptance/bundle/resources/volumes/drift/comment_out_of_band/output.txt create mode 100644 acceptance/bundle/resources/volumes/drift/comment_out_of_band/script create mode 100644 acceptance/bundle/resources/volumes/drift/comment_out_of_band/test.toml diff --git a/.nextchanges/bundles/schema-comment-nothing-to-update.md b/.nextchanges/bundles/schema-comment-nothing-to-update.md index 01dc55eca9f..d7e77b70434 100644 --- a/.nextchanges/bundles/schema-comment-nothing-to-update.md +++ b/.nextchanges/bundles/schema-comment-nothing-to-update.md @@ -1 +1 @@ -Fixed `bundle deploy` failing with `UpdateSchema Nothing to update` on the direct engine when a schema's comment was set outside the bundle. +Fixed `bundle deploy` failing with `Nothing to update` on the direct engine when a schema's, catalog's or volume's comment was set outside the bundle. diff --git a/acceptance/bundle/resources/catalogs/drift/comment_out_of_band/databricks.yml.tmpl b/acceptance/bundle/resources/catalogs/drift/comment_out_of_band/databricks.yml.tmpl new file mode 100644 index 00000000000..4c684900b5b --- /dev/null +++ b/acceptance/bundle/resources/catalogs/drift/comment_out_of_band/databricks.yml.tmpl @@ -0,0 +1,7 @@ +bundle: + name: test-bundle + +resources: + catalogs: + catalog1: + name: test-catalog-$UNIQUE_NAME diff --git a/acceptance/bundle/resources/catalogs/drift/comment_out_of_band/out.test.toml b/acceptance/bundle/resources/catalogs/drift/comment_out_of_band/out.test.toml new file mode 100644 index 00000000000..8c52d40aa2d --- /dev/null +++ b/acceptance/bundle/resources/catalogs/drift/comment_out_of_band/out.test.toml @@ -0,0 +1,3 @@ +Cloud = true +RequiresUnityCatalog = true +EnvMatrix.DATABRICKS_BUNDLE_ENGINE = ["direct"] diff --git a/acceptance/bundle/resources/catalogs/drift/comment_out_of_band/output.txt b/acceptance/bundle/resources/catalogs/drift/comment_out_of_band/output.txt new file mode 100644 index 00000000000..833502b60af --- /dev/null +++ b/acceptance/bundle/resources/catalogs/drift/comment_out_of_band/output.txt @@ -0,0 +1,57 @@ + +=== Deploy a catalog that does not declare a comment +>>> [CLI] bundle deploy +Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files... +Created catalogs.catalog1 +Files: 0 uploaded, 0 deleted +Resources: 1 created, 0 changed, 0 deleted, 0 unchanged + +=== Set the comment out of band, the way Catalog Explorer does +=== The remote comment is drift, so the plan updates the catalog +>>> [CLI] bundle plan --output json +{ + "action": "update", + "remote": "set outside the bundle" +} + +=== Redeploy clears the comment +>>> [CLI] bundle deploy +Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files... +Updated catalogs.catalog1 +Files: 0 uploaded, 0 deleted +Resources: 0 created, 1 changed, 0 deleted, 0 unchanged + +=== The comment is gone +>>> [CLI] api get /api/2.1/unity-catalog/catalogs/test-catalog-[UNIQUE_NAME] +"" + +=== Redeploy is a no-op +>>> [CLI] bundle deploy +Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files... +Files: 0 uploaded, 0 deleted +Resources: 0 created, 0 changed, 0 deleted, 1 unchanged + +>>> [CLI] bundle destroy --auto-approve +The following resources will be deleted: + delete resources.catalogs.catalog1 + +All files and directories at the following location will be deleted: /Workspace/Users/[USERNAME]/.bundle/test-bundle/default + +Destroy: 1 deleted + +=== The UpdateCatalog payloads the deploys sent +>>> print_requests.py --method PATCH //unity-catalog/catalogs +{ + "method": "PATCH", + "path": "/api/2.1/unity-catalog/catalogs/test-catalog-[UNIQUE_NAME]", + "body": { + "comment": "set outside the bundle" + } +} +{ + "method": "PATCH", + "path": "/api/2.1/unity-catalog/catalogs/test-catalog-[UNIQUE_NAME]", + "body": { + "comment": "" + } +} diff --git a/acceptance/bundle/resources/catalogs/drift/comment_out_of_band/script b/acceptance/bundle/resources/catalogs/drift/comment_out_of_band/script new file mode 100644 index 00000000000..6f1a938177d --- /dev/null +++ b/acceptance/bundle/resources/catalogs/drift/comment_out_of_band/script @@ -0,0 +1,32 @@ +echo "*" > .gitignore +envsubst < databricks.yml.tmpl > databricks.yml + +CATALOG="test-catalog-${UNIQUE_NAME}" + +# print_requests.py consumes out.requests.txt, so it has to run after the last +# request the test makes, which is the destroy below. +cleanup() { + trace $CLI bundle destroy --auto-approve + + title "The UpdateCatalog payloads the deploys sent" + trace print_requests.py --method PATCH //unity-catalog/catalogs +} +trap cleanup EXIT + +title "Deploy a catalog that does not declare a comment" +trace $CLI bundle deploy + +title "Set the comment out of band, the way Catalog Explorer does" +MSYS_NO_PATHCONV=1 $CLI api patch "/api/2.1/unity-catalog/catalogs/$CATALOG" --json '{"comment":"set outside the bundle"}' > /dev/null + +title "The remote comment is drift, so the plan updates the catalog" +trace $CLI bundle plan --output json | jq '.plan[].changes.comment' + +title "Redeploy clears the comment" +trace $CLI bundle deploy + +title "The comment is gone" +MSYS_NO_PATHCONV=1 trace $CLI api get "/api/2.1/unity-catalog/catalogs/$CATALOG" | jq '.comment' + +title "Redeploy is a no-op" +trace $CLI bundle deploy diff --git a/acceptance/bundle/resources/catalogs/drift/comment_out_of_band/test.toml b/acceptance/bundle/resources/catalogs/drift/comment_out_of_band/test.toml new file mode 100644 index 00000000000..ae0b1a870d3 --- /dev/null +++ b/acceptance/bundle/resources/catalogs/drift/comment_out_of_band/test.toml @@ -0,0 +1,11 @@ +Cloud = true +RequiresUnityCatalog = true + +# UpdateCatalog payload construction is direct-engine-specific. +EnvMatrix.DATABRICKS_BUNDLE_ENGINE = ["direct"] + +Ignore = [ + ".databricks", + ".gitignore", + "databricks.yml", +] diff --git a/acceptance/bundle/resources/volumes/drift/comment_out_of_band/databricks.yml.tmpl b/acceptance/bundle/resources/volumes/drift/comment_out_of_band/databricks.yml.tmpl new file mode 100644 index 00000000000..dd5d0340df0 --- /dev/null +++ b/acceptance/bundle/resources/volumes/drift/comment_out_of_band/databricks.yml.tmpl @@ -0,0 +1,13 @@ +bundle: + name: test-bundle + +resources: + schemas: + schema1: + catalog_name: main + name: test-schema-$UNIQUE_NAME + volumes: + volume1: + catalog_name: main + schema_name: ${resources.schemas.schema1.name} + name: test-volume-$UNIQUE_NAME diff --git a/acceptance/bundle/resources/volumes/drift/comment_out_of_band/out.test.toml b/acceptance/bundle/resources/volumes/drift/comment_out_of_band/out.test.toml new file mode 100644 index 00000000000..8c52d40aa2d --- /dev/null +++ b/acceptance/bundle/resources/volumes/drift/comment_out_of_band/out.test.toml @@ -0,0 +1,3 @@ +Cloud = true +RequiresUnityCatalog = true +EnvMatrix.DATABRICKS_BUNDLE_ENGINE = ["direct"] diff --git a/acceptance/bundle/resources/volumes/drift/comment_out_of_band/output.txt b/acceptance/bundle/resources/volumes/drift/comment_out_of_band/output.txt new file mode 100644 index 00000000000..6479c07eec7 --- /dev/null +++ b/acceptance/bundle/resources/volumes/drift/comment_out_of_band/output.txt @@ -0,0 +1,68 @@ + +=== Deploy a volume that does not declare a comment +>>> [CLI] bundle deploy +Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files... +Created schemas.schema1 +Created volumes.volume1 +Files: 0 uploaded, 0 deleted +Resources: 2 created, 0 changed, 0 deleted, 0 unchanged + +=== Set the comment out of band, the way Catalog Explorer does +=== The remote comment is drift, so the plan updates the volume +>>> [CLI] bundle plan --output json +{ + "action": "update", + "remote": "set outside the bundle" +} + +=== Redeploy clears the comment +>>> [CLI] bundle deploy +Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files... +Updated volumes.volume1 +Files: 0 uploaded, 0 deleted +Resources: 0 created, 1 changed, 0 deleted, 1 unchanged + +=== The comment is gone +>>> [CLI] api get /api/2.1/unity-catalog/volumes/main.test-schema-[UNIQUE_NAME].test-volume-[UNIQUE_NAME] +"" + +=== Redeploy is a no-op +>>> [CLI] bundle deploy +Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files... +Files: 0 uploaded, 0 deleted +Resources: 0 created, 0 changed, 0 deleted, 2 unchanged + +>>> [CLI] bundle destroy --auto-approve +The following resources will be deleted: + delete resources.schemas.schema1 + delete resources.volumes.volume1 + +This action will result in the deletion of the following UC schemas. Any underlying data may be lost: + delete resources.schemas.schema1 + +This action will result in the deletion of the following volumes. +For managed volumes, the files stored in the volume are also deleted from your +cloud tenant within 30 days. For external volumes, the metadata about the volume +is removed from the catalog, but the underlying files are not deleted: + delete resources.volumes.volume1 + +All files and directories at the following location will be deleted: /Workspace/Users/[USERNAME]/.bundle/test-bundle/default + +Destroy: 2 deleted + +=== The UpdateVolume payloads the deploys sent +>>> print_requests.py --method PATCH //unity-catalog/volumes +{ + "method": "PATCH", + "path": "/api/2.1/unity-catalog/volumes/main.test-schema-[UNIQUE_NAME].test-volume-[UNIQUE_NAME]", + "body": { + "comment": "set outside the bundle" + } +} +{ + "method": "PATCH", + "path": "/api/2.1/unity-catalog/volumes/main.test-schema-[UNIQUE_NAME].test-volume-[UNIQUE_NAME]", + "body": { + "comment": "" + } +} diff --git a/acceptance/bundle/resources/volumes/drift/comment_out_of_band/script b/acceptance/bundle/resources/volumes/drift/comment_out_of_band/script new file mode 100644 index 00000000000..c176403ba00 --- /dev/null +++ b/acceptance/bundle/resources/volumes/drift/comment_out_of_band/script @@ -0,0 +1,32 @@ +echo "*" > .gitignore +envsubst < databricks.yml.tmpl > databricks.yml + +VOLUME="main.test-schema-${UNIQUE_NAME}.test-volume-${UNIQUE_NAME}" + +# print_requests.py consumes out.requests.txt, so it has to run after the last +# request the test makes, which is the destroy below. +cleanup() { + trace $CLI bundle destroy --auto-approve + + title "The UpdateVolume payloads the deploys sent" + trace print_requests.py --method PATCH //unity-catalog/volumes +} +trap cleanup EXIT + +title "Deploy a volume that does not declare a comment" +trace $CLI bundle deploy + +title "Set the comment out of band, the way Catalog Explorer does" +MSYS_NO_PATHCONV=1 $CLI api patch "/api/2.1/unity-catalog/volumes/$VOLUME" --json '{"comment":"set outside the bundle"}' > /dev/null + +title "The remote comment is drift, so the plan updates the volume" +trace $CLI bundle plan --output json | jq '.plan["resources.volumes.volume1"].changes.comment' + +title "Redeploy clears the comment" +trace $CLI bundle deploy + +title "The comment is gone" +MSYS_NO_PATHCONV=1 trace $CLI api get "/api/2.1/unity-catalog/volumes/$VOLUME" | jq '.comment' + +title "Redeploy is a no-op" +trace $CLI bundle deploy diff --git a/acceptance/bundle/resources/volumes/drift/comment_out_of_band/test.toml b/acceptance/bundle/resources/volumes/drift/comment_out_of_band/test.toml new file mode 100644 index 00000000000..bec056028b6 --- /dev/null +++ b/acceptance/bundle/resources/volumes/drift/comment_out_of_band/test.toml @@ -0,0 +1,11 @@ +Cloud = true +RequiresUnityCatalog = true + +# UpdateVolume payload construction is direct-engine-specific. +EnvMatrix.DATABRICKS_BUNDLE_ENGINE = ["direct"] + +Ignore = [ + ".databricks", + ".gitignore", + "databricks.yml", +] diff --git a/bundle/direct/dresources/catalog.go b/bundle/direct/dresources/catalog.go index 604100e92dd..54afbb1fd31 100644 --- a/bundle/direct/dresources/catalog.go +++ b/bundle/direct/dresources/catalog.go @@ -62,7 +62,7 @@ func (r *ResourceCatalog) DoUpdate(ctx context.Context, id string, config *catal Options: config.Options, Owner: "", // Not supported by DABs Properties: config.Properties, - ForceSendFields: utils.FilterFields[catalog.UpdateCatalog](config.ForceSendFields, "EnablePredictiveOptimization", "IsolationMode", "Owner"), + ForceSendFields: forceSendComment(utils.FilterFields[catalog.UpdateCatalog](config.ForceSendFields, "EnablePredictiveOptimization", "IsolationMode", "Owner")), } response, err := r.client.Catalogs.Update(ctx, updateRequest) @@ -86,7 +86,7 @@ func (r *ResourceCatalog) DoUpdateWithID(ctx context.Context, id string, config Options: config.Options, Owner: "", // Not supported by DABs Properties: config.Properties, - ForceSendFields: utils.FilterFields[catalog.UpdateCatalog](config.ForceSendFields, "EnablePredictiveOptimization", "IsolationMode", "Owner"), + ForceSendFields: forceSendComment(utils.FilterFields[catalog.UpdateCatalog](config.ForceSendFields, "EnablePredictiveOptimization", "IsolationMode", "Owner")), } if config.Name != id { diff --git a/bundle/direct/dresources/schema.go b/bundle/direct/dresources/schema.go index 86b7f81762c..ea406e2684e 100644 --- a/bundle/direct/dresources/schema.go +++ b/bundle/direct/dresources/schema.go @@ -56,15 +56,9 @@ func (r *ResourceSchema) DoUpdate(ctx context.Context, id string, config *catalo NewName: "", // We recreate schemas on name change intentionally. Owner: "", // Not supported by DABs Properties: config.Properties, - ForceSendFields: utils.FilterFields[catalog.UpdateSchema](config.ForceSendFields, "EnablePredictiveOptimization", "NewName", "Owner"), + ForceSendFields: forceSendComment(utils.FilterFields[catalog.UpdateSchema](config.ForceSendFields, "EnablePredictiveOptimization", "NewName", "Owner")), } - // UC answers a PATCH that carries no field with "Nothing to update" (400) instead of - // treating it as a no-op, and omitempty drops every field the config leaves unset. - // Always sending comment keeps the payload non-empty and makes clearing a comment - // that was set outside the bundle explicit. - updateRequest.ForceSendFields = append(updateRequest.ForceSendFields, "Comment") - response, err := r.client.Schemas.Update(ctx, updateRequest) if err != nil { return nil, err diff --git a/bundle/direct/dresources/util.go b/bundle/direct/dresources/util.go index fc68f3ea37c..51db2a5dcdf 100644 --- a/bundle/direct/dresources/util.go +++ b/bundle/direct/dresources/util.go @@ -65,3 +65,14 @@ func collectLeafUpdatePathsWithPrefix(changes Changes, prefix string) []string { slices.Sort(paths) return paths } + +// forceSendComment adds Comment to a ForceSendFields list, so a comment the config no +// longer sets serializes as "" instead of being dropped by omitempty. +// +// The UC update APIs answer a PATCH that carries no field with "Nothing to update" (400) +// rather than treating it as a no-op. A resource whose only updatable field is its comment +// would otherwise become undeployable the moment someone sets a description on it outside +// the bundle. Sending the empty value also makes clearing such a comment actually happen. +func forceSendComment(forceSendFields []string) []string { + return append(forceSendFields, "Comment") +} diff --git a/bundle/direct/dresources/volume.go b/bundle/direct/dresources/volume.go index 6c96e66eccb..ae56bb4f21e 100644 --- a/bundle/direct/dresources/volume.go +++ b/bundle/direct/dresources/volume.go @@ -55,7 +55,7 @@ func (r *ResourceVolume) DoUpdate(ctx context.Context, id string, config *catalo NewName: "", // Not supported by Update(). Needs DoUpdateWithID() Owner: "", // Not supported by DABs - ForceSendFields: utils.FilterFields[catalog.UpdateVolumeRequestContent](config.ForceSendFields, "NewName", "Owner"), + ForceSendFields: forceSendComment(utils.FilterFields[catalog.UpdateVolumeRequestContent](config.ForceSendFields, "NewName", "Owner")), } nameFromID, err := getNameFromID(id) @@ -87,7 +87,7 @@ func (r *ResourceVolume) DoUpdateWithID(ctx context.Context, id string, config * NewName: "", // Initialized below if needed Owner: "", // Not supported by DABs - ForceSendFields: utils.FilterFields[catalog.UpdateVolumeRequestContent](config.ForceSendFields, "Owner"), + ForceSendFields: forceSendComment(utils.FilterFields[catalog.UpdateVolumeRequestContent](config.ForceSendFields, "Owner")), } items := strings.Split(id, ".") diff --git a/libs/testserver/catalogs.go b/libs/testserver/catalogs.go index 1d0bc065681..4c1c864b1a4 100644 --- a/libs/testserver/catalogs.go +++ b/libs/testserver/catalogs.go @@ -88,6 +88,11 @@ func (s *FakeWorkspace) CatalogsUpdate(req Request, name string) Response { } } + fields, errResponse := parseUCUpdate(req.Body, "UpdateCatalog") + if errResponse != nil { + return *errResponse + } + var updateRequest catalog.UpdateCatalog if err := json.Unmarshal(req.Body, &updateRequest); err != nil { return Response{ @@ -96,9 +101,13 @@ func (s *FakeWorkspace) CatalogsUpdate(req Request, name string) Response { } } - // Update only the fields that can be updated - if updateRequest.Comment != "" { + // Update only the fields that can be updated. Comment is keyed off presence rather + // than a non-empty value so an explicit empty comment clears it, the way UC does. + if _, ok := fields["comment"]; ok { existing.Comment = updateRequest.Comment + // UC echoes a comment once it has been set, including when it was set to "", + // so keep it in the response rather than letting omitempty drop it. + existing.ForceSendFields = append(existing.ForceSendFields, "Comment") } if updateRequest.CustomMaxRetentionHours != 0 { existing.CustomMaxRetentionHours = updateRequest.CustomMaxRetentionHours diff --git a/libs/testserver/fake_workspace.go b/libs/testserver/fake_workspace.go index 1caec84d1e4..d5af448c312 100644 --- a/libs/testserver/fake_workspace.go +++ b/libs/testserver/fake_workspace.go @@ -5,6 +5,7 @@ import ( "encoding/binary" "encoding/json" "fmt" + "net/http" "os" "path" "path/filepath" @@ -254,6 +255,37 @@ func (s *FakeWorkspace) LockUnlock() func() { return func() { s.mu.Unlock() } } +// parseUCUpdate decodes a Unity Catalog update payload into its raw fields. It returns a +// rejection response when the body carries no field to act on: UC answers such a PATCH with +// " Nothing to update." (400) rather than treating it as a no-op. A key set to +// null does not count. Verified against a real workspace for schemas, volumes and catalogs: +// {} and {"comment": null} are rejected, while {"comment": ""} and +// {"custom_max_retention_hours": 0} are accepted. +func parseUCUpdate(body []byte, operation string) (map[string]json.RawMessage, *Response) { + var fields map[string]json.RawMessage + + if err := json.Unmarshal(body, &fields); err != nil { + return nil, &Response{ + Body: fmt.Sprintf("internal error: %s", err), + StatusCode: http.StatusInternalServerError, + } + } + + for _, value := range fields { + if string(value) != "null" { + return fields, nil + } + } + + return nil, &Response{ + StatusCode: http.StatusBadRequest, + Body: map[string]string{ + "error_code": "INVALID_PARAMETER_VALUE", + "message": operation + " Nothing to update.", + }, + } +} + // Generic functions to handle map operations func MapGet[T any](w *FakeWorkspace, collection map[string]T, key string) Response { defer w.LockUnlock()() diff --git a/libs/testserver/schemas.go b/libs/testserver/schemas.go index 7de58a8a2bf..72fd4564278 100644 --- a/libs/testserver/schemas.go +++ b/libs/testserver/schemas.go @@ -80,26 +80,9 @@ func (s *FakeWorkspace) SchemasUpdate(req Request, name string) Response { } } - var fields map[string]json.RawMessage - - if err := json.Unmarshal(req.Body, &fields); err != nil { - return Response{ - Body: fmt.Sprintf("internal error: %s", err), - StatusCode: http.StatusInternalServerError, - } - } - - // UC rejects a PATCH that carries no field to update instead of treating it as a - // no-op. Verified against a real workspace: {} and {"comment": null} are rejected, - // while {"comment": ""} and {"custom_max_retention_hours": 0} are accepted. - if !hasFieldToUpdate(fields) { - return Response{ - StatusCode: http.StatusBadRequest, - Body: map[string]string{ - "error_code": "INVALID_PARAMETER_VALUE", - "message": "UpdateSchema Nothing to update.", - }, - } + fields, errResponse := parseUCUpdate(req.Body, "UpdateSchema") + if errResponse != nil { + return *errResponse } var schemaUpdate catalog.SchemaInfo @@ -135,14 +118,3 @@ func (s *FakeWorkspace) SchemasUpdate(req Request, name string) Response { Body: existing, } } - -// hasFieldToUpdate reports whether an update payload carries at least one field the -// backend can act on. A key set to null does not count. -func hasFieldToUpdate(fields map[string]json.RawMessage) bool { - for _, value := range fields { - if string(value) != "null" { - return true - } - } - return false -} diff --git a/libs/testserver/volumes.go b/libs/testserver/volumes.go index 88eae7ac021..5a6923b0e89 100644 --- a/libs/testserver/volumes.go +++ b/libs/testserver/volumes.go @@ -76,6 +76,11 @@ func (s *FakeWorkspace) VolumesUpdate(req Request, fullname string) Response { } } + fields, errResponse := parseUCUpdate(req.Body, "UpdateVolume") + if errResponse != nil { + return *errResponse + } + var request catalog.UpdateVolumeRequestContent if err := json.Unmarshal(req.Body, &request); err != nil { @@ -85,8 +90,13 @@ func (s *FakeWorkspace) VolumesUpdate(req Request, fullname string) Response { } } - if request.Comment != "" { + // Keyed off presence rather than a non-empty value so an explicit empty comment + // clears the stored one, the way UC does. + if _, ok := fields["comment"]; ok { existing.Comment = request.Comment + // UC echoes a comment once it has been set, including when it was set to "", + // so keep it in the response rather than letting omitempty drop it. + existing.ForceSendFields = append(existing.ForceSendFields, "Comment") } if request.Owner != "" { From a2dddae21cef95981d0e5848eaccf23f3270950e Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Sat, 22 Aug 2026 11:42:46 +0200 Subject: [PATCH 5/5] Make the comment drift fixtures use a unique bundle name The bundle name is the workspace state path, and cloud tests share one real workspace, so the hardcoded "test-bundle" made these three fight over the same deploy.lock as every other test using that name. They passed run alone and failed under parallelism: the integration run reported success while retrying them on nearly every environment. Co-authored-by: Isaac --- .../drift/comment_out_of_band/databricks.yml.tmpl | 2 +- .../catalogs/drift/comment_out_of_band/output.txt | 8 ++++---- .../schemas/drift/comment_out_of_band/databricks.yml.tmpl | 2 +- .../schemas/drift/comment_out_of_band/output.txt | 8 ++++---- .../volumes/drift/comment_out_of_band/databricks.yml.tmpl | 2 +- .../volumes/drift/comment_out_of_band/output.txt | 8 ++++---- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/acceptance/bundle/resources/catalogs/drift/comment_out_of_band/databricks.yml.tmpl b/acceptance/bundle/resources/catalogs/drift/comment_out_of_band/databricks.yml.tmpl index 4c684900b5b..b7fa6d6d952 100644 --- a/acceptance/bundle/resources/catalogs/drift/comment_out_of_band/databricks.yml.tmpl +++ b/acceptance/bundle/resources/catalogs/drift/comment_out_of_band/databricks.yml.tmpl @@ -1,5 +1,5 @@ bundle: - name: test-bundle + name: test-bundle-$UNIQUE_NAME resources: catalogs: diff --git a/acceptance/bundle/resources/catalogs/drift/comment_out_of_band/output.txt b/acceptance/bundle/resources/catalogs/drift/comment_out_of_band/output.txt index 833502b60af..6ff82f588e6 100644 --- a/acceptance/bundle/resources/catalogs/drift/comment_out_of_band/output.txt +++ b/acceptance/bundle/resources/catalogs/drift/comment_out_of_band/output.txt @@ -1,7 +1,7 @@ === Deploy a catalog that does not declare a comment >>> [CLI] bundle deploy -Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files... +Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle-[UNIQUE_NAME]/default/files... Created catalogs.catalog1 Files: 0 uploaded, 0 deleted Resources: 1 created, 0 changed, 0 deleted, 0 unchanged @@ -16,7 +16,7 @@ Resources: 1 created, 0 changed, 0 deleted, 0 unchanged === Redeploy clears the comment >>> [CLI] bundle deploy -Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files... +Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle-[UNIQUE_NAME]/default/files... Updated catalogs.catalog1 Files: 0 uploaded, 0 deleted Resources: 0 created, 1 changed, 0 deleted, 0 unchanged @@ -27,7 +27,7 @@ Resources: 0 created, 1 changed, 0 deleted, 0 unchanged === Redeploy is a no-op >>> [CLI] bundle deploy -Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files... +Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle-[UNIQUE_NAME]/default/files... Files: 0 uploaded, 0 deleted Resources: 0 created, 0 changed, 0 deleted, 1 unchanged @@ -35,7 +35,7 @@ Resources: 0 created, 0 changed, 0 deleted, 1 unchanged The following resources will be deleted: delete resources.catalogs.catalog1 -All files and directories at the following location will be deleted: /Workspace/Users/[USERNAME]/.bundle/test-bundle/default +All files and directories at the following location will be deleted: /Workspace/Users/[USERNAME]/.bundle/test-bundle-[UNIQUE_NAME]/default Destroy: 1 deleted diff --git a/acceptance/bundle/resources/schemas/drift/comment_out_of_band/databricks.yml.tmpl b/acceptance/bundle/resources/schemas/drift/comment_out_of_band/databricks.yml.tmpl index e3283c6b3bf..50720b62560 100644 --- a/acceptance/bundle/resources/schemas/drift/comment_out_of_band/databricks.yml.tmpl +++ b/acceptance/bundle/resources/schemas/drift/comment_out_of_band/databricks.yml.tmpl @@ -1,5 +1,5 @@ bundle: - name: test-bundle + name: test-bundle-$UNIQUE_NAME resources: schemas: diff --git a/acceptance/bundle/resources/schemas/drift/comment_out_of_band/output.txt b/acceptance/bundle/resources/schemas/drift/comment_out_of_band/output.txt index f82449ce7a2..d45016243ea 100644 --- a/acceptance/bundle/resources/schemas/drift/comment_out_of_band/output.txt +++ b/acceptance/bundle/resources/schemas/drift/comment_out_of_band/output.txt @@ -1,7 +1,7 @@ === Deploy a schema that does not declare a comment >>> [CLI] bundle deploy -Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files... +Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle-[UNIQUE_NAME]/default/files... Created schemas.schema1 Files: 0 uploaded, 0 deleted Resources: 1 created, 0 changed, 0 deleted, 0 unchanged @@ -16,7 +16,7 @@ Resources: 1 created, 0 changed, 0 deleted, 0 unchanged === Redeploy clears the comment >>> [CLI] bundle deploy -Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files... +Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle-[UNIQUE_NAME]/default/files... Updated schemas.schema1 Files: 0 uploaded, 0 deleted Resources: 0 created, 1 changed, 0 deleted, 0 unchanged @@ -27,7 +27,7 @@ Resources: 0 created, 1 changed, 0 deleted, 0 unchanged === Redeploy is a no-op >>> [CLI] bundle deploy -Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files... +Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle-[UNIQUE_NAME]/default/files... Files: 0 uploaded, 0 deleted Resources: 0 created, 0 changed, 0 deleted, 1 unchanged @@ -38,7 +38,7 @@ The following resources will be deleted: This action will result in the deletion of the following UC schemas. Any underlying data may be lost: delete resources.schemas.schema1 -All files and directories at the following location will be deleted: /Workspace/Users/[USERNAME]/.bundle/test-bundle/default +All files and directories at the following location will be deleted: /Workspace/Users/[USERNAME]/.bundle/test-bundle-[UNIQUE_NAME]/default Destroy: 1 deleted diff --git a/acceptance/bundle/resources/volumes/drift/comment_out_of_band/databricks.yml.tmpl b/acceptance/bundle/resources/volumes/drift/comment_out_of_band/databricks.yml.tmpl index dd5d0340df0..084b752f4a8 100644 --- a/acceptance/bundle/resources/volumes/drift/comment_out_of_band/databricks.yml.tmpl +++ b/acceptance/bundle/resources/volumes/drift/comment_out_of_band/databricks.yml.tmpl @@ -1,5 +1,5 @@ bundle: - name: test-bundle + name: test-bundle-$UNIQUE_NAME resources: schemas: diff --git a/acceptance/bundle/resources/volumes/drift/comment_out_of_band/output.txt b/acceptance/bundle/resources/volumes/drift/comment_out_of_band/output.txt index 6479c07eec7..c1e1f119fa1 100644 --- a/acceptance/bundle/resources/volumes/drift/comment_out_of_band/output.txt +++ b/acceptance/bundle/resources/volumes/drift/comment_out_of_band/output.txt @@ -1,7 +1,7 @@ === Deploy a volume that does not declare a comment >>> [CLI] bundle deploy -Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files... +Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle-[UNIQUE_NAME]/default/files... Created schemas.schema1 Created volumes.volume1 Files: 0 uploaded, 0 deleted @@ -17,7 +17,7 @@ Resources: 2 created, 0 changed, 0 deleted, 0 unchanged === Redeploy clears the comment >>> [CLI] bundle deploy -Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files... +Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle-[UNIQUE_NAME]/default/files... Updated volumes.volume1 Files: 0 uploaded, 0 deleted Resources: 0 created, 1 changed, 0 deleted, 1 unchanged @@ -28,7 +28,7 @@ Resources: 0 created, 1 changed, 0 deleted, 1 unchanged === Redeploy is a no-op >>> [CLI] bundle deploy -Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files... +Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle-[UNIQUE_NAME]/default/files... Files: 0 uploaded, 0 deleted Resources: 0 created, 0 changed, 0 deleted, 2 unchanged @@ -46,7 +46,7 @@ cloud tenant within 30 days. For external volumes, the metadata about the volume is removed from the catalog, but the underlying files are not deleted: delete resources.volumes.volume1 -All files and directories at the following location will be deleted: /Workspace/Users/[USERNAME]/.bundle/test-bundle/default +All files and directories at the following location will be deleted: /Workspace/Users/[USERNAME]/.bundle/test-bundle-[UNIQUE_NAME]/default Destroy: 2 deleted