Skip to content

feat(python-setup): open the compute picker inline when no compute is attached - #2114

Merged
rugpanov merged 5 commits into
mainfrom
python-setup-select-compute
Aug 14, 2026
Merged

feat(python-setup): open the compute picker inline when no compute is attached#2114
rugpanov merged 5 commits into
mainfrom
python-setup-select-compute

Conversation

@rugpanov

Copy link
Copy Markdown
Contributor

Why

Clicking Set up Python environment with no compute attached dead-ended on a "Select a cluster or serverless compute before setting up the environment" warning, forcing the user to leave the flow, attach compute, and come back. A serverless session missing only its version already prompts inline and continues — the no-compute case should be just as direct.

What

  • resolveCompute (pythonSetupDeps.ts) — when nothing is attached, open the existing compute picker inline, then re-read the attachment and continue setup against whatever the user selected.
  • attachClusterQuickPick command (ConnectionCommands.ts) — its returned promise now resolves only once the picker has fully closed (after any attach/enable it triggers, or immediately on dismissal), so a caller can await the outcome and re-read state. Existing fire-and-forget callers ignore the result, unchanged.
  • extension.ts — wire promptSelectCompute to the compute-picker command.

Behavior preserved

  • Pick a cluster → setup runs against it. Pick serverless → the version sub-picker runs (already wired when the feature is on), then setup proceeds.
  • Dismiss the picker → the attachment is unchanged, so the flow falls through to today's exact behavior: the guidance warning + the no-compute telemetry. The picker is purely an added opportunity — nothing regresses.

Backward compatibility

attachClusterQuickPick is a public command; its executeCommand promise now settles after the picker closes instead of immediately. The three existing callers (cluster tree-item click, EnvironmentDependenciesVerifier, run-flow promptForClusterAttach) are all fire-and-forget and ignore the result — verified no regression, only more-correct resolution timing.

Verification

  • Unit suite green (462 passing), including new resolveCompute cases: picker opened when none attached, runs against the attached compute, not opened when a cluster is already attached, version prompted when the picker leaves serverless version-less.
  • yarn fix / test:lint clean.

This pull request and its description were written by Isaac.

@rugpanov
rugpanov deployed to test-trigger-is August 13, 2026 15:17 — with GitHub Actions Active
@rugpanov
rugpanov deployed to test-trigger-is August 13, 2026 15:17 — with GitHub Actions Active
@rugpanov

Copy link
Copy Markdown
Contributor Author

🤖 Integration tests triggered for e2a168cf — ⏳ running.
View run

@rugpanov
rugpanov deployed to test-trigger-is August 13, 2026 15:35 — with GitHub Actions Active
@rugpanov
rugpanov deployed to test-trigger-is August 13, 2026 15:35 — with GitHub Actions Active
@rugpanov
rugpanov requested a review from misha-db August 13, 2026 15:37
@rugpanov

rugpanov commented Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Integration tests ✅ all 35 test jobs passed for 1c0a5cb6.
View run

@rugpanov
rugpanov deployed to test-trigger-is August 13, 2026 21:51 — with GitHub Actions Active
@rugpanov
rugpanov deployed to test-trigger-is August 13, 2026 21:52 — with GitHub Actions Active
@rugpanov

rugpanov commented Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Integration tests ✅ all 35 test jobs passed for b97354bb.
View run

@rugpanov

Copy link
Copy Markdown
Contributor Author

🤖 Integration tests triggered for c22d384b — ⏳ running.
View run

@rugpanov
rugpanov deployed to test-trigger-is August 14, 2026 05:57 — with GitHub Actions Active
@rugpanov
rugpanov deployed to test-trigger-is August 14, 2026 05:58 — with GitHub Actions Active
@rugpanov

rugpanov commented Aug 14, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Integration tests ✅ all 35 test jobs passed for c801ac61.
View run

@rugpanov
rugpanov force-pushed the python-setup-select-compute branch from c801ac6 to f26d817 Compare August 14, 2026 12:22
@rugpanov
rugpanov deployed to test-trigger-is August 14, 2026 12:22 — with GitHub Actions Active
@rugpanov
rugpanov deployed to test-trigger-is August 14, 2026 12:23 — with GitHub Actions Active
@rugpanov

rugpanov commented Aug 14, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Integration tests ✅ all 35 test jobs passed for f26d8172.
View run

@rugpanov
rugpanov enabled auto-merge (squash) August 14, 2026 13:29
Why:
Clicking "Set up Python environment" with no compute attached dead-ended
on a "select a cluster or serverless compute first" warning, forcing the
user to leave the flow, attach compute, and come back. A serverless
session missing only its version already prompts inline and continues;
the no-compute case should be just as direct.

What:
- resolveCompute (pythonSetupDeps): when nothing is attached, open the
  existing compute picker inline, then re-read the attachment and
  continue setup against whatever the user selected. Dismissing the
  picker leaves the attachment unchanged, so the flow still falls through
  to the existing guidance message + no-compute telemetry -- nothing
  regresses, the picker is only an added opportunity.
- attachClusterQuickPick command (ConnectionCommands): its returned
  promise now resolves only once the picker has fully closed (after any
  attach/enable it triggers, or immediately on dismissal), so a caller
  can await the outcome and re-read state. Existing fire-and-forget
  callers ignore the result unchanged.
- extension.ts: wire promptSelectCompute to the compute-picker command.

Verification:
- yarn build; unit suite green (462 passing) incl. new resolveCompute
  cases: picker opened when none attached, runs against the attached
  compute, not opened when a cluster is already attached, version
  prompted when the picker leaves serverless version-less.
- yarn fix / test:lint clean.

Co-authored-by: Isaac
Why:
Code review (Codex + a Claude reviewer, converging independently) caught
that re-reading the attached compute right after the picker closed is
deterministically stale for a cluster: ConnectionManager.attachCluster
only writes the `clusterId` config, and the cluster object is rebuilt by
a separate, network-gated, fire-and-forget config listener that the
attach never awaits. So the immediate re-read saw `cluster: undefined`
and setup dead-ended on the very message this feature removes. (The
serverless path only worked by luck -- enableServerless sets its state
synchronously.) The first cut's passing test masked this by mutating the
mock synchronously.

What:
- attachClusterQuickPick command now RETURNS the chosen compute
  (SelectedCompute: cluster or version-complete serverless) or undefined
  on dismissal, so callers use the selection directly. selectServerless
  returns the confirmed version. Existing fire-and-forget callers ignore
  the new return value, unchanged.
- resolveCompute (pythonSetupDeps) consumes that return value instead of
  re-reading connectionManager state, eliminating the race.
- Harden the accept handler while here (review nits): guard a repeated
  Enter / empty selection, and catch+log so a failing attach can't leak
  an unhandled rejection or leave the picker open.
- Tests rewritten to model the real contract: the picker returns the
  compute while attachedCompute stays `none`, proving the flow no longer
  depends on a re-read.

Verification:
- yarn build; full unit suite green (736 passing). yarn fix / test:lint
  clean.

Co-authored-by: Isaac
…te type

Why:
Round-1 multi-source review (Codex + a Claude reviewer) surfaced three
points. Codex's "attach failure returns as success" was verified a false
positive: setup-local receives the clusterId/version descriptor directly
(setupLocalArgs), so it is valid regardless of whether the config write
persisted, and @onerror already surfaces any failure to the user. The two
actionable notes were a test-coverage gap on the picker's producer logic
and an unchecked type link.

What:
- Add unit tests for attachClusterQuickPickCommand's return contract via a
  scriptable QuickPick fake: resolves to the attached cluster (attaching
  once), undefined on dismissal, undefined on empty accept, and the
  `settled` re-entry guard (a second Enter neither re-attaches nor changes
  the result). This is the riskiest new code and had no producer-side test.
- Alias SelectedCompute to SetupCompute (the setup-local compute shape)
  instead of re-declaring it, so drift is a compile error rather than a
  silent mismatch through executeCommand's unchecked generic.
- Use Loggers.Extension (the enum) instead of the "Extension" string
  literal, matching the codebase convention.

Verification:
- yarn build; full unit suite green (740 passing, +4 new). yarn fix /
  test:lint clean.

Co-authored-by: Isaac
… + tests

Why:
Iterative review re-raised that the picker returns the chosen compute even
when attachCluster/enableServerless silently fail (they are @onerror with
throw:false, so a config-write failure shows a popup but does not throw).
Decision: keep this best-effort -- the returned descriptor is the compute
the user picked and is all setup-local needs (it takes the id/version
directly), and the failure is already surfaced to the user. The prior code
comment overclaimed that the catch nulls the selection on attach failure,
which is dead for those swallowed operations.

What:
- Correct the catch comment: it is defense-in-depth for an UNEXPECTED throw
  (version sub-picker, openExternal, a future non-decorated path), not a
  success/failure discriminator for the @onError-swallowed attach/enable.
- Document at the cluster branch why returning the descriptor is intentional
  even when the attach's persistence fails.
- Add contract tests: the chosen cluster is still returned when the attach
  silently fails (best-effort), and an unexpected throw settles the Promise
  to undefined (no hang, no selection).

Verification:
- yarn build; full unit suite green (742 passing, +2). yarn fix / test:lint
  clean.

Co-authored-by: Isaac
Why:
The explanatory comments added across the feature were far longer than the
code warranted.

What:
- Condense the doc/inline comments in ConnectionCommands.ts (picker command,
  settle guard, best-effort attach, catch, SelectedCompute, selectServerless),
  pythonSetupDeps.ts (promptSelectCompute, resolveCompute), extension.ts, and
  the two test files. No code or behavior changes.

Verification:
- yarn build; full unit suite green (742 passing). yarn fix / test:lint clean.

Co-authored-by: Isaac
@rugpanov
rugpanov force-pushed the python-setup-select-compute branch from f26d817 to 001396e Compare August 14, 2026 13:29
@rugpanov
rugpanov deployed to test-trigger-is August 14, 2026 13:30 — with GitHub Actions Active
@rugpanov
rugpanov merged commit 74b150b into main Aug 14, 2026
6 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

If integration tests don't run automatically, an authorized user can run them manually by following the instructions below:

Trigger:
go/deco-tests-run/vscode

Inputs:

  • PR number: 2114
  • Commit SHA: 001396e468081b98d6a5ecbffa72b2340f917ea1

Checks will be approved automatically on success.

@rugpanov
rugpanov deployed to test-trigger-is August 14, 2026 13:30 — with GitHub Actions Active
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants