From 3fbfa371aa28dcf0a99a29abb0d5e673e3b28acd Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Wed, 15 Apr 2026 16:32:51 +0000 Subject: [PATCH 1/6] Fix false duplicate source code path error for git-sourced apps When multiple apps use git_source instead of source_code_path, the duplicate path check incorrectly flags them because all git-sourced apps have an empty SourceCodePath, colliding on the same map key "". Skip the duplicate check when SourceCodePath is empty. Task: 001.md Co-authored-by: Isaac --- bundle/apps/validate.go | 18 ++++++++-------- bundle/apps/validate_test.go | 40 ++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 8 deletions(-) diff --git a/bundle/apps/validate.go b/bundle/apps/validate.go index 6c6403e06f..fdcb121e13 100644 --- a/bundle/apps/validate.go +++ b/bundle/apps/validate.go @@ -42,15 +42,17 @@ func (v *validate) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagnostics continue } - if _, ok := usedSourceCodePaths[app.SourceCodePath]; ok { - diags = append(diags, diag.Diagnostic{ - Severity: diag.Error, - Summary: "Duplicate app source code path", - Detail: fmt.Sprintf("app resource '%s' has the same source code path as app resource '%s', this will lead to the app configuration being overriden by each other", key, usedSourceCodePaths[app.SourceCodePath]), - Locations: b.Config.GetLocations(fmt.Sprintf("resources.apps.%s.source_code_path", key)), - }) + if app.SourceCodePath != "" { + if _, ok := usedSourceCodePaths[app.SourceCodePath]; ok { + diags = append(diags, diag.Diagnostic{ + Severity: diag.Error, + Summary: "Duplicate app source code path", + Detail: fmt.Sprintf("app resource '%s' has the same source code path as app resource '%s', this will lead to the app configuration being overriden by each other", key, usedSourceCodePaths[app.SourceCodePath]), + Locations: b.Config.GetLocations(fmt.Sprintf("resources.apps.%s.source_code_path", key)), + }) + } + usedSourceCodePaths[app.SourceCodePath] = key } - usedSourceCodePaths[app.SourceCodePath] = key diags = diags.Extend(warnForAppResourcePermissions(b, key, app)) } diff --git a/bundle/apps/validate_test.go b/bundle/apps/validate_test.go index ffc4fde45e..e504b75343 100644 --- a/bundle/apps/validate_test.go +++ b/bundle/apps/validate_test.go @@ -221,6 +221,46 @@ func TestAppsValidateResourcePermissionsWarning(t *testing.T) { } } +func TestAppsValidateMultipleGitSourceAppsNoDuplicate(t *testing.T) { + tmpDir := t.TempDir() + + b := &bundle.Bundle{ + BundleRootPath: tmpDir, + SyncRootPath: tmpDir, + SyncRoot: vfs.MustNew(tmpDir), + Config: config.Root{ + Workspace: config.Workspace{ + FilePath: "/foo/bar/", + }, + Resources: config.Resources{ + Apps: map[string]*resources.App{ + "app1": { + App: apps.App{ + Name: "app1", + }, + GitSource: &apps.GitSource{ + Branch: "main", + }, + }, + "app2": { + App: apps.App{ + Name: "app2", + }, + GitSource: &apps.GitSource{ + Branch: "dev", + }, + }, + }, + }, + }, + } + + bundletest.SetLocation(b, ".", []dyn.Location{{File: filepath.Join(tmpDir, "databricks.yml")}}) + + diags := bundle.ApplySeq(t.Context(), b, Validate()) + require.Empty(t, diags) +} + func TestAppsValidateBothSourceCodePathAndGitSource(t *testing.T) { tmpDir := t.TempDir() testutil.Touch(t, tmpDir, "app1", "app.py") From 474500fe91808b5eee3bd25352cc2920bb91df98 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Wed, 15 Apr 2026 16:39:12 +0000 Subject: [PATCH 2/6] Add changelog entry for git-sourced apps bugfix Co-authored-by: Isaac --- NEXT_CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEXT_CHANGELOG.md b/NEXT_CHANGELOG.md index 0e4d6de08f..a57b713188 100644 --- a/NEXT_CHANGELOG.md +++ b/NEXT_CHANGELOG.md @@ -9,6 +9,7 @@ * Added `--limit` flag to all paginated list commands for client-side result capping ([#4984](https://github.com/databricks/cli/pull/4984)). ### Bundles +* Fix false duplicate source code path error for git-sourced apps (denik/random-bugfixes-2) ### Dependency updates From 63819c1906ba3c9605453d2d752a66692494caeb Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Thu, 16 Apr 2026 10:37:53 +0000 Subject: [PATCH 3/6] Replace unit test with acceptance test for git-sourced apps duplicate check Task: 002.md Co-authored-by: Isaac --- .../git_source_no_duplicate/databricks.yml | 13 ++++++ .../git_source_no_duplicate/out.test.toml | 5 +++ .../apps/git_source_no_duplicate/output.txt | 9 +++++ .../apps/git_source_no_duplicate/script | 1 + .../apps/git_source_no_duplicate/test.toml | 5 +++ bundle/apps/validate_test.go | 40 ------------------- 6 files changed, 33 insertions(+), 40 deletions(-) create mode 100644 acceptance/bundle/apps/git_source_no_duplicate/databricks.yml create mode 100644 acceptance/bundle/apps/git_source_no_duplicate/out.test.toml create mode 100644 acceptance/bundle/apps/git_source_no_duplicate/output.txt create mode 100644 acceptance/bundle/apps/git_source_no_duplicate/script create mode 100644 acceptance/bundle/apps/git_source_no_duplicate/test.toml diff --git a/acceptance/bundle/apps/git_source_no_duplicate/databricks.yml b/acceptance/bundle/apps/git_source_no_duplicate/databricks.yml new file mode 100644 index 0000000000..5c06ac8a46 --- /dev/null +++ b/acceptance/bundle/apps/git_source_no_duplicate/databricks.yml @@ -0,0 +1,13 @@ +bundle: + name: test-bundle + +resources: + apps: + app1: + name: app1 + git_source: + branch: main + app2: + name: app2 + git_source: + branch: dev diff --git a/acceptance/bundle/apps/git_source_no_duplicate/out.test.toml b/acceptance/bundle/apps/git_source_no_duplicate/out.test.toml new file mode 100644 index 0000000000..d560f1de04 --- /dev/null +++ b/acceptance/bundle/apps/git_source_no_duplicate/out.test.toml @@ -0,0 +1,5 @@ +Local = true +Cloud = false + +[EnvMatrix] + DATABRICKS_BUNDLE_ENGINE = ["terraform", "direct"] diff --git a/acceptance/bundle/apps/git_source_no_duplicate/output.txt b/acceptance/bundle/apps/git_source_no_duplicate/output.txt new file mode 100644 index 0000000000..d44a21b582 --- /dev/null +++ b/acceptance/bundle/apps/git_source_no_duplicate/output.txt @@ -0,0 +1,9 @@ + +>>> [CLI] bundle validate +Name: test-bundle +Target: default +Workspace: + User: [USERNAME] + Path: /Workspace/Users/[USERNAME]/.bundle/test-bundle/default + +Validation OK! diff --git a/acceptance/bundle/apps/git_source_no_duplicate/script b/acceptance/bundle/apps/git_source_no_duplicate/script new file mode 100644 index 0000000000..5350876150 --- /dev/null +++ b/acceptance/bundle/apps/git_source_no_duplicate/script @@ -0,0 +1 @@ +trace $CLI bundle validate diff --git a/acceptance/bundle/apps/git_source_no_duplicate/test.toml b/acceptance/bundle/apps/git_source_no_duplicate/test.toml new file mode 100644 index 0000000000..a5b2fe2819 --- /dev/null +++ b/acceptance/bundle/apps/git_source_no_duplicate/test.toml @@ -0,0 +1,5 @@ +RecordRequests = false + +Ignore = [ + '.databricks', +] diff --git a/bundle/apps/validate_test.go b/bundle/apps/validate_test.go index e504b75343..ffc4fde45e 100644 --- a/bundle/apps/validate_test.go +++ b/bundle/apps/validate_test.go @@ -221,46 +221,6 @@ func TestAppsValidateResourcePermissionsWarning(t *testing.T) { } } -func TestAppsValidateMultipleGitSourceAppsNoDuplicate(t *testing.T) { - tmpDir := t.TempDir() - - b := &bundle.Bundle{ - BundleRootPath: tmpDir, - SyncRootPath: tmpDir, - SyncRoot: vfs.MustNew(tmpDir), - Config: config.Root{ - Workspace: config.Workspace{ - FilePath: "/foo/bar/", - }, - Resources: config.Resources{ - Apps: map[string]*resources.App{ - "app1": { - App: apps.App{ - Name: "app1", - }, - GitSource: &apps.GitSource{ - Branch: "main", - }, - }, - "app2": { - App: apps.App{ - Name: "app2", - }, - GitSource: &apps.GitSource{ - Branch: "dev", - }, - }, - }, - }, - }, - } - - bundletest.SetLocation(b, ".", []dyn.Location{{File: filepath.Join(tmpDir, "databricks.yml")}}) - - diags := bundle.ApplySeq(t.Context(), b, Validate()) - require.Empty(t, diags) -} - func TestAppsValidateBothSourceCodePathAndGitSource(t *testing.T) { tmpDir := t.TempDir() testutil.Touch(t, tmpDir, "app1", "app.py") From a1311abcc730b4022a0a24d30d71b95803618f3b Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Thu, 16 Apr 2026 14:26:37 +0000 Subject: [PATCH 4/6] Add regression evidence for git-sourced apps duplicate check test Include the output of running the acceptance test against v0.296.0 (`-useversion 0.296.0`), confirming the test catches a real regression: the old CLI falsely reports "Duplicate app source code path" for git-sourced apps that have no source_code_path set. Task: 003.md Co-authored-by: Isaac --- .../apps/git_source_no_duplicate/regression.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 acceptance/bundle/apps/git_source_no_duplicate/regression.txt diff --git a/acceptance/bundle/apps/git_source_no_duplicate/regression.txt b/acceptance/bundle/apps/git_source_no_duplicate/regression.txt new file mode 100644 index 0000000000..7e56c9ffce --- /dev/null +++ b/acceptance/bundle/apps/git_source_no_duplicate/regression.txt @@ -0,0 +1,16 @@ +Output of `go test ./acceptance -run TestAccept/bundle/apps/git_source_no_duplicate -useversion 0.296.0`: + +>>> [CLI] bundle validate +Error: Duplicate app source code path + +app resource 'app1' has the same source code path as app resource 'app2', this will lead to the app configuration being overriden by each other + +Name: test-bundle +Target: default +Workspace: + User: [USERNAME] + Path: /Workspace/Users/[USERNAME]/.bundle/test-bundle/default + +Found 1 error + +Exit code: 1 From 17d77e870113a664a9bce0116cd05b3185ac94e6 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Thu, 16 Apr 2026 14:57:11 +0000 Subject: [PATCH 5/6] Reverted by user via WEB UI --- .../apps/git_source_no_duplicate/regression.txt | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 acceptance/bundle/apps/git_source_no_duplicate/regression.txt diff --git a/acceptance/bundle/apps/git_source_no_duplicate/regression.txt b/acceptance/bundle/apps/git_source_no_duplicate/regression.txt deleted file mode 100644 index 7e56c9ffce..0000000000 --- a/acceptance/bundle/apps/git_source_no_duplicate/regression.txt +++ /dev/null @@ -1,16 +0,0 @@ -Output of `go test ./acceptance -run TestAccept/bundle/apps/git_source_no_duplicate -useversion 0.296.0`: - ->>> [CLI] bundle validate -Error: Duplicate app source code path - -app resource 'app1' has the same source code path as app resource 'app2', this will lead to the app configuration being overriden by each other - -Name: test-bundle -Target: default -Workspace: - User: [USERNAME] - Path: /Workspace/Users/[USERNAME]/.bundle/test-bundle/default - -Found 1 error - -Exit code: 1 From 5bddac7eb90a72cefcda41623498e9cc53519ebe Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Thu, 16 Apr 2026 14:57:52 +0000 Subject: [PATCH 6/6] Update NEXT_CHANGELOG.md with PR #4996 --- NEXT_CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEXT_CHANGELOG.md b/NEXT_CHANGELOG.md index a57b713188..6f8559cfc1 100644 --- a/NEXT_CHANGELOG.md +++ b/NEXT_CHANGELOG.md @@ -9,7 +9,7 @@ * Added `--limit` flag to all paginated list commands for client-side result capping ([#4984](https://github.com/databricks/cli/pull/4984)). ### Bundles -* Fix false duplicate source code path error for git-sourced apps (denik/random-bugfixes-2) +* Fix false duplicate source code path error for git-sourced apps ([#4996](https://github.com/databricks/cli/pull/4996)) ### Dependency updates