fix(python-setup): resolve a missing serverless version instead of aborting - #2088
Merged
Merged
Conversation
rugpanov
temporarily deployed
to
test-trigger-is
August 6, 2026 12:05 — with
GitHub Actions
Inactive
rugpanov
temporarily deployed
to
test-trigger-is
August 6, 2026 12:05 — with
GitHub Actions
Inactive
rugpanov
requested a deployment
to
test-trigger-is
August 6, 2026 12:05 — with
GitHub Actions
Queued
Contributor
Author
|
🤖 Integration tests triggered for |
rugpanov
temporarily deployed
to
test-trigger-is
August 6, 2026 12:29 — with
GitHub Actions
Inactive
rugpanov
temporarily deployed
to
test-trigger-is
August 6, 2026 12:29 — with
GitHub Actions
Inactive
rugpanov
requested a deployment
to
test-trigger-is
August 6, 2026 12:30 — with
GitHub Actions
Queued
Contributor
Author
|
🤖 Integration tests triggered for |
… no compute *Why* `resolveComputeFrom` collapsed "nothing attached" and "serverless attached but no version persisted" into a single `undefined`, so the setup entry told users to select compute they had already selected. The two states need opposite handling, and a third is coming (the user dismissing a prompt), which must not be counted as a dead-end click. *What* Return a tagged `ComputeResolution` from the pure classifier, with `needsServerlessVersion` as its own state, and give the `resolveCompute` seam a `ResolvedCompute` union whose `cancelled` case stops the flow silently. The new state is mapped to `none` in the wiring for now, so behaviour is unchanged until the prompt is wired up. *Verification* yarn test:unit (477 passing; the 6 remaining failures are pre-existing on the base commit), yarn test:lint. Co-authored-by: Isaac
…llector *Why* The collector was private to ConnectionCommands, but the setup flow needs the same evidence to resolve a missing serverless version. Sharing one pipeline also means future picker changes land in both places at once. *What* Move it to python-setup/utils/serverlessVersionObservations.ts behind an injected getValidateConfig/projectRoot pair, keeping the per-source guards so one failing source never discards the other. ConnectionCommands now calls the util. No behaviour change. *Verification* yarn test:unit (481 passing, 4 new collector cases; the 6 remaining failures are pre-existing on the base commit), yarn test:lint. Co-authored-by: Isaac
*Why* The setup flow needs to ask for a missing serverless version, and the collect->score->pick pipeline already existed but only as three pieces wired together inside the compute picker. *What* Add makeServerlessVersionPrompt, composing the observation collector, the scorer, and the QuickPick into the single thunk the setup wiring wants. `pick` stays injectable so the composition is tested without a VS Code host. *Verification* yarn test:unit (483 passing) -- covers bundle evidence outranking the bare fallback and the dismissal path. yarn test:lint. Co-authored-by: Isaac
…orting *Why* Pressing the setup entry with serverless attached but no version persisted showed "Select a cluster or serverless compute before setting up the environment" and aborted, making the feature unreachable for those projects while naming the wrong problem -- the user had selected compute, only the version was missing. That state is reachable in normal use: a serverlessComputeId auto config enables serverless without opening the picker, a selection made while the feature was disabled records no version, and a persisted version outside the supported range is dropped on load. *What* Ask for the version on the spot using the existing scorer and picker, persist it with the serverless selection so the question is asked once, and continue the run. Dismissing the prompt stops the flow silently and records nothing, so the no-compute metric keeps meaning "the CTA had nothing to do". *Verification* yarn test:unit (489 passing; the 6 remaining failures are pre-existing on the base commit) -- covers prompt+persist, dismissal, the cluster / nothing-attached / already-versioned paths never prompting, and a failed persist still running. yarn test:lint. Co-authored-by: Isaac
rugpanov
force-pushed
the
rugpanov/python-setup-resolve-serverless-version
branch
from
August 6, 2026 12:56
55129ea to
1a564a0
Compare
rugpanov
temporarily deployed
to
test-trigger-is
August 6, 2026 12:56 — with
GitHub Actions
Inactive
Contributor
|
If integration tests don't run automatically, an authorized user can run them manually by following the instructions below: Trigger: Inputs:
Checks will be approved automatically on success. |
rugpanov
temporarily deployed
to
test-trigger-is
August 6, 2026 12:56 — with
GitHub Actions
Inactive
rugpanov
requested a deployment
to
test-trigger-is
August 6, 2026 12:57 — with
GitHub Actions
Queued
Contributor
Author
|
🤖 Integration tests triggered for |
misha-db
approved these changes
Aug 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Pressing the uv-native "set up Python environment" entry with serverless attached
but no serverless version persisted showed:
…and aborted — asking the user to select compute they had already selected, with
no hint that the missing piece was a version. The feature was unreachable for
those projects.
That state is not just a legacy leftover; four live paths produce it:
serverlessComputeId: autoconfig enables serverless viaupdateServerlesswithout ever opening the version picker.
selectServerless()enables serverless with noversion — enabling the flag later leaves the project version-less.
isSupportedVersion(e.g. a hand-edited"7") issilently dropped to
undefinedon load, then dead-ends on the same message.vscode.overrides.jsonwithserverless: trueand no
serverlessVersionkey — the original repro.What
Ask for the version on the spot, using the scorer and picker that already exist,
persist it with the serverless selection so the question is asked once, then
continue the run.
resolveComputeFromstays pure but returns a taggedComputeResolution, withneedsServerlessVersionas its own state rather than anotherundefined.resolveComputeseam returns a separateResolvedComputeunion whosecancelledcase is distinct fromnone: dismissing the prompt stops the flowsilently and records nothing, so the
no_computemetric keeps meaning "the CTAhad nothing to do" instead of absorbing deliberate bail-outs.
connectionManager.enableServerless(version). That callonly records the version while serverless is still enabled — then it does not
re-attach compute, fire a compute-change event, or re-report
COMPUTE_SELECTED. NoConnectionManagerchange was needed. Because theguarantee is conditional,
resolveComputere-reads the attachment after theprompt (below) rather than trusting the pre-prompt snapshot.
ConnectionCommandsintoserverlessVersionObservations.ts, so compute selection and the setup flowshare one collect → score → pick pipeline.
Prompting sits after the visibility gate and before the attempt is recorded, so
we never prompt where the feature isn't offered and user think-time stays out of
the setup-duration metric. A failed config write still lets the run proceed —
persistence only buys "don't ask again", so losing it shouldn't cost the user the
run they asked for.
The picker doesn't set
ignoreFocusOut, so compute can change while it is open.resolveComputetherefore re-classifiesattachedCompute()once the promptreturns and persists only while the state it asked about still holds; otherwise it
skips the write and returns the fresh resolution, so the run follows what is
attached now. Without that re-read the write is destructive rather than merely
stale:
attachClustercallsdisableServerless(), soenableServerlesstakesits full branch and detaches the cluster the user just picked. The same re-read
stops a version that landed from elsewhere (a concurrent compute-picker run, a
config reload) from being overwritten by the answer to a stale question.
Path 3 above is fixed as a side effect: an out-of-range persisted version now
prompts instead of dead-ending.
Backward compatibility
The whole feature is behind
databricks.experiments.optIntocontainingenvironment.pythonSetup, so there is no change for anyone without the opt-in.The only persisted-state write is
serverlessVersion— an already-shippedoverrideable key that
selectServerlesswrites today — into.databricks/bundle/<target>/vscode.overrides.json. No format change, nomigration. Both unions are internal to
python-setup/.Verification
yarn test:unit— 492 passing, up from 475 on the base commit. The 6remaining failures (CLI embedding, profile loading) are pre-existing on
mainand byte-identical to the baseline captured before these changes.
yarn test:lintclean.17 new tests cover: prompt + persist; dismissal staying silent with zero
telemetry; the three paths that must never prompt (cluster attached, nothing
attached, serverless already versioned); a failed persist still running; the
collector's per-source guards in both directions; and the three
compute-changed-during-the-prompt cases (cluster attached, everything detached, a
version recorded elsewhere), each of which fails without the post-prompt re-read.
Not yet manually verified against a live workspace — that needs the opt-in plus a
project with
serverless: trueand noserverlessVersion.This pull request and its description were written by Isaac.