Repository navigation
Conversation
A null in an included file removes the value it lands on from databricks.yml and earlier includes, also a whole resource or section. A null in a target removes the value from the configuration when the target is selected: a resource, a field, a map entry, a list, and a field of a task, job cluster, job parameter or pipeline cluster matched by its key. A null that has nothing to remove adds nothing, without a warning; an empty targets.<name> or variables.<name> still declares the target or variable. Nulls do not survive the typed round trip between mutators, so the nulls of the target sections are kept on the side until the target is merged. Co-authored-by: Isaac <no-reply@databricks.com>
… change Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: Isaac <no-reply@databricks.com>
|
Commit: Regression test reportSelected 14 changed tests (limit=20, 0 not selected) 28 tests: regression=28 unreleased=0 coverage=0 failing=0
TestAccept/bundle/deploy/mlops-stacks/DMS=: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌main (e9e2d63): latest (v1.23.0): same output as main (e9e2d63) TestAccept/bundle/deploy/mlops-stacks/DMS=true: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌main (e9e2d63): latest (v1.23.0): same output as main (e9e2d63) TestAccept/bundle/run_as/empty_override/DMS=: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌main (e9e2d63): latest (v1.23.0): same output as main (e9e2d63) TestAccept/bundle/run_as/empty_override/DMS=true: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌main (e9e2d63): latest (v1.23.0): TestAccept/bundle/validate/empty_tasks/DMS=: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌main (e9e2d63): latest (v1.23.0): same output as main (e9e2d63) TestAccept/bundle/validate/empty_tasks/DMS=true: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌main (e9e2d63): latest (v1.23.0): same output as main (e9e2d63) TestAccept/bundle/validate/nulls/include_removes/DMS=: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌main (e9e2d63): latest (v1.23.0): same output as main (e9e2d63) TestAccept/bundle/validate/nulls/include_removes/DMS=true: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌main (e9e2d63): latest (v1.23.0): TestAccept/bundle/validate/nulls/include_target_overrides/DMS=: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌main (e9e2d63): latest (v1.23.0): same output as main (e9e2d63) TestAccept/bundle/validate/nulls/include_target_overrides/DMS=true: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌main (e9e2d63): latest (v1.23.0): same output as main (e9e2d63) TestAccept/bundle/validate/nulls/resources_container/DMS=: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌main (e9e2d63): latest (v1.23.0): same output as main (e9e2d63) TestAccept/bundle/validate/nulls/resources_container/DMS=true: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌main (e9e2d63): latest (v1.23.0): same output as main (e9e2d63) TestAccept/bundle/validate/nulls/root_without_base/DMS=: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌main (e9e2d63): latest (v1.23.0): same output as main (e9e2d63) TestAccept/bundle/validate/nulls/root_without_base/DMS=true: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌main (e9e2d63): latest (v1.23.0): same output as main (e9e2d63) TestAccept/bundle/validate/nulls/schedule_default_materialization/DMS=: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌main (e9e2d63): latest (v1.23.0): same output as main (e9e2d63) TestAccept/bundle/validate/nulls/schedule_default_materialization/DMS=true: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌main (e9e2d63): latest (v1.23.0): same output as main (e9e2d63) TestAccept/bundle/validate/nulls/target_keyed_slices/DMS=: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌main (e9e2d63): latest (v1.23.0): same output as main (e9e2d63) TestAccept/bundle/validate/nulls/target_keyed_slices/DMS=true: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌main (e9e2d63): latest (v1.23.0): same output as main (e9e2d63) TestAccept/bundle/validate/nulls/target_removes_job_fields/DMS=: branch ✅ | main (e9e2d63) ❌ | latest (v1.23.0) ❌main (e9e2d63): latest (v1.23.0): same output as main (e9e2d63) 9 more failure details omitted, see the full report in the run. |
Integration test reportCommit: b7e451e
Top 6 slowest tests (at least 2 minutes):
|
An empty resources.<type>.<name>, artifacts.<name> or scripts.<name> in a file is kept as a declaration, like an empty target or variable, so that it is still reported as undefined or not configured. Target nulls are applied with MergeRemovingNulls instead of dropping all nulls at the end, which removed those declarations too. Keyed sequences with nulls are merged by key with the root before the fields are merged. Co-authored-by: Isaac <no-reply@databricks.com>
Changes
A null now removes the value it overrides; previously every such null was ignored (recorded in #7260, which this is stacked on).
targets.<t>.<...>: nullremoves the value from the configuration when the target is selected: a resource (resources.jobs.foo: nullleavesfooout of that target), a field, a block, a map entry (tags.x), a list, and the top-level fields a target replaces (mode,cluster_id,run_as, variabledefault/lookup).job_clusters, job parameters and pipeline clusters, a null field of an element removes that field from the element with the same key, e.g.- task_key: t1withmax_retries: null.databricks.ymland earlier includes, including a whole resource or section. Target overrides split across includes compose in file order: a later null beats an earlier value and a later value beats an earlier null.expected a ... value, found nullwarning. This also holds for nulls indatabricks.ymloutside targets, so an emptyrun_as:no longer errors, andresources: null/schedule: nullare fine. An empty named entry (targets.<name>:,variables.<name>:,resources.<type>.<name>:,artifacts.<name>:,scripts.<name>:) in a file still declares the entry, so empty targets and variables keep working and empty resources, artifacts and scripts are still reported.Nulls don't survive the typed round trip that runs around every mutator, and a null scalar doesn't convert to the typed config at all. So
Rootkeeps the target sections with their nulls on the side (withNulls) and puts them back into the target when it is merged. A keyed list that holds nulls is merged by key with the root's list at that point, becauseMergeJobTasksand friends run later, when the nulls are gone. New inlibs/dyn:merge.MergeKeepingNulls,merge.MergeRemovingNulls,merge.ElementsByKeyKeepingNulls,dyn.DropNullsand theconvert.KeepNullsnormalize option.Why
To leave a resource out of one target, or undo a field set at the base level, without restructuring the configuration.
Tests
The tests from #7260 now show the removals. Existing goldens that change:
run_as/empty_override(an emptyrun_as:in a target now removesrun_as),validate/empty_tasksandvalidate/required(a nulltasks/run_job_taskis dropped), andvalidate/presets_name_prefix_devanddeploy/mlops-stacks(no null warning). Unit tests for the new merge modes andDropNulls.This pull request and its description were written by Isaac.