Skip to content

Pin serverless databricks-connect by major (~=17.0, not ~=17.3.0) - #15

Merged
rugpanov merged 1 commit into
mainfrom
fix/serverless-dbconnect-major-pin
Aug 11, 2026
Merged

Pin serverless databricks-connect by major (~=17.0, not ~=17.3.0)#15
rugpanov merged 1 commit into
mainfrom
fix/serverless-dbconnect-major-pin

Conversation

@rugpanov

Copy link
Copy Markdown
Collaborator

Problem

For serverless, the dev-group databricks-connect pin resolved too narrowly. dbconnect_pin() took the first two segments of the listed version (17.3.1~=17.3.0), producing a compatible-release pin of >=17.3.0, <17.4.0. That locks databricks-connect to a single minor line and only picks up patch bumps — but a serverless environment version tracks a whole major runtime line, so it should follow the latest release within that major.

Fix

Pin by bare major: ~=MAJOR.0 (e.g. 17.3.1databricks-connect~=17.0, resolving >=17.0, <18.0). One-line change in envgen.py; the committed serverless pyprojects are regenerated to match.

env before after
serverless-v1 ~=14.3.0 ~=14.0
serverless-v2 ~=15.4.0 ~=15.0
serverless-v3 ~=16.4.0 ~=16.0
serverless-v4 ~=17.3.0 ~=17.0
serverless-v5 ~=18.0.0 ~=18.0
serverless-v5-ml ~=18.0.0 ~=18.0

The DBR path is unaffected — it passes an explicit MAJOR.MINOR pin derived per point-release page, which is intended there.

Verification

Regenerated serverless output matches the committed files byte-for-byte (no drift), so a future sync.py run won't revert it.

This pull request and its description were written by Isaac.

A serverless environment version tracks a whole major runtime line, not a
single point release, but dbconnect_pin() took the first two version segments
(17.3.1 -> ~=17.3.0), locking the dev-group databricks-connect to one minor
line (>=17.3.0, <17.4.0) and only picking up patches.

Pin by bare major instead — ~=MAJOR.0 (17.3.1 -> databricks-connect~=17.0,
resolving >=17.0, <18.0) — so it tracks the latest release within the major.
Regenerate the committed serverless pyprojects to match; the DBR path is
unaffected (it passes an explicit MAJOR.MINOR pin per point-release page).

Co-authored-by: Isaac
@anton-107
anton-107 self-requested a review August 11, 2026 05:48
@anton-107

Copy link
Copy Markdown
Collaborator

Reviewed at f303e33. I'd like to hold this one — I think the loosened pin breaks a cross-repo contract the CLI depends on, and I'm also not convinced the premise is right. Details below; happy to be argued out of the second part.

1. It corrupts the version the CLI reports to users

The CLI reads the pin string verbatim out of the published pyproject.toml (libs/localenv/constraints.go:74, consumed at pipeline.go:179) and derives the version it shows users by taking everything from the first digit onward (versionFromPin, pipeline.go:551). I ran your branch's dbconnect_pin directly and traced it through:

published pin CLI reports dbconnectVersion
databricks-connect~=17.3.0 (today) 17.3.0 — correct
databricks-connect~=17.0 (this PR) 17.0 — not an installable version

With ~=17.0, uv resolves to the newest 17.x — say 17.3.1 — while the CLI advertises 17.0. Two things make this worse than a cosmetic slip:

  • --dry-run never self-corrects. Validate is stubbed out in check mode (pipeline.go:203-211), so the wrong value is the only value a dry-run user ever sees. On a real run validate overwrites it with the installed version (pipeline.go:462-467), so dry-run and real runs disagree — the most confusing possible shape.
  • It's in the --output json contract the VS Code extension consumes, not just human-readable output.

The pipeline won't fail, at least: validate only asserts the major matches (pipeline.go:446). So this silently reports wrong data rather than erroring.

2. It reshapes every future sync, not just the six files

dbconnect_pin is the default path for all serverless envs, so this isn't a one-time regeneration — a future listing of 19.0.1 becomes ~=19.0, and so on. Worth stating in the description, since it's a permanent change to the generation rule.

3. I don't think the premise holds

The PR argues a serverless environment version "tracks a whole major runtime line." That's true of the runtime, but it's not what these artifacts are for. Per this repo's own README, the goal is reproducing one runtime snapshot — "matching the exact Python version, databricks-connect version, and transitive dependency set."

