Skip to content

Distinguish "not supported" from "not deployed" in bundle summary - #6583

Merged
janniklasrose merged 27 commits into
mainfrom
janniklasrose/summary-url-not-supported
Sep 9, 2026
Merged

janniklasrose merged 27 commits into
mainfrom
janniklasrose/summary-url-not-supported

Conversation

@janniklasrose

@janniklasrose janniklasrose commented Sep 9, 2026

Copy link
Copy Markdown
Member

resource.GetURL() == "" did not distinguish between "not deployed yet" and "resource does not support URLs".

Add a boolean return value to the method to allow callers (bundle summary, bundle open, pipelines open pipelines deploy) to adjust the messaging.

janniklasrose and others added 22 commits August 31, 2026 11:57
## Changes

Bump `github.com/databricks/databricks-sdk-go` from v0.175.0 to v0.177.0
and the pinned OpenAPI spec SHA to `0f2c9a3d`.

Regenerated all downstream artifacts from the new spec: CLI command stubs,
bundle JSON schema, validation, direct-engine resources, pydabs models, and
the DABs<->TF field map. User-visible additions include the jobs continuous
`maintenance_window` field and the pipelines RabbitMQ connector options; the
postgres branch `source_snapshot` field is now handled as immutable/input-only
by the direct engine.

The v0.177.0 `ml.*` field removals (feature-engineering) are not referenced by
hand-written CLI code, so they required no source changes. The SDK now marks
the pipelines `continuous` field deprecated; it remains a supported bundle
config field, so its four usages carry `//nolint:staticcheck` (SA1019).

## Why

Keep the CLI current with the latest SDK and provide a clean base for
upcoming feature work.

## Tests

Acceptance goldens regenerated via `-update` (help text + refschema). The
non-update verify pass is green apart from load-induced terraform-engine
timeout flakes, each confirmed passing in isolation. Root-module unit suite
passes (9532 tests). `./task fmt`, `./task lint`, and `./task checks` clean.

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

Add the `postgres_snapshot_schedules` bundle resource, which manages the
automatic-snapshot schedule of a Lakebase Postgres branch.

The snapshot schedule is a per-branch singleton with no create or delete API —
only `GetSnapshotSchedule` and `UpdateSnapshotSchedule`. The resource maps the
lifecycle onto that single write call:

- create/update set the branch's schedule via `UpdateSnapshotSchedule`
  (update_mask `schedule`, awaiting the long-running operation);
- delete disables automatic snapshots by setting an empty cadence set, since
  DoDelete also fires when the resource is removed from config, not only on
  `bundle destroy`;
- `branch` composes the schedule's hierarchical name and is a provided id field
  (a change recreates).

Modeled on the existing `postgres_*` resources. Direct engine only: the schedule
was added in databricks-sdk-go v0.177.0 and the pinned Terraform provider has no
equivalent resource yet, so the acceptance and bind tests are pinned to the
direct engine.

## Tests

- direct-engine unit CRUD (`bundle/direct/dresources`);
- acceptance (direct engine), four end-to-end scenarios, each reading the
  schedule back with `postgres get-snapshot-schedule`:
  - `basic`: create with a cadence, in-place cadence update, then remove the
    resource from config, which disables the schedule (reads back
    `schedule: null`);
  - `update`: add the schedule to an already-deployed branch, then remove it;
  - `out-of-band`: an out-of-band `update-snapshot-schedule` is detected as
    drift by `bundle plan` (`update postgres_snapshot_schedules.main_schedule`)
    and reconciled back by deploy;
  - `orphaned`: removing the branch from config while keeping the schedule that
    references it — the reference still resolves from the deployed state, so
    validate passes and plan sequences a branch delete alongside a schedule
    recreate (documented, not a validation error);
- the invariant and bind/unbind suites;
- resource-enumeration unit tests (bind support, run_as, permissions,
  target-mode) extended for the new type.

Acceptance goldens regenerated via `-update`; the verify pass is green apart
from pre-existing load-induced terraform-engine timeout flakes, each confirmed
passing in isolation.

Co-authored-by: Isaac <no-reply@databricks.com>
Drop the `update` subtest (create/update/remove is already covered by
`basic`) and the `orphaned` subtest (deleting a branch while keeping a
schedule that references it is user error — it plans but fails at apply,
which we don't need to pin in a golden).

Co-authored-by: Isaac <no-reply@databricks.com>
DoCreate built the schedule resource name as `config.Branch + "/snapshot-schedule"`,
which doubles the separator if a user writes `branch:` with a trailing slash.
Route it through snapshotScheduleName, which trims trailing slashes first, and
cover it with a unit test.

Co-authored-by: Isaac <no-reply@databricks.com>
Add a `bundle plan` after the removal step in the basic acceptance test; it
reports "0 to add, 0 to change, 0 to delete" (project and branch unchanged),
confirming the disable settled cleanly and leaves no lingering drift.

Co-authored-by: Isaac <no-reply@databricks.com>
…s-snapshot-schedules

# Conflicts:
#	.nextchanges/dependency-updates/bump-sdk-0.177.0.md
#	bundle/terraform_dabs_map/generated.go
#	go.mod
Completes wiring for the postgres_snapshot_schedules resource so it
satisfies the repo-wide "for all resources" guard tests:

- Add MarshalJSON/UnmarshalJSON to resources.PostgresSnapshotSchedule so
  the outer wrapper's id/url/lifecycle/modified_status survive a JSON
  round-trip instead of being dropped by the embedded config marshaler
  (mirrors resources.PostgresBranch).
- Pin the resource to Beta via launchStageOverrides and cover it in the
  launch-stage override test.
- Populate PostgresSnapshotSchedules in the StateToBundle fixtures.
- Mark it direct-engine only in the Terraform lifecycle test; the pinned
  provider has no resource that maps to a snapshot schedule.

Regenerate the resource's out.test.toml snapshots to pick up the DMS
EnvMatrix inherited from a parent test.toml.

Co-authored-by: Isaac <no-reply@databricks.com>
Add the required bullet marker and trailing PR link so the fragment
passes check-changelog.

Co-authored-by: Isaac <no-reply@databricks.com>
The snapshot schedule has no web UI page of its own. Per agreement with
the Postgres team, point its URL at the parent branch's restore view:
lakebase/projects/{project_id}/branches/{branch_id}/restore, resolved
from the resource's branch. Covered in TestInitializeURLs and reflected
in the bind acceptance golden.

Co-authored-by: Isaac <no-reply@databricks.com>
Register a postgres_snapshot_schedules pattern (lakebase/%s/restore, %s =
parent branch) and use workspaceurls.ResourceURL in InitializeURL instead
of hand-assembling the path, matching every other resource.

Co-authored-by: Isaac <no-reply@databricks.com>
Adding postgres_snapshot_schedules to workspaceurls broke tests that
assert the exact ResourceTypes() list (cmd/experimental open command and
its acceptance golden); update them.

Also derive the branch from the schedule's resolved ID rather than the
Branch field, which may hold an unresolved "${...}" reference at summary
time. This matches the other parent-referencing postgres resources and
correctly shows "(not deployed)" until the schedule has an ID.

Co-authored-by: Isaac <no-reply@databricks.com>
It now has a workspace URL, so TestBundleResourcePluralNamesResolveInWorkspaceURLs
requires it to resolve rather than be empty.

Co-authored-by: Isaac <no-reply@databricks.com>
Main's new TestMarshalerValueReceiver requires marshalling by value and by
pointer to agree; match the sibling postgres configs.

Co-authored-by: Isaac <no-reply@databricks.com>
The Lakebase web UI addresses resources by uid, not by the resource name
in bundle state, so the name-based URL was wrong. Revert to no URL (back
in the noURL allowlist) until a uid-based scheme is designed.

Co-authored-by: Isaac <no-reply@databricks.com>
The backend rejects a snapshot schedule on any non-root branch ("not
allowed to snapshot non-root branch"), which surfaced only on cloud. Teach
the testserver the same rule, and point the acceptance and CRUD fixtures at
the project's implicit root "production" branch instead of a child branch.

Co-authored-by: Isaac <no-reply@databricks.com>
The schedule's resource name is its ID ("{branch}/snapshot-schedule");
return it from GetName so bundle summary shows it instead of a blank,
matching the SecretScope precedent (per review feedback).

Co-authored-by: Isaac <no-reply@databricks.com>
…s-snapshot-schedules

# Conflicts:
#	bundle/config/resources.go
#	bundle/config/resources_test.go
#	bundle/direct/dresources/all_test.go
The Python codegen had no mapping for duration.Duration (the schedule's
retention type), failing pydabs-codegen with a KeyError. Treat it as a
str-serialized primitive, matching time.Time (PRIMITIVES + RENAMES + the
test-case synthesizer), and regenerate the PyDABs module. Add the required
acceptance/bundle/python support fixture and refresh the core public-API
snapshot.

Co-authored-by: Isaac <no-reply@databricks.com>
Resource types that never expose a workspace URL (the postgres_* resources, secret scopes, external locations, snapshots) rendered "URL:  (not deployed)" in `bundle summary` even after a successful deploy, which was misleading.

Add a type-level SupportsURL() to the ConfigResource interface (default true on BaseResource, overridden to false on the no-URL types) and render "(not supported)" for those, while keeping "(not deployed)" for URL-capable resources that are not deployed yet.

Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: Isaac <no-reply@databricks.com>
Base automatically changed from janniklasrose/postgres-snapshot-schedules to main September 9, 2026 07:53
…-url-not-supported

# Conflicts:
#	acceptance/bundle/deployment/bind/postgres_snapshot_schedule/output.txt
#	bundle/config/resources/postgres_snapshot_schedule.go
@eng-dev-ecosystem-bot

eng-dev-ecosystem-bot commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: 47c0de4

Run: 34414350173

Env 💚​RECOVERED ✅​pass 🙈​skip Time
💚​ aws linux 1 303 18 10:50
💚​ aws windows 1 305 16 9:34
💚​ azure linux 1 274 25 5:52
💚​ azure windows 1 276 23 4:00
💚​ gcp linux 1 275 25 5:17
💚​ gcp windows 1 277 23 4:01
Test Name aws linux aws windows azure linux azure windows gcp linux gcp windows
💚​ TestAccept 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R
Top 6 slowest tests (at least 2 minutes):
duration env testname
3:59 gcp windows TestAccept
3:58 azure windows TestAccept
3:56 aws windows TestAccept
2:19 gcp linux TestAccept
2:11 aws linux TestAccept
2:09 azure linux TestAccept

bundle open and pipelines open told the user a no-URL resource might just need deploying ("has it been deployed?"), and pipelines deploy printed "View your <resource> here:" with a blank URL for such resources. Guard all three on SupportsURL() so the message is honest and the blank line is skipped.

Co-authored-by: Isaac <no-reply@databricks.com>
Comment thread bundle/config/resources.go Outdated
Comment on lines +69 to +72
// SupportsURL reports whether this resource type can have a workspace URL.
// It distinguishes an empty GetURL() that means "not deployed yet" from one
// that means the type never has a URL.
SupportsURL() bool

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alternative: GetURL() (string, bool)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

slight preference for this, no chance of two methods going out of sync.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep, already refactored :-) also makes it clear for the caller of GetURL

database1:
Name:
URL: (not deployed)
URL: (not supported)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be read a bit like resource is not supported (e.g. engine limitation), not that URL is not supported.

Maybe it should be "(unknown)" or "(not available)".

Actually, why show "URL:" row at all for such cases? Cannot we just omit it?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think any string has the potential to be misunderstood. +1 to skip the line for resources that don't support it

return ""
}

func (b *PostgresSnapshotSchedule) SupportsURL() bool {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is GetURL() returning "" not enough?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetURL() == "" currently means either not supported (InitializeURL is no-op) or not deployed yet (InitializeURL guarded on e.g. r.ID being empty)

Address review: rather than a separate SupportsURL() method, GetURL now returns (url, supported), following the (value, ok) idiom (cf. context.Context.Deadline). The default lives on BaseResource like GetLifecycle, so the 27 trivial 'return X.URL' overrides are dropped and only the 9 no-URL types override to return ("", false).

Also consolidate the changelog into a single generic entry covering all affected commands.

Co-authored-by: Isaac <no-reply@databricks.com>
Per review: instead of printing a placeholder like "(not supported)" (which reads ambiguously), the summary template now skips the URL line entirely when GetURL reports the type has no URL. URL-capable resources are unchanged, including the "(not deployed)" case.

Co-authored-by: Isaac <no-reply@databricks.com>
@@ -18,15 +18,12 @@ Resources:
Postgres branches:
main:
Name:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

out of scope for this PR, but related theme: why do we show Name: without a value there? Is it because there is no Name or it not known yet?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Taking a look as follow-up

@denik

denik commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

description is out of date and overly verbose

@janniklasrose
janniklasrose marked this pull request as ready for review September 9, 2026 12:37
@janniklasrose
janniklasrose added this pull request to the merge queue Sep 9, 2026
Merged via the queue into main with commit 162cc17 Sep 9, 2026
35 checks passed
@janniklasrose
janniklasrose deleted the janniklasrose/summary-url-not-supported branch September 9, 2026 23:35
@eng-dev-ecosystem-bot

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: 162cc17

Run: 34417615193

Env ❌​FAIL 🟨​KNOWN 🔄​flaky 💚​RECOVERED 🙈​SKIP ✅​pass 🙈​skip Time
❌​ aws linux 4 1 1 1590 1029 198:09
❌​ aws windows 4 1 2 1 1494 1052 215:02
🔄​ azure linux 3 1 1405 1078 138:20
💚​ azure windows 1 1 1313 1101 151:14
💚​ gcp linux 1 1 1393 1082 149:57
🔄​ gcp windows 3 1 1297 1105 169:28
12 interesting tests: 6 flaky, 4 FAIL, 1 KNOWN, 1 SKIP
Test Name aws linux aws windows azure linux azure windows gcp linux gcp windows
🟨​ TestAccept 🟨​K 🟨​K 🔄​f 💚​R 💚​R 🔄​f
🔄​ TestAccept/bundle/invariant/delete_idempotent ✅​p ✅​p ✅​p ✅​p ✅​p 🔄​f
🔄​ TestAccept/bundle/invariant/delete_idempotent/DATABRICKS_BUNDLE_ENGINE=direct/DMS=/INPUT_CONFIG=vector_search_endpoint.yml.tmpl/READPLAN=1 ✅​p ✅​p ✅​p ✅​p ✅​p 🔄​f
🔄​ TestAccept/bundle/resources/dashboards/change-serialized-dashboard ✅​p ✅​p 🔄​f ✅​p ✅​p ✅​p
🔄​ TestAccept/bundle/resources/dashboards/change-serialized-dashboard/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/READPLAN= ✅​p ✅​p 🔄​f ✅​p ✅​p ✅​p
❌​ TestAccept/bundle/resources/postgres_snapshot_schedules/basic ❌​F ❌​F 🙈​s 🙈​s 🙈​s 🙈​s
❌​ TestAccept/bundle/resources/postgres_snapshot_schedules/basic/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ❌​F
❌​ TestAccept/bundle/resources/postgres_snapshot_schedules/out-of-band ❌​F ❌​F 🙈​s 🙈​s 🙈​s 🙈​s
❌​ TestAccept/bundle/resources/postgres_snapshot_schedules/out-of-band/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ❌​F ❌​F
🔄​ TestAccept/bundle/resources/vector_search_endpoints/drift/recreated_same_name ✅​p 🔄​f ✅​p ✅​p ✅​p ✅​p
🔄​ TestAccept/bundle/resources/vector_search_endpoints/drift/recreated_same_name/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true ✅​p 🔄​f ✅​p ✅​p ✅​p ✅​p
🙈​ TestAccept/ssh/connection 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
Top 50 slowest tests (at least 2 minutes):
duration env testname
14:38 aws windows TestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
13:20 gcp linux TestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
13:16 gcp windows TestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
13:15 aws linux TestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
13:04 gcp linux TestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
12:46 gcp windows TestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
12:44 aws linux TestAccept/bundle/invariant/delete_idempotent/DATABRICKS_BUNDLE_ENGINE=direct/DMS=/INPUT_CONFIG=cluster_apply_policy_default_values.yml.tmpl/READPLAN=
12:16 aws linux TestAccept/bundle/resources/clusters/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
12:05 gcp linux TestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
11:38 aws linux TestAccept/bundle/resources/clusters/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
11:36 aws linux TestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
11:10 aws linux TestAccept/bundle/invariant/delete_idempotent/DATABRICKS_BUNDLE_ENGINE=direct/DMS=/INPUT_CONFIG=cluster_apply_policy_default_values.yml.tmpl/READPLAN=1
11:00 gcp windows TestAccept/bundle/resources/clusters/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
10:48 aws linux TestAccept/bundle/invariant/delete_idempotent/DATABRICKS_BUNDLE_ENGINE=direct/DMS=/INPUT_CONFIG=cluster.yml.tmpl/READPLAN=1
10:47 aws linux TestAccept/bundle/deploy/spark-jar-task/DATABRICKS_BUNDLE_ENGINE=terraform/DMS=
10:41 aws windows TestAccept/bundle/resources/clusters/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
10:39 aws linux TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=/INPUT_CONFIG=cluster_apply_policy_default_values.yml.tmpl/READPLAN=1
9:38 aws windows TestAccept/bundle/invariant/destroy_idempotent/DATABRICKS_BUNDLE_ENGINE=direct/DMS=/INPUT_CONFIG=cluster_apply_policy_default_values.yml.tmpl/READPLAN=
9:19 aws linux TestAccept/bundle/invariant/destroy_idempotent/DATABRICKS_BUNDLE_ENGINE=direct/DMS=/INPUT_CONFIG=cluster.yml.tmpl/READPLAN=1
9:17 aws linux TestAccept/bundle/invariant/destroy_idempotent/DATABRICKS_BUNDLE_ENGINE=direct/DMS=/INPUT_CONFIG=cluster_apply_policy_default_values.yml.tmpl/READPLAN=
9:07 aws windows TestAccept/bundle/invariant/delete_idempotent/DATABRICKS_BUNDLE_ENGINE=direct/DMS=/INPUT_CONFIG=cluster_apply_policy_default_values.yml.tmpl/READPLAN=
8:39 gcp windows TestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
8:27 aws windows TestAccept/bundle/invariant/destroy_idempotent/DATABRICKS_BUNDLE_ENGINE=direct/DMS=/INPUT_CONFIG=cluster_apply_policy_default_values.yml.tmpl/READPLAN=1
8:03 aws linux TestAccept/bundle/resources/clusters/resize-terminated-fallback/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
7:46 aws linux TestAccept/bundle/resources/clusters/deploy/simple/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
7:46 gcp windows TestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
7:46 aws windows TestAccept/bundle/deploy/spark-jar-task/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
7:44 aws linux TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=cluster.yml.tmpl/READPLAN=1
7:40 aws linux TestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
7:40 gcp linux TestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
7:33 aws windows TestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
7:28 aws windows TestAccept/bundle/resources/clusters/resize-terminated-fallback/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
7:25 aws windows TestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
7:25 gcp linux TestAccept/bundle/resources/clusters/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
7:23 aws windows TestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
7:18 aws linux TestAccept/bundle/invariant/destroy_idempotent/DATABRICKS_BUNDLE_ENGINE=direct/DMS=/INPUT_CONFIG=cluster.yml.tmpl/READPLAN=
7:16 aws linux TestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
7:13 aws linux TestAccept/bundle/invariant/destroy_idempotent/DATABRICKS_BUNDLE_ENGINE=direct/DMS=/INPUT_CONFIG=cluster_apply_policy_default_values.yml.tmpl/READPLAN=1
7:13 aws linux TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=terraform/DMS=
7:06 gcp linux TestAccept/bundle/resources/clusters/deploy/local_ssd_count/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
7:06 aws windows TestAccept/bundle/invariant/destroy_idempotent/DATABRICKS_BUNDLE_ENGINE=direct/DMS=/INPUT_CONFIG=cluster.yml.tmpl/READPLAN=
7:05 azure linux TestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
7:04 aws linux TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=cluster_apply_policy_default_values.yml.tmpl/READPLAN=1
7:01 aws linux TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true/INPUT_CONFIG=cluster.yml.tmpl/READPLAN=
6:54 azure linux TestAccept/bundle/config-remote-sync/multiple_resources/DATABRICKS_BUNDLE_ENGINE=terraform/DMS=
6:54 azure linux TestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
6:53 gcp windows TestAccept/bundle/resources/clusters/deploy/local_ssd_count/DATABRICKS_BUNDLE_ENGINE=direct/DMS=
6:52 azure windows TestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
6:51 gcp linux TestAccept/bundle/config-remote-sync/multiple_resources/DATABRICKS_BUNDLE_ENGINE=direct/DMS=true
6:51 azure windows TestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct/DMS=

janniklasrose added a commit that referenced this pull request Sep 15, 2026
)

