Honor --key in bundle generate dashboard and make lookup flags mutually exclusive#5492
Conversation
The dashboard generator always derived the resource key from the display name even though --key is documented in its help text and honored by the other generate commands. Also enforce that only one of --existing-path, --existing-id, and --resource is provided instead of silently preferring one over the others. Co-authored-by: Isaac
Integration test reportCommit: 0b839b4
23 interesting tests: 13 SKIP, 7 KNOWN, 3 RECOVERED
Top 4 slowest tests (at least 2 minutes):
|
Co-authored-by: Isaac
| cmd.MarkFlagsMutuallyExclusive( | ||
| "existing-path", | ||
| "existing-id", | ||
| "resource", | ||
| ) |
There was a problem hiding this comment.
What would happen before this? Based on a quick view it seems that previously there was some precedence between flags where some would get ignored. Not good.
However, now we'll throw an error. Is this a breaking changes? What if people are using multiple flags somewhere and it just works for them?
There was a problem hiding this comment.
Good question. Before this change the three lookup flags weren't validated together, so combining them silently applied a precedence: --resource beat --existing-path beat --existing-id. If you passed more than one, the lower-precedence flags were just ignored and you got output based on a flag you may not have intended, with no signal that part of your invocation was dropped.
So yes, it's technically a behavior change: an invocation that passed multiple lookup flags and "worked" before will now error. But it only ever "worked" by silently ignoring input, so any such invocation was already producing a result the user didn't fully specify. A couple of things keep the risk low:
- The error fires at flag-parse time, before any API call or file write, and cobra names the conflicting flags, so the fix is obvious (drop the extra flag).
- Exactly-one-required was already the documented contract here (the existing
MarkFlagsOneRequiredand the comment above it), this just enforces the other half of it. - It matches how the sibling generate commands treat their flags, and the repo's own CLI UX guidance: reject incompatible inputs early with an actionable error rather than silently ignoring a flag.
I'll add a NEXT_CHANGELOG.md entry noting the behavior change so it shows up in the release notes.
## Release v1.6.0 ### CLI * `ssh connect` now accepts a `--base-environment` flag to run a serverless session on a custom base environment. It takes an `env.yaml` path, a `workspace-base-environments/...` resource ID, or a base environment display name, and is rejected together with `--environment-version` or `--cluster` ([#5706](#5706)). * `databricks aitools install` is now plugin-first: it installs the Databricks plugin through each agent's own CLI (Claude Code, Codex, GitHub Copilot) instead of copying raw skill files. Agents without a plugin (OpenCode, Antigravity) still get skill files, and Cursor prints the `/add-plugin databricks` step. Use `--skills-only` to force raw skill files for every agent, or `--path <dir>` to write skills to a directory ([#5738](#5738)). * `databricks labs list` now only shows projects that can be installed ([#5560](#5560)). ### Bundles * direct: Fixed persistent drift on `model_serving_endpoints` caused by the `traffic_config` field ([#5708](#5708)). * direct: Fix spurious update when `apply_policy_default_values: true` is set on job task, for-each-task, or job cluster new_cluster ([#5731](#5731)). Also fix spurious updates for for-each-task clusters due to missing backend defaults for `data_security_mode`, `node_type_id`, `driver_node_type_id`, `driver_instance_pool_id`, `enable_elastic_disk`, and `enable_local_disk_encryption`. * direct: Cluster resize now falls back to regular update if resize fails due to `INVALID_STATE` ([#5716](#5716)). * `bundle generate dashboard` now honors the `--key` flag when naming the generated resource, and rejects combining `--existing-path`, `--existing-id`, and `--resource` instead of silently ignoring all but one ([#5492](#5492)). * Fixed `bundle deployment migrate` failing on `model_serving_endpoints`/`database_instances` with permissions (regression since v1.5.0) ([#5775](#5775)). * After a terraform deploy, the CLI now dry-runs a migration to the direct engine (writing nothing locally or remotely) and reports the outcome via telemetry, warning if the migration could not be completed ([#5797](#5797)). ### Dependency updates * Bump `github.com/databricks/databricks-sdk-go` from v0.147.0 to v0.152.0 ([#5773](#5773)). * Bump Terraform provider from v1.118.0 to v1.120.0 ([#5792](#5792)).
Why
Found during a full-repo review of the CLI.
bundle generate dashboardsilently ignored the--keyflag, even though its own help text documents it and every other generate command (job, pipeline, alert) honors it. In addition, the three lookup flags (--existing-path,--existing-id,--resource) could be combined freely, with one silently shadowing the others, so users got no signal that part of their invocation was ignored.Changes
Before, the dashboard resource key was always derived from the dashboard's display name and conflicting lookup flags were silently accepted; now
--keytakes precedence over the derived key and passing more than one lookup flag fails with a validation error.cmd/bundle/generate/dashboard.go: readcmd.Flag("key")and fall back to the normalized display name when it is empty, matching the pattern used byjob.go. Thekeyflag is a persistent flag on the parentgeneratecommand.cmd/bundle/generate/dashboard.go: mark--existing-path,--existing-id, and--resourceas mutually exclusive. Combined with the existingMarkFlagsOneRequired, exactly one lookup flag is now required, which is what the existing comment already promised.Test plan
TestDashboard_LookupFlagsAreMutuallyExclusivecovering all three conflicting flag pairs (go test ./cmd/bundle/generate/)acceptance/bundle/generate/dashboard_existing_path_nominalacceptance test with a--key custom_keyinvocation; verified the generated config uses the custom key (go test ./acceptance -run TestAccept/bundle/generate/dashboard_existing_path_nominal, both engine variants pass)./task fmt-q,./task lint-q, and./task checkspassThis pull request and its description were written by Isaac.