Concretely: [tool.uv] constraint-dependencies in serverless-v4 stays pinned at that snapshot's grpcio~=1.67.0, pyarrow~=19.0.1, protobuf~=5.29.4, pandas~=2.2.3. Loosening databricks-connect to any 17.x while its transitive deps remain pinned to the 17.3-era set means the first later 17.x that raises a dependency floor produces an unsatisfiable resolution. This loosens the one package whose version defines the snapshot, while leaving everything it depends on frozen.

Also: ~=14.0 is a wider loosening than the table suggests — it spans 14.0 through 14.3+, and no serverless environment version was ever pinned to 14.0.

What I'd suggest

Mostly I want to understand the motivating problem, since that changes the answer:

  • If it's patch-currency (picking up fixes within the minor line), ~=17.3 is the PEP 440 spelling you want — it allows 17.3.x and 17.4 without abandoning the line. Note ~=17.3.0 already allows patch bumps, so if that's the goal this may be a no-op.
  • If bare-major really is intended, then versionFromPin on the CLI side needs to stop treating a pin as a version first, and that fix should ship before this. Otherwise there's a window where the CLI reports 17.0 to users.

Either way, this coupling deserves a test on at least one side — the fact that a one-line change to envgen.py can silently alter CLI user-facing output, with nothing failing anywhere, is the real gap here. There's currently no test suite for envgen.py at all, and the pin-string format is an undocumented contract between the two repos.

Reviewed with Claude Code; all claims above were verified by running the branch's dbconnect_pin and reading the CLI consumer.

@rugpanov
rugpanov merged commit 63de106 into main Aug 11, 2026
yolocs pushed a commit to yolocs/dbcli that referenced this pull request Aug 11, 2026
… setup-local --dry-run (databricks#6218)

## Summary

Found in code review of the unveil PR (databricks#5835). P1, not P0: it only
affects `--dry-run`; real runs are correct.

`versionFromPin` in `libs/localenv/pipeline.go` derives the reported
`dbconnectVersion` by taking everything from the first digit of the
published pin string. A pin string is not a version:

- A point pin like `~=17.3.0` happens to return `17.3.0` (correct).
- A major-only pin like `~=17.0` returns `"17.0"` — a `major.minor`
floor that nothing installs. Serverless has pinned by major (`~=17.0`,
not `~=17.3.0`) since databricks/environments#15 (merged 2026-08-11), so
this is live now for serverless targets.

On a real run `validate` overwrites `dbconnectVersion` with the
actually-installed version, so the reported value is correct. Under
`--dry-run`, `validate` is stubbed, so the fabricated value is what gets
reported — dry-run and real runs disagree, and the `--output json`
contract the VS Code extension consumes carries the wrong value in
dry-run. No wrong install happens; the provisioned venv is still
correct.

## Fix

Gate the reported version behind a new `dbcVersionFromPin`, which emits
a version only when the pin carries a full `major.minor.patch` (e.g.
`~=17.3.0` → `17.3.0`) and returns `""` (omitted from JSON) for a
range-only pin such as `~=17.0`.

The key constraint: `versionFromPin` has two callers. Hardening it
directly would break `dbcMajorFromPin`'s major extraction for `~=17.0`
and regress *real* runs (validate would fail to determine the major) —
worse than the dry-run bug. So the gate is applied only to the reporting
path; `versionFromPin` is left untouched.

## Tests

The ticket noted nothing tested this cross-repo coupling. Added:

- `TestPipelineDryRunOmitsFabricatedDBConnectVersion` — end-to-end
dry-run with a `~=17.0` pin (written red-first; reported `17.0` before
the fix).
- `TestDBCVersionFromPin` — table-driven, including the `~=17.0`
bare-major case.
- `TestDBCMajorFromPinHandlesMajorOnlyPin` — guards that the real-run
major path still works for `~=17.0`.

`go test ./libs/localenv` (170 pass) and related acceptance tests (9
pass) are green; the existing JSON goldens use a full `17.2.0` pin, so
their output is unchanged. `go vet`, `golangci-lint`, and `gofmt` are
clean.

No changelog fragment: `setup-local` is still hidden pending the unveil
(databricks#5835), matching the prior decision to drop a premature fragment for
it.

This pull request and its description were written by Isaac.
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