Skip to content

Conversation

kanterov
Copy link
Collaborator

@kanterov kanterov commented Sep 2, 2025

Changes

Move python outside of the experimental section.

The change is backward-compatible and forward-compatible. If CLI is using a newer or older version of databricks-bundles, it will continue to work. It's implemented by copying the content of python into experimental.python. If we don't offer compatibility, there is a risk that previously deployed resources will be erased because we wouldn't be able to load resources.

See also #3539

Why

Python support for Databricks Asset Bundles is graduating from the experimental status.

Tests

Acceptance tests check that previous databricks-bundles versions continue to work.

@kanterov kanterov force-pushed the python-non-experimental branch from fe939e5 to 3c1043c Compare September 2, 2025 14:15
@eng-dev-ecosystem-bot
Copy link
Collaborator

Run: 17406397515

Env ✅​pass 🔄​flaky 🙈​skip
✅​ aws linux 308 511
🔄​ aws windows 306 3 510
Test Name aws windows
TestAccept 🔄​flaky
TestAccept/bundle/templates/default-python/integration_classic 🔄​flaky
TestAccept/bundle/templates/default-python/integration_classic/DATABRICKS_CLI_DEPLOYMENT=terraform/UV_PYTHON=3.13 🔄​flaky

@eng-dev-ecosystem-bot
Copy link
Collaborator

eng-dev-ecosystem-bot commented Sep 2, 2025

Run: 17553097768