`resource.GetURL() == ""` did not distinguish between "not deployed yet"
and "resource does not support URLs".

Add a boolean return value to the method to allow callers (`bundle
summary`, `bundle open`, `pipelines open` `pipelines deploy`) to adjust
the messaging.

---------

Co-authored-by: Isaac <no-reply@databricks.com>
deco-sdk-tagging Bot added a commit that referenced this pull request Sep 16, 2026
## Release v1.17.0

### Notable Changes

 * Bump the direct deployment state version to 3. Clients older than v1.8.0 will reject bundles deployed with this release. ([#6713](#6713))

### CLI

 * Add an `INVALID_REFRESH_TOKEN` error code to `databricks auth token --output json` failures. ([#6684](#6684))
 * Add experimental `databricks auth docker configure` to configure Docker credential helper access for Databricks Artifact Registry. ([#6700](#6700))
 * Add experimental `databricks auth docker token` to generate Docker credentials for Databricks Artifact Registry. ([#6699](#6699))
 * `databricks environments setup-local` now reports the `E_PROVISION_CONFLICT` error code instead of the generic `E_PROVISION` when `uv sync` fails to resolve a dependency conflict. ([#6666](#6666))
 * Preserve SSH sessions across temporary tunnel disconnects, with bounded replay and backpressure for large transfers. ([#6650](#6650))
 * Allow OAuth U2M logins to override the CLI client ID with `--client-id`, profile `client_id`, or `DATABRICKS_CLIENT_ID`. ([#6594](#6594))

### Bundles

 * direct: Store a dashboard's `serialized_dashboard` in state as a content hash instead of its full contents. ([#6105](#6105))
 * direct: Fix pipelines recreation when the whole `ingestion_definition` block is added or removed. ([#6589](#6589))
 * `bundle plan`, `deploy`, and `destroy` no longer report removing `permissions`, `grants`, or secret scope ACLs from a bundle as a deletion, since it leaves the resource untouched. ([#6647](#6647))
 * `bundle plan` and `deploy` no longer list or count a resource that was already deleted remotely as a deletion, matching `bundle destroy`; applying still cleans up its stale state entry. ([#6675](#6675))
 * Fix `bundle run` failing with `expected an int, found a string` when an unrelated resource references another resource that is not deployed. `bundle run` now resolves `${resources.*}` references only within the resource being run. ([#6690](#6690))
 * Add grants support for the AI Gateway `model_service`, `mcp_service`, and `model_provider_service` resources (direct engine). ([#6635](#6635))
 * Add bundle support for the AI Gateway `mcp_service` resource (direct engine). ([#6633](#6633))
 * Add bundle support for the AI Gateway `model_provider_service` resource (direct engine). ([#6634](#6634))
 * Add bundle support for the AI Gateway `model_service` resource (direct engine). ([#6525](#6525))
 * Prevent resource drift on catalogs if `storage_root` contained a trailing slash in the URL. ([#6622](#6622))
 * Fixed a "lineage mismatch in state files" error that could occur after destroying a bundle and redeploying it from another machine. `bundle destroy` now removes the local state file so no stale lineage is left behind, and prunes the state directories it leaves empty (such as `.internal/` and `sync-snapshots/`). ([#6210](#6210), [#6685](#6685))
 * direct: `bundle plan` no longer reports a permanent update on a cluster that uses a cluster policy: when the cluster spec sets `policy_id`, a field present in the remote but absent from the bundle config is not treated as drift. ([#6531](#6531))
 * `bundle deploy` on the direct engine now reports each resource as soon as it is deployed, instead of listing them all after the deployment finishes. A deploy that fails part way through now reports the resources it did apply. ([#6361](#6361))
 * Direct-engine bundles no longer flag phantom drift on server-populated nested fields under reused config types (e.g. `external_locations` file-event-queue resource IDs, `database_instances` parent-instance refs, `apps` git credential ID). ([#6618](#6618))
 * `databricks bundle generate app` now reproduces a git-backed app's `git_repository` and `git_source` configuration instead of emitting a workspace `source_code_path`, so generating from a Git-deployed app no longer silently converts it to workspace source. ([#6656](#6656))
 * Improved configuration load time for bundles with many included files. ([#6195](#6195))
 * `bundle destroy` no longer deletes triggered job runs, leaving them untouched on the backend. ([#6672](#6672))
 * direct: resources.job\_runs: new lifecycle.triggers.on\_file\_change setting to restart the run when monitored files change. Can be set to a series of paths or globs. ([#6309](#6309))
 * Bundle summary now shows a name for Postgres branches, endpoints, databases, and roles instead of a blank Name field. ([#6663](#6663))
 * Added PyDABs (Python) support for cluster policies, dashboards, and Genie spaces. ([#6585](#6585))
 * CLI commands no longer imply that a resource whose type has no workspace URL is merely not deployed yet. ([#6583](#6583))
 * Capture the implicit dependency a vector search index has on a catalog or schema defined in the same bundle, so the catalog and schema are deployed first. ([#6655](#6655))

### Dependency Updates

 * Bump dependencies with known vulnerabilities. ([#6695](#6695))
 * Bump `github.com/databricks/databricks-sdk-go` from v0.177.0 to v0.178.0. ([#6673](#6673))
 * Bump Terraform provider from v1.131.0 to v1.132.0. ([#6671](#6671))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants