From 43b0cbe512cb4709e62eb969c3d6f90b7b3a800a Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Fri, 30 Oct 2026 12:54:17 +0100 Subject: [PATCH 1/3] acc: record how includes and target overrides merge, and how nulls are handled Acceptance tests that pin today's merge semantics of included files and target overrides, section by section, and show that null values never override a value from databricks.yml or another file. Co-authored-by: Isaac --- .../include_vs_target/include/databricks.yml | 53 ++++++++++ .../include_vs_target/include/override.yml | 45 +++++++++ .../validate/include_vs_target/out.test.toml | 2 + .../include_vs_target/output.include.json | 98 +++++++++++++++++++ .../include_vs_target/output.target.json | 89 +++++++++++++++++ .../validate/include_vs_target/output.txt | 58 +++++++++++ .../bundle/validate/include_vs_target/script | 9 ++ .../include_vs_target/target/databricks.yml | 98 +++++++++++++++++++ .../validate/include_vs_target/test.toml | 10 ++ .../bundle/validate/includes/order/conf/a.yml | 5 + .../bundle/validate/includes/order/conf/b.yml | 2 + .../validate/includes/order/databricks.yml | 12 +++ .../validate/includes/order/out.test.toml | 2 + .../bundle/validate/includes/order/output.txt | 11 +++ .../bundle/validate/includes/order/script | 2 + .../bundle/validate/includes/order/z.yml | 5 + .../includes/run_as_merged/databricks.yml | 13 +++ .../includes/run_as_merged/out.test.toml | 2 + .../includes/run_as_merged/output.txt | 11 +++ .../includes/run_as_merged/override.yml | 2 + .../validate/includes/run_as_merged/script | 2 + .../a.yml | 8 ++ .../b.yml | 8 ++ .../databricks.yml | 21 ++++ .../out.test.toml | 2 + .../output.txt | 11 +++ .../script | 2 + .../includes/same_resource_in_two_files/a.yml | 6 ++ .../includes/same_resource_in_two_files/b.yml | 6 ++ .../same_resource_in_two_files/databricks.yml | 6 ++ .../same_resource_in_two_files/out.test.toml | 2 + .../same_resource_in_two_files/output.txt | 21 ++++ .../same_resource_in_two_files/script | 2 + .../complex_variable_default/databricks.yml | 24 +++++ .../complex_variable_default/out.test.toml | 2 + .../nulls/complex_variable_default/output.txt | 11 +++ .../complex_variable_default/override.yml | 4 + .../nulls/complex_variable_default/script | 2 + .../include_does_not_override/databricks.yml | 38 +++++++ .../include_does_not_override/out.test.toml | 2 + .../include_does_not_override/output.txt | 66 +++++++++++++ .../include_does_not_override/override.yml | 27 +++++ .../nulls/include_does_not_override/script | 2 + .../databricks.yml | 10 ++ .../out.test.toml | 2 + .../output.txt | 16 +++ .../override.yml | 3 + .../include_resource_is_a_definition/script | 2 + .../target_does_not_override/databricks.yml | 65 ++++++++++++ .../target_does_not_override/out.test.toml | 2 + .../nulls/target_does_not_override/output.txt | 82 ++++++++++++++++ .../nulls/target_does_not_override/script | 2 + .../databricks.yml | 40 ++++++++ .../out.test.toml | 2 + .../output.txt | 50 ++++++++++ .../target_resource_does_not_override/root.py | 1 + .../target_resource_does_not_override/script | 2 + .../targets/empty_values/databricks.yml | 36 +++++++ .../targets/empty_values/out.test.toml | 2 + .../validate/targets/empty_values/output.txt | 26 +++++ .../validate/targets/empty_values/script | 2 + .../targets/job_fields_merge/databricks.yml | 42 ++++++++ .../validate/targets/job_fields_merge/dev.py | 1 + .../targets/job_fields_merge/out.test.toml | 2 + .../targets/job_fields_merge/output.txt | 43 ++++++++ .../validate/targets/job_fields_merge/root.py | 1 + .../validate/targets/job_fields_merge/script | 2 + .../resource_key_collision/databricks.yml | 14 +++ .../resource_key_collision/out.test.toml | 2 + .../targets/resource_key_collision/output.txt | 15 +++ .../targets/resource_key_collision/script | 3 + .../targets/resource_key_collision/test.toml | 1 + .../validate/targets/split_across_files/a.yml | 11 +++ .../targets/split_across_files/databricks.yml | 17 ++++ .../targets/split_across_files/out.test.toml | 2 + .../targets/split_across_files/output.txt | 13 +++ .../targets/split_across_files/script | 2 + .../targets/top_level_fields/databricks.yml | 15 +++ .../targets/top_level_fields/out.test.toml | 2 + .../targets/top_level_fields/output.txt | 10 ++ .../validate/targets/top_level_fields/script | 2 + .../targets/unknown_sections/databricks.yml | 14 +++ .../targets/unknown_sections/out.test.toml | 2 + .../targets/unknown_sections/output.txt | 24 +++++ .../validate/targets/unknown_sections/script | 2 + 85 files changed, 1391 insertions(+) create mode 100644 acceptance/bundle/validate/include_vs_target/include/databricks.yml create mode 100644 acceptance/bundle/validate/include_vs_target/include/override.yml create mode 100644 acceptance/bundle/validate/include_vs_target/out.test.toml create mode 100644 acceptance/bundle/validate/include_vs_target/output.include.json create mode 100644 acceptance/bundle/validate/include_vs_target/output.target.json create mode 100644 acceptance/bundle/validate/include_vs_target/output.txt create mode 100644 acceptance/bundle/validate/include_vs_target/script create mode 100644 acceptance/bundle/validate/include_vs_target/target/databricks.yml create mode 100644 acceptance/bundle/validate/include_vs_target/test.toml create mode 100644 acceptance/bundle/validate/includes/order/conf/a.yml create mode 100644 acceptance/bundle/validate/includes/order/conf/b.yml create mode 100644 acceptance/bundle/validate/includes/order/databricks.yml create mode 100644 acceptance/bundle/validate/includes/order/out.test.toml create mode 100644 acceptance/bundle/validate/includes/order/output.txt create mode 100644 acceptance/bundle/validate/includes/order/script create mode 100644 acceptance/bundle/validate/includes/order/z.yml create mode 100644 acceptance/bundle/validate/includes/run_as_merged/databricks.yml create mode 100644 acceptance/bundle/validate/includes/run_as_merged/out.test.toml create mode 100644 acceptance/bundle/validate/includes/run_as_merged/output.txt create mode 100644 acceptance/bundle/validate/includes/run_as_merged/override.yml create mode 100644 acceptance/bundle/validate/includes/run_as_merged/script create mode 100644 acceptance/bundle/validate/includes/same_resource_in_target_of_two_files/a.yml create mode 100644 acceptance/bundle/validate/includes/same_resource_in_target_of_two_files/b.yml create mode 100644 acceptance/bundle/validate/includes/same_resource_in_target_of_two_files/databricks.yml create mode 100644 acceptance/bundle/validate/includes/same_resource_in_target_of_two_files/out.test.toml create mode 100644 acceptance/bundle/validate/includes/same_resource_in_target_of_two_files/output.txt create mode 100644 acceptance/bundle/validate/includes/same_resource_in_target_of_two_files/script create mode 100644 acceptance/bundle/validate/includes/same_resource_in_two_files/a.yml create mode 100644 acceptance/bundle/validate/includes/same_resource_in_two_files/b.yml create mode 100644 acceptance/bundle/validate/includes/same_resource_in_two_files/databricks.yml create mode 100644 acceptance/bundle/validate/includes/same_resource_in_two_files/out.test.toml create mode 100644 acceptance/bundle/validate/includes/same_resource_in_two_files/output.txt create mode 100644 acceptance/bundle/validate/includes/same_resource_in_two_files/script create mode 100644 acceptance/bundle/validate/nulls/complex_variable_default/databricks.yml create mode 100644 acceptance/bundle/validate/nulls/complex_variable_default/out.test.toml create mode 100644 acceptance/bundle/validate/nulls/complex_variable_default/output.txt create mode 100644 acceptance/bundle/validate/nulls/complex_variable_default/override.yml create mode 100644 acceptance/bundle/validate/nulls/complex_variable_default/script create mode 100644 acceptance/bundle/validate/nulls/include_does_not_override/databricks.yml create mode 100644 acceptance/bundle/validate/nulls/include_does_not_override/out.test.toml create mode 100644 acceptance/bundle/validate/nulls/include_does_not_override/output.txt create mode 100644 acceptance/bundle/validate/nulls/include_does_not_override/override.yml create mode 100644 acceptance/bundle/validate/nulls/include_does_not_override/script create mode 100644 acceptance/bundle/validate/nulls/include_resource_is_a_definition/databricks.yml create mode 100644 acceptance/bundle/validate/nulls/include_resource_is_a_definition/out.test.toml create mode 100644 acceptance/bundle/validate/nulls/include_resource_is_a_definition/output.txt create mode 100644 acceptance/bundle/validate/nulls/include_resource_is_a_definition/override.yml create mode 100644 acceptance/bundle/validate/nulls/include_resource_is_a_definition/script create mode 100644 acceptance/bundle/validate/nulls/target_does_not_override/databricks.yml create mode 100644 acceptance/bundle/validate/nulls/target_does_not_override/out.test.toml create mode 100644 acceptance/bundle/validate/nulls/target_does_not_override/output.txt create mode 100644 acceptance/bundle/validate/nulls/target_does_not_override/script create mode 100644 acceptance/bundle/validate/nulls/target_resource_does_not_override/databricks.yml create mode 100644 acceptance/bundle/validate/nulls/target_resource_does_not_override/out.test.toml create mode 100644 acceptance/bundle/validate/nulls/target_resource_does_not_override/output.txt create mode 100644 acceptance/bundle/validate/nulls/target_resource_does_not_override/root.py create mode 100644 acceptance/bundle/validate/nulls/target_resource_does_not_override/script create mode 100644 acceptance/bundle/validate/targets/empty_values/databricks.yml create mode 100644 acceptance/bundle/validate/targets/empty_values/out.test.toml create mode 100644 acceptance/bundle/validate/targets/empty_values/output.txt create mode 100644 acceptance/bundle/validate/targets/empty_values/script create mode 100644 acceptance/bundle/validate/targets/job_fields_merge/databricks.yml create mode 100644 acceptance/bundle/validate/targets/job_fields_merge/dev.py create mode 100644 acceptance/bundle/validate/targets/job_fields_merge/out.test.toml create mode 100644 acceptance/bundle/validate/targets/job_fields_merge/output.txt create mode 100644 acceptance/bundle/validate/targets/job_fields_merge/root.py create mode 100644 acceptance/bundle/validate/targets/job_fields_merge/script create mode 100644 acceptance/bundle/validate/targets/resource_key_collision/databricks.yml create mode 100644 acceptance/bundle/validate/targets/resource_key_collision/out.test.toml create mode 100644 acceptance/bundle/validate/targets/resource_key_collision/output.txt create mode 100644 acceptance/bundle/validate/targets/resource_key_collision/script create mode 100644 acceptance/bundle/validate/targets/resource_key_collision/test.toml create mode 100644 acceptance/bundle/validate/targets/split_across_files/a.yml create mode 100644 acceptance/bundle/validate/targets/split_across_files/databricks.yml create mode 100644 acceptance/bundle/validate/targets/split_across_files/out.test.toml create mode 100644 acceptance/bundle/validate/targets/split_across_files/output.txt create mode 100644 acceptance/bundle/validate/targets/split_across_files/script create mode 100644 acceptance/bundle/validate/targets/top_level_fields/databricks.yml create mode 100644 acceptance/bundle/validate/targets/top_level_fields/out.test.toml create mode 100644 acceptance/bundle/validate/targets/top_level_fields/output.txt create mode 100644 acceptance/bundle/validate/targets/top_level_fields/script create mode 100644 acceptance/bundle/validate/targets/unknown_sections/databricks.yml create mode 100644 acceptance/bundle/validate/targets/unknown_sections/out.test.toml create mode 100644 acceptance/bundle/validate/targets/unknown_sections/output.txt create mode 100644 acceptance/bundle/validate/targets/unknown_sections/script diff --git a/acceptance/bundle/validate/include_vs_target/include/databricks.yml b/acceptance/bundle/validate/include_vs_target/include/databricks.yml new file mode 100644 index 00000000000..c564d61e2b8 --- /dev/null +++ b/acceptance/bundle/validate/include_vs_target/include/databricks.yml @@ -0,0 +1,53 @@ +bundle: + name: test-bundle + cluster_id: root-cluster + git: + branch: root-branch + +workspace: + root_path: /Workspace/root + file_path: /Workspace/root/files + +artifacts: + whl: + type: whl + build: build-root + files: + - source: root.whl + +experimental: + skip_name_prefix_for_schema: true + +presets: + name_prefix: root- + tags: + root: "1" + +sync: + include: + - databricks.yml + +permissions: + - level: CAN_MANAGE + user_name: ${workspace.current_user.userName} + +variables: + scalar: + description: from root + default: root + complex: + type: complex + default: + root: root + shared: root + list: [root] + +scripts: + root_script: + content: echo root + +run_as: + user_name: root@example.com + +include: + - override.yml diff --git a/acceptance/bundle/validate/include_vs_target/include/override.yml b/acceptance/bundle/validate/include_vs_target/include/override.yml new file mode 100644 index 00000000000..0352505956a --- /dev/null +++ b/acceptance/bundle/validate/include_vs_target/include/override.yml @@ -0,0 +1,45 @@ +bundle: + cluster_id: override-cluster + git: + origin_url: https://override.example.com + +workspace: + root_path: /Workspace/override + +artifacts: + whl: + build: build-override + files: + - source: override.whl + +experimental: + python_wheel_wrapper: true + +presets: + name_prefix: override- + tags: + override: "1" + +sync: + include: + - "*.yml" + +permissions: + - level: CAN_VIEW + group_name: viewers + +variables: + scalar: + default: override + complex: + default: + override: override + shared: override + list: [override] + +scripts: + override_script: + content: echo override + +run_as: + service_principal_name: override-sp diff --git a/acceptance/bundle/validate/include_vs_target/out.test.toml b/acceptance/bundle/validate/include_vs_target/out.test.toml new file mode 100644 index 00000000000..a927a5fbc06 --- /dev/null +++ b/acceptance/bundle/validate/include_vs_target/out.test.toml @@ -0,0 +1,2 @@ +Cloud = false +EnvMatrix.DMS = ["", "true"] diff --git a/acceptance/bundle/validate/include_vs_target/output.include.json b/acceptance/bundle/validate/include_vs_target/output.include.json new file mode 100644 index 00000000000..6f9f584cd41 --- /dev/null +++ b/acceptance/bundle/validate/include_vs_target/output.include.json @@ -0,0 +1,98 @@ +{ + "bundle": { + "cluster_id": "override-cluster", + "git": { + "branch": "root-branch", + "origin_url": "https://override.example.com" + } + }, + "workspace": { + "root_path": "/Workspace/override", + "file_path": "/Workspace/root/files" + }, + "artifacts": { + "whl": { + "build": "build-override", + "files": [ + { + "source": "[BUNDLE_ROOT]/root.whl" + }, + { + "source": "[BUNDLE_ROOT]/override.whl" + } + ], + "path": "[BUNDLE_ROOT]", + "type": "whl" + } + }, + "experimental": { + "python_wheel_wrapper": true, + "skip_name_prefix_for_schema": true + }, + "presets": { + "name_prefix": "override-", + "tags": { + "override": "1", + "root": "1" + } + }, + "sync": { + "include": [ + "databricks.yml", + "*.yml" + ], + "paths": [ + "." + ] + }, + "permissions": [ + { + "level": "CAN_MANAGE", + "user_name": "[USERNAME]" + }, + { + "group_name": "viewers", + "level": "CAN_VIEW" + } + ], + "variables": { + "complex": { + "default": { + "list": [ + "root", + "override" + ], + "override": "override", + "root": "root", + "shared": "override" + }, + "type": "complex", + "value": { + "list": [ + "root", + "override" + ], + "override": "override", + "root": "root", + "shared": "override" + } + }, + "scalar": { + "default": "override", + "description": "from root", + "value": "override" + } + }, + "scripts": { + "override_script": { + "content": "echo override" + }, + "root_script": { + "content": "echo root" + } + }, + "run_as": { + "service_principal_name": "override-sp", + "user_name": "root@example.com" + } +} diff --git a/acceptance/bundle/validate/include_vs_target/output.target.json b/acceptance/bundle/validate/include_vs_target/output.target.json new file mode 100644 index 00000000000..b738aea4515 --- /dev/null +++ b/acceptance/bundle/validate/include_vs_target/output.target.json @@ -0,0 +1,89 @@ +{ + "bundle": { + "cluster_id": "override-cluster", + "git": { + "branch": "root-branch", + "origin_url": "https://override.example.com" + } + }, + "workspace": { + "root_path": "/Workspace/override", + "file_path": "/Workspace/root/files" + }, + "artifacts": { + "whl": { + "build": "build-override", + "files": [ + { + "source": "[BUNDLE_ROOT]/root.whl" + }, + { + "source": "[BUNDLE_ROOT]/override.whl" + } + ], + "path": "[BUNDLE_ROOT]", + "type": "whl" + } + }, + "experimental": { + "skip_name_prefix_for_schema": true + }, + "presets": { + "name_prefix": "override-", + "tags": { + "override": "1", + "root": "1" + } + }, + "sync": { + "include": [ + "databricks.yml", + "*.yml" + ], + "paths": [ + "." + ] + }, + "permissions": [ + { + "level": "CAN_MANAGE", + "user_name": "[USERNAME]" + }, + { + "group_name": "viewers", + "level": "CAN_VIEW" + } + ], + "variables": { + "complex": { + "default": { + "list": [ + "override" + ], + "override": "override", + "shared": "override" + }, + "type": "complex", + "value": { + "list": [ + "override" + ], + "override": "override", + "shared": "override" + } + }, + "scalar": { + "default": "override", + "description": "from root", + "value": "override" + } + }, + "scripts": { + "root_script": { + "content": "echo root" + } + }, + "run_as": { + "service_principal_name": "override-sp" + } +} diff --git a/acceptance/bundle/validate/include_vs_target/output.txt b/acceptance/bundle/validate/include_vs_target/output.txt new file mode 100644 index 00000000000..20eaa79ff48 --- /dev/null +++ b/acceptance/bundle/validate/include_vs_target/output.txt @@ -0,0 +1,58 @@ + +>>> [CLI] bundle validate -o json + +>>> [CLI] bundle validate -o json -t dev +Warning: unknown field: experimental + at targets.dev + in databricks.yml:68:5 + +Warning: unknown field: scripts + at targets.dev + in databricks.yml:93:5 + + +>>> diff.py output.include.json output.target.json +--- output.include.json ++++ output.target.json +@@ -27,5 +27,4 @@ + }, + "experimental": { +- "python_wheel_wrapper": true, + "skip_name_prefix_for_schema": true + }, +@@ -60,9 +59,7 @@ + "default": { + "list": [ +- "root", + "override" + ], + "override": "override", +- "root": "root", + "shared": "override" + }, +@@ -70,9 +67,7 @@ + "value": { + "list": [ +- "root", + "override" + ], + "override": "override", +- "root": "root", + "shared": "override" + } +@@ -85,7 +80,4 @@ + }, + "scripts": { +- "override_script": { +- "content": "echo override" +- }, + "root_script": { + "content": "echo root" +@@ -93,6 +85,5 @@ + }, + "run_as": { +- "service_principal_name": "override-sp", +- "user_name": "root@example.com" ++ "service_principal_name": "override-sp" + } + } diff --git a/acceptance/bundle/validate/include_vs_target/script b/acceptance/bundle/validate/include_vs_target/script new file mode 100644 index 00000000000..27236e057c2 --- /dev/null +++ b/acceptance/bundle/validate/include_vs_target/script @@ -0,0 +1,9 @@ +# The same overrides applied from an included file and from the selected target. +SECTIONS='{bundle: (.bundle | {cluster_id, git: (.git | {branch, origin_url})}), workspace: (.workspace | {root_path, file_path}), artifacts, experimental, presets, sync, permissions, variables, scripts, run_as}' + +cd include +errcode trace $CLI bundle validate -o json | jq "$SECTIONS" > ../output.include.json +cd ../target +errcode trace $CLI bundle validate -o json -t dev | jq "$SECTIONS" > ../output.target.json +cd .. +trace diff.py output.include.json output.target.json diff --git a/acceptance/bundle/validate/include_vs_target/target/databricks.yml b/acceptance/bundle/validate/include_vs_target/target/databricks.yml new file mode 100644 index 00000000000..f858062af6f --- /dev/null +++ b/acceptance/bundle/validate/include_vs_target/target/databricks.yml @@ -0,0 +1,98 @@ +bundle: + name: test-bundle + cluster_id: root-cluster + git: + branch: root-branch + +workspace: + root_path: /Workspace/root + file_path: /Workspace/root/files + +artifacts: + whl: + type: whl + build: build-root + files: + - source: root.whl + +experimental: + skip_name_prefix_for_schema: true + +presets: + name_prefix: root- + tags: + root: "1" + +sync: + include: + - databricks.yml + +permissions: + - level: CAN_MANAGE + user_name: ${workspace.current_user.userName} + +variables: + scalar: + description: from root + default: root + complex: + type: complex + default: + root: root + shared: root + list: [root] + +scripts: + root_script: + content: echo root + +run_as: + user_name: root@example.com + +targets: + dev: + bundle: + cluster_id: override-cluster + git: + origin_url: https://override.example.com + + workspace: + root_path: /Workspace/override + + artifacts: + whl: + build: build-override + files: + - source: override.whl + + experimental: + python_wheel_wrapper: true + + presets: + name_prefix: override- + tags: + override: "1" + + sync: + include: + - "*.yml" + + permissions: + - level: CAN_VIEW + group_name: viewers + + variables: + scalar: + default: override + complex: + default: + override: override + shared: override + list: [override] + + scripts: + override_script: + content: echo override + + run_as: + service_principal_name: override-sp diff --git a/acceptance/bundle/validate/include_vs_target/test.toml b/acceptance/bundle/validate/include_vs_target/test.toml new file mode 100644 index 00000000000..33effd019f6 --- /dev/null +++ b/acceptance/bundle/validate/include_vs_target/test.toml @@ -0,0 +1,10 @@ +Ignore = [".databricks"] + +[[Repls]] +Old = '\\\\' +New = '/' + +# Both bundles resolve paths against their own directory. +[[Repls]] +Old = '\[TEST_TMP_DIR\]/(include|target)' +New = '[BUNDLE_ROOT]' diff --git a/acceptance/bundle/validate/includes/order/conf/a.yml b/acceptance/bundle/validate/includes/order/conf/a.yml new file mode 100644 index 00000000000..138f15ee124 --- /dev/null +++ b/acceptance/bundle/validate/includes/order/conf/a.yml @@ -0,0 +1,5 @@ +presets: + name_prefix: conf-a- + +workspace: + root_path: /Workspace/conf-a diff --git a/acceptance/bundle/validate/includes/order/conf/b.yml b/acceptance/bundle/validate/includes/order/conf/b.yml new file mode 100644 index 00000000000..8296658ac77 --- /dev/null +++ b/acceptance/bundle/validate/includes/order/conf/b.yml @@ -0,0 +1,2 @@ +presets: + name_prefix: conf-b- diff --git a/acceptance/bundle/validate/includes/order/databricks.yml b/acceptance/bundle/validate/includes/order/databricks.yml new file mode 100644 index 00000000000..340fb4b5108 --- /dev/null +++ b/acceptance/bundle/validate/includes/order/databricks.yml @@ -0,0 +1,12 @@ +bundle: + name: test-bundle + +include: + - z.yml + - "conf/*.yml" + +presets: + name_prefix: root- + +workspace: + root_path: /Workspace/root diff --git a/acceptance/bundle/validate/includes/order/out.test.toml b/acceptance/bundle/validate/includes/order/out.test.toml new file mode 100644 index 00000000000..a927a5fbc06 --- /dev/null +++ b/acceptance/bundle/validate/includes/order/out.test.toml @@ -0,0 +1,2 @@ +Cloud = false +EnvMatrix.DMS = ["", "true"] diff --git a/acceptance/bundle/validate/includes/order/output.txt b/acceptance/bundle/validate/includes/order/output.txt new file mode 100644 index 00000000000..95357dc6449 --- /dev/null +++ b/acceptance/bundle/validate/includes/order/output.txt @@ -0,0 +1,11 @@ + +>>> [CLI] bundle validate -o json +{ + "include": [ + "z.yml", + "conf/a.yml", + "conf/b.yml" + ], + "name_prefix": "conf-b-", + "root_path": "/Workspace/conf-a" +} diff --git a/acceptance/bundle/validate/includes/order/script b/acceptance/bundle/validate/includes/order/script new file mode 100644 index 00000000000..3bc8ad721c1 --- /dev/null +++ b/acceptance/bundle/validate/includes/order/script @@ -0,0 +1,2 @@ +# Includes override databricks.yml and each other in include order; matches of a glob are sorted. +trace $CLI bundle validate -o json | jq '{include, name_prefix: .presets.name_prefix, root_path: .workspace.root_path}' diff --git a/acceptance/bundle/validate/includes/order/z.yml b/acceptance/bundle/validate/includes/order/z.yml new file mode 100644 index 00000000000..b1e4bae0001 --- /dev/null +++ b/acceptance/bundle/validate/includes/order/z.yml @@ -0,0 +1,5 @@ +presets: + name_prefix: z- + +workspace: + root_path: /Workspace/z diff --git a/acceptance/bundle/validate/includes/run_as_merged/databricks.yml b/acceptance/bundle/validate/includes/run_as_merged/databricks.yml new file mode 100644 index 00000000000..91d5d6aff38 --- /dev/null +++ b/acceptance/bundle/validate/includes/run_as_merged/databricks.yml @@ -0,0 +1,13 @@ +bundle: + name: test-bundle + +include: + - override.yml + +run_as: + user_name: root@example.com + +resources: + jobs: + foo: + name: foo diff --git a/acceptance/bundle/validate/includes/run_as_merged/out.test.toml b/acceptance/bundle/validate/includes/run_as_merged/out.test.toml new file mode 100644 index 00000000000..a927a5fbc06 --- /dev/null +++ b/acceptance/bundle/validate/includes/run_as_merged/out.test.toml @@ -0,0 +1,2 @@ +Cloud = false +EnvMatrix.DMS = ["", "true"] diff --git a/acceptance/bundle/validate/includes/run_as_merged/output.txt b/acceptance/bundle/validate/includes/run_as_merged/output.txt new file mode 100644 index 00000000000..fa194e22d08 --- /dev/null +++ b/acceptance/bundle/validate/includes/run_as_merged/output.txt @@ -0,0 +1,11 @@ + +>>> [CLI] bundle validate -o json +Error: run_as section must specify exactly one non-empty identity: user_name, service_principal_name, or group_name + in databricks.yml:8:3 + + +Exit code: 1 +{ + "service_principal_name": "override-sp", + "user_name": "root@example.com" +} diff --git a/acceptance/bundle/validate/includes/run_as_merged/override.yml b/acceptance/bundle/validate/includes/run_as_merged/override.yml new file mode 100644 index 00000000000..c400dcb4f46 --- /dev/null +++ b/acceptance/bundle/validate/includes/run_as_merged/override.yml @@ -0,0 +1,2 @@ +run_as: + service_principal_name: override-sp diff --git a/acceptance/bundle/validate/includes/run_as_merged/script b/acceptance/bundle/validate/includes/run_as_merged/script new file mode 100644 index 00000000000..37ce58ede0e --- /dev/null +++ b/acceptance/bundle/validate/includes/run_as_merged/script @@ -0,0 +1,2 @@ +# An included run_as is merged into the root one rather than replacing it (unlike a target run_as). +errcode trace $CLI bundle validate -o json | jq .run_as diff --git a/acceptance/bundle/validate/includes/same_resource_in_target_of_two_files/a.yml b/acceptance/bundle/validate/includes/same_resource_in_target_of_two_files/a.yml new file mode 100644 index 00000000000..8adcd72a749 --- /dev/null +++ b/acceptance/bundle/validate/includes/same_resource_in_target_of_two_files/a.yml @@ -0,0 +1,8 @@ +targets: + dev: + resources: + jobs: + foo: + name: foo-a + tags: + a: "1" diff --git a/acceptance/bundle/validate/includes/same_resource_in_target_of_two_files/b.yml b/acceptance/bundle/validate/includes/same_resource_in_target_of_two_files/b.yml new file mode 100644 index 00000000000..1f7e9e5aae2 --- /dev/null +++ b/acceptance/bundle/validate/includes/same_resource_in_target_of_two_files/b.yml @@ -0,0 +1,8 @@ +targets: + dev: + resources: + jobs: + foo: + name: foo-b + tags: + b: "1" diff --git a/acceptance/bundle/validate/includes/same_resource_in_target_of_two_files/databricks.yml b/acceptance/bundle/validate/includes/same_resource_in_target_of_two_files/databricks.yml new file mode 100644 index 00000000000..656d12df952 --- /dev/null +++ b/acceptance/bundle/validate/includes/same_resource_in_target_of_two_files/databricks.yml @@ -0,0 +1,21 @@ +bundle: + name: test-bundle + +include: + - a.yml + - b.yml + +resources: + jobs: + foo: + name: foo-root + tags: + root: "1" + +targets: + dev: + resources: + jobs: + foo: + tags: + root_dev: "1" diff --git a/acceptance/bundle/validate/includes/same_resource_in_target_of_two_files/out.test.toml b/acceptance/bundle/validate/includes/same_resource_in_target_of_two_files/out.test.toml new file mode 100644 index 00000000000..a927a5fbc06 --- /dev/null +++ b/acceptance/bundle/validate/includes/same_resource_in_target_of_two_files/out.test.toml @@ -0,0 +1,2 @@ +Cloud = false +EnvMatrix.DMS = ["", "true"] diff --git a/acceptance/bundle/validate/includes/same_resource_in_target_of_two_files/output.txt b/acceptance/bundle/validate/includes/same_resource_in_target_of_two_files/output.txt new file mode 100644 index 00000000000..bea40bca155 --- /dev/null +++ b/acceptance/bundle/validate/includes/same_resource_in_target_of_two_files/output.txt @@ -0,0 +1,11 @@ + +>>> [CLI] bundle validate -o json -t dev +{ + "name": "foo-b", + "tags": { + "a": "1", + "b": "1", + "root": "1", + "root_dev": "1" + } +} diff --git a/acceptance/bundle/validate/includes/same_resource_in_target_of_two_files/script b/acceptance/bundle/validate/includes/same_resource_in_target_of_two_files/script new file mode 100644 index 00000000000..089daeb7ba6 --- /dev/null +++ b/acceptance/bundle/validate/includes/same_resource_in_target_of_two_files/script @@ -0,0 +1,2 @@ +# The same resource overridden in a target in several files is merged without an error; the last file wins. +trace $CLI bundle validate -o json -t dev | jq '.resources.jobs.foo | {name, tags}' diff --git a/acceptance/bundle/validate/includes/same_resource_in_two_files/a.yml b/acceptance/bundle/validate/includes/same_resource_in_two_files/a.yml new file mode 100644 index 00000000000..5286c4e86d5 --- /dev/null +++ b/acceptance/bundle/validate/includes/same_resource_in_two_files/a.yml @@ -0,0 +1,6 @@ +resources: + jobs: + foo: + name: foo-a + tags: + a: "1" diff --git a/acceptance/bundle/validate/includes/same_resource_in_two_files/b.yml b/acceptance/bundle/validate/includes/same_resource_in_two_files/b.yml new file mode 100644 index 00000000000..bd50389abde --- /dev/null +++ b/acceptance/bundle/validate/includes/same_resource_in_two_files/b.yml @@ -0,0 +1,6 @@ +resources: + jobs: + foo: + description: foo-b + tags: + b: "1" diff --git a/acceptance/bundle/validate/includes/same_resource_in_two_files/databricks.yml b/acceptance/bundle/validate/includes/same_resource_in_two_files/databricks.yml new file mode 100644 index 00000000000..e125367ca46 --- /dev/null +++ b/acceptance/bundle/validate/includes/same_resource_in_two_files/databricks.yml @@ -0,0 +1,6 @@ +bundle: + name: test-bundle + +include: + - a.yml + - b.yml diff --git a/acceptance/bundle/validate/includes/same_resource_in_two_files/out.test.toml b/acceptance/bundle/validate/includes/same_resource_in_two_files/out.test.toml new file mode 100644 index 00000000000..a927a5fbc06 --- /dev/null +++ b/acceptance/bundle/validate/includes/same_resource_in_two_files/out.test.toml @@ -0,0 +1,2 @@ +Cloud = false +EnvMatrix.DMS = ["", "true"] diff --git a/acceptance/bundle/validate/includes/same_resource_in_two_files/output.txt b/acceptance/bundle/validate/includes/same_resource_in_two_files/output.txt new file mode 100644 index 00000000000..0340ca9307e --- /dev/null +++ b/acceptance/bundle/validate/includes/same_resource_in_two_files/output.txt @@ -0,0 +1,21 @@ + +>>> [CLI] bundle validate -o json +Error: multiple resources or scripts have been defined with the same key: foo + at resources.jobs.foo + in a.yml:4:7 + b.yml:4:7 + + +Exit code: 1 +{ + "jobs": { + "foo": { + "description": "foo-b", + "name": "foo-a", + "tags": { + "a": "1", + "b": "1" + } + } + } +} diff --git a/acceptance/bundle/validate/includes/same_resource_in_two_files/script b/acceptance/bundle/validate/includes/same_resource_in_two_files/script new file mode 100644 index 00000000000..0c988ddaadb --- /dev/null +++ b/acceptance/bundle/validate/includes/same_resource_in_two_files/script @@ -0,0 +1,2 @@ +# A resource defined in two files is an error; the definitions are merged. +errcode trace $CLI bundle validate -o json | jq .resources diff --git a/acceptance/bundle/validate/nulls/complex_variable_default/databricks.yml b/acceptance/bundle/validate/nulls/complex_variable_default/databricks.yml new file mode 100644 index 00000000000..61076ba988b --- /dev/null +++ b/acceptance/bundle/validate/nulls/complex_variable_default/databricks.yml @@ -0,0 +1,24 @@ +bundle: + name: test-bundle + +include: + - override.yml + +variables: + from_include: + type: complex + default: + key: root + other: root + from_target: + type: complex + default: + key: root + other: root + +targets: + dev: + variables: + from_target: + default: + key: null diff --git a/acceptance/bundle/validate/nulls/complex_variable_default/out.test.toml b/acceptance/bundle/validate/nulls/complex_variable_default/out.test.toml new file mode 100644 index 00000000000..a927a5fbc06 --- /dev/null +++ b/acceptance/bundle/validate/nulls/complex_variable_default/out.test.toml @@ -0,0 +1,2 @@ +Cloud = false +EnvMatrix.DMS = ["", "true"] diff --git a/acceptance/bundle/validate/nulls/complex_variable_default/output.txt b/acceptance/bundle/validate/nulls/complex_variable_default/output.txt new file mode 100644 index 00000000000..8770f614222 --- /dev/null +++ b/acceptance/bundle/validate/nulls/complex_variable_default/output.txt @@ -0,0 +1,11 @@ + +>>> [CLI] bundle validate -o json -t dev +{ + "from_include": { + "key": "root", + "other": "root" + }, + "from_target": { + "key": null + } +} diff --git a/acceptance/bundle/validate/nulls/complex_variable_default/override.yml b/acceptance/bundle/validate/nulls/complex_variable_default/override.yml new file mode 100644 index 00000000000..077041a6a79 --- /dev/null +++ b/acceptance/bundle/validate/nulls/complex_variable_default/override.yml @@ -0,0 +1,4 @@ +variables: + from_include: + default: + key: null diff --git a/acceptance/bundle/validate/nulls/complex_variable_default/script b/acceptance/bundle/validate/nulls/complex_variable_default/script new file mode 100644 index 00000000000..bf71bb8ce83 --- /dev/null +++ b/acceptance/bundle/validate/nulls/complex_variable_default/script @@ -0,0 +1,2 @@ +# A null inside a complex variable default is ignored when merged from an include, but kept when the target replaces the whole default. +trace $CLI bundle validate -o json -t dev | jq '.variables | map_values(.value)' diff --git a/acceptance/bundle/validate/nulls/include_does_not_override/databricks.yml b/acceptance/bundle/validate/nulls/include_does_not_override/databricks.yml new file mode 100644 index 00000000000..84a78c8916c --- /dev/null +++ b/acceptance/bundle/validate/nulls/include_does_not_override/databricks.yml @@ -0,0 +1,38 @@ +bundle: + name: test-bundle + cluster_id: root-cluster + +include: + - override.yml + +workspace: + root_path: /Workspace/root + +presets: + name_prefix: root- + tags: + root: "1" + +sync: + include: + - databricks.yml + +permissions: + - level: CAN_MANAGE + user_name: ${workspace.current_user.userName} + +variables: + scalar: + default: root + complex: + type: complex + default: + key: root + +run_as: + user_name: root@example.com + +artifacts: + whl: + type: whl + build: build-root diff --git a/acceptance/bundle/validate/nulls/include_does_not_override/out.test.toml b/acceptance/bundle/validate/nulls/include_does_not_override/out.test.toml new file mode 100644 index 00000000000..a927a5fbc06 --- /dev/null +++ b/acceptance/bundle/validate/nulls/include_does_not_override/out.test.toml @@ -0,0 +1,2 @@ +Cloud = false +EnvMatrix.DMS = ["", "true"] diff --git a/acceptance/bundle/validate/nulls/include_does_not_override/output.txt b/acceptance/bundle/validate/nulls/include_does_not_override/output.txt new file mode 100644 index 00000000000..e12f3c6470f --- /dev/null +++ b/acceptance/bundle/validate/nulls/include_does_not_override/output.txt @@ -0,0 +1,66 @@ + +>>> [CLI] bundle validate -o json +Warning: expected a string value, found null + at bundle.cluster_id + in override.yml:2:15 + +Warning: expected a string value, found null + at workspace.root_path + in override.yml:5:14 + +Warning: expected a string value, found null + at presets.name_prefix + in override.yml:8:15 + +Warning: expected a string value, found null + at presets.tags.root + in override.yml:10:11 + +{ + "cluster_id": "root-cluster", + "root_path": "/Workspace/root", + "presets": { + "name_prefix": "root-", + "tags": { + "root": "1" + } + }, + "sync": { + "include": [ + "databricks.yml" + ], + "paths": [ + "." + ] + }, + "permissions": [ + { + "level": "CAN_MANAGE", + "user_name": "[USERNAME]" + } + ], + "variables": { + "complex": { + "default": { + "key": "root" + }, + "type": "complex", + "value": { + "key": "root" + } + }, + "scalar": { + "default": "root", + "value": "root" + } + }, + "run_as": { + "user_name": "root@example.com" + }, + "artifacts": { + "whl": { + "type": "whl", + "build": "build-root" + } + } +} diff --git a/acceptance/bundle/validate/nulls/include_does_not_override/override.yml b/acceptance/bundle/validate/nulls/include_does_not_override/override.yml new file mode 100644 index 00000000000..ee7f141246c --- /dev/null +++ b/acceptance/bundle/validate/nulls/include_does_not_override/override.yml @@ -0,0 +1,27 @@ +bundle: + cluster_id: null + +workspace: + root_path: ~ + +presets: + name_prefix: + tags: + root: null + +sync: + include: null + +permissions: null + +variables: + scalar: + default: null + complex: + default: + key: null + +run_as: null + +artifacts: + whl: null diff --git a/acceptance/bundle/validate/nulls/include_does_not_override/script b/acceptance/bundle/validate/nulls/include_does_not_override/script new file mode 100644 index 00000000000..5f367e7d8ed --- /dev/null +++ b/acceptance/bundle/validate/nulls/include_does_not_override/script @@ -0,0 +1,2 @@ +# Null values in an included file leave the values from databricks.yml in place; null strings are reported. +trace $CLI bundle validate -o json | jq '{cluster_id: .bundle.cluster_id, root_path: .workspace.root_path, presets, sync, permissions, variables, run_as, artifacts: (.artifacts | map_values({type, build}))}' diff --git a/acceptance/bundle/validate/nulls/include_resource_is_a_definition/databricks.yml b/acceptance/bundle/validate/nulls/include_resource_is_a_definition/databricks.yml new file mode 100644 index 00000000000..4e60eeffbcd --- /dev/null +++ b/acceptance/bundle/validate/nulls/include_resource_is_a_definition/databricks.yml @@ -0,0 +1,10 @@ +bundle: + name: test-bundle + +include: + - override.yml + +resources: + jobs: + foo: + name: foo diff --git a/acceptance/bundle/validate/nulls/include_resource_is_a_definition/out.test.toml b/acceptance/bundle/validate/nulls/include_resource_is_a_definition/out.test.toml new file mode 100644 index 00000000000..a927a5fbc06 --- /dev/null +++ b/acceptance/bundle/validate/nulls/include_resource_is_a_definition/out.test.toml @@ -0,0 +1,2 @@ +Cloud = false +EnvMatrix.DMS = ["", "true"] diff --git a/acceptance/bundle/validate/nulls/include_resource_is_a_definition/output.txt b/acceptance/bundle/validate/nulls/include_resource_is_a_definition/output.txt new file mode 100644 index 00000000000..5b5f38dd53d --- /dev/null +++ b/acceptance/bundle/validate/nulls/include_resource_is_a_definition/output.txt @@ -0,0 +1,16 @@ + +>>> [CLI] bundle validate -o json +Error: multiple resources or scripts have been defined with the same key: foo + at resources.jobs.foo + in databricks.yml:10:7 + override.yml:3:9 + + +Exit code: 1 +{ + "jobs": { + "foo": { + "name": "foo" + } + } +} diff --git a/acceptance/bundle/validate/nulls/include_resource_is_a_definition/override.yml b/acceptance/bundle/validate/nulls/include_resource_is_a_definition/override.yml new file mode 100644 index 00000000000..50e35f69c76 --- /dev/null +++ b/acceptance/bundle/validate/nulls/include_resource_is_a_definition/override.yml @@ -0,0 +1,3 @@ +resources: + jobs: + foo: diff --git a/acceptance/bundle/validate/nulls/include_resource_is_a_definition/script b/acceptance/bundle/validate/nulls/include_resource_is_a_definition/script new file mode 100644 index 00000000000..1ec6d0b9748 --- /dev/null +++ b/acceptance/bundle/validate/nulls/include_resource_is_a_definition/script @@ -0,0 +1,2 @@ +# A null resource in an included file counts as a second definition of the resource. +errcode trace $CLI bundle validate -o json | jq .resources diff --git a/acceptance/bundle/validate/nulls/target_does_not_override/databricks.yml b/acceptance/bundle/validate/nulls/target_does_not_override/databricks.yml new file mode 100644 index 00000000000..3f73a36819e --- /dev/null +++ b/acceptance/bundle/validate/nulls/target_does_not_override/databricks.yml @@ -0,0 +1,65 @@ +bundle: + name: test-bundle + cluster_id: root-cluster + mode: development + git: + branch: root-branch + +workspace: + root_path: ~/root + +presets: + name_prefix: root-${workspace.current_user.short_name}- + tags: + root: "1" + +sync: + include: + - databricks.yml + +permissions: + - level: CAN_MANAGE + user_name: ${workspace.current_user.userName} + +variables: + shorthand: + default: root + scalar: + default: root + with_lookup: + lookup: + cluster: some-test-cluster + +run_as: + user_name: root@example.com + +artifacts: + whl: + type: whl + build: build-root + +targets: + dev: + mode: null + cluster_id: null + git: null + run_as: null + bundle: + cluster_id: null + workspace: + root_path: null + presets: + name_prefix: null + tags: + root: null + sync: + include: null + permissions: null + variables: + shorthand: null + scalar: + default: null + with_lookup: + default: null + artifacts: + whl: null diff --git a/acceptance/bundle/validate/nulls/target_does_not_override/out.test.toml b/acceptance/bundle/validate/nulls/target_does_not_override/out.test.toml new file mode 100644 index 00000000000..a927a5fbc06 --- /dev/null +++ b/acceptance/bundle/validate/nulls/target_does_not_override/out.test.toml @@ -0,0 +1,2 @@ +Cloud = false +EnvMatrix.DMS = ["", "true"] diff --git a/acceptance/bundle/validate/nulls/target_does_not_override/output.txt b/acceptance/bundle/validate/nulls/target_does_not_override/output.txt new file mode 100644 index 00000000000..82baabdd32e --- /dev/null +++ b/acceptance/bundle/validate/nulls/target_does_not_override/output.txt @@ -0,0 +1,82 @@ + +>>> [CLI] bundle validate -o json -t dev +Warning: expected a string value, found null + at targets.dev.mode + in databricks.yml:43:11 + +Warning: expected a string value, found null + at targets.dev.cluster_id + in databricks.yml:44:17 + +Warning: expected a string value, found null + at targets.dev.bundle.cluster_id + in databricks.yml:48:19 + +Warning: expected a string value, found null + at targets.dev.workspace.root_path + in databricks.yml:50:18 + +Warning: expected a string value, found null + at targets.dev.presets.name_prefix + in databricks.yml:52:20 + +Warning: expected a string value, found null + at targets.dev.presets.tags.root + in databricks.yml:54:15 + +{ + "bundle": { + "mode": "development", + "cluster_id": "root-cluster", + "git": { + "branch": "root-branch" + } + }, + "root_path": "/Workspace/Users/[USERNAME]/root", + "presets": { + "name_prefix": "root-[USERNAME]-", + "tags": { + "dev": "[USERNAME]", + "root": "1" + } + }, + "sync": { + "include": [ + "databricks.yml" + ], + "paths": [ + "." + ] + }, + "permissions": [ + { + "level": "CAN_MANAGE", + "user_name": "[USERNAME]" + } + ], + "variables": { + "scalar": { + "default": "root", + "value": "root" + }, + "shorthand": { + "default": "root", + "value": "root" + }, + "with_lookup": { + "lookup": { + "cluster": "some-test-cluster" + }, + "value": "4321" + } + }, + "run_as": { + "user_name": "root@example.com" + }, + "artifacts": { + "whl": { + "type": "whl", + "build": "build-root" + } + } +} diff --git a/acceptance/bundle/validate/nulls/target_does_not_override/script b/acceptance/bundle/validate/nulls/target_does_not_override/script new file mode 100644 index 00000000000..0c1b7c1d7bc --- /dev/null +++ b/acceptance/bundle/validate/nulls/target_does_not_override/script @@ -0,0 +1,2 @@ +# Null values in a target leave the root values in place, including fields a target otherwise replaces (mode, cluster_id, run_as, variable defaults and lookups). +trace $CLI bundle validate -o json -t dev | jq '{bundle: (.bundle | {mode, cluster_id, git: (.git | {branch})}), root_path: .workspace.root_path, presets: (.presets | {name_prefix, tags}), sync, permissions, variables, run_as, artifacts: (.artifacts | map_values({type, build}))}' diff --git a/acceptance/bundle/validate/nulls/target_resource_does_not_override/databricks.yml b/acceptance/bundle/validate/nulls/target_resource_does_not_override/databricks.yml new file mode 100644 index 00000000000..8b306c625d9 --- /dev/null +++ b/acceptance/bundle/validate/nulls/target_resource_does_not_override/databricks.yml @@ -0,0 +1,40 @@ +bundle: + name: test-bundle + +resources: + jobs: + foo: + name: foo + max_concurrent_runs: 5 + queue: + enabled: false + tags: + root: "1" + email_notifications: + on_failure: + - root@example.com + tasks: + - task_key: t1 + notebook_task: + notebook_path: ./root.py + bar: + name: bar + +targets: + dev: + resources: + jobs: + foo: + name: null + max_concurrent_runs: null + queue: + enabled: null + tags: + root: null + email_notifications: + on_failure: + - null + tasks: + - task_key: t1 + notebook_task: null + bar: null diff --git a/acceptance/bundle/validate/nulls/target_resource_does_not_override/out.test.toml b/acceptance/bundle/validate/nulls/target_resource_does_not_override/out.test.toml new file mode 100644 index 00000000000..a927a5fbc06 --- /dev/null +++ b/acceptance/bundle/validate/nulls/target_resource_does_not_override/out.test.toml @@ -0,0 +1,2 @@ +Cloud = false +EnvMatrix.DMS = ["", "true"] diff --git a/acceptance/bundle/validate/nulls/target_resource_does_not_override/output.txt b/acceptance/bundle/validate/nulls/target_resource_does_not_override/output.txt new file mode 100644 index 00000000000..8f6f9a0550f --- /dev/null +++ b/acceptance/bundle/validate/nulls/target_resource_does_not_override/output.txt @@ -0,0 +1,50 @@ + +>>> [CLI] bundle validate -o json -t dev +Warning: expected a string value, found null + at targets.dev.resources.jobs.foo.name + in databricks.yml:28:17 + +Warning: expected a int value, found null + at targets.dev.resources.jobs.foo.max_concurrent_runs + in databricks.yml:29:32 + +Warning: expected a bool value, found null + at targets.dev.resources.jobs.foo.queue.enabled + in databricks.yml:31:22 + +Warning: expected a string value, found null + at targets.dev.resources.jobs.foo.tags.root + in databricks.yml:33:19 + +Warning: expected a string value, found null + at targets.dev.resources.jobs.foo.email_notifications.on_failure[0] + in databricks.yml:36:17 + +{ + "foo": { + "name": "foo", + "max_concurrent_runs": 5, + "queue": { + "enabled": false + }, + "tags": { + "root": "1" + }, + "email_notifications": { + "on_failure": [ + "root@example.com" + ] + }, + "tasks": [ + { + "notebook_task": { + "notebook_path": "/Workspace/Users/[USERNAME]/.bundle/test-bundle/dev/files/root" + }, + "task_key": "t1" + } + ] + }, + "bar": { + "name": "bar" + } +} diff --git a/acceptance/bundle/validate/nulls/target_resource_does_not_override/root.py b/acceptance/bundle/validate/nulls/target_resource_does_not_override/root.py new file mode 100644 index 00000000000..1645e04b1de --- /dev/null +++ b/acceptance/bundle/validate/nulls/target_resource_does_not_override/root.py @@ -0,0 +1 @@ +# Databricks notebook source diff --git a/acceptance/bundle/validate/nulls/target_resource_does_not_override/script b/acceptance/bundle/validate/nulls/target_resource_does_not_override/script new file mode 100644 index 00000000000..510381f2184 --- /dev/null +++ b/acceptance/bundle/validate/nulls/target_resource_does_not_override/script @@ -0,0 +1,2 @@ +# Null values in a target resource override, including a null resource, leave the root values in place. +trace $CLI bundle validate -o json -t dev | jq '.resources.jobs | {foo: (.foo | {name, max_concurrent_runs, queue, tags, email_notifications, tasks}), bar: (.bar | {name})}' diff --git a/acceptance/bundle/validate/targets/empty_values/databricks.yml b/acceptance/bundle/validate/targets/empty_values/databricks.yml new file mode 100644 index 00000000000..76bc049ba9f --- /dev/null +++ b/acceptance/bundle/validate/targets/empty_values/databricks.yml @@ -0,0 +1,36 @@ +bundle: + name: test-bundle + +presets: + name_prefix: root- + jobs_max_concurrent_runs: 7 + pipelines_development: true + +sync: + include: + - databricks.yml + +permissions: + - level: CAN_MANAGE + user_name: ${workspace.current_user.userName} + +resources: + jobs: + foo: + name: foo + tags: + root: "1" + +targets: + dev: + presets: + name_prefix: "" + jobs_max_concurrent_runs: 0 + pipelines_development: false + sync: + include: [] + permissions: [] + resources: + jobs: + foo: + tags: {} diff --git a/acceptance/bundle/validate/targets/empty_values/out.test.toml b/acceptance/bundle/validate/targets/empty_values/out.test.toml new file mode 100644 index 00000000000..a927a5fbc06 --- /dev/null +++ b/acceptance/bundle/validate/targets/empty_values/out.test.toml @@ -0,0 +1,2 @@ +Cloud = false +EnvMatrix.DMS = ["", "true"] diff --git a/acceptance/bundle/validate/targets/empty_values/output.txt b/acceptance/bundle/validate/targets/empty_values/output.txt new file mode 100644 index 00000000000..e3b6de8834a --- /dev/null +++ b/acceptance/bundle/validate/targets/empty_values/output.txt @@ -0,0 +1,26 @@ + +>>> [CLI] bundle validate -o json -t dev +{ + "presets": { + "jobs_max_concurrent_runs": 0, + "name_prefix": "", + "pipelines_development": false + }, + "sync": { + "include": [ + "databricks.yml" + ], + "paths": [ + "." + ] + }, + "permissions": [ + { + "level": "CAN_MANAGE", + "user_name": "[USERNAME]" + } + ], + "tags": { + "root": "1" + } +} diff --git a/acceptance/bundle/validate/targets/empty_values/script b/acceptance/bundle/validate/targets/empty_values/script new file mode 100644 index 00000000000..d16edf478b9 --- /dev/null +++ b/acceptance/bundle/validate/targets/empty_values/script @@ -0,0 +1,2 @@ +# A target overrides with "", 0 and false, but [] and {} do not clear a list or a map. +trace $CLI bundle validate -o json -t dev | jq '{presets, sync, permissions, tags: .resources.jobs.foo.tags}' diff --git a/acceptance/bundle/validate/targets/job_fields_merge/databricks.yml b/acceptance/bundle/validate/targets/job_fields_merge/databricks.yml new file mode 100644 index 00000000000..d4c557e3b2b --- /dev/null +++ b/acceptance/bundle/validate/targets/job_fields_merge/databricks.yml @@ -0,0 +1,42 @@ +bundle: + name: test-bundle + +resources: + jobs: + foo: + name: foo-root + description: root + tags: + root: "1" + shared: root + email_notifications: + on_failure: + - root@example.com + tasks: + - task_key: t1 + notebook_task: + notebook_path: ./root.py + libraries: + - pypi: + package: root + +targets: + dev: + resources: + jobs: + foo: + name: foo-dev + tags: + dev: "1" + shared: dev + email_notifications: + on_failure: + - dev@example.com + tasks: + - task_key: t1 + libraries: + - pypi: + package: dev + - task_key: t2 + notebook_task: + notebook_path: ./dev.py diff --git a/acceptance/bundle/validate/targets/job_fields_merge/dev.py b/acceptance/bundle/validate/targets/job_fields_merge/dev.py new file mode 100644 index 00000000000..1645e04b1de --- /dev/null +++ b/acceptance/bundle/validate/targets/job_fields_merge/dev.py @@ -0,0 +1 @@ +# Databricks notebook source diff --git a/acceptance/bundle/validate/targets/job_fields_merge/out.test.toml b/acceptance/bundle/validate/targets/job_fields_merge/out.test.toml new file mode 100644 index 00000000000..a927a5fbc06 --- /dev/null +++ b/acceptance/bundle/validate/targets/job_fields_merge/out.test.toml @@ -0,0 +1,2 @@ +Cloud = false +EnvMatrix.DMS = ["", "true"] diff --git a/acceptance/bundle/validate/targets/job_fields_merge/output.txt b/acceptance/bundle/validate/targets/job_fields_merge/output.txt new file mode 100644 index 00000000000..965839edcb5 --- /dev/null +++ b/acceptance/bundle/validate/targets/job_fields_merge/output.txt @@ -0,0 +1,43 @@ + +>>> [CLI] bundle validate -o json -t dev +{ + "name": "foo-dev", + "description": "root", + "tags": { + "dev": "1", + "root": "1", + "shared": "dev" + }, + "email_notifications": { + "on_failure": [ + "root@example.com", + "dev@example.com" + ] + }, + "tasks": [ + { + "libraries": [ + { + "pypi": { + "package": "root" + } + }, + { + "pypi": { + "package": "dev" + } + } + ], + "notebook_task": { + "notebook_path": "/Workspace/Users/[USERNAME]/.bundle/test-bundle/dev/files/root" + }, + "task_key": "t1" + }, + { + "notebook_task": { + "notebook_path": "/Workspace/Users/[USERNAME]/.bundle/test-bundle/dev/files/dev" + }, + "task_key": "t2" + } + ] +} diff --git a/acceptance/bundle/validate/targets/job_fields_merge/root.py b/acceptance/bundle/validate/targets/job_fields_merge/root.py new file mode 100644 index 00000000000..1645e04b1de --- /dev/null +++ b/acceptance/bundle/validate/targets/job_fields_merge/root.py @@ -0,0 +1 @@ +# Databricks notebook source diff --git a/acceptance/bundle/validate/targets/job_fields_merge/script b/acceptance/bundle/validate/targets/job_fields_merge/script new file mode 100644 index 00000000000..a7167d464aa --- /dev/null +++ b/acceptance/bundle/validate/targets/job_fields_merge/script @@ -0,0 +1,2 @@ +# A target override merges into the job field by field: maps merge, lists are concatenated, tasks merge by task_key. +trace $CLI bundle validate -o json -t dev | jq '.resources.jobs.foo | {name, description, tags, email_notifications, tasks}' diff --git a/acceptance/bundle/validate/targets/resource_key_collision/databricks.yml b/acceptance/bundle/validate/targets/resource_key_collision/databricks.yml new file mode 100644 index 00000000000..6f09f579da4 --- /dev/null +++ b/acceptance/bundle/validate/targets/resource_key_collision/databricks.yml @@ -0,0 +1,14 @@ +bundle: + name: test-bundle + +resources: + jobs: + foo: + name: foo + +targets: + dev: + resources: + pipelines: + foo: + name: foo diff --git a/acceptance/bundle/validate/targets/resource_key_collision/out.test.toml b/acceptance/bundle/validate/targets/resource_key_collision/out.test.toml new file mode 100644 index 00000000000..a927a5fbc06 --- /dev/null +++ b/acceptance/bundle/validate/targets/resource_key_collision/out.test.toml @@ -0,0 +1,2 @@ +Cloud = false +EnvMatrix.DMS = ["", "true"] diff --git a/acceptance/bundle/validate/targets/resource_key_collision/output.txt b/acceptance/bundle/validate/targets/resource_key_collision/output.txt new file mode 100644 index 00000000000..27753d32d1e --- /dev/null +++ b/acceptance/bundle/validate/targets/resource_key_collision/output.txt @@ -0,0 +1,15 @@ + +>>> [CLI] bundle validate -t dev +Name: test-bundle +Target: dev +Workspace: + User: [USERNAME] + Path: /Workspace/Users/[USERNAME]/.bundle/test-bundle/dev + +Validation OK! + +>>> [CLI] bundle plan -t dev --select foo +Error: ambiguous resource: foo (can resolve to jobs.foo, pipelines.foo); use a qualified name to disambiguate + + +Exit code: 1 diff --git a/acceptance/bundle/validate/targets/resource_key_collision/script b/acceptance/bundle/validate/targets/resource_key_collision/script new file mode 100644 index 00000000000..191ecac0690 --- /dev/null +++ b/acceptance/bundle/validate/targets/resource_key_collision/script @@ -0,0 +1,3 @@ +# A target can add a resource with the key of a resource of another type; validate accepts it, --select finds it ambiguous. +trace $CLI bundle validate -t dev +errcode trace $CLI bundle plan -t dev --select foo diff --git a/acceptance/bundle/validate/targets/resource_key_collision/test.toml b/acceptance/bundle/validate/targets/resource_key_collision/test.toml new file mode 100644 index 00000000000..e3079a544fc --- /dev/null +++ b/acceptance/bundle/validate/targets/resource_key_collision/test.toml @@ -0,0 +1 @@ +Badness = 'Resource keys must be unique across types (see select/ambiguous), but the check runs before target overrides, so a target can add a colliding key.' diff --git a/acceptance/bundle/validate/targets/split_across_files/a.yml b/acceptance/bundle/validate/targets/split_across_files/a.yml new file mode 100644 index 00000000000..91e6ac51ca5 --- /dev/null +++ b/acceptance/bundle/validate/targets/split_across_files/a.yml @@ -0,0 +1,11 @@ +workspace: + root_path: /Workspace/a + artifact_path: /Workspace/a/artifacts + +targets: + dev: + workspace: + root_path: /Workspace/dev-a + sync: + include: + - a.yml diff --git a/acceptance/bundle/validate/targets/split_across_files/databricks.yml b/acceptance/bundle/validate/targets/split_across_files/databricks.yml new file mode 100644 index 00000000000..90c46ace030 --- /dev/null +++ b/acceptance/bundle/validate/targets/split_across_files/databricks.yml @@ -0,0 +1,17 @@ +bundle: + name: test-bundle + +include: + - a.yml + +workspace: + root_path: /Workspace/root + +targets: + dev: + workspace: + root_path: /Workspace/dev-root + file_path: /Workspace/dev-root/files + sync: + include: + - databricks.yml diff --git a/acceptance/bundle/validate/targets/split_across_files/out.test.toml b/acceptance/bundle/validate/targets/split_across_files/out.test.toml new file mode 100644 index 00000000000..a927a5fbc06 --- /dev/null +++ b/acceptance/bundle/validate/targets/split_across_files/out.test.toml @@ -0,0 +1,2 @@ +Cloud = false +EnvMatrix.DMS = ["", "true"] diff --git a/acceptance/bundle/validate/targets/split_across_files/output.txt b/acceptance/bundle/validate/targets/split_across_files/output.txt new file mode 100644 index 00000000000..7ba7ae32421 --- /dev/null +++ b/acceptance/bundle/validate/targets/split_across_files/output.txt @@ -0,0 +1,13 @@ + +>>> [CLI] bundle validate -o json -t dev +{ + "workspace": { + "root_path": "/Workspace/dev-a", + "file_path": "/Workspace/dev-root/files", + "artifact_path": "/Workspace/a/artifacts" + }, + "sync": [ + "databricks.yml", + "a.yml" + ] +} diff --git a/acceptance/bundle/validate/targets/split_across_files/script b/acceptance/bundle/validate/targets/split_across_files/script new file mode 100644 index 00000000000..d5ebd463c6d --- /dev/null +++ b/acceptance/bundle/validate/targets/split_across_files/script @@ -0,0 +1,2 @@ +# A target defined in several files is merged like any other section, then applied on top of all files. +trace $CLI bundle validate -o json -t dev | jq '{workspace: (.workspace | {root_path, file_path, artifact_path}), sync: .sync.include}' diff --git a/acceptance/bundle/validate/targets/top_level_fields/databricks.yml b/acceptance/bundle/validate/targets/top_level_fields/databricks.yml new file mode 100644 index 00000000000..79155b9a0b2 --- /dev/null +++ b/acceptance/bundle/validate/targets/top_level_fields/databricks.yml @@ -0,0 +1,15 @@ +bundle: + name: test-bundle + cluster_id: root-cluster + git: + branch: root-branch + origin_url: https://root.example.com + +targets: + dev: + mode: development + cluster_id: dev-cluster + git: + branch: dev-branch + bundle: + cluster_id: dev-bundle-cluster diff --git a/acceptance/bundle/validate/targets/top_level_fields/out.test.toml b/acceptance/bundle/validate/targets/top_level_fields/out.test.toml new file mode 100644 index 00000000000..a927a5fbc06 --- /dev/null +++ b/acceptance/bundle/validate/targets/top_level_fields/out.test.toml @@ -0,0 +1,2 @@ +Cloud = false +EnvMatrix.DMS = ["", "true"] diff --git a/acceptance/bundle/validate/targets/top_level_fields/output.txt b/acceptance/bundle/validate/targets/top_level_fields/output.txt new file mode 100644 index 00000000000..d1d16ea0187 --- /dev/null +++ b/acceptance/bundle/validate/targets/top_level_fields/output.txt @@ -0,0 +1,10 @@ + +>>> [CLI] bundle validate -o json -t dev +{ + "mode": "development", + "cluster_id": "dev-cluster", + "git": { + "branch": "dev-branch", + "origin_url": "https://root.example.com" + } +} diff --git a/acceptance/bundle/validate/targets/top_level_fields/script b/acceptance/bundle/validate/targets/top_level_fields/script new file mode 100644 index 00000000000..a995639b677 --- /dev/null +++ b/acceptance/bundle/validate/targets/top_level_fields/script @@ -0,0 +1,2 @@ +# Target mode, cluster_id and git apply to the bundle section; cluster_id wins over bundle.cluster_id in the same target. +trace $CLI bundle validate -o json -t dev | jq '.bundle | {mode, cluster_id, git: (.git | {branch, origin_url})}' diff --git a/acceptance/bundle/validate/targets/unknown_sections/databricks.yml b/acceptance/bundle/validate/targets/unknown_sections/databricks.yml new file mode 100644 index 00000000000..fcfffc3fbe2 --- /dev/null +++ b/acceptance/bundle/validate/targets/unknown_sections/databricks.yml @@ -0,0 +1,14 @@ +bundle: + name: test-bundle + +targets: + dev: + experimental: + python_wheel_wrapper: true + scripts: + s: + content: echo dev + python: + venv_path: .venv + include: + - other.yml diff --git a/acceptance/bundle/validate/targets/unknown_sections/out.test.toml b/acceptance/bundle/validate/targets/unknown_sections/out.test.toml new file mode 100644 index 00000000000..a927a5fbc06 --- /dev/null +++ b/acceptance/bundle/validate/targets/unknown_sections/out.test.toml @@ -0,0 +1,2 @@ +Cloud = false +EnvMatrix.DMS = ["", "true"] diff --git a/acceptance/bundle/validate/targets/unknown_sections/output.txt b/acceptance/bundle/validate/targets/unknown_sections/output.txt new file mode 100644 index 00000000000..d2c9def3b25 --- /dev/null +++ b/acceptance/bundle/validate/targets/unknown_sections/output.txt @@ -0,0 +1,24 @@ + +>>> [CLI] bundle validate -o json -t dev +Warning: unknown field: experimental + at targets.dev + in databricks.yml:6:5 + +Warning: unknown field: scripts + at targets.dev + in databricks.yml:8:5 + +Warning: unknown field: python + at targets.dev + in databricks.yml:11:5 + +Warning: unknown field: include + at targets.dev + in databricks.yml:13:5 + +{ + "experimental": null, + "scripts": null, + "python": null, + "include": null +} diff --git a/acceptance/bundle/validate/targets/unknown_sections/script b/acceptance/bundle/validate/targets/unknown_sections/script new file mode 100644 index 00000000000..aab0d4173f7 --- /dev/null +++ b/acceptance/bundle/validate/targets/unknown_sections/script @@ -0,0 +1,2 @@ +# experimental, scripts, python and include cannot be set in a target. +trace $CLI bundle validate -o json -t dev | jq '{experimental, scripts, python, include}' From bbd119f7aa372fe9629340f6c2c135ffd3bdbc20 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Fri, 30 Oct 2026 13:11:36 +0100 Subject: [PATCH 2/3] acc: normalize Windows separators in includes/order Co-authored-by: Isaac --- acceptance/bundle/validate/includes/order/test.toml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 acceptance/bundle/validate/includes/order/test.toml diff --git a/acceptance/bundle/validate/includes/order/test.toml b/acceptance/bundle/validate/includes/order/test.toml new file mode 100644 index 00000000000..9de0e5001e5 --- /dev/null +++ b/acceptance/bundle/validate/includes/order/test.toml @@ -0,0 +1,4 @@ +# Expanded include paths use the OS path separator. +[[Repls]] +Old = '\\\\' +New = '/' From 36d4c3a89e3f67861a8a21724d02ee99af1fc19b Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Fri, 30 Oct 2026 15:18:04 +0100 Subject: [PATCH 3/3] acc: record deploy, summary and run with a target-added colliding resource key Moves validate/targets/resource_key_collision to run/ambiguous_key_from_target. Co-authored-by: Isaac --- .../ambiguous_key_from_target}/databricks.yml | 5 ++- .../ambiguous_key_from_target}/out.test.toml | 0 .../run/ambiguous_key_from_target/output.txt | 37 +++++++++++++++++++ .../run/ambiguous_key_from_target/script | 6 +++ .../run/ambiguous_key_from_target/test.toml | 1 + .../targets/resource_key_collision/output.txt | 15 -------- .../targets/resource_key_collision/script | 3 -- .../targets/resource_key_collision/test.toml | 1 - 8 files changed, 47 insertions(+), 21 deletions(-) rename acceptance/bundle/{validate/targets/resource_key_collision => run/ambiguous_key_from_target}/databricks.yml (63%) rename acceptance/bundle/{validate/targets/resource_key_collision => run/ambiguous_key_from_target}/out.test.toml (100%) create mode 100644 acceptance/bundle/run/ambiguous_key_from_target/output.txt create mode 100644 acceptance/bundle/run/ambiguous_key_from_target/script create mode 100644 acceptance/bundle/run/ambiguous_key_from_target/test.toml delete mode 100644 acceptance/bundle/validate/targets/resource_key_collision/output.txt delete mode 100644 acceptance/bundle/validate/targets/resource_key_collision/script delete mode 100644 acceptance/bundle/validate/targets/resource_key_collision/test.toml diff --git a/acceptance/bundle/validate/targets/resource_key_collision/databricks.yml b/acceptance/bundle/run/ambiguous_key_from_target/databricks.yml similarity index 63% rename from acceptance/bundle/validate/targets/resource_key_collision/databricks.yml rename to acceptance/bundle/run/ambiguous_key_from_target/databricks.yml index 6f09f579da4..521ffc6c1e6 100644 --- a/acceptance/bundle/validate/targets/resource_key_collision/databricks.yml +++ b/acceptance/bundle/run/ambiguous_key_from_target/databricks.yml @@ -4,11 +4,12 @@ bundle: resources: jobs: foo: - name: foo + name: foo-job targets: dev: + default: true resources: pipelines: foo: - name: foo + name: foo-pipeline diff --git a/acceptance/bundle/validate/targets/resource_key_collision/out.test.toml b/acceptance/bundle/run/ambiguous_key_from_target/out.test.toml similarity index 100% rename from acceptance/bundle/validate/targets/resource_key_collision/out.test.toml rename to acceptance/bundle/run/ambiguous_key_from_target/out.test.toml diff --git a/acceptance/bundle/run/ambiguous_key_from_target/output.txt b/acceptance/bundle/run/ambiguous_key_from_target/output.txt new file mode 100644 index 00000000000..64e654b4407 --- /dev/null +++ b/acceptance/bundle/run/ambiguous_key_from_target/output.txt @@ -0,0 +1,37 @@ + +>>> [CLI] bundle validate +Name: test-bundle +Target: dev +Workspace: + User: [USERNAME] + Path: /Workspace/Users/[USERNAME]/.bundle/test-bundle/dev + +Validation OK! + +>>> [CLI] bundle deploy +Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/dev/files... +Created jobs.foo +Created pipelines.foo +Files: 1 uploaded, 0 deleted +Resources: 2 created, 0 changed, 0 deleted, 0 unchanged + +>>> [CLI] bundle summary +Name: test-bundle +Target: dev +Workspace: + User: [USERNAME] + Path: /Workspace/Users/[USERNAME]/.bundle/test-bundle/dev +Resources: + Jobs: + foo: + Name: foo-job + URL: [DATABRICKS_URL]/jobs/[FOO_ID]?w=[WORKSPACE_ID] + Pipelines: + foo: + Name: foo-pipeline + URL: [DATABRICKS_URL]/pipelines/[FOO_ID_2]?w=[WORKSPACE_ID] + +>>> [CLI] bundle run foo +Error: multiple resources with key "foo" found + +Exit code: 1 diff --git a/acceptance/bundle/run/ambiguous_key_from_target/script b/acceptance/bundle/run/ambiguous_key_from_target/script new file mode 100644 index 00000000000..a71ae1d326f --- /dev/null +++ b/acceptance/bundle/run/ambiguous_key_from_target/script @@ -0,0 +1,6 @@ +# A target adds pipelines.foo next to jobs.foo: validate, deploy and summary accept it, run fails as ambiguous. +trace $CLI bundle validate +trace $CLI bundle deploy +replace_ids.py +trace $CLI bundle summary +errcode trace $CLI bundle run foo diff --git a/acceptance/bundle/run/ambiguous_key_from_target/test.toml b/acceptance/bundle/run/ambiguous_key_from_target/test.toml new file mode 100644 index 00000000000..721a5538b69 --- /dev/null +++ b/acceptance/bundle/run/ambiguous_key_from_target/test.toml @@ -0,0 +1 @@ +Badness = 'Resource keys must be unique across resource types (see select/ambiguous), but the check runs before target overrides, so a target can add pipelines.foo next to jobs.foo and only commands that look up the key fail.' diff --git a/acceptance/bundle/validate/targets/resource_key_collision/output.txt b/acceptance/bundle/validate/targets/resource_key_collision/output.txt deleted file mode 100644 index 27753d32d1e..00000000000 --- a/acceptance/bundle/validate/targets/resource_key_collision/output.txt +++ /dev/null @@ -1,15 +0,0 @@ - ->>> [CLI] bundle validate -t dev -Name: test-bundle -Target: dev -Workspace: - User: [USERNAME] - Path: /Workspace/Users/[USERNAME]/.bundle/test-bundle/dev - -Validation OK! - ->>> [CLI] bundle plan -t dev --select foo -Error: ambiguous resource: foo (can resolve to jobs.foo, pipelines.foo); use a qualified name to disambiguate - - -Exit code: 1 diff --git a/acceptance/bundle/validate/targets/resource_key_collision/script b/acceptance/bundle/validate/targets/resource_key_collision/script deleted file mode 100644 index 191ecac0690..00000000000 --- a/acceptance/bundle/validate/targets/resource_key_collision/script +++ /dev/null @@ -1,3 +0,0 @@ -# A target can add a resource with the key of a resource of another type; validate accepts it, --select finds it ambiguous. -trace $CLI bundle validate -t dev -errcode trace $CLI bundle plan -t dev --select foo diff --git a/acceptance/bundle/validate/targets/resource_key_collision/test.toml b/acceptance/bundle/validate/targets/resource_key_collision/test.toml deleted file mode 100644 index e3079a544fc..00000000000 --- a/acceptance/bundle/validate/targets/resource_key_collision/test.toml +++ /dev/null @@ -1 +0,0 @@ -Badness = 'Resource keys must be unique across types (see select/ambiguous), but the check runs before target overrides, so a target can add a colliding key.'