Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
2725b5d
Add bare template for importing existing resources
janniklasrose Oct 15, 2026
82852ca
Add --init-bare flag for bundle generate no-bundle path
janniklasrose Oct 15, 2026
98d367e
Add generate parity test anchored to bundle resources
janniklasrose Oct 15, 2026
cc235a3
Regenerate acceptance test outputs and add default-bare template test
janniklasrose Oct 15, 2026
f369a8d
Add changelog entry for --init-bare flag
janniklasrose Oct 15, 2026
9ae6a83
Update template tests to include default-bare
janniklasrose Oct 15, 2026
514482b
Improve parity test and wire --init-bare into all generators
janniklasrose Oct 15, 2026
cbbf984
Regenerate help output for bundle generate and init commands
janniklasrose Oct 15, 2026
32634e1
Wire ensureGenerateBundle into dashboard, genie_space; add flag rejec…
janniklasrose Oct 15, 2026
650a6e8
Fix cmdio initialization for bundle generate workspace client setup
janniklasrose Oct 15, 2026
bca9b73
Add spec for bundle generate coverage
janniklasrose Oct 30, 2026
01efcac
Merge remote-tracking branch 'origin/main' into specwork/bundle-generate
janniklasrose Nov 4, 2026
168163d
Load the bundle once per generate command and gate --init-bare flags …
janniklasrose Nov 4, 2026
127b4ba
Render the default-bare template into the output directory itself
janniklasrose Nov 4, 2026
bb4ebb3
Anchor the generate parity test to config.SupportedResources
janniklasrose Nov 4, 2026
32057b2
Add acceptance tests for bundle generate --init-bare
janniklasrose Nov 4, 2026
4811903
Link the changelog fragment to the PR
janniklasrose Nov 4, 2026
7507ca6
Put the changelog PR link after the period as the checker expects
janniklasrose Nov 4, 2026
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/bundle-generate-init-bare.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* Add the `default-bare` template to `databricks bundle init` and the `--init-bare` flag to `databricks bundle generate`, which creates that bare bundle in the current directory when there is no `databricks.yml` yet. ([#7355](https://github.com/databricks/cli/pull/7355))
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Cloud = false
EnvMatrix.DMS = ["", "true"]
22 changes: 22 additions & 0 deletions acceptance/bundle/generate/init_bare_rejected_flags/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

>>> errcode [CLI] bundle generate job --existing-job-id 1234
Error: no databricks.yml found in this directory or any parent; run `databricks bundle init default-bare` first or re-run with --init-bare

Exit code: 1

>>> errcode [CLI] bundle generate job --existing-job-id 1234 --init-bare --bind
Error: --bind requires an existing bundle and cannot be combined with --init-bare

Exit code: 1

>>> errcode [CLI] bundle generate dashboard --resource my_dashboard --init-bare
Error: --resource requires an existing bundle and cannot be combined with --init-bare

Exit code: 1

>>> errcode [CLI] bundle generate genie-space --resource my_space --watch --init-bare
Error: --resource requires an existing bundle and cannot be combined with --init-bare

Exit code: 1

>>> find.py databricks.yml --expect 0
9 changes: 9 additions & 0 deletions acceptance/bundle/generate/init_bare_rejected_flags/script
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# There is no databricks.yml here. Without --init-bare generate points at it.
trace errcode $CLI bundle generate job --existing-job-id 1234

# Flags that need an existing bundle are rejected before anything is written.
trace errcode $CLI bundle generate job --existing-job-id 1234 --init-bare --bind
trace errcode $CLI bundle generate dashboard --resource my_dashboard --init-bare
trace errcode $CLI bundle generate genie-space --resource my_space --watch --init-bare

trace find.py 'databricks.yml' --expect 0
2 changes: 2 additions & 0 deletions acceptance/bundle/generate/job_init_bare/out.test.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Cloud = false
EnvMatrix.DMS = ["", "true"]
47 changes: 47 additions & 0 deletions acceptance/bundle/generate/job_init_bare/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@

>>> [CLI] bundle generate job --existing-job-id 1234 --key out --init-bare
No databricks.yml found. Initializing a bare bundle skeleton.
Welcome to the bare Declarative Automation Bundle template!

This template creates the smallest bundle skeleton, meant for importing existing resources with `databricks bundle generate`.

Your workspace at [DATABRICKS_URL] is used for initialization.

✨ Your bare bundle has been created.

Add generated resources under `resources/` and supporting code under `src/`.
File successfully saved to src/outnotebook.py
Job configuration successfully saved to resources/out.job.yml

>>> find.py ^(resources|src)/
resources/.gitkeep
resources/out.job.yml
src/.gitkeep
src/outnotebook.py

>>> cat databricks.yml
# This is a Declarative Automation Bundle definition for my_project.
# See https://docs.databricks.com/dev-tools/bundles/index.html for documentation.
bundle:
name: my_project
uuid: [UUID]

include:
- resources/*.yml

targets:
dev:
default: true
mode: development
workspace:
host: [DATABRICKS_URL]

>>> cat resources/out.job.yml
resources:
jobs:
out:
name: gitjob
tasks:
- task_key: test_task
notebook_task:
notebook_path: ../src/outnotebook.py
13 changes: 13 additions & 0 deletions acceptance/bundle/generate/job_init_bare/script
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# The bundle takes its name from the directory it is created in.
mkdir my_project
cd my_project

# There is no databricks.yml here; --init-bare creates the bare bundle first.
trace $CLI bundle generate job --existing-job-id 1234 --key out --init-bare

trace find.py '^(resources|src)/'
trace cat databricks.yml
trace cat resources/out.job.yml

cd ..
rm -r my_project
35 changes: 35 additions & 0 deletions acceptance/bundle/generate/job_init_bare/test.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
[[Server]]
Pattern = "GET /api/2.2/jobs/get"
Response.Body = '''
{
"job_id": 11223344,
"settings": {
"name": "gitjob",
"tasks": [
{
"task_key": "test_task",
"notebook_task": {
"notebook_path": "/Workspace/Users/tester@databricks.com/outnotebook"
}
}
]
}
}
'''

[[Server]]
Pattern = "GET /api/2.0/workspace/get-status"
Response.Body = '''
{
"path": "/Workspace/Users/tester@databricks.com/outnotebook",
"object_type": "NOTEBOOK",
"language": "PYTHON",
"repos_export_format": "SOURCE"
}
'''

[[Server]]
Pattern = "GET /api/2.0/workspace/export"
Response.Body = '''
print("Hello, World!")
'''
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ Flags:

Global Flags:
--debug enable debug logging
--init-bare create a bare bundle in the current directory if there is no databricks.yml yet
--key string resource key to use for the generated configuration
-o, --output type output type: text or json (default text)
-p, --profile string ~/.databrickscfg profile
Expand Down
1 change: 1 addition & 0 deletions acceptance/bundle/help/bundle-generate-job/output.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Flags:

Global Flags:
--debug enable debug logging
--init-bare create a bare bundle in the current directory if there is no databricks.yml yet
--key string resource key to use for the generated configuration
-o, --output type output type: text or json (default text)
-p, --profile string ~/.databrickscfg profile
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Flags:

Global Flags:
--debug enable debug logging
--init-bare create a bare bundle in the current directory if there is no databricks.yml yet
--key string resource key to use for the generated configuration
-o, --output type output type: text or json (default text)
-p, --profile string ~/.databrickscfg profile
Expand Down
3 changes: 3 additions & 0 deletions acceptance/bundle/help/bundle-generate/output.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Common patterns:
databricks bundle generate dashboard --existing-path /my-dashboard --key sales_dash
databricks bundle generate dashboard --resource my_dashboard --watch --force # Keep local copy in sync. Useful for development.
databricks bundle generate dashboard --resource my_dashboard --force # Do a one-time sync.
databricks bundle generate job --existing-job-id 123 --init-bare # Start a new bundle from an existing job.

Migration workflows:

Expand All @@ -22,6 +23,7 @@ Migration workflows:

Use --key to specify the resource name in your bundle configuration.
Use --bind to automatically bind the generated resource to the existing workspace resource.
Use --init-bare to create a bare bundle in the current directory when there is no databricks.yml yet.

Usage:
databricks bundle generate [command]
Expand All @@ -36,6 +38,7 @@ Available Commands:

Flags:
-h, --help help for generate
--init-bare create a bare bundle in the current directory if there is no databricks.yml yet
--key string resource key to use for the generated configuration

Global Flags:
Expand Down
1 change: 1 addition & 0 deletions acceptance/bundle/help/bundle-init/output.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ TEMPLATE_PATH optionally specifies which template to use. It can be one of the f
- default-python: The default Python template for Notebooks and Lakeflow
- default-sql: The default SQL template for .sql files that run with Databricks SQL
- default-minimal: The minimal template, for advanced users
- default-bare: The bare template for importing existing resources
- default-scala: The default Scala template for JAR jobs
- lakeflow-integrations: The template for Lakeflow integrations
- dbt-sql: The dbt SQL template (databricks.com/blog/delivering-cost-effective-data-real-time-dbt-and-databricks)
Expand Down
3 changes: 3 additions & 0 deletions acceptance/bundle/templates/default-bare/minimal/input.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"project_name": "my_bare_bundle"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Cloud = false
EnvMatrix.DMS = [""]
30 changes: 30 additions & 0 deletions acceptance/bundle/templates/default-bare/minimal/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@

>>> [CLI] bundle init default-bare --config-file ./input.json --output-dir output -o json
Welcome to the bare Declarative Automation Bundle template!

This template creates the smallest bundle skeleton, meant for importing existing resources with `databricks bundle generate`.

Your workspace at [DATABRICKS_URL] is used for initialization.

✨ Your bare bundle has been created.

Add generated resources under `resources/` and supporting code under `src/`.
{
"outputs": [
".gitignore",
"README.md",
"databricks.yml",
"resources/.gitkeep",
"src/.gitkeep"
]
}

>>> [CLI] bundle validate -t dev
Name: my_bare_bundle
Target: dev
Workspace:
Host: [DATABRICKS_URL]
User: [USERNAME]
Path: /Workspace/Users/[USERNAME]/.bundle/my_bare_bundle/dev

Validation OK!
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# my_bare_bundle

This is a bare Declarative Automation Bundle skeleton.

- Put generated bundle resource definitions in `resources/`
- Put notebooks, scripts, and other source files in `src/`
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# This is a Declarative Automation Bundle definition for my_bare_bundle.
# See https://docs.databricks.com/dev-tools/bundles/index.html for documentation.
bundle:
name: my_bare_bundle
uuid: [UUID]

include:
- resources/*.yml

targets:
dev:
default: true
mode: development
workspace:
host: [DATABRICKS_URL]
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.databricks/
.venv/
dist/
Empty file.
15 changes: 15 additions & 0 deletions acceptance/bundle/templates/default-bare/minimal/script
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
trace $CLI bundle init default-bare --config-file ./input.json --output-dir output -o json

cd output

# Verify that empty directories are preserved
[ -d "src" ] || exit 1
[ -d "resources" ] || exit 1

trace $CLI bundle validate -t dev

# Do not affect this repository's git behaviour #2318
mv .gitignore out.gitignore
rm -r .databricks

cd ..
6 changes: 5 additions & 1 deletion cmd/bundle/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

func newGenerateCommand() *cobra.Command {
var key string
var initBare bool

cmd := &cobra.Command{
Use: "generate",
Expand All @@ -19,6 +20,7 @@ Common patterns:
databricks bundle generate dashboard --existing-path /my-dashboard --key sales_dash
databricks bundle generate dashboard --resource my_dashboard --watch --force # Keep local copy in sync. Useful for development.
databricks bundle generate dashboard --resource my_dashboard --force # Do a one-time sync.
databricks bundle generate job --existing-job-id 123 --init-bare # Start a new bundle from an existing job.

Migration workflows:

Expand All @@ -32,7 +34,8 @@ Migration workflows:
2. Deploy: databricks bundle deploy

Use --key to specify the resource name in your bundle configuration.
Use --bind to automatically bind the generated resource to the existing workspace resource.`,
Use --bind to automatically bind the generated resource to the existing workspace resource.
Use --init-bare to create a bare bundle in the current directory when there is no databricks.yml yet.`,
}

cmd.AddCommand(generate.NewGenerateJobCommand())
Expand All @@ -42,5 +45,6 @@ Use --bind to automatically bind the generated resource to the existing workspac
cmd.AddCommand(generate.NewGenerateAppCommand())
cmd.AddCommand(generate.NewGenerateGenieSpaceCommand())
cmd.PersistentFlags().StringVar(&key, "key", "", `resource key to use for the generated configuration`)
cmd.PersistentFlags().BoolVar(&initBare, "init-bare", false, `create a bare bundle in the current directory if there is no databricks.yml yet`)
return cmd
}
12 changes: 4 additions & 8 deletions cmd/bundle/generate/alert.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@ import (
"path/filepath"

"github.com/databricks/cli/bundle/generate"
"github.com/databricks/cli/cmd/root"
"github.com/databricks/cli/libs/cmdio"
"github.com/databricks/cli/libs/dyn"
"github.com/databricks/cli/libs/dyn/yamlsaver"
"github.com/databricks/cli/libs/logdiag"
"github.com/databricks/cli/libs/textutil"
"github.com/databricks/databricks-sdk-go/apierr"
"github.com/databricks/databricks-sdk-go/service/sql"
Expand Down Expand Up @@ -62,13 +60,11 @@ After generation, you can deploy this alert to other targets using:
cmd.Flags().BoolVarP(&force, "force", "f", false, `force overwrite existing files in the output directory`)

cmd.RunE = func(cmd *cobra.Command, args []string) error {
ctx := logdiag.InitContext(cmd.Context())
cmd.SetContext(ctx)

b := root.MustConfigureBundle(cmd)
if b == nil || logdiag.HasError(ctx) {
return root.ErrAlreadyPrinted
b, err := configureBundle(cmd)
if err != nil {
return err
}
ctx := cmd.Context()

w := b.WorkspaceClient(ctx)

Expand Down
12 changes: 4 additions & 8 deletions cmd/bundle/generate/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@ import (

"github.com/databricks/cli/bundle/generate"
"github.com/databricks/cli/cmd/bundle/deployment"
"github.com/databricks/cli/cmd/root"
"github.com/databricks/cli/libs/cmdio"
"github.com/databricks/cli/libs/dyn"
"github.com/databricks/cli/libs/dyn/yamlsaver"
"github.com/databricks/cli/libs/logdiag"
"github.com/databricks/cli/libs/textutil"
"github.com/databricks/databricks-sdk-go/service/apps"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -62,13 +60,11 @@ per target environment.`,
cmd.Flags().MarkHidden("bind")

cmd.RunE = func(cmd *cobra.Command, args []string) error {
ctx := logdiag.InitContext(cmd.Context())
cmd.SetContext(ctx)

b := root.MustConfigureBundle(cmd)
if b == nil || logdiag.HasError(ctx) {
return root.ErrAlreadyPrinted
b, err := configureBundle(cmd, "bind")
if err != nil {
return err
}
ctx := cmd.Context()

w := b.WorkspaceClient(ctx)
cmdio.LogString(ctx, fmt.Sprintf("Loading app '%s' configuration", appName))
Expand Down
10 changes: 4 additions & 6 deletions cmd/bundle/generate/dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,13 +400,11 @@ func (d *dashboard) runForExisting(ctx context.Context, b *bundle.Bundle) {
}

func (d *dashboard) RunE(cmd *cobra.Command, args []string) error {
ctx := logdiag.InitContext(cmd.Context())
cmd.SetContext(ctx)

b := root.MustConfigureBundle(cmd)
if b == nil || logdiag.HasError(ctx) {
return root.ErrAlreadyPrinted
b, err := configureBundle(cmd, "bind", "resource", "watch")
if err != nil {
return err
}
ctx := cmd.Context()

d.initialize(ctx, b)
if logdiag.HasError(ctx) {
Expand Down
Loading
Loading