Skip to content

[VPEX][3/8] Add local-env constraint fetch with offline cache#5826

Open
rugpanov wants to merge 5 commits into
dbconnect/02-targetfrom
dbconnect/03-constraints
Open

[VPEX][3/8] Add local-env constraint fetch with offline cache#5826
rugpanov wants to merge 5 commits into
dbconnect/02-targetfrom
dbconnect/03-constraints

Conversation

@rugpanov

@rugpanov rugpanov commented Jul 3, 2026

Copy link
Copy Markdown

Context

PR 3 of 8 in the stacked databricks local-env python sync series (see #5823 for the full plan). Stacked on #5824 — review #5823 and #5824 first; this PR's diff is only constraints.go + its test.

What this PR contains

constraints.go — constraint fetch with an offline cache. Fetches the per-environment pyproject.toml for a resolved env key and parses out requires-python, the databricks-connect pin, and the [tool.uv] constraint-dependencies.

Failure classification:

  • 404E_ENV_UNSUPPORTED (a resolvable target with no published environment; no cache fallback, since a missing key is a distinct non-transient condition).
  • transport / non-404 HTTPE_FETCH, falling back to the last-good cached copy.

The fetched body is validated by parseConstraints before it is written to the cache, so a malformed 2xx response cannot poison the cache and break a later transport-failure run that would otherwise serve the bad copy.

Dependencies & surface

Depends on the foundation PR (#5823) for NewError and the E_FETCH / E_ENV_UNSUPPORTED codes. Still dormant — nothing imports the package yet.

This pull request and its description were written by Isaac.

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Waiting for approval

Could not determine reviewers from git history.
Round-robin suggestion: @renaudhartert-db

Eligible reviewers: @andrewnester, @anton-107, @denik, @janniklasrose, @pietern, @renaudhartert-db, @shreyas-goenka, @simonfaltum

Suggestions based on git history. See OWNERS for ownership rules.

@eng-dev-ecosystem-bot

eng-dev-ecosystem-bot commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: 79890ca

Run: 28679377569

Env 🔄​flaky 💚​RECOVERED 🙈​SKIP ✅​pass 🙈​skip Time
💚​ aws linux 7 14 230 1045 4:08
💚​ aws windows 7 14 232 1043 3:55
💚​ aws-ucws linux 7 14 314 963 5:34
💚​ aws-ucws windows 7 14 316 961 4:08
💚​ azure linux 4 15 230 1044 4:19
💚​ azure windows 4 15 232 1042 3:44
💚​ azure-ucws linux 4 15 316 960 5:17
🔄​ azure-ucws windows 2 2 15 318 958 5:45
💚​ gcp linux 4 15 229 1046 3:52
💚​ gcp windows 4 15 231 1044 3:55
21 interesting tests: 14 SKIP, 5 RECOVERED, 2 flaky
Test Name aws linux aws windows aws-ucws linux aws-ucws windows azure linux azure windows azure-ucws linux azure-ucws windows gcp linux gcp windows
💚​ TestAccept 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R
🙈​ TestAccept/bundle/invariant/no_drift 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/permissions 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/with_permissions 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
💚​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions 💚​R 💚​R 💚​R 💚​R 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
💚​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions/DATABRICKS_BUNDLE_ENGINE=direct 💚​R 💚​R 💚​R 💚​R
💚​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions/DATABRICKS_BUNDLE_ENGINE=terraform 💚​R 💚​R 💚​R 💚​R
🙈​ TestAccept/bundle/resources/postgres_branches/basic 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_branches/recreate 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_branches/replace_existing 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_branches/update_protected 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_branches/without_branch_id 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_endpoints/basic 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_projects/update_display_name 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/synced_database_tables/basic 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/vector_search_endpoints/drift/recreated_same_name 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/vector_search_indexes/recreate/embedding_dimension 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/ssh/connection 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
💚​ TestFetchRepositoryInfoAPI_FromRepo 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R
🔄​ TestFetchRepositoryInfoAPI_FromRepo/root 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 🔄​f 💚​R 💚​R
🔄​ TestFetchRepositoryInfoAPI_FromRepo/subdir 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 🔄​f 💚​R 💚​R
Top 5 slowest tests (at least 2 minutes):
duration env testname
3:11 gcp windows TestAccept
3:07 aws-ucws windows TestAccept
3:04 aws windows TestAccept
3:01 azure-ucws windows TestAccept
2:45 azure windows TestAccept

@rugpanov rugpanov force-pushed the dbconnect/02-target branch from 5fdb8b6 to 2092138 Compare July 3, 2026 13:20
@rugpanov rugpanov force-pushed the dbconnect/03-constraints branch from d867d1f to 64d8996 Compare July 3, 2026 13:20
@rugpanov rugpanov temporarily deployed to test-trigger-is July 3, 2026 13:21 — with GitHub Actions Inactive
@rugpanov rugpanov temporarily deployed to test-trigger-is July 3, 2026 13:21 — with GitHub Actions Inactive
@rugpanov rugpanov changed the title Add dbconnect constraint fetch with offline cache [VPEX][3/8] Add local-env constraint fetch with offline cache Jul 3, 2026
@rugpanov rugpanov force-pushed the dbconnect/02-target branch from 2092138 to 22d1137 Compare July 3, 2026 15:26
@rugpanov rugpanov force-pushed the dbconnect/03-constraints branch from 64d8996 to 3fd0bfe Compare July 3, 2026 15:26
@rugpanov rugpanov temporarily deployed to test-trigger-is July 3, 2026 15:27 — with GitHub Actions Inactive
@rugpanov rugpanov temporarily deployed to test-trigger-is July 3, 2026 15:27 — with GitHub Actions Inactive
@rugpanov rugpanov force-pushed the dbconnect/03-constraints branch from 3fd0bfe to ce01647 Compare July 3, 2026 15:31
@rugpanov rugpanov temporarily deployed to test-trigger-is July 3, 2026 15:31 — with GitHub Actions Inactive
@rugpanov rugpanov temporarily deployed to test-trigger-is July 3, 2026 15:31 — with GitHub Actions Inactive
@rugpanov rugpanov temporarily deployed to test-trigger-is July 3, 2026 15:42 — with GitHub Actions Inactive
@rugpanov rugpanov temporarily deployed to test-trigger-is July 3, 2026 15:42 — with GitHub Actions Inactive
@rugpanov rugpanov force-pushed the dbconnect/02-target branch from 8d309ae to d9b9c50 Compare July 3, 2026 18:15
@rugpanov rugpanov force-pushed the dbconnect/03-constraints branch from 797c4ac to 03b4a2b Compare July 3, 2026 18:15
@rugpanov rugpanov temporarily deployed to test-trigger-is July 3, 2026 18:15 — with GitHub Actions Inactive
@rugpanov rugpanov temporarily deployed to test-trigger-is July 3, 2026 18:15 — with GitHub Actions Inactive
@rugpanov rugpanov force-pushed the dbconnect/02-target branch from d9b9c50 to 77ac2c8 Compare July 3, 2026 18:27
@rugpanov rugpanov force-pushed the dbconnect/03-constraints branch from 03b4a2b to 7eaf270 Compare July 3, 2026 18:27
@rugpanov rugpanov temporarily deployed to test-trigger-is July 3, 2026 18:27 — with GitHub Actions Inactive
@rugpanov rugpanov temporarily deployed to test-trigger-is July 3, 2026 18:27 — with GitHub Actions Inactive
Third in the stacked local-env series.

constraints.go fetches the per-environment pyproject.toml for a resolved
env key and parses out requires-python, the databricks-connect pin, and the
[tool.uv] constraint-dependencies. It caches each fetch on disk and
classifies failures: a 404 is E_ENV_UNSUPPORTED (a resolvable target with no
published environment, no cache fallback), while a transport or non-404 HTTP
failure is E_FETCH and falls back to the last-good cached copy.

The fetched body is validated by parseConstraints before it is written to
the cache, so a malformed 2xx response cannot poison the cache and break a
later transport-failure run that would otherwise serve the bad copy.

Depends on the foundation PR for NewError and the E_FETCH /
E_ENV_UNSUPPORTED codes. Still dormant.

Co-authored-by: Isaac
rugpanov added 4 commits July 3, 2026 21:13
…ache, exact dep match

Review of the constraint-fetch layer surfaced several defects, all fixed here:

- parseConstraints accepted valid-but-empty TOML: a 200 body with no
  [project].requires-python returned an empty result that would be cached and
  only fail confusingly later. It now errors when requires-python is absent.

- The cache write assumed cacheDir already existed. On a fresh machine the
  first fetch succeeded but os.WriteFile failed (no such directory), so the
  cache never populated and offline runs got E_FETCH. writeCacheAtomic now
  MkdirAll's the parent.

- The cache write was non-atomic (os.WriteFile truncates in place), so a
  concurrent transport-failure reader could observe a partial file.
  writeCacheAtomic writes a temp file and renames it into place.

- databricks-connect detection used a bare string prefix, so a sibling like
  "databricks-connectors==1.0" matched first and was returned instead of the
  real pin. isDatabricksConnectDep now requires a package-name boundary.

- sanitizeEnvKey collapsed only "/", leaving a Windows "\" to be treated as a
  separator by filepath.Join; it now collapses both.

Co-authored-by: Isaac
Round-2 review noted that mapping an env key to a cache filename by replacing
"/" with "__" was not injective: distinct keys like "a/b" and "a__b" collided
on the same file, so a cached copy for one environment could be served for
another on a transport-failure fallback. cacheFileName now appends a short
sha256 of the raw env key to the readable slug, guaranteeing distinct keys get
distinct files (env keys are internally generated and never actually collide
today, but the cache should not depend on that).

Co-authored-by: Isaac
Round-3 review noted isDatabricksConnectDep was case-sensitive, but Python
package names are case-insensitive (PEP 503): a valid entry like
"Databricks-Connect==16.4.0" went undetected, leaving the pin empty. The match
now lowercases the entry before comparing; the caller still stores the original
casing.

Co-authored-by: Isaac
Round-4 review found isDatabricksConnectDep matched only case, missing PEP 503
name equivalence: "databricks_connect" and "databricks.connect" (and other
whitespace) were not recognized. The check now extracts the leading package
name up to the first PEP 508 delimiter and compares it under PEP 503
normalization (lowercase, collapse runs of -, _, . to a single -), so all
spellings match while a distinct package like databricks-connectors does not.

Co-authored-by: Isaac
@rugpanov rugpanov force-pushed the dbconnect/02-target branch from 77ac2c8 to 436dabf Compare July 3, 2026 19:14
@rugpanov rugpanov force-pushed the dbconnect/03-constraints branch from 7eaf270 to 79890ca Compare July 3, 2026 19:14
@rugpanov rugpanov temporarily deployed to test-trigger-is July 3, 2026 19:15 — with GitHub Actions Inactive
@rugpanov rugpanov temporarily deployed to test-trigger-is July 3, 2026 19:15 — with GitHub Actions Inactive
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.

2 participants