Env ✅​pass ❌​FAIL 🔄​flaky 🙈​skip
✅​ aws linux 308 524
✅​ aws windows 309 523
✅​ aws-ucws linux 420 422
✅​ aws-ucws windows 421 421
✅​ azure linux 308 523
🔄​ azure windows 306 3 522
✅​ azure-ucws linux 420 421
✅​ azure-ucws windows 421 420
❌​ gcp linux 282 25 525
❌​ gcp windows 290 18 524
40 failing tests:
Test Name azure windows gcp linux gcp windows
TestAccept 🔄​flaky ❌​FAIL ❌​FAIL
TestAccept/bundle/deploy/files/no-snapshot-sync ✅​pass ❌​FAIL ✅​pass
TestAccept/bundle/deploy/files/no-snapshot-sync/DATABRICKS_CLI_DEPLOYMENT=direct-exp ✅​pass ❌​FAIL ✅​pass
TestAccept/bundle/deploy/files/no-snapshot-sync/DATABRICKS_CLI_DEPLOYMENT=terraform ✅​pass ❌​FAIL ✅​pass
TestAccept/bundle/deploy/jobs/check-metadata ✅​pass ❌​FAIL ✅​pass
TestAccept/bundle/deploy/jobs/check-metadata/DATABRICKS_CLI_DEPLOYMENT=terraform ✅​pass ❌​FAIL ✅​pass
TestAccept/bundle/deploy/jobs/double-underscore-keys ✅​pass ❌​FAIL ✅​pass
TestAccept/bundle/deploy/jobs/double-underscore-keys/DATABRICKS_CLI_DEPLOYMENT=direct-exp ✅​pass ❌​FAIL ✅​pass
TestAccept/bundle/deploy/jobs/fail-on-active-runs ✅​pass ❌​FAIL ❌​FAIL
TestAccept/bundle/deploy/jobs/fail-on-active-runs/DATABRICKS_CLI_DEPLOYMENT=direct-exp ✅​pass ❌​FAIL ❌​FAIL
TestAccept/bundle/deploy/pipeline/allow-duplicate-names ✅​pass ✅​pass ❌​FAIL
TestAccept/bundle/deploy/pipeline/allow-duplicate-names/DATABRICKS_CLI_DEPLOYMENT=direct-exp ✅​pass ✅​pass ❌​FAIL
TestAccept/bundle/deploy/pipeline/allow-duplicate-names/DATABRICKS_CLI_DEPLOYMENT=terraform ✅​pass ✅​pass ❌​FAIL
TestAccept/bundle/deploy/pipeline/auto-approve ✅​pass ✅​pass ❌​FAIL
TestAccept/bundle/deploy/pipeline/auto-approve/DATABRICKS_CLI_DEPLOYMENT=direct-exp ✅​pass ✅​pass ❌​FAIL
TestAccept/bundle/deploy/pipeline/auto-approve/DATABRICKS_CLI_DEPLOYMENT=terraform ✅​pass ✅​pass ❌​FAIL
TestAccept/bundle/destroy/jobs-and-pipeline ✅​pass ❌​FAIL ✅​pass
TestAccept/bundle/destroy/jobs-and-pipeline/DATABRICKS_CLI_DEPLOYMENT=direct-exp ✅​pass ❌​FAIL ✅​pass
TestAccept/bundle/destroy/jobs-and-pipeline/DATABRICKS_CLI_DEPLOYMENT=terraform ✅​pass ❌​FAIL ✅​pass
TestAccept/bundle/local_state_staleness ✅​pass ❌​FAIL ✅​pass
TestAccept/bundle/local_state_staleness/DATABRICKS_CLI_DEPLOYMENT=direct-exp ✅​pass ❌​FAIL ✅​pass
TestAccept/bundle/local_state_staleness/DATABRICKS_CLI_DEPLOYMENT=terraform ✅​pass ❌​FAIL ✅​pass
TestAccept/bundle/resources/pipelines/update ✅​pass ❌​FAIL ✅​pass
TestAccept/bundle/resources/pipelines/update/DATABRICKS_CLI_DEPLOYMENT=direct-exp ✅​pass ❌​FAIL ✅​pass
TestAccept/bundle/templates/default-python/combinations/classic 🔄​flaky ❌​FAIL ❌​FAIL
TestAccept/bundle/templates/default-python/combinations/classic/DATABRICKS_CLI_DEPLOYMENT=direct-exp/DLT=no/NBOOK=no/PY=yes ✅​pass ✅​pass ❌​FAIL
TestAccept/bundle/templates/default-python/combinations/classic/DATABRICKS_CLI_DEPLOYMENT=direct-exp/DLT=yes/NBOOK=no/PY=yes 🔄​flaky ✅​pass ✅​pass
TestAccept/bundle/templates/default-python/combinations/classic/DATABRICKS_CLI_DEPLOYMENT=terraform/DLT=no/NBOOK=yes/PY=no ✅​pass ❌​FAIL ✅​pass
TestAccept/bundle/templates/default-python/combinations/classic/DATABRICKS_CLI_DEPLOYMENT=terraform/DLT=no/NBOOK=yes/PY=yes ✅​pass ❌​FAIL ✅​pass
TestAccept/bundle/templates/default-python/combinations/classic/DATABRICKS_CLI_DEPLOYMENT=terraform/DLT=yes/NBOOK=no/PY=no ✅​pass ❌​FAIL ✅​pass
TestAccept/bundle/templates/default-python/combinations/classic/DATABRICKS_CLI_DEPLOYMENT=terraform/DLT=yes/NBOOK=no/PY=yes ✅​pass ❌​FAIL ✅​pass
TestAccept/bundle/templates/default-python/combinations/classic/DATABRICKS_CLI_DEPLOYMENT=terraform/DLT=yes/NBOOK=yes/PY=no ✅​pass ❌​FAIL ✅​pass
TestAccept/bundle/templates/default-python/combinations/classic/DATABRICKS_CLI_DEPLOYMENT=terraform/DLT=yes/NBOOK=yes/PY=yes ✅​pass ✅​pass ❌​FAIL
TestAccept/bundle/templates/default-python/integration_classic ✅​pass ✅​pass ❌​FAIL
TestAccept/bundle/templates/default-python/integration_classic/DATABRICKS_CLI_DEPLOYMENT=direct-exp/UV_PYTHON=3.9 ✅​pass ✅​pass ❌​FAIL
TestAccept/bundle/templates/default-python/integration_classic/DATABRICKS_CLI_DEPLOYMENT=terraform/UV_PYTHON=3.10 ✅​pass ✅​pass ❌​FAIL
TestAccept/bundle/templates/default-python/integration_classic/DATABRICKS_CLI_DEPLOYMENT=terraform/UV_PYTHON=3.11 ✅​pass ✅​pass ❌​FAIL
TestAccept/bundle/templates/default-python/integration_classic/DATABRICKS_CLI_DEPLOYMENT=terraform/UV_PYTHON=3.12 ✅​pass ✅​pass ❌​FAIL
TestAccept/bundle/templates/default-python/integration_classic/DATABRICKS_CLI_DEPLOYMENT=terraform/UV_PYTHON=3.13 ✅​pass ✅​pass ❌​FAIL
TestLock ✅​pass ❌​FAIL ✅​pass

[EnvMatrix]
DATABRICKS_CLI_DEPLOYMENT = ["terraform", "direct-exp"]
UV_ARGS = ["--with databricks-bundles==0.7.3", "--with-requirements requirements-latest.txt --no-cache"]
UV_ARGS = ["--with databricks-bundles==0.266.0", "--with-requirements requirements-latest.txt --no-cache"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it intentional to test only 0.266.0? What about the most recent release or main?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need some version from the past, and it was selected to be 0.266.0. It doesn't have to be the latest release. We just need to select a version that users might pin.

The second case for UV_ARGS is testing against the latest version from main

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense to test past version -- please add a comment that this is intentional.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does UV_ARGS="--with-requirements requirements-latest.txt --no-cache" results in testing the python package from the current branch or latest release from PyPI. Please add a comment as well, it's not clear.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 , I've clarified. It's using the same commit as acceptance tests

// don't execute for phases for 'pydabs' section
if phase == PythonMutatorPhaseLoadResources || phase == PythonMutatorPhaseApplyMutators {
if experimentalPythonEnabled && pythonEnabled {
if !reflect.DeepEqual(experimental.Python, b.Config.Python) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why reflect.Equal? Why not require users specify this once?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see below that this is to make python package work but IMO we should separate what we require from users and what we send to Python. E.g. we can have validator that requires that only one is present but then duplicate and send both to Python.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first time we call "getOpts", only 1 property can be specified. The second time, we call "getOpts" on the mutated bundle that contains both options specified after we have called applyBackwardsCompatibilityFixes, so we need to allow this case as well.

Here, we call applyBackwardsCompatibilityFixes before getOpts, so even the first time, we expect both options to be set.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we call it twice? cannot we remember the output from the first call?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our mutators are intended to be stateless, so we can't remember. And we call Python mutator twice in the mutator pipeline

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our mutators are intended to be stateless, so we can't remember. And we call Python mutator twice in the mutator pipeline

You can certainly have a field on *Bundle to track state relevant for you. Especially if it saves work and simplifies code.

Copy link
Collaborator Author

@kanterov kanterov Sep 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. I just don't see a problem. If we want the bundle spec to be stable, we should allow specifying both properties during the transition period.

mutators:
- "mutators:add_task_1"
- "mutators:add_task_2"
python:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to have acceptance tests for new functionality:

  • only experimental.python is provided
  • both are provided and equal
  • both are provided and not equal

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 , added in the latest commit

github-merge-queue bot pushed a commit that referenced this pull request Sep 8, 2025
## Changes
Support reading both `python` and `experimental.python` configs. If both
are set, their value should be equivalent.

After we introduce the `python` section into the CLI, it has to keep
setting both `python` and `experimental.python` into the payload for
backward compatibility. After that, Python code can start erroring out
if `experimental/python` is set but not `python` because it means that
users have an outdated CLI version.

See also #3540

## Why
It's a step toward graduating `python` outside the `experimental`
section.

## Tests
Unit tests and existing acceptance tests
@kanterov kanterov force-pushed the python-non-experimental branch from d77a490 to f751173 Compare September 8, 2025 13:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants