Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .nextchanges/bundles/generate-app-git.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* `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.
2 changes: 2 additions & 0 deletions acceptance/bundle/generate/app_git_backed/databricks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
bundle:
name: app_git_backed
12 changes: 12 additions & 0 deletions acceptance/bundle/generate/app_git_backed/out.app.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
resources:
apps:
out:
name: my_git_app
description: This is a git-backed app
git_repository:
url: https://github.com/my-org/my-repo
provider: gitHub
auto_deploy: true
git_source:
branch: main
source_code_path: apps/my-app
3 changes: 3 additions & 0 deletions acceptance/bundle/generate/app_git_backed/out.test.toml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions acceptance/bundle/generate/app_git_backed/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Loading app 'my_git_app' configuration
App configuration successfully saved to out.app.yml
Warning: Generated configuration is not included in the bundle

The file out.app.yml is not matched by any pattern in the 'include' section of databricks.yml,
so it will not be deployed. Add a matching entry to the 'include' section, for example:

include:
- *.yml

1 change: 1 addition & 0 deletions acceptance/bundle/generate/app_git_backed/script
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
$CLI bundle generate app --existing-app-name my_git_app --config-dir . --key out
18 changes: 18 additions & 0 deletions acceptance/bundle/generate/app_git_backed/test.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[[Server]]
Pattern = "GET /api/2.0/apps/my_git_app"
Response.Body = '''
{
"app_id": "1234567890",
"name": "my_git_app",
"description": "This is a git-backed app",
"git_repository": {
"url": "https://github.com/my-org/my-repo",
"provider": "gitHub",
"auto_deploy": true
},
"git_source": {
"branch": "main",
"source_code_path": "apps/my-app"
}
}
'''
61 changes: 58 additions & 3 deletions bundle/generate/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,21 @@ func ConvertAppToValue(app *apps.App, sourceCodePath string) (dyn.Value, error)
// The majority of fields of the app struct are read-only.
// We copy the relevant fields manually.
dv := map[string]dyn.Value{
"name": dyn.NewValue(app.Name, []dyn.Location{{Line: 1}}),
"description": dyn.NewValue(app.Description, []dyn.Location{{Line: 2}}),
"source_code_path": dyn.NewValue(sourceCodePath, []dyn.Location{{Line: 3}}),
"name": dyn.NewValue(app.Name, []dyn.Location{{Line: 1}}),
"description": dyn.NewValue(app.Description, []dyn.Location{{Line: 2}}),
}

// For a git-backed app, emit git_repository + git_source instead of a
// workspace source_code_path. Otherwise the generated bundle would silently
// down-convert the app to workspace source and point source_code_path at a
// local directory that has nothing downloaded into it.
if app.GitRepository != nil {
dv["git_repository"] = gitRepositoryValue(app.GitRepository)
if gs := gitSourceValue(app); gs.Kind() != dyn.KindNil {
dv["git_source"] = gs
}
} else {
dv["source_code_path"] = dyn.NewValue(sourceCodePath, []dyn.Location{{Line: 4}})
}

if ar.Kind() != dyn.KindNil {
Expand All @@ -26,3 +38,46 @@ func ConvertAppToValue(app *apps.App, sourceCodePath string) (dyn.Value, error)

return dyn.V(dv), nil
}

func gitRepositoryValue(r *apps.GitRepository) dyn.Value {
m := map[string]dyn.Value{
"url": dyn.NewValue(r.Url, []dyn.Location{{Line: 1}}),
"provider": dyn.NewValue(r.Provider, []dyn.Location{{Line: 2}}),
}
if r.AutoDeploy {
m["auto_deploy"] = dyn.NewValue(r.AutoDeploy, []dyn.Location{{Line: 3}})
}
return dyn.NewValue(m, []dyn.Location{{Line: 3}})
}

// gitSourceValue returns the reference the app deploys from (branch, tag, or
// commit, plus an optional repo-relative source_code_path). It prefers the
// configured git_source and falls back to the default source of the app's most
// recent deployment. System-populated fields (resolved_commit and the nested
// git_repository) are intentionally omitted.
func gitSourceValue(app *apps.App) dyn.Value {
src := app.GitSource
if src == nil {
src = app.DefaultGitSource
}
if src == nil {
return dyn.NilValue
}

m := map[string]dyn.Value{}
switch {
case src.Branch != "":
m["branch"] = dyn.NewValue(src.Branch, []dyn.Location{{Line: 1}})
case src.Tag != "":
m["tag"] = dyn.NewValue(src.Tag, []dyn.Location{{Line: 1}})
case src.Commit != "":
m["commit"] = dyn.NewValue(src.Commit, []dyn.Location{{Line: 1}})
}
if src.SourceCodePath != "" {
m["source_code_path"] = dyn.NewValue(src.SourceCodePath, []dyn.Location{{Line: 2}})
}
if len(m) == 0 {
return dyn.NilValue
}
return dyn.NewValue(m, []dyn.Location{{Line: 4}})
}
6 changes: 4 additions & 2 deletions cmd/bundle/generate/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,10 @@ per target environment.`,

sourceCodePath := app.DefaultSourceCodePath
// If the source code path is not set, we don't need to download anything.
// This is the case for apps that are not yet deployed.
if sourceCodePath != "" {
// This is the case for apps that are not yet deployed. A git-backed app
// keeps its source in Git rather than the workspace, so there is nothing
// to download and ConvertAppToValue emits git_repository/git_source instead.
if app.GitRepository == nil && sourceCodePath != "" {
err = downloader.MarkDirectoryForDownload(ctx, &sourceCodePath)
if err != nil {
return err
Expand Down
Loading