Skip to content

direct: support references to/from grants#4774

Merged
denik merged 34 commits intomainfrom
denik/grants-references
Mar 18, 2026
Merged

direct: support references to/from grants#4774
denik merged 34 commits intomainfrom
denik/grants-references

Conversation

@denik
Copy link
Copy Markdown
Contributor

@denik denik commented Mar 18, 2026

Follow up to #4703 but for grants.

Allows references to/from grant objects and removes grants.grants in the path.

denik and others added 29 commits March 17, 2026 19:52
Apply the same EmbeddedSlice pattern used for permissions to grants:
- Rename GrantsState.Grants to GrantsState.EmbeddedSlice (json:"_")
- Add migrateV2ToV3 to rename "grants" → "_" key in existing state
- Bump state version to 3
- Add grant_ref acceptance test skeleton

Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Regenerate grants plan outputs (JSON key "grants" → "_")
- Add grant_ref test output with reference resolution
- Add schema_with_grants and schema_grant_ref invariant configs
- Update refschema to show grants[*] embedded slice fields
- Update state version in migration/future_version tests
- Add exclusions for new grant configs in migrate/continue_293 tests

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Version 2 should encompass both permissions and grants migrations.
The v2→v3 migration function is still present but unreferenced.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
The EmbeddedSlice convention is detected by Go field name, not JSON tag.
Keeping "grants" as the JSON tag avoids needing a state migration entirely,
since existing v2 state files already use the "grants" key.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Use "grants" instead of "__embed__" / "_" as the JSON key for grants
EmbeddedSlice, and revert state version from 3 to 2 in test outputs.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Match what permissions does: compare grant entries by principal name
instead of by slice index, enabling more accurate change detection.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Remove grantKey and KeyedSlices() from ResourceGrants (out of scope)
- Add migrateV2ToV3 that renames "grants" → "__embed__" in grant state entries
- Bump currentStateVersion to 3
- Use slices.Sort instead of sort.Slice for privileges

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Grants and permissions migrations are now both part of the v1→v2
migration step. This keeps currentStateVersion at 2.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Use structpath.ParsePath + StringKey to identify migration targets
  instead of strings.HasSuffix
- Replace json.RawMessage in oldGrantsStateV1 with []catalog.PrivilegeAssignment
  and use explicit copy, matching the pattern in migratePermissionsEntry

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@denik denik temporarily deployed to test-trigger-is March 18, 2026 09:06 — with GitHub Actions Inactive
@denik denik temporarily deployed to test-trigger-is March 18, 2026 09:18 — with GitHub Actions Inactive
State version < 2 cannot contain __embed__ format, so the
"might already be migrated" guards are unnecessary.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@denik denik temporarily deployed to test-trigger-is March 18, 2026 09:21 — with GitHub Actions Inactive
@denik denik changed the title WIP grants references direct: support references to/from grants Mar 18, 2026
@denik denik temporarily deployed to test-trigger-is March 18, 2026 09:32 — with GitHub Actions Inactive
The result is parsed again later, indentation is unnecessary.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@denik denik force-pushed the denik/grants-references branch from 1af04cd to ed528f7 Compare March 18, 2026 09:32
@denik denik marked this pull request as ready for review March 18, 2026 09:33
@denik denik temporarily deployed to test-trigger-is March 18, 2026 09:33 — with GitHub Actions Inactive
Copy link
Copy Markdown
Member

@simonfaltum simonfaltum left a comment

Choose a reason for hiding this comment

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

Review (automated, 2 agents)

Verdict: Approved

0 Critical | 0 Major | 0 Gap | 2 Nit | 1 Suggestion

Clean, well-executed PR. Correctly follows the established EmbeddedSlice pattern from PR #4703. Migration is properly folded into v1->v2. The switch from strings.HasSuffix to structpath.ParsePath for migration key-matching is a correctness improvement. Test coverage is thorough.

See inline comment for the one suggestion.

Comment on lines +135 to +137
EmbeddedSlice: make([]catalog.PrivilegeAssignment, len(old.Grants)),
}
copy(newState.EmbeddedSlice, old.Grants)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[Suggestion] Simplify: direct assignment instead of make + copy

Unlike the permissions migration which transforms field names (permission_level -> level), the grants migration keeps the same inner type (catalog.PrivilegeAssignment). The make + copy is unnecessary. Since old goes out of scope immediately, a direct assignment is simpler and equivalent:

newState := dresources.GrantsState{
	SecurableType: old.SecurableType,
	FullName:      old.FullName,
	EmbeddedSlice: old.Grants,
}

Found by: Both reviewers independently

old.Grants is a fresh local allocation from json.Unmarshal, no aliasing risk.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@denik denik temporarily deployed to test-trigger-is March 18, 2026 10:29 — with GitHub Actions Inactive
SecurableType string `json:"securable_type"`
FullName string `json:"full_name"`
Grants []catalog.PrivilegeAssignment `json:"grants,omitempty"`
EmbeddedSlice []catalog.PrivilegeAssignment `json:"__embed__,omitempty"`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you copy the comment about the significance of __embed__ here as well?

Any future such type must use the same, so the more comments the better.

Can be in a different PR.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Sure, although I hope we actually limit this pattern to grants / permissions.

@denik denik temporarily deployed to test-trigger-is March 18, 2026 10:51 — with GitHub Actions Inactive
@denik denik enabled auto-merge March 18, 2026 11:07
@denik denik added this pull request to the merge queue Mar 18, 2026
Merged via the queue into main with commit ed6f73f Mar 18, 2026
23 checks passed
@denik denik deleted the denik/grants-references branch March 18, 2026 11:28
@eng-dev-ecosystem-bot
Copy link
Copy Markdown
Collaborator

Commit: ed6f73f

Run: 23242525284

Env ❌​FAIL 🟨​KNOWN 🔄​flaky 💚​RECOVERED 🙈​SKIP ✅​pass 🙈​skip Time
❌​ aws linux 3 7 1 9 496 750 50:33
❌​ aws windows 3 7 1 9 468 758 49:48
❌​ aws-ucws linux 2 5 5 21 1 769 600 98:40
❌​ aws-ucws windows 2 3 6 21 1 733 611 93:02
❌​ azure linux 3 1 1 11 499 748 53:32
❌​ azure windows 3 1 2 1 11 469 756 57:08
❌​ azure-ucws linux 2 1 4 4 10 750 603 88:40
❌​ azure-ucws windows 2 1 5 4 10 712 614 88:57
❌​ gcp linux 3 1 1 11 482 756 50:38
❌​ gcp windows 3 1 1 11 454 764 50:57
41 interesting tests: 15 RECOVERED, 11 KNOWN, 9 flaky, 5 FAIL, 1 SKIP
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 🟨​K 🟨​K 🟨​K 🟨​K 🟨​K 🟨​K 🟨​K 🟨​K 🟨​K 🟨​K
❌​ TestAccept/bundle/apps/job_permissions ❌​F ❌​F 🔄​f 🔄​f ❌​F ❌​F 🔄​f ✅​p ❌​F ❌​F
❌​ TestAccept/bundle/apps/job_permissions/DATABRICKS_BUNDLE_ENGINE=direct ❌​F ❌​F ✅​p ✅​p ❌​F ❌​F 🔄​f 🔄​f ❌​F ❌​F
❌​ TestAccept/bundle/apps/job_permissions/DATABRICKS_BUNDLE_ENGINE=terraform ❌​F ❌​F 🔄​f 🔄​f ❌​F ❌​F ✅​p 🔄​f ❌​F ❌​F
🔄​ TestAccept/bundle/integration_whl/interactive_single_user ✅​p ✅​p ✅​p ✅​p ✅​p 🔄​f ✅​p ✅​p ✅​p ✅​p
🔄​ TestAccept/bundle/integration_whl/interactive_single_user/DATABRICKS_BUNDLE_ENGINE=direct ✅​p ✅​p ✅​p ✅​p ✅​p 🔄​f ✅​p ✅​p ✅​p ✅​p
❌​ TestAccept/bundle/invariant/no_drift 🙈​s 🙈​s ❌​F ❌​F 🙈​s 🙈​s ❌​F ❌​F 🙈​s 🙈​s
❌​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=schema_grant_ref.yml.tmpl ❌​F ❌​F ❌​F ❌​F
🔄​ TestAccept/bundle/resources/clusters/run/spark_python_task ✅​p ✅​p ✅​p ✅​p ✅​p ✅​p 🔄​f ✅​p ✅​p ✅​p
🔄​ TestAccept/bundle/resources/clusters/run/spark_python_task/DATABRICKS_BUNDLE_ENGINE=direct ✅​p ✅​p ✅​p ✅​p ✅​p ✅​p 🔄​f ✅​p ✅​p ✅​p
🙈​ TestAccept/bundle/resources/permissions 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🔄​ TestAccept/bundle/resources/permissions/factcheck ✅​p ✅​p ✅​p ✅​p ✅​p ✅​p ✅​p 🔄​f 🙈​s 🙈​s
🔄​ TestAccept/bundle/resources/permissions/factcheck/DATABRICKS_BUNDLE_ENGINE=terraform ✅​p ✅​p ✅​p ✅​p ✅​p ✅​p ✅​p 🔄​f
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/with_permissions 🟨​K 🟨​K 💚​R 💚​R 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/with_permissions/DATABRICKS_BUNDLE_ENGINE=direct 🟨​K 🟨​K 💚​R 💚​R
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/with_permissions/DATABRICKS_BUNDLE_ENGINE=terraform 🟨​K 🟨​K 💚​R 💚​R
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions 🟨​K 🟨​K 💚​R 💚​R 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions/DATABRICKS_BUNDLE_ENGINE=direct 🟨​K 🟨​K 💚​R 💚​R
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions/DATABRICKS_BUNDLE_ENGINE=terraform 🟨​K 🟨​K 💚​R 💚​R
🔄​ TestAccept/bundle/resources/postgres_branches/basic 🙈​S 🙈​S 🔄​f 🔄​f 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🔄​ TestAccept/bundle/resources/postgres_branches/basic/DATABRICKS_BUNDLE_ENGINE=direct 🔄​f 🔄​f
💚​ TestAccept/bundle/resources/postgres_branches/basic/DATABRICKS_BUNDLE_ENGINE=terraform 💚​R 💚​R
🟨​ TestAccept/bundle/resources/postgres_branches/recreate 🙈​S 🙈​S 🟨​K 🔄​f 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🟨​ TestAccept/bundle/resources/postgres_branches/recreate/DATABRICKS_BUNDLE_ENGINE=direct 🟨​K 🔄​f
💚​ TestAccept/bundle/resources/postgres_branches/recreate/DATABRICKS_BUNDLE_ENGINE=terraform 💚​R 💚​R
💚​ TestAccept/bundle/resources/postgres_branches/update_protected 🙈​S 🙈​S 💚​R 💚​R 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
💚​ TestAccept/bundle/resources/postgres_branches/update_protected/DATABRICKS_BUNDLE_ENGINE=direct 💚​R 💚​R
💚​ TestAccept/bundle/resources/postgres_branches/update_protected/DATABRICKS_BUNDLE_ENGINE=terraform 💚​R 💚​R
💚​ TestAccept/bundle/resources/postgres_branches/without_branch_id 🙈​S 🙈​S 💚​R 💚​R 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
💚​ TestAccept/bundle/resources/postgres_branches/without_branch_id/DATABRICKS_BUNDLE_ENGINE=direct 💚​R 💚​R
💚​ TestAccept/bundle/resources/postgres_branches/without_branch_id/DATABRICKS_BUNDLE_ENGINE=terraform 💚​R 💚​R
💚​ TestAccept/bundle/resources/postgres_endpoints/basic 🙈​S 🙈​S 💚​R 💚​R 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
💚​ TestAccept/bundle/resources/postgres_endpoints/basic/DATABRICKS_BUNDLE_ENGINE=terraform 💚​R 💚​R
💚​ TestAccept/bundle/resources/postgres_endpoints/recreate 🙈​S 🙈​S 💚​R 💚​R 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🟨​ TestAccept/bundle/resources/postgres_projects/update_display_name 🙈​S 🙈​S 🟨​K 🟨​K 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🟨​ TestAccept/bundle/resources/postgres_projects/update_display_name/DATABRICKS_BUNDLE_ENGINE=terraform 🟨​K 🟨​K
💚​ TestAccept/bundle/resources/synced_database_tables/basic 🙈​S 🙈​S 💚​R 💚​R 🙈​S 🙈​S 💚​R 💚​R 🙈​S 🙈​S
💚​ TestAccept/bundle/resources/synced_database_tables/basic/DATABRICKS_BUNDLE_ENGINE=direct 💚​R 💚​R 💚​R 💚​R
💚​ TestAccept/bundle/resources/synced_database_tables/basic/DATABRICKS_BUNDLE_ENGINE=terraform 💚​R 💚​R 💚​R 💚​R
🔄​ TestAccept/ssh/connect-serverless-gpu 🙈​s 🙈​s 🔄​f ✅​p 🙈​s 🙈​s ✅​p 🔄​f 🙈​s 🙈​s
💚​ TestAccept/ssh/connection 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R
Top 50 slowest tests (at least 2 minutes):
duration env testname
15:43 azure windows TestAccept/bundle/resources/permissions/factcheck/DATABRICKS_BUNDLE_ENGINE=terraform
14:46 aws-ucws windows TestAccept/bundle/resources/model_serving_endpoints/running-endpoint/DATABRICKS_BUNDLE_ENGINE=direct
14:18 aws-ucws windows TestAccept/bundle/resources/model_serving_endpoints/running-endpoint/DATABRICKS_BUNDLE_ENGINE=terraform
13:59 gcp windows TestAccept/bundle/integration_whl/interactive_cluster_dynamic_version/DATABRICKS_BUNDLE_ENGINE=terraform/DATA_SECURITY_MODE=SINGLE_USER
12:31 azure-ucws windows TestAccept/bundle/integration_whl/interactive_cluster/DATABRICKS_BUNDLE_ENGINE=direct
12:07 azure-ucws linux TestAccept/bundle/integration_whl/interactive_single_user/DATABRICKS_BUNDLE_ENGINE=terraform
11:41 azure-ucws linux TestAccept/bundle/integration_whl/interactive_cluster_dynamic_version/DATABRICKS_BUNDLE_ENGINE=direct/DATA_SECURITY_MODE=USER_ISOLATION
11:21 azure-ucws linux TestAccept/bundle/integration_whl/interactive_cluster_dynamic_version/DATABRICKS_BUNDLE_ENGINE=terraform/DATA_SECURITY_MODE=SINGLE_USER
10:36 gcp windows TestAccept/bundle/integration_whl/interactive_single_user/DATABRICKS_BUNDLE_ENGINE=terraform
10:34 gcp linux TestAccept/bundle/integration_whl/interactive_single_user/DATABRICKS_BUNDLE_ENGINE=terraform
10:14 gcp linux TestAccept/bundle/integration_whl/interactive_cluster_dynamic_version/DATABRICKS_BUNDLE_ENGINE=terraform/DATA_SECURITY_MODE=SINGLE_USER
9:45 aws-ucws linux TestAccept/bundle/resources/model_serving_endpoints/running-endpoint/DATABRICKS_BUNDLE_ENGINE=direct
8:49 gcp windows TestAccept/bundle/integration_whl/interactive_cluster_dynamic_version/DATABRICKS_BUNDLE_ENGINE=terraform/DATA_SECURITY_MODE=USER_ISOLATION
8:48 gcp windows TestAccept/bundle/integration_whl/interactive_cluster/DATABRICKS_BUNDLE_ENGINE=terraform
8:42 aws linux TestAccept/bundle/integration_whl/interactive_single_user/DATABRICKS_BUNDLE_ENGINE=terraform
8:28 aws-ucws linux TestAccept/bundle/resources/model_serving_endpoints/running-endpoint/DATABRICKS_BUNDLE_ENGINE=terraform
8:22 aws-ucws linux TestAccept/bundle/integration_whl/interactive_single_user/DATABRICKS_BUNDLE_ENGINE=terraform
8:19 azure-ucws windows TestAccept/bundle/integration_whl/interactive_single_user/DATABRICKS_BUNDLE_ENGINE=terraform
8:14 gcp windows TestAccept/bundle/integration_whl/interactive_cluster_dynamic_version/DATABRICKS_BUNDLE_ENGINE=direct/DATA_SECURITY_MODE=USER_ISOLATION
8:07 gcp linux TestAccept/bundle/integration_whl/interactive_cluster_dynamic_version/DATABRICKS_BUNDLE_ENGINE=direct/DATA_SECURITY_MODE=SINGLE_USER
7:56 gcp windows TestAccept/bundle/integration_whl/interactive_cluster_dynamic_version/DATABRICKS_BUNDLE_ENGINE=direct/DATA_SECURITY_MODE=SINGLE_USER
7:39 gcp linux TestAccept/bundle/integration_whl/interactive_cluster/DATABRICKS_BUNDLE_ENGINE=direct
7:39 gcp windows TestAccept/bundle/integration_whl/base/DATABRICKS_BUNDLE_ENGINE=terraform
7:37 gcp linux TestAccept/bundle/integration_whl/base/DATABRICKS_BUNDLE_ENGINE=terraform
7:36 aws-ucws linux TestAccept/bundle/resources/database_instances/single-instance/DATABRICKS_BUNDLE_ENGINE=direct
7:33 gcp linux TestAccept/bundle/integration_whl/interactive_single_user/DATABRICKS_BUNDLE_ENGINE=direct
7:32 aws-ucws linux TestAccept/bundle/integration_whl/interactive_cluster_dynamic_version/DATABRICKS_BUNDLE_ENGINE=terraform/DATA_SECURITY_MODE=USER_ISOLATION
7:31 aws-ucws windows TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=synced_database_table.yml.tmpl
7:30 gcp windows TestAccept/bundle/integration_whl/interactive_cluster/DATABRICKS_BUNDLE_ENGINE=direct
7:27 aws windows TestAccept/bundle/integration_whl/custom_params/DATABRICKS_BUNDLE_ENGINE=terraform
7:24 azure windows TestAccept/bundle/integration_whl/interactive_cluster/DATABRICKS_BUNDLE_ENGINE=terraform
7:22 gcp linux TestAccept/bundle/run/app-with-job/DATABRICKS_BUNDLE_ENGINE=direct
7:20 aws-ucws linux TestAccept/bundle/invariant/migrate/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=synced_database_table.yml.tmpl
7:19 aws linux TestAccept/bundle/integration_whl/interactive_cluster_dynamic_version/DATABRICKS_BUNDLE_ENGINE=terraform/DATA_SECURITY_MODE=USER_ISOLATION
7:18 aws windows TestAccept/bundle/integration_whl/custom_params/DATABRICKS_BUNDLE_ENGINE=direct
7:18 azure-ucws linux TestAccept/bundle/integration_whl/interactive_cluster_dynamic_version/DATABRICKS_BUNDLE_ENGINE=direct/DATA_SECURITY_MODE=SINGLE_USER
7:15 aws-ucws linux TestAccept/bundle/integration_whl/interactive_cluster_dynamic_version/DATABRICKS_BUNDLE_ENGINE=direct/DATA_SECURITY_MODE=USER_ISOLATION
7:14 gcp windows TestAccept/bundle/integration_whl/base/DATABRICKS_BUNDLE_ENGINE=direct
7:13 aws-ucws windows TestAccept/bundle/integration_whl/base/DATABRICKS_BUNDLE_ENGINE=direct
7:13 gcp windows TestAccept/bundle/run/app-with-job/DATABRICKS_BUNDLE_ENGINE=direct
7:11 gcp linux TestAccept/bundle/integration_whl/base/DATABRICKS_BUNDLE_ENGINE=direct
7:07 gcp linux TestAccept/bundle/run/app-with-job/DATABRICKS_BUNDLE_ENGINE=terraform
7:05 gcp linux TestAccept/bundle/integration_whl/interactive_cluster/DATABRICKS_BUNDLE_ENGINE=terraform
7:04 aws linux TestAccept/bundle/integration_whl/base/DATABRICKS_BUNDLE_ENGINE=terraform
7:04 gcp windows TestAccept/bundle/run/app-with-job/DATABRICKS_BUNDLE_ENGINE=terraform
7:02 aws-ucws windows TestAccept/bundle/integration_whl/base/DATABRICKS_BUNDLE_ENGINE=terraform
7:02 aws linux TestAccept/bundle/integration_whl/interactive_cluster_dynamic_version/DATABRICKS_BUNDLE_ENGINE=direct/DATA_SECURITY_MODE=USER_ISOLATION
7:01 aws-ucws linux TestAccept/bundle/resources/permissions/factcheck/DATABRICKS_BUNDLE_ENGINE=terraform
6:55 azure-ucws linux TestAccept/bundle/resources/model_serving_endpoints/running-endpoint/DATABRICKS_BUNDLE_ENGINE=direct
6:48 aws windows TestAccept/bundle/integration_whl/base/DATABRICKS_BUNDLE_ENGINE=terraform

deco-sdk-tagging bot added a commit that referenced this pull request Mar 18, 2026
## Release v0.295.0

### Notable Changes

* Databricks Asset Bundles have been renamed to Declarative Automation Bundles (DABs). This is a non-breaking change; no code or configuration modifications are required. See the [FAQ](https://docs.databricks.com/aws/en/dev-tools/bundles/faqs#why-was-databricks-asset-bundles-renamed-to-declarative-automation-bundles).
* Add `bundle.engine` config setting to select the deployment engine (`terraform` or [`direct`](https://docs.databricks.com/aws/en/dev-tools/bundles/direct)). The `bundle.engine` setting takes precedence over the `DATABRICKS_BUNDLE_ENGINE` environment variable. When the configured engine doesn't match existing deployment state, a warning is issued and the existing engine is used ([#4749](#4749), [#4782](#4782))

### CLI
* Add `databricks auth switch` command for setting the default profile ([#4651](#4651))
* Add positional argument support to `auth logout` ([#4744](#4744))
* Strip trailing slash from host in `auth login`, `auth token`, and `configure` commands ([#4633](#4633))

### Bundles
* Standardize `personal_schemas` enum across bundle templates ([#4401](#4401))
* engine/direct: Fix permanent drift on experiment name field ([#4627](#4627))
* engine/direct: Fix permissions state path to match input config schema ([#4703](#4703))
* Add default project name and success message to default-scala template ([#4661](#4661))
* Skip enum validation for unresolved variable references ([#4752](#4752))
* engine/direct: Support references to/from grants ([#4774](#4774))
github-merge-queue bot pushed a commit that referenced this pull request Mar 18, 2026
## Why

The CLI's CODEOWNERS catch-all assigns 6 people to every PR outside a
few narrow paths. This creates review noise and diffuses responsibility.
We want targeted reviewer suggestions based on who actually worked on
the changed code recently.

## Changes

Before: Every PR touching core code auto-assigns all 6 CODEOWNERS. No
signal about who is best suited to review.

Now: A new GitHub Action analyzes git history of the changed files and
posts a PR comment with two sections:
- **Suggested reviewers** (1-3 people best suited based on
recency-weighted git history)
- **Eligible reviewers** (everyone from CODEOWNERS who could review,
minus the suggested ones)

This is additive only. CODEOWNERS and auto-assign stay unchanged.

How it works:
- Triggers on PR open, synchronize, and ready-for-review (skips drafts
and fork PRs)
- Classifies changed files by type (source=1.0, tests=0.3,
acceptance=0.2, generated=0.0)
- Scores contributors using recency-weighted commit history (half-life
150 days)
- Resolves git author names to GitHub logins via the GitHub API (no
hardcoded alias table to maintain)
- Parses `.github/CODEOWNERS` to find eligible reviewers for the changed
paths
- Updates the comment in-place on re-runs (no notification churn)

Implementation: a single Python script (`tools/suggest_reviewers.py`,
281 lines) and a minimal workflow YAML.

## Test plan

- [x] Action ran on this PR itself and posted a comment successfully
- [x] Verified script parses cleanly, passed `make checks`, passed `ruff
format`
- [x] Dry-run tested against 4 recent merged PRs with different
characteristics:

**PR #4784** (66 files, by pietern, big DABs rename):
```
## Suggested reviewers
- @denik -- recent work in `./`, `bundle/`, `cmd/bundle/generate/`
Confidence: high

## Eligible reviewers
@andrewnester, @anton-107, @lennartkats-db, @shreyas-goenka, @simonfaltum
```
Correctly identifies Denis as the clear top reviewer (2x second place
score). All 6 CODEOWNERS shown as eligible.

**PR #4782** (13 files, by denik, bundle engine priority):
```
## Suggested reviewers
- @andrewnester -- recent work in `bundle/schema/`, `bundle/internal/schema/`, `cmd/bundle/generate/`
- @pietern -- recent work in `bundle/schema/`, `cmd/bundle/generate/`, `bundle/internal/schema/`
- @shreyas-goenka -- recent work in `bundle/schema/`, `bundle/internal/schema/`, `cmd/bundle/`
Confidence: medium

## Eligible reviewers
@anton-107, @simonfaltum
```
Suggests 3 reviewers when scores are close. Remaining CODEOWNERS shown
as eligible.

**PR #4785** (2 files, by MarioCadenas, apps bug fix):
```
## Suggested reviewers
- @arsenyinfo -- recent work in `cmd/apps/`
- @pietern -- recent work in `cmd/apps/`
- @pkosiec -- recent work in `cmd/apps/`
Confidence: low

## Eligible reviewers
@databricks/eng-apps-devex
```
Correctly suggests apps-area contributors (not the catch-all
CODEOWNERS). Shows the apps team as eligible. Low confidence since only
2 files.

**PR #4774** (28 files, by denik, direct engine grants):
```
## Suggested reviewers
- @andrewnester -- recent work in `bundle/direct/dresources/`, `acceptance/bundle/invariant/`
- @shreyas-goenka -- recent work in `bundle/direct/dresources/`
Confidence: high

## Eligible reviewers
@anton-107, @pietern, @simonfaltum
```
Correctly identifies the two main bundle/direct contributors. High
confidence with clear score separation.
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.

4 participants