From 9fc49eef14bb1f3d81c485f2aaf5f1297666ba8c Mon Sep 17 00:00:00 2001 From: simonfaltum Date: Tue, 9 Jun 2026 21:57:10 +0200 Subject: [PATCH 1/4] Fix sync --dry-run mutating the remote workspace A dry-run sync against a missing remote path created the directory, and applyPut opened local files before checking DryRun, so a file vanishing mid-run failed the preview. Skip the mkdir and the local open in dry-run mode. Co-authored-by: Isaac --- .../cmd/sync-dryrun-missing-remote/hello.py | 1 + .../sync-dryrun-missing-remote/out.test.toml | 3 ++ .../cmd/sync-dryrun-missing-remote/output.txt | 38 +++++++++++++++++++ .../cmd/sync-dryrun-missing-remote/script | 27 +++++++++++++ .../cmd/sync-dryrun-missing-remote/test.toml | 1 + integration/cmd/sync/sync_test.go | 10 ++--- libs/sync/path.go | 10 ++++- libs/sync/sync.go | 2 +- libs/sync/watchdog.go | 12 +++--- libs/sync/watchdog_test.go | 23 +++++++++++ 10 files changed, 114 insertions(+), 13 deletions(-) create mode 100644 acceptance/cmd/sync-dryrun-missing-remote/hello.py create mode 100644 acceptance/cmd/sync-dryrun-missing-remote/out.test.toml create mode 100644 acceptance/cmd/sync-dryrun-missing-remote/output.txt create mode 100644 acceptance/cmd/sync-dryrun-missing-remote/script create mode 100644 acceptance/cmd/sync-dryrun-missing-remote/test.toml create mode 100644 libs/sync/watchdog_test.go diff --git a/acceptance/cmd/sync-dryrun-missing-remote/hello.py b/acceptance/cmd/sync-dryrun-missing-remote/hello.py new file mode 100644 index 00000000000..11b15b1a458 --- /dev/null +++ b/acceptance/cmd/sync-dryrun-missing-remote/hello.py @@ -0,0 +1 @@ +print("hello") diff --git a/acceptance/cmd/sync-dryrun-missing-remote/out.test.toml b/acceptance/cmd/sync-dryrun-missing-remote/out.test.toml new file mode 100644 index 00000000000..f784a183258 --- /dev/null +++ b/acceptance/cmd/sync-dryrun-missing-remote/out.test.toml @@ -0,0 +1,3 @@ +Local = true +Cloud = false +EnvMatrix.DATABRICKS_BUNDLE_ENGINE = ["terraform", "direct"] diff --git a/acceptance/cmd/sync-dryrun-missing-remote/output.txt b/acceptance/cmd/sync-dryrun-missing-remote/output.txt new file mode 100644 index 00000000000..5fd287c3e66 --- /dev/null +++ b/acceptance/cmd/sync-dryrun-missing-remote/output.txt @@ -0,0 +1,38 @@ + +>>> [CLI] sync . /Users/[USERNAME]/missing-dir --dry-run +Warn: Running in dry-run mode. No actual changes will be made. +Initial Sync Complete +Uploaded .gitignore +Uploaded hello.py + +>>> print_requests.py --sort //api/ + +>>> [CLI] sync . /Users/[USERNAME]/missing-dir +Initial Sync Complete +Uploaded .gitignore +Uploaded hello.py + +>>> print_requests.py --sort //api/ +{ + "method": "POST", + "path": "/api/2.0/workspace-files/import-file/Users/[USERNAME]/missing-dir/.gitignore", + "q": { + "overwrite": "true" + }, + "raw_body": ".databricks/\nscript\ntest.toml\noutput.txt\nout.requests.txt\nrepls.json\n" +} +{ + "method": "POST", + "path": "/api/2.0/workspace-files/import-file/Users/[USERNAME]/missing-dir/hello.py", + "q": { + "overwrite": "true" + }, + "raw_body": "print(\"hello\")\n" +} +{ + "method": "POST", + "path": "/api/2.0/workspace/mkdirs", + "body": { + "path": "/Users/[USERNAME]/missing-dir" + } +} diff --git a/acceptance/cmd/sync-dryrun-missing-remote/script b/acceptance/cmd/sync-dryrun-missing-remote/script new file mode 100644 index 00000000000..b6bea1162f6 --- /dev/null +++ b/acceptance/cmd/sync-dryrun-missing-remote/script @@ -0,0 +1,27 @@ +mkdir .git +cat > .gitignore << EOF +.databricks/ +script +test.toml +output.txt +out.requests.txt +repls.json +EOF + +cleanup() { + rm -rf .git .gitignore .databricks +} +trap cleanup EXIT + +# The remote directory does not exist: a dry run must not create it or upload +# anything, so no mutating requests may be recorded by the print_requests.py +# call below. +# Note: output line starting with Action lists files in non-deterministic order so we filter it out +trace $CLI sync . /Users/$CURRENT_USER_NAME/missing-dir --dry-run | grep -v "^Action" | sort + +trace print_requests.py --sort //api/ + +# Without --dry-run the same sync creates the remote directory and uploads files. +trace $CLI sync . /Users/$CURRENT_USER_NAME/missing-dir | grep -v "^Action" | sort + +trace print_requests.py --sort //api/ diff --git a/acceptance/cmd/sync-dryrun-missing-remote/test.toml b/acceptance/cmd/sync-dryrun-missing-remote/test.toml new file mode 100644 index 00000000000..159efe02696 --- /dev/null +++ b/acceptance/cmd/sync-dryrun-missing-remote/test.toml @@ -0,0 +1 @@ +RecordRequests = true diff --git a/integration/cmd/sync/sync_test.go b/integration/cmd/sync/sync_test.go index 96f00284919..e170c6259bc 100644 --- a/integration/cmd/sync/sync_test.go +++ b/integration/cmd/sync/sync_test.go @@ -493,12 +493,12 @@ func TestSyncEnsureRemotePathIsUsableIfRepoDoesntExist(t *testing.T) { // Hypothetical repo path doesn't exist. nonExistingRepoPath := fmt.Sprintf("/Repos/%s/%s", me.UserName, testutil.RandomName("doesnt-exist-")) - err = sync.EnsureRemotePathIsUsable(ctx, wsc, nonExistingRepoPath, nil) + err = sync.EnsureRemotePathIsUsable(ctx, wsc, nonExistingRepoPath, nil, false) assert.ErrorContains(t, err, " does not exist; please create it first") // Paths nested under a hypothetical repo path should yield the same error. nestedPath := path.Join(nonExistingRepoPath, "nested/directory") - err = sync.EnsureRemotePathIsUsable(ctx, wsc, nestedPath, nil) + err = sync.EnsureRemotePathIsUsable(ctx, wsc, nestedPath, nil, false) assert.ErrorContains(t, err, " does not exist; please create it first") } @@ -509,12 +509,12 @@ func TestSyncEnsureRemotePathIsUsableIfRepoExists(t *testing.T) { _, remoteRepoPath := setupRepo(t, wsc, ctx) // Repo itself is usable. - err := sync.EnsureRemotePathIsUsable(ctx, wsc, remoteRepoPath, nil) + err := sync.EnsureRemotePathIsUsable(ctx, wsc, remoteRepoPath, nil, false) assert.NoError(t, err) // Path nested under repo path is usable. nestedPath := path.Join(remoteRepoPath, "nested/directory") - err = sync.EnsureRemotePathIsUsable(ctx, wsc, nestedPath, nil) + err = sync.EnsureRemotePathIsUsable(ctx, wsc, nestedPath, nil, false) assert.NoError(t, err) // Verify that the directory has been created. @@ -531,7 +531,7 @@ func TestSyncEnsureRemotePathIsUsableInWorkspace(t *testing.T) { require.NoError(t, err) remotePath := fmt.Sprintf("/Users/%s/%s", me.UserName, testutil.RandomName("ensure-path-exists-test-")) - err = sync.EnsureRemotePathIsUsable(ctx, wsc, remotePath, me) + err = sync.EnsureRemotePathIsUsable(ctx, wsc, remotePath, me, false) assert.NoError(t, err) // Clean up directory after test. diff --git a/libs/sync/path.go b/libs/sync/path.go index 6976fd8e0d6..46a020d5c97 100644 --- a/libs/sync/path.go +++ b/libs/sync/path.go @@ -24,7 +24,8 @@ func repoPathForPath(me *iam.User, remotePath string) string { // EnsureRemotePathIsUsable checks if the specified path is nested under // expected base paths and if it is a directory or repository. -func EnsureRemotePathIsUsable(ctx context.Context, wsc *databricks.WorkspaceClient, remotePath string, me *iam.User) error { +// If dryRun is set, a missing remote directory is not created. +func EnsureRemotePathIsUsable(ctx context.Context, wsc *databricks.WorkspaceClient, remotePath string, me *iam.User, dryRun bool) error { var err error // TODO: we should cache CurrentUser.Me at the SDK level @@ -55,6 +56,13 @@ func EnsureRemotePathIsUsable(ctx context.Context, wsc *databricks.WorkspaceClie } } + // A dry run must not modify the workspace, so skip creating the + // missing directory. There is nothing left to validate about a + // directory that doesn't exist yet. + if dryRun { + return nil + } + // The workspace path doesn't exist. Create it and try again. err = wsc.Workspace.MkdirsByPath(ctx, remotePath) //nolint:staticcheck // Deprecated in SDK v0.127.0. Migration to WorkspaceHierarchyService tracked separately. if err != nil { diff --git a/libs/sync/sync.go b/libs/sync/sync.go index c65b49eb775..6d7708c8b37 100644 --- a/libs/sync/sync.go +++ b/libs/sync/sync.go @@ -84,7 +84,7 @@ func New(ctx context.Context, opts SyncOptions) (*Sync, error) { } // Verify that the remote path we're about to synchronize to is valid and allowed. - err = EnsureRemotePathIsUsable(ctx, opts.WorkspaceClient, opts.RemotePath, opts.CurrentUser) + err = EnsureRemotePathIsUsable(ctx, opts.WorkspaceClient, opts.RemotePath, opts.CurrentUser, opts.DryRun) if err != nil { return nil, err } diff --git a/libs/sync/watchdog.go b/libs/sync/watchdog.go index 4a47acfb836..d3bb57662d9 100644 --- a/libs/sync/watchdog.go +++ b/libs/sync/watchdog.go @@ -63,14 +63,14 @@ func (s *Sync) applyMkdir(ctx context.Context, localName string) error { func (s *Sync) applyPut(ctx context.Context, localName string) error { s.notifyProgress(ctx, EventActionPut, localName, 0.0) - localFile, err := s.LocalRoot.Open(localName) - if err != nil { - return err - } + if !s.DryRun { + localFile, err := s.LocalRoot.Open(localName) + if err != nil { + return err + } - defer localFile.Close() + defer localFile.Close() - if !s.DryRun { opts := []filer.WriteMode{filer.CreateParentDirectories, filer.OverwriteIfExists} err = s.filer.Write(ctx, localName, localFile, opts...) if err != nil { diff --git a/libs/sync/watchdog_test.go b/libs/sync/watchdog_test.go new file mode 100644 index 00000000000..2cbcb0d280a --- /dev/null +++ b/libs/sync/watchdog_test.go @@ -0,0 +1,23 @@ +package sync + +import ( + "testing" + + "github.com/databricks/cli/libs/vfs" + "github.com/stretchr/testify/assert" +) + +func TestApplyPutDryRunSkipsLocalRead(t *testing.T) { + s := &Sync{ + SyncOptions: &SyncOptions{ + LocalRoot: vfs.MustNew(t.TempDir()), + DryRun: true, + }, + notifier: &NopNotifier{}, + } + + // A file that disappeared between listing and upload must not fail a dry + // run. The nil filer also guarantees no write is attempted. + err := s.applyPut(t.Context(), "missing.txt") + assert.NoError(t, err) +} From 2a5014e52853cc3177bfa1e02618cd029580d887 Mon Sep 17 00:00:00 2001 From: simonfaltum Date: Tue, 9 Jun 2026 23:58:47 +0200 Subject: [PATCH 2/4] Remove redundant comments Co-authored-by: Isaac --- acceptance/cmd/sync-dryrun-missing-remote/script | 5 +---- libs/sync/path.go | 4 +--- libs/sync/watchdog_test.go | 3 +-- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/acceptance/cmd/sync-dryrun-missing-remote/script b/acceptance/cmd/sync-dryrun-missing-remote/script index b6bea1162f6..406cc8f1763 100644 --- a/acceptance/cmd/sync-dryrun-missing-remote/script +++ b/acceptance/cmd/sync-dryrun-missing-remote/script @@ -13,15 +13,12 @@ cleanup() { } trap cleanup EXIT -# The remote directory does not exist: a dry run must not create it or upload -# anything, so no mutating requests may be recorded by the print_requests.py -# call below. +# A dry run must not create the missing remote dir or upload anything. # Note: output line starting with Action lists files in non-deterministic order so we filter it out trace $CLI sync . /Users/$CURRENT_USER_NAME/missing-dir --dry-run | grep -v "^Action" | sort trace print_requests.py --sort //api/ -# Without --dry-run the same sync creates the remote directory and uploads files. trace $CLI sync . /Users/$CURRENT_USER_NAME/missing-dir | grep -v "^Action" | sort trace print_requests.py --sort //api/ diff --git a/libs/sync/path.go b/libs/sync/path.go index 46a020d5c97..f98099d2b81 100644 --- a/libs/sync/path.go +++ b/libs/sync/path.go @@ -56,9 +56,7 @@ func EnsureRemotePathIsUsable(ctx context.Context, wsc *databricks.WorkspaceClie } } - // A dry run must not modify the workspace, so skip creating the - // missing directory. There is nothing left to validate about a - // directory that doesn't exist yet. + // A dry run must not create the missing directory; nothing left to validate. if dryRun { return nil } diff --git a/libs/sync/watchdog_test.go b/libs/sync/watchdog_test.go index 2cbcb0d280a..91378017fbc 100644 --- a/libs/sync/watchdog_test.go +++ b/libs/sync/watchdog_test.go @@ -16,8 +16,7 @@ func TestApplyPutDryRunSkipsLocalRead(t *testing.T) { notifier: &NopNotifier{}, } - // A file that disappeared between listing and upload must not fail a dry - // run. The nil filer also guarantees no write is attempted. + // The missing file must not fail a dry run; the nil filer guarantees no write is attempted. err := s.applyPut(t.Context(), "missing.txt") assert.NoError(t, err) } From af243c0a957deafba5674193194f874f588df259 Mon Sep 17 00:00:00 2001 From: simonfaltum Date: Wed, 10 Jun 2026 07:25:12 +0200 Subject: [PATCH 3/4] Fix sync-dryrun acceptance test on Windows Git Bash rewrites the /Users/... argument to C:/Program Files/Git/Users/... before the CLI sees it, so the recorded request paths diverged; MSYS_NO_PATHCONV=1 disables that conversion. Also force LF on committed .py fixtures so the uploaded raw_body does not gain a CR on Windows checkouts. Co-authored-by: Isaac --- acceptance/.gitattributes | 1 + acceptance/cmd/sync-dryrun-missing-remote/script | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/acceptance/.gitattributes b/acceptance/.gitattributes index 8d48122750e..3160a60475a 100644 --- a/acceptance/.gitattributes +++ b/acceptance/.gitattributes @@ -4,6 +4,7 @@ # uploading the file's content to a workspace. *.txt text eol=lf *.lvdash.json text eol=lf +*.py text eol=lf # The out.test.toml file is autogenerated based on the merged test.toml view. out.test.toml linguist-generated=true diff --git a/acceptance/cmd/sync-dryrun-missing-remote/script b/acceptance/cmd/sync-dryrun-missing-remote/script index 406cc8f1763..38c118bcd02 100644 --- a/acceptance/cmd/sync-dryrun-missing-remote/script +++ b/acceptance/cmd/sync-dryrun-missing-remote/script @@ -15,10 +15,11 @@ trap cleanup EXIT # A dry run must not create the missing remote dir or upload anything. # Note: output line starting with Action lists files in non-deterministic order so we filter it out -trace $CLI sync . /Users/$CURRENT_USER_NAME/missing-dir --dry-run | grep -v "^Action" | sort +# MSYS_NO_PATHCONV=1 prevents Git Bash on Windows from converting /Users/... to C:/Program Files/Git/Users/... +MSYS_NO_PATHCONV=1 trace $CLI sync . /Users/$CURRENT_USER_NAME/missing-dir --dry-run | grep -v "^Action" | sort trace print_requests.py --sort //api/ -trace $CLI sync . /Users/$CURRENT_USER_NAME/missing-dir | grep -v "^Action" | sort +MSYS_NO_PATHCONV=1 trace $CLI sync . /Users/$CURRENT_USER_NAME/missing-dir | grep -v "^Action" | sort trace print_requests.py --sort //api/ From 4b0eafb0ac42775871f2ef706315dabdac515e21 Mon Sep 17 00:00:00 2001 From: Pieter Noordhuis Date: Wed, 10 Jun 2026 09:49:22 +0200 Subject: [PATCH 4/4] Fix bundle validate creating the remote file path Validation ran files_to_sync with a regular sync object, whose setup creates workspace.file_path if it is missing. Validate must not have side effects, so construct the sync in dry-run mode: the read-only path checks still run, but a missing directory is no longer created. Deploy now performs the mkdir itself instead of inheriting the directory from a prior validate, as reflected in the regenerated request recordings. Removes files.GetSync; files_to_sync was its only caller and now needs to set DryRun on the options before constructing the sync. Co-authored-by: Isaac --- NEXT_CHANGELOG.md | 1 + .../resource_deps/remote_app_url/output.txt | 14 +++++------ .../target-is-passed/default/out.requests.txt | 24 ------------------- .../from_flag/out.requests.txt | 24 ------------------- .../target-is-passed/default/out.requests.txt | 24 ------------------- .../from_flag/out.requests.txt | 24 ------------------- .../classic/out.requests.dev.direct.txt | 7 ++++++ .../classic/out.requests.dev.terraform.txt | 7 ++++++ .../classic/out.requests.prod.direct.txt | 7 ++++++ .../classic/out.requests.prod.terraform.txt | 7 ++++++ .../serverless/out.requests.dev.direct.txt | 7 ++++++ .../serverless/out.requests.dev.terraform.txt | 7 ++++++ .../serverless/out.requests.prod.direct.txt | 7 ++++++ .../out.requests.prod.terraform.txt | 7 ++++++ acceptance/bundle/user_agent/output.txt | 8 +++---- .../simple/out.requests.deploy.direct.json | 24 +++++++++++++++++++ .../simple/out.requests.deploy.terraform.json | 24 +++++++++++++++++++ .../simple/out.requests.validate.direct.json | 24 ------------------- .../out.requests.validate.terraform.json | 24 ------------------- .../bundle/validate/no_writes/databricks.yml | 2 ++ .../bundle/validate/no_writes/out.test.toml | 3 +++ .../bundle/validate/no_writes/output.txt | 11 +++++++++ acceptance/bundle/validate/no_writes/script | 5 ++++ .../bundle/validate/no_writes/test.toml | 1 + bundle/config/validate/files_to_sync.go | 14 +++++++++-- bundle/deploy/files/sync.go | 8 ------- 26 files changed, 150 insertions(+), 165 deletions(-) create mode 100644 acceptance/bundle/validate/no_writes/databricks.yml create mode 100644 acceptance/bundle/validate/no_writes/out.test.toml create mode 100644 acceptance/bundle/validate/no_writes/output.txt create mode 100644 acceptance/bundle/validate/no_writes/script create mode 100644 acceptance/bundle/validate/no_writes/test.toml diff --git a/NEXT_CHANGELOG.md b/NEXT_CHANGELOG.md index db25ff3c12a..cd7926ccacd 100644 --- a/NEXT_CHANGELOG.md +++ b/NEXT_CHANGELOG.md @@ -12,6 +12,7 @@ * Set the default `data_security_mode` to `DATA_SECURITY_MODE_AUTO` in bundle templates ([#5452](https://github.com/databricks/cli/pull/5452)). * Mark vector search index index_subtype as backend_default to prevent drift after deployment ([#5454](https://github.com/databricks/cli/pull/5454)). * `bundle deployment migrate`: handle resources added to or removed from `databricks.yml` since the last Terraform deploy ([#5463](https://github.com/databricks/cli/pull/5463)). +* Fixed `bundle validate` creating the remote file path if it did not exist; validation no longer performs any write operations ([#5528](https://github.com/databricks/cli/pull/5528)). ### Dependency updates diff --git a/acceptance/bundle/resource_deps/remote_app_url/output.txt b/acceptance/bundle/resource_deps/remote_app_url/output.txt index 81b300ab11f..951bea9629f 100644 --- a/acceptance/bundle/resource_deps/remote_app_url/output.txt +++ b/acceptance/bundle/resource_deps/remote_app_url/output.txt @@ -15,13 +15,6 @@ create pipelines.mypipeline Plan: 2 to add, 0 to change, 0 to delete, 0 unchanged >>> print_requests.py ^//import-file/ -{ - "method": "POST", - "path": "/api/2.0/workspace/mkdirs", - "body": { - "path": "/Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files" - } -} >>> [CLI] bundle deploy Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files... @@ -45,6 +38,13 @@ Deployment complete! "path": "/Workspace/Users/[USERNAME]/.bundle/test-bundle/default/artifacts/.internal" } } +{ + "method": "POST", + "path": "/api/2.0/workspace/mkdirs", + "body": { + "path": "/Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files" + } +} { "method": "POST", "path": "/api/2.0/apps", diff --git a/acceptance/bundle/run/inline-script/databricks-cli/target-is-passed/default/out.requests.txt b/acceptance/bundle/run/inline-script/databricks-cli/target-is-passed/default/out.requests.txt index 0c815411ae9..aa0412db327 100644 --- a/acceptance/bundle/run/inline-script/databricks-cli/target-is-passed/default/out.requests.txt +++ b/acceptance/bundle/run/inline-script/databricks-cli/target-is-passed/default/out.requests.txt @@ -23,27 +23,3 @@ "path": "/Workspace/Users/[USERNAME]/.bundle/test-bundle/pat/files" } } -{ - "headers": { - "Authorization": [ - "Bearer [DATABRICKS_TOKEN]" - ] - }, - "method": "POST", - "path": "/api/2.0/workspace/mkdirs", - "body": { - "path": "/Workspace/Users/[USERNAME]/.bundle/test-bundle/pat/files" - } -} -{ - "headers": { - "Authorization": [ - "Bearer [DATABRICKS_TOKEN]" - ] - }, - "method": "GET", - "path": "/api/2.0/workspace/get-status", - "q": { - "path": "/Workspace/Users/[USERNAME]/.bundle/test-bundle/pat/files" - } -} diff --git a/acceptance/bundle/run/inline-script/databricks-cli/target-is-passed/from_flag/out.requests.txt b/acceptance/bundle/run/inline-script/databricks-cli/target-is-passed/from_flag/out.requests.txt index 6ba1aad2544..6d221ca084f 100644 --- a/acceptance/bundle/run/inline-script/databricks-cli/target-is-passed/from_flag/out.requests.txt +++ b/acceptance/bundle/run/inline-script/databricks-cli/target-is-passed/from_flag/out.requests.txt @@ -51,27 +51,3 @@ "path": "/Workspace/Users/[USERNAME]/.bundle/test-bundle/oauth/files" } } -{ - "headers": { - "Authorization": [ - "Bearer oauth-token" - ] - }, - "method": "POST", - "path": "/api/2.0/workspace/mkdirs", - "body": { - "path": "/Workspace/Users/[USERNAME]/.bundle/test-bundle/oauth/files" - } -} -{ - "headers": { - "Authorization": [ - "Bearer oauth-token" - ] - }, - "method": "GET", - "path": "/api/2.0/workspace/get-status", - "q": { - "path": "/Workspace/Users/[USERNAME]/.bundle/test-bundle/oauth/files" - } -} diff --git a/acceptance/bundle/run/scripts/databricks-cli/target-is-passed/default/out.requests.txt b/acceptance/bundle/run/scripts/databricks-cli/target-is-passed/default/out.requests.txt index 93542472ac5..e90d023a48b 100644 --- a/acceptance/bundle/run/scripts/databricks-cli/target-is-passed/default/out.requests.txt +++ b/acceptance/bundle/run/scripts/databricks-cli/target-is-passed/default/out.requests.txt @@ -36,27 +36,3 @@ "path": "/Workspace/Users/[USERNAME]/.bundle/foobar/pat/files" } } -{ - "headers": { - "Authorization": [ - "Bearer [DATABRICKS_TOKEN]" - ] - }, - "method": "POST", - "path": "/api/2.0/workspace/mkdirs", - "body": { - "path": "/Workspace/Users/[USERNAME]/.bundle/foobar/pat/files" - } -} -{ - "headers": { - "Authorization": [ - "Bearer [DATABRICKS_TOKEN]" - ] - }, - "method": "GET", - "path": "/api/2.0/workspace/get-status", - "q": { - "path": "/Workspace/Users/[USERNAME]/.bundle/foobar/pat/files" - } -} diff --git a/acceptance/bundle/run/scripts/databricks-cli/target-is-passed/from_flag/out.requests.txt b/acceptance/bundle/run/scripts/databricks-cli/target-is-passed/from_flag/out.requests.txt index 6ce820c124f..84276fce06d 100644 --- a/acceptance/bundle/run/scripts/databricks-cli/target-is-passed/from_flag/out.requests.txt +++ b/acceptance/bundle/run/scripts/databricks-cli/target-is-passed/from_flag/out.requests.txt @@ -64,27 +64,3 @@ "path": "/Workspace/Users/[USERNAME]/.bundle/foobar/oauth/files" } } -{ - "headers": { - "Authorization": [ - "Bearer oauth-token" - ] - }, - "method": "POST", - "path": "/api/2.0/workspace/mkdirs", - "body": { - "path": "/Workspace/Users/[USERNAME]/.bundle/foobar/oauth/files" - } -} -{ - "headers": { - "Authorization": [ - "Bearer oauth-token" - ] - }, - "method": "GET", - "path": "/api/2.0/workspace/get-status", - "q": { - "path": "/Workspace/Users/[USERNAME]/.bundle/foobar/oauth/files" - } -} diff --git a/acceptance/bundle/templates/default-python/classic/out.requests.dev.direct.txt b/acceptance/bundle/templates/default-python/classic/out.requests.dev.direct.txt index 60e8a1a0f34..8c3637d3bec 100644 --- a/acceptance/bundle/templates/default-python/classic/out.requests.dev.direct.txt +++ b/acceptance/bundle/templates/default-python/classic/out.requests.dev.direct.txt @@ -44,6 +44,13 @@ "path": "/Workspace/Users/[USERNAME]/.bundle/my_default_python/dev/artifacts/.internal" } } +{ + "method": "POST", + "path": "/api/2.0/workspace/mkdirs", + "body": { + "path": "/Workspace/Users/[USERNAME]/.bundle/my_default_python/dev/files" + } +} { "method": "POST", "path": "/api/2.0/workspace/mkdirs", diff --git a/acceptance/bundle/templates/default-python/classic/out.requests.dev.terraform.txt b/acceptance/bundle/templates/default-python/classic/out.requests.dev.terraform.txt index 173c894ac7f..1714d704159 100644 --- a/acceptance/bundle/templates/default-python/classic/out.requests.dev.terraform.txt +++ b/acceptance/bundle/templates/default-python/classic/out.requests.dev.terraform.txt @@ -44,6 +44,13 @@ "path": "/Workspace/Users/[USERNAME]/.bundle/my_default_python/dev/artifacts/.internal" } } +{ + "method": "POST", + "path": "/api/2.0/workspace/mkdirs", + "body": { + "path": "/Workspace/Users/[USERNAME]/.bundle/my_default_python/dev/files" + } +} { "method": "POST", "path": "/api/2.0/workspace/mkdirs", diff --git a/acceptance/bundle/templates/default-python/classic/out.requests.prod.direct.txt b/acceptance/bundle/templates/default-python/classic/out.requests.prod.direct.txt index 467ff7e75cd..118f384cabc 100644 --- a/acceptance/bundle/templates/default-python/classic/out.requests.prod.direct.txt +++ b/acceptance/bundle/templates/default-python/classic/out.requests.prod.direct.txt @@ -47,6 +47,13 @@ "path": "/Workspace/Users/[USERNAME]/.bundle/my_default_python/prod/artifacts/.internal" } } +{ + "method": "POST", + "path": "/api/2.0/workspace/mkdirs", + "body": { + "path": "/Workspace/Users/[USERNAME]/.bundle/my_default_python/prod/files" + } +} { "method": "POST", "path": "/api/2.0/workspace/mkdirs", diff --git a/acceptance/bundle/templates/default-python/classic/out.requests.prod.terraform.txt b/acceptance/bundle/templates/default-python/classic/out.requests.prod.terraform.txt index 1211c38babb..3bfc5ddc7d6 100644 --- a/acceptance/bundle/templates/default-python/classic/out.requests.prod.terraform.txt +++ b/acceptance/bundle/templates/default-python/classic/out.requests.prod.terraform.txt @@ -47,6 +47,13 @@ "path": "/Workspace/Users/[USERNAME]/.bundle/my_default_python/prod/artifacts/.internal" } } +{ + "method": "POST", + "path": "/api/2.0/workspace/mkdirs", + "body": { + "path": "/Workspace/Users/[USERNAME]/.bundle/my_default_python/prod/files" + } +} { "method": "POST", "path": "/api/2.0/workspace/mkdirs", diff --git a/acceptance/bundle/templates/default-python/serverless/out.requests.dev.direct.txt b/acceptance/bundle/templates/default-python/serverless/out.requests.dev.direct.txt index c5d9ae4c6b2..98e0d302f4a 100644 --- a/acceptance/bundle/templates/default-python/serverless/out.requests.dev.direct.txt +++ b/acceptance/bundle/templates/default-python/serverless/out.requests.dev.direct.txt @@ -46,6 +46,13 @@ "path": "/Workspace/Users/[USERNAME]/.bundle/my_default_python/dev/artifacts/.internal" } } +{ + "method": "POST", + "path": "/api/2.0/workspace/mkdirs", + "body": { + "path": "/Workspace/Users/[USERNAME]/.bundle/my_default_python/dev/files" + } +} { "method": "POST", "path": "/api/2.0/workspace/mkdirs", diff --git a/acceptance/bundle/templates/default-python/serverless/out.requests.dev.terraform.txt b/acceptance/bundle/templates/default-python/serverless/out.requests.dev.terraform.txt index 4dfb549b054..eade8f9387e 100644 --- a/acceptance/bundle/templates/default-python/serverless/out.requests.dev.terraform.txt +++ b/acceptance/bundle/templates/default-python/serverless/out.requests.dev.terraform.txt @@ -46,6 +46,13 @@ "path": "/Workspace/Users/[USERNAME]/.bundle/my_default_python/dev/artifacts/.internal" } } +{ + "method": "POST", + "path": "/api/2.0/workspace/mkdirs", + "body": { + "path": "/Workspace/Users/[USERNAME]/.bundle/my_default_python/dev/files" + } +} { "method": "POST", "path": "/api/2.0/workspace/mkdirs", diff --git a/acceptance/bundle/templates/default-python/serverless/out.requests.prod.direct.txt b/acceptance/bundle/templates/default-python/serverless/out.requests.prod.direct.txt index d7a761ae4cc..c43bb77d488 100644 --- a/acceptance/bundle/templates/default-python/serverless/out.requests.prod.direct.txt +++ b/acceptance/bundle/templates/default-python/serverless/out.requests.prod.direct.txt @@ -49,6 +49,13 @@ "path": "/Workspace/Users/[USERNAME]/.bundle/my_default_python/prod/artifacts/.internal" } } +{ + "method": "POST", + "path": "/api/2.0/workspace/mkdirs", + "body": { + "path": "/Workspace/Users/[USERNAME]/.bundle/my_default_python/prod/files" + } +} { "method": "POST", "path": "/api/2.0/workspace/mkdirs", diff --git a/acceptance/bundle/templates/default-python/serverless/out.requests.prod.terraform.txt b/acceptance/bundle/templates/default-python/serverless/out.requests.prod.terraform.txt index ae401a3c97a..ff9f68a517f 100644 --- a/acceptance/bundle/templates/default-python/serverless/out.requests.prod.terraform.txt +++ b/acceptance/bundle/templates/default-python/serverless/out.requests.prod.terraform.txt @@ -49,6 +49,13 @@ "path": "/Workspace/Users/[USERNAME]/.bundle/my_default_python/prod/artifacts/.internal" } } +{ + "method": "POST", + "path": "/api/2.0/workspace/mkdirs", + "body": { + "path": "/Workspace/Users/[USERNAME]/.bundle/my_default_python/prod/files" + } +} { "method": "POST", "path": "/api/2.0/workspace/mkdirs", diff --git a/acceptance/bundle/user_agent/output.txt b/acceptance/bundle/user_agent/output.txt index b517b83889e..c8684c2e448 100644 --- a/acceptance/bundle/user_agent/output.txt +++ b/acceptance/bundle/user_agent/output.txt @@ -8,6 +8,7 @@ OK deploy.direct /api/2.0/workspace/get-status engine/direct OK deploy.direct /api/2.0/workspace/get-status engine/direct OK deploy.direct /api/2.0/workspace/get-status engine/direct OK deploy.direct /api/2.0/workspace/get-status engine/direct +OK deploy.direct /api/2.0/workspace/get-status engine/direct OK deploy.direct /api/2.0/workspace-files/import-file/Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files/empty.py engine/direct OK deploy.direct /api/2.0/workspace-files/import-file/Workspace/Users/[USERNAME]/.bundle/test-bundle/default/state/deploy.lock engine/direct OK deploy.direct /api/2.0/workspace-files/import-file/Workspace/Users/[USERNAME]/.bundle/test-bundle/default/state/deployment.json engine/direct @@ -16,6 +17,7 @@ OK deploy.direct /api/2.0/workspace-files/import-file/Workspace/Users/[USERNAM OK deploy.direct /api/2.0/workspace/delete engine/direct OK deploy.direct /api/2.0/workspace/delete engine/direct OK deploy.direct /api/2.0/workspace/mkdirs engine/direct +OK deploy.direct /api/2.0/workspace/mkdirs engine/direct OK deploy.direct /api/2.1/unity-catalog/schemas engine/direct MISS deploy.direct /.well-known/databricks-config 'cli/[DEV_VERSION] databricks-sdk-go/[SDK_VERSION] go/[GO_VERSION] os/[OS]' MISS deploy.terraform /api/2.0/preview/scim/v2/Me 'cli/[DEV_VERSION] databricks-sdk-go/[SDK_VERSION] go/[GO_VERSION] os/[OS] cmd/bundle_deploy cmd-exec-id/[UUID] interactive/none auth/pat' @@ -28,6 +30,7 @@ OK deploy.terraform /api/2.0/workspace/get-status engine/terraform OK deploy.terraform /api/2.0/workspace/get-status engine/terraform OK deploy.terraform /api/2.0/workspace/get-status engine/terraform OK deploy.terraform /api/2.0/workspace/get-status engine/terraform +OK deploy.terraform /api/2.0/workspace/get-status engine/terraform OK deploy.terraform /api/2.0/workspace-files/import-file/Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files/empty.py engine/terraform OK deploy.terraform /api/2.0/workspace-files/import-file/Workspace/Users/[USERNAME]/.bundle/test-bundle/default/state/deploy.lock engine/terraform OK deploy.terraform /api/2.0/workspace-files/import-file/Workspace/Users/[USERNAME]/.bundle/test-bundle/default/state/deployment.json engine/terraform @@ -36,6 +39,7 @@ OK deploy.terraform /api/2.0/workspace-files/import-file/Workspace/Users/[USER OK deploy.terraform /api/2.0/workspace/delete engine/terraform OK deploy.terraform /api/2.0/workspace/delete engine/terraform OK deploy.terraform /api/2.0/workspace/mkdirs engine/terraform +OK deploy.terraform /api/2.0/workspace/mkdirs engine/terraform MISS deploy.terraform /.well-known/databricks-config 'cli/[DEV_VERSION] databricks-sdk-go/[SDK_VERSION] go/[GO_VERSION] os/[OS]' MISS deploy.terraform /api/2.0/preview/scim/v2/Me 'databricks-tf-provider/1.117.0 databricks-sdk-go/[SDK_VERSION] go/1.25.8 os/[OS] cli/[DEV_VERSION] terraform/1.5.5 auth/pat' MISS deploy.terraform /api/2.0/preview/scim/v2/Me 'databricks-tf-provider/1.117.0 databricks-sdk-go/[SDK_VERSION] go/1.25.8 os/[OS] cli/[DEV_VERSION] terraform/1.5.5 auth/pat' @@ -132,11 +136,7 @@ MISS summary.terraform /api/2.0/workspace/get-status 'cli/[DEV_VERSION] databric MISS summary.terraform /.well-known/databricks-config 'cli/[DEV_VERSION] databricks-sdk-go/[SDK_VERSION] go/[GO_VERSION] os/[OS]' MISS validate.direct /api/2.0/preview/scim/v2/Me 'cli/[DEV_VERSION] databricks-sdk-go/[SDK_VERSION] go/[GO_VERSION] os/[OS] cmd/bundle_validate cmd-exec-id/[UUID] interactive/none auth/pat' MISS validate.direct /api/2.0/workspace/get-status 'cli/[DEV_VERSION] databricks-sdk-go/[SDK_VERSION] go/[GO_VERSION] os/[OS] cmd/bundle_validate cmd-exec-id/[UUID] interactive/none auth/pat' -MISS validate.direct /api/2.0/workspace/get-status 'cli/[DEV_VERSION] databricks-sdk-go/[SDK_VERSION] go/[GO_VERSION] os/[OS] cmd/bundle_validate cmd-exec-id/[UUID] interactive/none auth/pat' -MISS validate.direct /api/2.0/workspace/mkdirs 'cli/[DEV_VERSION] databricks-sdk-go/[SDK_VERSION] go/[GO_VERSION] os/[OS] cmd/bundle_validate cmd-exec-id/[UUID] interactive/none auth/pat' MISS validate.direct /.well-known/databricks-config 'cli/[DEV_VERSION] databricks-sdk-go/[SDK_VERSION] go/[GO_VERSION] os/[OS]' MISS validate.terraform /api/2.0/preview/scim/v2/Me 'cli/[DEV_VERSION] databricks-sdk-go/[SDK_VERSION] go/[GO_VERSION] os/[OS] cmd/bundle_validate cmd-exec-id/[UUID] interactive/none auth/pat' MISS validate.terraform /api/2.0/workspace/get-status 'cli/[DEV_VERSION] databricks-sdk-go/[SDK_VERSION] go/[GO_VERSION] os/[OS] cmd/bundle_validate cmd-exec-id/[UUID] interactive/none auth/pat' -MISS validate.terraform /api/2.0/workspace/get-status 'cli/[DEV_VERSION] databricks-sdk-go/[SDK_VERSION] go/[GO_VERSION] os/[OS] cmd/bundle_validate cmd-exec-id/[UUID] interactive/none auth/pat' -MISS validate.terraform /api/2.0/workspace/mkdirs 'cli/[DEV_VERSION] databricks-sdk-go/[SDK_VERSION] go/[GO_VERSION] os/[OS] cmd/bundle_validate cmd-exec-id/[UUID] interactive/none auth/pat' MISS validate.terraform /.well-known/databricks-config 'cli/[DEV_VERSION] databricks-sdk-go/[SDK_VERSION] go/[GO_VERSION] os/[OS]' diff --git a/acceptance/bundle/user_agent/simple/out.requests.deploy.direct.json b/acceptance/bundle/user_agent/simple/out.requests.deploy.direct.json index cc39aad6e9b..a046d70fa98 100644 --- a/acceptance/bundle/user_agent/simple/out.requests.deploy.direct.json +++ b/acceptance/bundle/user_agent/simple/out.requests.deploy.direct.json @@ -71,6 +71,18 @@ "path": "/Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files" } } +{ + "headers": { + "User-Agent": [ + "cli/[DEV_VERSION] databricks-sdk-go/[SDK_VERSION] go/[GO_VERSION] os/[OS] cmd/bundle_deploy cmd-exec-id/[UUID] interactive/none engine/direct auth/pat" + ] + }, + "method": "GET", + "path": "/api/2.0/workspace/get-status", + "q": { + "path": "/Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files" + } +} { "headers": { "User-Agent": [ @@ -274,6 +286,18 @@ "path": "/Workspace/Users/[USERNAME]/.bundle/test-bundle/default/artifacts/.internal" } } +{ + "headers": { + "User-Agent": [ + "cli/[DEV_VERSION] databricks-sdk-go/[SDK_VERSION] go/[GO_VERSION] os/[OS] cmd/bundle_deploy cmd-exec-id/[UUID] interactive/none engine/direct auth/pat" + ] + }, + "method": "POST", + "path": "/api/2.0/workspace/mkdirs", + "body": { + "path": "/Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files" + } +} { "headers": { "User-Agent": [ diff --git a/acceptance/bundle/user_agent/simple/out.requests.deploy.terraform.json b/acceptance/bundle/user_agent/simple/out.requests.deploy.terraform.json index 152e0040eaf..73fbe0acd22 100644 --- a/acceptance/bundle/user_agent/simple/out.requests.deploy.terraform.json +++ b/acceptance/bundle/user_agent/simple/out.requests.deploy.terraform.json @@ -71,6 +71,18 @@ "path": "/Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files" } } +{ + "headers": { + "User-Agent": [ + "cli/[DEV_VERSION] databricks-sdk-go/[SDK_VERSION] go/[GO_VERSION] os/[OS] cmd/bundle_deploy cmd-exec-id/[UUID] interactive/none engine/terraform auth/pat" + ] + }, + "method": "GET", + "path": "/api/2.0/workspace/get-status", + "q": { + "path": "/Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files" + } +} { "headers": { "User-Agent": [ @@ -300,6 +312,18 @@ "path": "/Workspace/Users/[USERNAME]/.bundle/test-bundle/default/artifacts/.internal" } } +{ + "headers": { + "User-Agent": [ + "cli/[DEV_VERSION] databricks-sdk-go/[SDK_VERSION] go/[GO_VERSION] os/[OS] cmd/bundle_deploy cmd-exec-id/[UUID] interactive/none engine/terraform auth/pat" + ] + }, + "method": "POST", + "path": "/api/2.0/workspace/mkdirs", + "body": { + "path": "/Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files" + } +} { "headers": { "User-Agent": [ diff --git a/acceptance/bundle/user_agent/simple/out.requests.validate.direct.json b/acceptance/bundle/user_agent/simple/out.requests.validate.direct.json index 8c64d6f74a5..f85bf0ae0b1 100644 --- a/acceptance/bundle/user_agent/simple/out.requests.validate.direct.json +++ b/acceptance/bundle/user_agent/simple/out.requests.validate.direct.json @@ -19,30 +19,6 @@ "path": "/Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files" } } -{ - "headers": { - "User-Agent": [ - "cli/[DEV_VERSION] databricks-sdk-go/[SDK_VERSION] go/[GO_VERSION] os/[OS] cmd/bundle_validate cmd-exec-id/[UUID] interactive/none auth/pat" - ] - }, - "method": "GET", - "path": "/api/2.0/workspace/get-status", - "q": { - "path": "/Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files" - } -} -{ - "headers": { - "User-Agent": [ - "cli/[DEV_VERSION] databricks-sdk-go/[SDK_VERSION] go/[GO_VERSION] os/[OS] cmd/bundle_validate cmd-exec-id/[UUID] interactive/none auth/pat" - ] - }, - "method": "POST", - "path": "/api/2.0/workspace/mkdirs", - "body": { - "path": "/Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files" - } -} { "headers": { "User-Agent": [ diff --git a/acceptance/bundle/user_agent/simple/out.requests.validate.terraform.json b/acceptance/bundle/user_agent/simple/out.requests.validate.terraform.json index 8c64d6f74a5..f85bf0ae0b1 100644 --- a/acceptance/bundle/user_agent/simple/out.requests.validate.terraform.json +++ b/acceptance/bundle/user_agent/simple/out.requests.validate.terraform.json @@ -19,30 +19,6 @@ "path": "/Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files" } } -{ - "headers": { - "User-Agent": [ - "cli/[DEV_VERSION] databricks-sdk-go/[SDK_VERSION] go/[GO_VERSION] os/[OS] cmd/bundle_validate cmd-exec-id/[UUID] interactive/none auth/pat" - ] - }, - "method": "GET", - "path": "/api/2.0/workspace/get-status", - "q": { - "path": "/Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files" - } -} -{ - "headers": { - "User-Agent": [ - "cli/[DEV_VERSION] databricks-sdk-go/[SDK_VERSION] go/[GO_VERSION] os/[OS] cmd/bundle_validate cmd-exec-id/[UUID] interactive/none auth/pat" - ] - }, - "method": "POST", - "path": "/api/2.0/workspace/mkdirs", - "body": { - "path": "/Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files" - } -} { "headers": { "User-Agent": [ diff --git a/acceptance/bundle/validate/no_writes/databricks.yml b/acceptance/bundle/validate/no_writes/databricks.yml new file mode 100644 index 00000000000..576d7a9ef25 --- /dev/null +++ b/acceptance/bundle/validate/no_writes/databricks.yml @@ -0,0 +1,2 @@ +bundle: + name: test-bundle diff --git a/acceptance/bundle/validate/no_writes/out.test.toml b/acceptance/bundle/validate/no_writes/out.test.toml new file mode 100644 index 00000000000..f784a183258 --- /dev/null +++ b/acceptance/bundle/validate/no_writes/out.test.toml @@ -0,0 +1,3 @@ +Local = true +Cloud = false +EnvMatrix.DATABRICKS_BUNDLE_ENGINE = ["terraform", "direct"] diff --git a/acceptance/bundle/validate/no_writes/output.txt b/acceptance/bundle/validate/no_writes/output.txt new file mode 100644 index 00000000000..a3d06b47348 --- /dev/null +++ b/acceptance/bundle/validate/no_writes/output.txt @@ -0,0 +1,11 @@ + +>>> [CLI] bundle validate +Name: test-bundle +Target: default +Workspace: + User: [USERNAME] + Path: /Workspace/Users/[USERNAME]/.bundle/test-bundle/default + +Validation OK! + +>>> print_requests.py --sort //api/ diff --git a/acceptance/bundle/validate/no_writes/script b/acceptance/bundle/validate/no_writes/script new file mode 100644 index 00000000000..35f0e48b61a --- /dev/null +++ b/acceptance/bundle/validate/no_writes/script @@ -0,0 +1,5 @@ +# Validate must not mutate the workspace: no write requests, e.g. mkdirs for +# a missing remote file path. print_requests.py prints all non-GET requests. +trace $CLI bundle validate + +trace print_requests.py --sort //api/ diff --git a/acceptance/bundle/validate/no_writes/test.toml b/acceptance/bundle/validate/no_writes/test.toml new file mode 100644 index 00000000000..159efe02696 --- /dev/null +++ b/acceptance/bundle/validate/no_writes/test.toml @@ -0,0 +1 @@ +RecordRequests = true diff --git a/bundle/config/validate/files_to_sync.go b/bundle/config/validate/files_to_sync.go index aea78f7104b..1bd92413c11 100644 --- a/bundle/config/validate/files_to_sync.go +++ b/bundle/config/validate/files_to_sync.go @@ -7,6 +7,7 @@ import ( "github.com/databricks/cli/bundle/deploy/files" "github.com/databricks/cli/libs/diag" "github.com/databricks/cli/libs/dyn" + "github.com/databricks/cli/libs/sync" ) func FilesToSync() bundle.ReadOnlyMutator { @@ -26,12 +27,21 @@ func (v *filesToSync) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagnost return nil } - sync, err := files.GetSync(ctx, b) + opts, err := files.GetSyncOptions(ctx, b) if err != nil { return diag.FromErr(err) } - fl, err := sync.GetFileList(ctx) + // Validation must not mutate the workspace; a dry-run sync skips creating + // a missing remote file path. + opts.DryRun = true + + s, err := sync.New(ctx, *opts) + if err != nil { + return diag.FromErr(err) + } + + fl, err := s.GetFileList(ctx) if err != nil { return diag.FromErr(err) } diff --git a/bundle/deploy/files/sync.go b/bundle/deploy/files/sync.go index 90f44a98d8b..e1116dd87a8 100644 --- a/bundle/deploy/files/sync.go +++ b/bundle/deploy/files/sync.go @@ -8,14 +8,6 @@ import ( "github.com/databricks/cli/libs/sync" ) -func GetSync(ctx context.Context, b *bundle.Bundle) (*sync.Sync, error) { - opts, err := GetSyncOptions(ctx, b) - if err != nil { - return nil, fmt.Errorf("cannot get sync options: %w", err) - } - return sync.New(ctx, *opts) -} - func GetSyncOptions(ctx context.Context, b *bundle.Bundle) (*sync.SyncOptions, error) { cacheDir, err := b.LocalStateDir(ctx) if err != nil {