diff --git a/NEXT_CHANGELOG.md b/NEXT_CHANGELOG.md index c6e54dc1fe..a51678b621 100644 --- a/NEXT_CHANGELOG.md +++ b/NEXT_CHANGELOG.md @@ -13,5 +13,6 @@ * When glob for wheels is used, like "\*.whl", it will filter out different version of the same package and will only take the most recent version. ([#2982](https://github.com/databricks/cli/pull/2982)) * When building Python artifacts as part of "bundle deploy" we no longer delete `dist`, `build`, `*egg-info` and `__pycache__` directories. ([#2982](https://github.com/databricks/cli/pull/2982)) * Fix variable resolution for lookup variables with other references ([#3054](https://github.com/databricks/cli/pull/3054)) +* Added preset `presets.artifacts_dynamic_version` that automatically enables `dynamic_version: true` on all "whl" artifacts. ### API Changes diff --git a/acceptance/bundle/artifacts/artifacts_dynamic_version/databricks.yml b/acceptance/bundle/artifacts/artifacts_dynamic_version/databricks.yml new file mode 100644 index 0000000000..c2134924c2 --- /dev/null +++ b/acceptance/bundle/artifacts/artifacts_dynamic_version/databricks.yml @@ -0,0 +1,10 @@ +presets: + artifacts_dynamic_version: true + +artifacts: + first_wheel: + type: whl + build: uv build --wheel + second_wheel: + type: jar + build: true diff --git a/acceptance/bundle/artifacts/artifacts_dynamic_version/output.txt b/acceptance/bundle/artifacts/artifacts_dynamic_version/output.txt new file mode 100644 index 0000000000..8b4936fa85 --- /dev/null +++ b/acceptance/bundle/artifacts/artifacts_dynamic_version/output.txt @@ -0,0 +1,18 @@ +{ + "first_wheel": { + "build": "uv build --wheel", + "dynamic_version": true, + "files": [ + { + "source": "[TEST_TMP_DIR]/dist/*.whl" + } + ], + "path": "[TEST_TMP_DIR]", + "type": "whl" + }, + "second_wheel": { + "build": "true", + "path": "[TEST_TMP_DIR]", + "type": "jar" + } +} diff --git a/acceptance/bundle/artifacts/artifacts_dynamic_version/script b/acceptance/bundle/artifacts/artifacts_dynamic_version/script new file mode 100644 index 0000000000..c3ba9bd25f --- /dev/null +++ b/acceptance/bundle/artifacts/artifacts_dynamic_version/script @@ -0,0 +1 @@ +$CLI bundle validate -o json | jq .artifacts diff --git a/acceptance/bundle/artifacts/artifacts_dynamic_version/test.toml b/acceptance/bundle/artifacts/artifacts_dynamic_version/test.toml new file mode 100644 index 0000000000..93ee159927 --- /dev/null +++ b/acceptance/bundle/artifacts/artifacts_dynamic_version/test.toml @@ -0,0 +1,5 @@ +RecordRequests = false + +[[Repls]] +Old = '\\\\' +New = '/' diff --git a/acceptance/bundle/debug/out.stderr.txt b/acceptance/bundle/debug/out.stderr.txt index 9e72c92fe2..614238bf53 100644 --- a/acceptance/bundle/debug/out.stderr.txt +++ b/acceptance/bundle/debug/out.stderr.txt @@ -52,6 +52,7 @@ 10:07:59 Debug: Apply pid=12345 mutator=CheckPermissions 10:07:59 Debug: Apply pid=12345 mutator=TranslatePaths 10:07:59 Debug: Apply pid=12345 mutator=PythonWrapperWarning +10:07:59 Debug: Apply pid=12345 mutator=ApplyArtifactsDynamicVersion 10:07:59 Debug: Apply pid=12345 mutator=artifacts.Prepare 10:07:59 Info: No local tasks in databricks.yml config, skipping auto detect pid=12345 mutator=artifacts.Prepare 10:07:59 Debug: Apply pid=12345 mutator=apps.Validate diff --git a/bundle/config/mutator/artifacts_dynamic_version.go b/bundle/config/mutator/artifacts_dynamic_version.go new file mode 100644 index 0000000000..9d66a7619b --- /dev/null +++ b/bundle/config/mutator/artifacts_dynamic_version.go @@ -0,0 +1,38 @@ +package mutator + +import ( + "context" + + "github.com/databricks/cli/bundle" + "github.com/databricks/cli/libs/diag" +) + +type artifactsUseDynamicVersion struct{} + +// ApplyArtifactsDynamicVersion configures all artifacts to use dynamic_version when the preset is enabled. +func ApplyArtifactsDynamicVersion() bundle.Mutator { + return &artifactsUseDynamicVersion{} +} + +func (m *artifactsUseDynamicVersion) Name() string { + return "ApplyArtifactsDynamicVersion" +} + +func (m *artifactsUseDynamicVersion) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagnostics { + if !b.Config.Presets.ArtifactsDynamicVersion { + return nil + } + + for _, a := range b.Config.Artifacts { + if a == nil { + continue + } + if a.Type != "whl" { + // This has no effect since we only apply DynamicVersion if type is "whl" but it makes output cleaner. + continue + } + a.DynamicVersion = true + } + + return nil +} diff --git a/bundle/config/presets.go b/bundle/config/presets.go index 252c5b5f74..46562067ae 100644 --- a/bundle/config/presets.go +++ b/bundle/config/presets.go @@ -24,6 +24,9 @@ type Presets struct { // File synchronization to ${workspace.file_path} is skipped. SourceLinkedDeployment *bool `json:"source_linked_deployment,omitempty"` + // ArtifactsDynamicVersion enables dynamic_version on every artifact. + ArtifactsDynamicVersion bool `json:"artifacts_dynamic_version,omitempty"` + // Tags to add to all resources. Tags map[string]string `json:"tags,omitempty"` } diff --git a/bundle/internal/schema/annotations.yml b/bundle/internal/schema/annotations.yml index c68bca50f9..a7ab9a8ba5 100644 --- a/bundle/internal/schema/annotations.yml +++ b/bundle/internal/schema/annotations.yml @@ -104,6 +104,9 @@ github.com/databricks/cli/bundle/config.Lock: "description": |- Whether to force this lock if it is enabled. github.com/databricks/cli/bundle/config.Presets: + "artifacts_dynamic_version": + "description": |- + Whether to enable dynamic_version on all artifacts. "jobs_max_concurrent_runs": "description": |- The maximum concurrent runs for a job. diff --git a/bundle/phases/initialize.go b/bundle/phases/initialize.go index c3d3d27656..7af9d61329 100644 --- a/bundle/phases/initialize.go +++ b/bundle/phases/initialize.go @@ -151,6 +151,11 @@ func Initialize(ctx context.Context, b *bundle.Bundle) diag.Diagnostics { // Provides warnings when Python wheel tasks are used with DBR < 13.3 or when wheel wrapper is incompatible with source-linked deployment trampoline.WrapperWarning(), + // Reads (typed): b.Config.Presets.ArtifactsDynamicVersion (checks if artifacts preset is enabled) + // Updates (typed): b.Config.Artifacts[].DynamicVersion (sets to true when preset is enabled) + // Applies the artifacts_dynamic_version preset to enable dynamic versioning on all artifacts + mutator.ApplyArtifactsDynamicVersion(), + // Reads (typed): b.Config.Artifacts, b.BundleRootPath (checks artifact configurations and bundle path) // Updates (typed): b.Config.Artifacts (auto-creates Python wheel artifact if none defined but setup.py exists) // Updates (dynamic): artifacts.*.{path,build_command,files.*.source} (sets default paths, build commands, and makes relative paths absolute) diff --git a/bundle/schema/jsonschema.json b/bundle/schema/jsonschema.json index 5b220c5c0b..517766be58 100644 --- a/bundle/schema/jsonschema.json +++ b/bundle/schema/jsonschema.json @@ -1795,6 +1795,10 @@ { "type": "object", "properties": { + "artifacts_dynamic_version": { + "description": "Whether to enable dynamic_version on all artifacts.", + "$ref": "#/$defs/bool" + }, "jobs_max_concurrent_runs": { "description": "The maximum concurrent runs for a job.", "$ref": "#/$defs/int"