mirror of https://github.com/databricks/cli.git
Compare commits
No commits in common. "511c8887a8b6b4916cf65e159d8d44a763c677eb" and "f2bba632cb8ab7649e5a80abd2aa106d631060a7" have entirely different histories.
511c8887a8
...
f2bba632cb
44
CHANGELOG.md
44
CHANGELOG.md
|
@ -1,49 +1,5 @@
|
||||||
# Version changelog
|
# Version changelog
|
||||||
|
|
||||||
## [Release] Release v0.239.0
|
|
||||||
|
|
||||||
### New feature announcement
|
|
||||||
|
|
||||||
#### Databricks Apps support
|
|
||||||
|
|
||||||
You can now manage Databricks Apps using DABs by defining an `app` resource in your bundle configuration.
|
|
||||||
For more information see Databricks documentation https://docs.databricks.com/en/dev-tools/bundles/resources.html#app
|
|
||||||
|
|
||||||
#### Referencing complex variables in complex variables
|
|
||||||
|
|
||||||
You can now reference complex variables within other complex variables.
|
|
||||||
For more details see https://github.com/databricks/cli/pull/2157
|
|
||||||
|
|
||||||
CLI:
|
|
||||||
* Filter out system clusters in cluster picker ([#2131](https://github.com/databricks/cli/pull/2131)).
|
|
||||||
* Add command line flags for fields that are not in the API request body ([#2155](https://github.com/databricks/cli/pull/2155)).
|
|
||||||
|
|
||||||
Bundles:
|
|
||||||
* Added support for Databricks Apps in DABs ([#1928](https://github.com/databricks/cli/pull/1928)).
|
|
||||||
* Allow artifact path to be located outside the sync root ([#2128](https://github.com/databricks/cli/pull/2128)).
|
|
||||||
* Retry app deployment if there is an active deployment in progress ([#2153](https://github.com/databricks/cli/pull/2153)).
|
|
||||||
* Resolve variables in a loop ([#2164](https://github.com/databricks/cli/pull/2164)).
|
|
||||||
* Improve resolution of complex variables within complex variables ([#2157](https://github.com/databricks/cli/pull/2157)).
|
|
||||||
* Added output message to warn about slower deployments with apps ([#2161](https://github.com/databricks/cli/pull/2161)).
|
|
||||||
* Patch references to UC schemas to capture dependencies automatically ([#1989](https://github.com/databricks/cli/pull/1989)).
|
|
||||||
* Format default-python template ([#2110](https://github.com/databricks/cli/pull/2110)).
|
|
||||||
* Encourage the use of root_path in production to ensure single deployment ([#1712](https://github.com/databricks/cli/pull/1712)).
|
|
||||||
* Log warnings to stderr for "bundle validate -o json" ([#2109](https://github.com/databricks/cli/pull/2109)).
|
|
||||||
|
|
||||||
API Changes:
|
|
||||||
* Changed `databricks account federation-policy update` command with new required argument order.
|
|
||||||
* Changed `databricks account service-principal-federation-policy update` command with new required argument order.
|
|
||||||
|
|
||||||
OpenAPI commit 779817ed8d63031f5ea761fbd25ee84f38feec0d (2025-01-08)
|
|
||||||
Dependency updates:
|
|
||||||
* Upgrade TF provider to 1.63.0 ([#2162](https://github.com/databricks/cli/pull/2162)).
|
|
||||||
* Bump golangci-lint version to v1.63.4 from v1.63.1 ([#2114](https://github.com/databricks/cli/pull/2114)).
|
|
||||||
* Bump astral-sh/setup-uv from 4 to 5 ([#2116](https://github.com/databricks/cli/pull/2116)).
|
|
||||||
* Bump golang.org/x/oauth2 from 0.24.0 to 0.25.0 ([#2080](https://github.com/databricks/cli/pull/2080)).
|
|
||||||
* Bump github.com/hashicorp/hc-install from 0.9.0 to 0.9.1 ([#2079](https://github.com/databricks/cli/pull/2079)).
|
|
||||||
* Bump golang.org/x/term from 0.27.0 to 0.28.0 ([#2078](https://github.com/databricks/cli/pull/2078)).
|
|
||||||
* Bump github.com/databricks/databricks-sdk-go from 0.54.0 to 0.55.0 ([#2126](https://github.com/databricks/cli/pull/2126)).
|
|
||||||
|
|
||||||
## [Release] Release v0.238.0
|
## [Release] Release v0.238.0
|
||||||
|
|
||||||
Bundles:
|
Bundles:
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
bundle:
|
|
||||||
name: complex-cross-ref
|
|
||||||
|
|
||||||
variables:
|
|
||||||
a:
|
|
||||||
default:
|
|
||||||
a_1: 500
|
|
||||||
a_2: ${var.b.b_2}
|
|
||||||
b:
|
|
||||||
default:
|
|
||||||
b_1: ${var.a.a_1}
|
|
||||||
b_2: 2.5
|
|
|
@ -1,22 +0,0 @@
|
||||||
{
|
|
||||||
"a": {
|
|
||||||
"default": {
|
|
||||||
"a_1": 500,
|
|
||||||
"a_2": 2.5
|
|
||||||
},
|
|
||||||
"value": {
|
|
||||||
"a_1": 500,
|
|
||||||
"a_2": 2.5
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"b": {
|
|
||||||
"default": {
|
|
||||||
"b_1": 500,
|
|
||||||
"b_2": 2.5
|
|
||||||
},
|
|
||||||
"value": {
|
|
||||||
"b_1": 500,
|
|
||||||
"b_2": 2.5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
$CLI bundle validate -o json | jq .variables
|
|
|
@ -1,7 +0,0 @@
|
||||||
bundle:
|
|
||||||
name: cycle
|
|
||||||
|
|
||||||
variables:
|
|
||||||
a:
|
|
||||||
default:
|
|
||||||
hello: ${var.a}
|
|
|
@ -1,9 +0,0 @@
|
||||||
Warning: Detected unresolved variables after 11 resolution rounds
|
|
||||||
|
|
||||||
Name: cycle
|
|
||||||
Target: default
|
|
||||||
Workspace:
|
|
||||||
User: $USERNAME
|
|
||||||
Path: /Workspace/Users/$USERNAME/.bundle/cycle/default
|
|
||||||
|
|
||||||
Found 1 warning
|
|
|
@ -1 +0,0 @@
|
||||||
$CLI bundle validate
|
|
|
@ -1,10 +0,0 @@
|
||||||
bundle:
|
|
||||||
name: cycle
|
|
||||||
|
|
||||||
variables:
|
|
||||||
a:
|
|
||||||
default:
|
|
||||||
hello: ${var.b}
|
|
||||||
b:
|
|
||||||
default:
|
|
||||||
hello: ${var.a}
|
|
|
@ -1,9 +0,0 @@
|
||||||
Warning: Detected unresolved variables after 11 resolution rounds
|
|
||||||
|
|
||||||
Name: cycle
|
|
||||||
Target: default
|
|
||||||
Workspace:
|
|
||||||
User: $USERNAME
|
|
||||||
Path: /Workspace/Users/$USERNAME/.bundle/cycle/default
|
|
||||||
|
|
||||||
Found 1 warning
|
|
|
@ -1 +0,0 @@
|
||||||
$CLI bundle validate
|
|
|
@ -1,3 +1,3 @@
|
||||||
{
|
{
|
||||||
"spark.databricks.sql.initial.catalog.name": "hive_metastore"
|
"spark.databricks.sql.initial.catalog.name": "${var.catalog}"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
bundle:
|
|
||||||
name: cycle
|
|
||||||
|
|
||||||
variables:
|
|
||||||
a:
|
|
||||||
default: ${var.b}
|
|
||||||
b:
|
|
||||||
default: ${var.a}
|
|
|
@ -1,14 +0,0 @@
|
||||||
Error: cycle detected in field resolution: variables.a.default -> var.b -> var.a -> var.b
|
|
||||||
|
|
||||||
{
|
|
||||||
"a": {
|
|
||||||
"default": "${var.b}",
|
|
||||||
"value": "${var.b}"
|
|
||||||
},
|
|
||||||
"b": {
|
|
||||||
"default": "${var.a}",
|
|
||||||
"value": "${var.a}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Exit code: 1
|
|
|
@ -1 +0,0 @@
|
||||||
$CLI bundle validate -o json | jq .variables
|
|
|
@ -3,7 +3,6 @@ package mutator
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/databricks/cli/bundle"
|
"github.com/databricks/cli/bundle"
|
||||||
"github.com/databricks/cli/bundle/config"
|
"github.com/databricks/cli/bundle/config"
|
||||||
|
@ -14,37 +13,15 @@ import (
|
||||||
"github.com/databricks/cli/libs/dyn/dynvar"
|
"github.com/databricks/cli/libs/dyn/dynvar"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
|
||||||
For pathological cases, output and time grow exponentially.
|
|
||||||
|
|
||||||
On my laptop, timings for acceptance/bundle/variables/complex-cycle:
|
|
||||||
rounds time
|
|
||||||
|
|
||||||
9 0.10s
|
|
||||||
10 0.13s
|
|
||||||
11 0.27s
|
|
||||||
12 0.68s
|
|
||||||
13 1.98s
|
|
||||||
14 6.28s
|
|
||||||
15 21.70s
|
|
||||||
16 78.16s
|
|
||||||
*/
|
|
||||||
const maxResolutionRounds = 11
|
|
||||||
|
|
||||||
type resolveVariableReferences struct {
|
type resolveVariableReferences struct {
|
||||||
prefixes []string
|
prefixes []string
|
||||||
pattern dyn.Pattern
|
pattern dyn.Pattern
|
||||||
lookupFn func(dyn.Value, dyn.Path, *bundle.Bundle) (dyn.Value, error)
|
lookupFn func(dyn.Value, dyn.Path, *bundle.Bundle) (dyn.Value, error)
|
||||||
skipFn func(dyn.Value) bool
|
skipFn func(dyn.Value) bool
|
||||||
extraRounds int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ResolveVariableReferences(prefixes ...string) bundle.Mutator {
|
func ResolveVariableReferences(prefixes ...string) bundle.Mutator {
|
||||||
return &resolveVariableReferences{
|
return &resolveVariableReferences{prefixes: prefixes, lookupFn: lookup}
|
||||||
prefixes: prefixes,
|
|
||||||
lookupFn: lookup,
|
|
||||||
extraRounds: maxResolutionRounds - 1,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ResolveVariableReferencesInLookup() bundle.Mutator {
|
func ResolveVariableReferencesInLookup() bundle.Mutator {
|
||||||
|
@ -109,36 +86,7 @@ func (m *resolveVariableReferences) Apply(ctx context.Context, b *bundle.Bundle)
|
||||||
varPath := dyn.NewPath(dyn.Key("var"))
|
varPath := dyn.NewPath(dyn.Key("var"))
|
||||||
|
|
||||||
var diags diag.Diagnostics
|
var diags diag.Diagnostics
|
||||||
maxRounds := 1 + m.extraRounds
|
|
||||||
|
|
||||||
for round := range maxRounds {
|
|
||||||
hasUpdates, newDiags := m.resolveOnce(b, prefixes, varPath)
|
|
||||||
|
|
||||||
diags = diags.Extend(newDiags)
|
|
||||||
|
|
||||||
if diags.HasError() {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if !hasUpdates {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if round >= maxRounds-1 {
|
|
||||||
diags = diags.Append(diag.Diagnostic{
|
|
||||||
Severity: diag.Warning,
|
|
||||||
Summary: fmt.Sprintf("Detected unresolved variables after %d resolution rounds", round+1),
|
|
||||||
// Would be nice to include names of the variables there, but that would complicate things more
|
|
||||||
})
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return diags
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *resolveVariableReferences) resolveOnce(b *bundle.Bundle, prefixes []dyn.Path, varPath dyn.Path) (bool, diag.Diagnostics) {
|
|
||||||
var diags diag.Diagnostics
|
|
||||||
hasUpdates := false
|
|
||||||
err := b.Config.Mutate(func(root dyn.Value) (dyn.Value, error) {
|
err := b.Config.Mutate(func(root dyn.Value) (dyn.Value, error) {
|
||||||
// Synthesize a copy of the root that has all fields that are present in the type
|
// Synthesize a copy of the root that has all fields that are present in the type
|
||||||
// but not set in the dynamic value set to their corresponding empty value.
|
// but not set in the dynamic value set to their corresponding empty value.
|
||||||
|
@ -181,7 +129,6 @@ func (m *resolveVariableReferences) resolveOnce(b *bundle.Bundle, prefixes []dyn
|
||||||
if m.skipFn != nil && m.skipFn(v) {
|
if m.skipFn != nil && m.skipFn(v) {
|
||||||
return dyn.InvalidValue, dynvar.ErrSkipResolution
|
return dyn.InvalidValue, dynvar.ErrSkipResolution
|
||||||
}
|
}
|
||||||
hasUpdates = true
|
|
||||||
return m.lookupFn(normalized, path, b)
|
return m.lookupFn(normalized, path, b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -202,6 +149,5 @@ func (m *resolveVariableReferences) resolveOnce(b *bundle.Bundle, prefixes []dyn
|
||||||
if err != nil {
|
if err != nil {
|
||||||
diags = diags.Extend(diag.FromErr(err))
|
diags = diags.Extend(diag.FromErr(err))
|
||||||
}
|
}
|
||||||
|
return diags
|
||||||
return hasUpdates, diags
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,11 @@ func Initialize() bundle.Mutator {
|
||||||
"workspace",
|
"workspace",
|
||||||
"variables",
|
"variables",
|
||||||
),
|
),
|
||||||
|
mutator.ResolveVariableReferences(
|
||||||
|
"bundle",
|
||||||
|
"workspace",
|
||||||
|
"variables",
|
||||||
|
),
|
||||||
|
|
||||||
mutator.MergeJobClusters(),
|
mutator.MergeJobClusters(),
|
||||||
mutator.MergeJobParameters(),
|
mutator.MergeJobParameters(),
|
||||||
|
|
Loading…
Reference in New Issue