Skip to content

Add GitHub Action to suggest PR reviewers based on git history - #4789

Merged
simonfaltum merged 4 commits into
mainfrom
simonfaltum/suggest-reviewers
Mar 18, 2026
Merged

Add GitHub Action to suggest PR reviewers based on git history#4789
simonfaltum merged 4 commits into
mainfrom
simonfaltum/suggest-reviewers

Conversation

@simonfaltum

@simonfaltumsimonfaltum commented Mar 18, 2026

Copy link
Copy Markdown
Member

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

  • Action ran on this PR itself and posted a comment successfully
  • Verified script parses cleanly, passed make checks, passed ruff format
  • 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.

Add a reviewer suggestion workflow that posts a PR comment with 1-2
suggested reviewers based on recency-weighted git history of changed
files. This is additive only, CODEOWNERS and auto-assign stay unchanged.
The action triggers on PR open and ready-for-review events, skips
drafts and fork PRs, and updates its comment in-place on re-runs.
Use gh api to resolve commit SHAs to GitHub logins automatically,
removing the need to maintain a manual author alias map. Also fix
error handling for gh subprocess failures, replace hardcoded
CODEOWNERS fallback with a link, add --since to bound git log,
and add synchronize trigger so suggestions update on new pushes.
Switch to deco runner group (IP allow list). Add CODEOWNERS parsing
to show eligible reviewers alongside the git-history-based suggestions.
Expand from 1-2 to 1-3 suggested reviewers with 1.5x threshold.
@github-actions

Copy link
Copy Markdown
Contributor

Eligible reviewers

Could not determine reviewers from git history. Based on CODEOWNERS, these people or teams could review:

@andrewnester, @anton-107, @denik, @pietern, @shreyas-goenka

Suggestions based on git history of 2 changed files (0 scored). See CODEOWNERS for path-specific ownership rules.

@eng-dev-ecosystem-bot

eng-dev-ecosystem-bot commented Mar 18, 2026

Copy link
Copy Markdown
Collaborator

Commit: 81c87b9

Run: 23256397493

Env🟨​KNOWN🔄​flaky💚​RECOVERED🙈​SKIP✅​pass🙈​skipTime
🟨​aws linux7192687976:34
🟨​aws windows7192707956:19
🔄​aws-ucws linux26936571214:10
🔄​aws-ucws windows26936771013:01
💚​azure linux2112717956:07
💚​azure windows2112737935:03
🔄​azure-ucws linux211136970811:22
🔄​azure-ucws windows21113717065:57
🔄​gcp linux22112657986:21
💚​gcp windows2112697966:29
20 interesting tests: 9 SKIP, 7 KNOWN, 4 flaky
Test Nameaws linuxaws windowsaws-ucws linuxaws-ucws windowsazure linuxazure windowsazure-ucws linuxazure-ucws windowsgcp linuxgcp windows
🟨​TestAccept🟨​K🟨​K🔄​f🔄​f💚​R💚​R💚​R💚​R💚​R💚​R
🙈​TestAccept/bundle/resources/permissions🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S
🟨​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🙈​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/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_endpoints/recreate🙈​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/ssh/connect-serverless-gpu🙈​s🙈​s✅​p✅​p🙈​s🙈​s🔄​f🔄​f🙈​s🙈​s
🔄​TestAccept/ssh/connection💚​R💚​R🔄​f🔄​f💚​R💚​R🔄​f🔄​f💚​R💚​R
🔄​TestFilerWorkspaceNotebook✅​p✅​p✅​p✅​p✅​p✅​p✅​p✅​p🔄​f✅​p
🔄​TestFilerWorkspaceNotebook/rNb.r✅​p✅​p✅​p✅​p✅​p✅​p✅​p✅​p🔄​f✅​p
Top 23 slowest tests (at least 2 minutes):
durationenvtestname
6:10aws-ucws linuxTestAccept/ssh/connection
6:00aws-ucws windowsTestAccept/ssh/connection
4:46gcp windowsTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
4:12gcp linuxTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:46gcp linuxTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:34gcp windowsTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:19azure-ucws linuxTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:12aws windowsTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:58aws-ucws windowsTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:58aws-ucws windowsTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:54aws windowsTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:53aws-ucws linuxTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:50aws linuxTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:49azure-ucws linuxTestAccept/ssh/connect-serverless-gpu
2:46aws linuxTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:42azure windowsTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:41aws-ucws linuxTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:37azure windowsTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:17azure linuxTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:15azure-ucws windowsTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:13azure-ucws linuxTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:06azure linuxTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:03azure-ucws windowsTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct

GITHUB_REPOSITORY: ${{ github.repository }}
PR_NUMBER: ${{ github.event.pull_request.number }}
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
run: python3 tools/suggest_reviewers.py

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.

Nit: let's use uv here (and setup-uv) to make sure we really run with 3.12.

Comment threadtools/suggest_reviewers.py Outdated
if p.name.startswith("out.") or p.name == "output.txt":
return 0.0
if path.startswith(("cmd/workspace/", "cmd/account/")):
return 0.0

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.

FYI, there are non-generated files as well in those directories.

@renaudhartert-dbrenaudhartert-db left a comment

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 we port that to TF and SDKs?

Remove the 0.0 weight override for cmd/workspace/ and cmd/account/
since those directories contain non-generated files too (denik).
Use uv + setup-uv to pin Python 3.12 (pietern).
@simonfaltum
simonfaltum added this pull request to the merge queueMar 18, 2026
Merged via the queue into main with commit a2e290dMar 18, 2026
19 checks passed
@simonfaltum
simonfaltum deleted the simonfaltum/suggest-reviewers branch March 18, 2026 17:32
@eng-dev-ecosystem-bot

Copy link
Copy Markdown
Collaborator

Commit: a2e290d

Run: 23258521387

Env❌​FAIL🟨​KNOWN🔄​flaky💚​RECOVERED🙈​SKIP✅​pass🙈​skipTime
❌​aws linux371949675054:10
❌​aws windows371946875850:07
❌​aws-ucws linux736231763600131:34
❌​aws-ucws windows538201729611108:09
❌​azure linux3111149974854:28
❌​azure windows3111147175655:54
❌​azure-ucws linux21741074760397:09
❌​azure-ucws windows21431071461486:32
❌​gcp linux3111148275652:47
❌​gcp windows3111145476453:17
46 interesting tests: 15 flaky, 14 RECOVERED, 9 KNOWN, 7 FAIL, 1 SKIP
Test Nameaws linuxaws windowsaws-ucws linuxaws-ucws windowsazure linuxazure windowsazure-ucws linuxazure-ucws windowsgcp linuxgcp windows
🟨​TestAccept🟨​K🟨​K🟨​K🟨​K🟨​K🟨​K🟨​K🟨​K🟨​K🟨​K
❌​TestAccept/bundle/apps/job_permissions❌​F❌​F❌​F❌​F❌​F❌​F✅​p🔄​f❌​F❌​F
❌​TestAccept/bundle/apps/job_permissions/DATABRICKS_BUNDLE_ENGINE=direct❌​F❌​F❌​F❌​F❌​F❌​F🔄​f🔄​f❌​F❌​F
❌​TestAccept/bundle/apps/job_permissions/DATABRICKS_BUNDLE_ENGINE=terraform❌​F❌​F❌​F❌​F❌​F❌​F🔄​f✅​p❌​F❌​F
❌​TestAccept/bundle/integration_whl/base✅​p✅​p❌​F✅​p✅​p✅​p✅​p✅​p✅​p✅​p
🔄​TestAccept/bundle/integration_whl/base/DATABRICKS_BUNDLE_ENGINE=direct✅​p✅​p🔄​f✅​p✅​p✅​p✅​p✅​p✅​p✅​p
❌​TestAccept/bundle/integration_whl/base/DATABRICKS_BUNDLE_ENGINE=terraform✅​p✅​p❌​F✅​p✅​p✅​p✅​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/model_serving_endpoints/basic🙈​s🙈​s✅​p✅​p🙈​s🙈​s🔄​f✅​p🙈​s🙈​s
🔄​TestAccept/bundle/resources/model_serving_endpoints/basic/DATABRICKS_BUNDLE_ENGINE=terraform✅​p✅​p🔄​f✅​p
🔄​TestAccept/bundle/resources/model_serving_endpoints/running-endpoint🙈​s🙈​s✅​p✅​p🙈​s🙈​s🔄​f✅​p🙈​s🙈​s
🔄​TestAccept/bundle/resources/model_serving_endpoints/running-endpoint/DATABRICKS_BUNDLE_ENGINE=direct✅​p✅​p🔄​f✅​p
🙈​TestAccept/bundle/resources/permissions🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S
🟨​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💚​R💚​R🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S
💚​TestAccept/bundle/resources/postgres_branches/basic/DATABRICKS_BUNDLE_ENGINE=direct💚​R💚​R
💚​TestAccept/bundle/resources/postgres_branches/basic/DATABRICKS_BUNDLE_ENGINE=terraform💚​R💚​R
🔄​TestAccept/bundle/resources/postgres_branches/recreate🙈​S🙈​S💚​R🔄​f🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S
🔄​TestAccept/bundle/resources/postgres_branches/recreate/DATABRICKS_BUNDLE_ENGINE=direct💚​R🔄​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🔄​f🔄​f🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S
🔄​TestAccept/bundle/resources/postgres_endpoints/basic/DATABRICKS_BUNDLE_ENGINE=terraform🔄​f🔄​f
💚​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/bundle/templates/default-python/integration_classic✅​p✅​p✅​p🔄​f✅​p✅​p✅​p✅​p✅​p✅​p
🔄​TestAccept/bundle/templates/default-python/integration_classic/DATABRICKS_BUNDLE_ENGINE=terraform/UV_PYTHON=3.11✅​p✅​p✅​p🔄​f✅​p✅​p✅​p✅​p✅​p✅​p
🔄​TestAccept/ssh/connect-serverless-gpu🙈​s🙈​s🔄​f🔄​f🙈​s🙈​s🔄​f🔄​f🙈​s🙈​s
🔄​TestAccept/ssh/connection💚​R💚​R💚​R🔄​f💚​R💚​R💚​R🔄​f💚​R💚​R
🔄​TestSparkJarTaskDeployAndRunOnWorkspace✅​p✅​p🔄​f✅​p✅​p✅​p✅​p✅​p✅​p✅​p
🔄​TestSparkJarTaskDeployAndRunOnWorkspace/Databricks_Runtime_15.4_LTS✅​p✅​p🔄​f✅​p✅​p✅​p✅​p✅​p✅​p✅​p
Top 50 slowest tests (at least 2 minutes):
durationenvtestname
15:08aws-ucws windowsTestAccept/bundle/resources/model_serving_endpoints/running-endpoint/DATABRICKS_BUNDLE_ENGINE=direct
14:51azure windowsTestAccept/bundle/integration_whl/base/DATABRICKS_BUNDLE_ENGINE=terraform
14:35gcp linuxTestAccept/bundle/integration_whl/interactive_cluster_dynamic_version/DATABRICKS_BUNDLE_ENGINE=terraform/DATA_SECURITY_MODE=SINGLE_USER
14:26aws-ucws windowsTestAccept/bundle/resources/model_serving_endpoints/running-endpoint/DATABRICKS_BUNDLE_ENGINE=terraform
14:23gcp windowsTestAccept/bundle/integration_whl/interactive_single_user/DATABRICKS_BUNDLE_ENGINE=terraform
13:51gcp windowsTestAccept/bundle/integration_whl/interactive_cluster_dynamic_version/DATABRICKS_BUNDLE_ENGINE=terraform/DATA_SECURITY_MODE=SINGLE_USER
11:27gcp linuxTestAccept/bundle/integration_whl/interactive_single_user/DATABRICKS_BUNDLE_ENGINE=terraform
11:21azure linuxTestAccept/bundle/integration_whl/base/DATABRICKS_BUNDLE_ENGINE=direct
11:20aws-ucws linuxTestAccept/bundle/integration_whl/base/DATABRICKS_BUNDLE_ENGINE=direct
10:45aws-ucws linuxTestAccept/bundle/resources/database_instances/single-instance/DATABRICKS_BUNDLE_ENGINE=terraform
10:25azure windowsTestAccept/bundle/integration_whl/base/DATABRICKS_BUNDLE_ENGINE=direct
10:03azure-ucws windowsTestAccept/bundle/integration_whl/interactive_single_user/DATABRICKS_BUNDLE_ENGINE=terraform
9:39aws windowsTestAccept/bundle/integration_whl/interactive_cluster_dynamic_version/DATABRICKS_BUNDLE_ENGINE=terraform/DATA_SECURITY_MODE=SINGLE_USER
9:36azure-ucws linuxTestAccept/bundle/integration_whl/interactive_single_user/DATABRICKS_BUNDLE_ENGINE=terraform
9:15azure windowsTestAccept/bundle/integration_whl/interactive_single_user/DATABRICKS_BUNDLE_ENGINE=terraform
9:15azure windowsTestAccept/bundle/integration_whl/interactive_cluster_dynamic_version/DATABRICKS_BUNDLE_ENGINE=terraform/DATA_SECURITY_MODE=SINGLE_USER
9:10aws-ucws linuxTestAccept/bundle/resources/model_serving_endpoints/running-endpoint/DATABRICKS_BUNDLE_ENGINE=terraform
9:04aws-ucws linuxTestAccept/bundle/integration_whl/interactive_single_user/DATABRICKS_BUNDLE_ENGINE=terraform
8:58aws-ucws windowsTestAccept/bundle/integration_whl/base/DATABRICKS_BUNDLE_ENGINE=direct
8:50azure linuxTestAccept/bundle/integration_whl/interactive_single_user/DATABRICKS_BUNDLE_ENGINE=terraform
8:46azure-ucws windowsTestAccept/bundle/integration_whl/base/DATABRICKS_BUNDLE_ENGINE=terraform
8:39gcp linuxTestAccept/bundle/run/app-with-job/DATABRICKS_BUNDLE_ENGINE=terraform
8:33azure-ucws linuxTestAccept/bundle/integration_whl/interactive_cluster_dynamic_version/DATABRICKS_BUNDLE_ENGINE=direct/DATA_SECURITY_MODE=USER_ISOLATION
8:26aws-ucws windowsTestAccept/bundle/invariant/migrate/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=synced_database_table.yml.tmpl
8:25gcp linuxTestAccept/bundle/run/app-with-job/DATABRICKS_BUNDLE_ENGINE=direct
8:20aws-ucws windowsTestSparkJarTaskDeployAndRunOnVolumes/Databricks_Runtime_13.3_LTS
8:18aws-ucws linuxTestAccept/bundle/resources/model_serving_endpoints/running-endpoint/DATABRICKS_BUNDLE_ENGINE=direct
8:17azure-ucws linuxTestSparkJarTaskDeployAndRunOnVolumes/Databricks_Runtime_14.3_LTS
8:17azure-ucws linuxTestSparkJarTaskDeployAndRunOnVolumes/Databricks_Runtime_15.4_LTS
8:16azure-ucws windowsTestAccept/bundle/integration_whl/custom_params/DATABRICKS_BUNDLE_ENGINE=terraform
8:15aws-ucws linuxTestSparkJarTaskDeployAndRunOnVolumes/Databricks_Runtime_15.4_LTS
8:14azure-ucws windowsTestAccept/bundle/integration_whl/base/DATABRICKS_BUNDLE_ENGINE=direct
8:14aws linuxTestAccept/bundle/resources/permissions/factcheck/DATABRICKS_BUNDLE_ENGINE=terraform
8:11gcp linuxTestAccept/bundle/integration_whl/interactive_cluster/DATABRICKS_BUNDLE_ENGINE=direct
8:11aws-ucws windowsTestAccept/bundle/integration_whl/base/DATABRICKS_BUNDLE_ENGINE=terraform
8:09gcp linuxTestAccept/bundle/integration_whl/interactive_cluster_dynamic_version/DATABRICKS_BUNDLE_ENGINE=direct/DATA_SECURITY_MODE=USER_ISOLATION
8:07gcp windowsTestAccept/bundle/integration_whl/custom_params/DATABRICKS_BUNDLE_ENGINE=terraform
8:06azure-ucws linuxTestAccept/bundle/integration_whl/interactive_cluster_dynamic_version/DATABRICKS_BUNDLE_ENGINE=terraform/DATA_SECURITY_MODE=USER_ISOLATION
8:00gcp windowsTestAccept/bundle/integration_whl/interactive_cluster_dynamic_version/DATABRICKS_BUNDLE_ENGINE=direct/DATA_SECURITY_MODE=USER_ISOLATION
7:55gcp windowsTestAccept/bundle/run/app-with-job/DATABRICKS_BUNDLE_ENGINE=direct
7:54gcp linuxTestAccept/bundle/integration_whl/base/DATABRICKS_BUNDLE_ENGINE=terraform
7:52azure-ucws windowsTestAccept/bundle/integration_whl/interactive_cluster/DATABRICKS_BUNDLE_ENGINE=direct
7:51gcp linuxTestAccept/bundle/integration_whl/interactive_cluster/DATABRICKS_BUNDLE_ENGINE=terraform
7:50aws-ucws windowsTestSparkJarTaskDeployAndRunOnVolumes/Databricks_Runtime_15.4_LTS
7:45azure-ucws windowsTestSparkJarTaskDeployAndRunOnVolumes/Databricks_Runtime_15.4_LTS
7:45azure-ucws windowsTestAccept/bundle/integration_whl/interactive_single_user/DATABRICKS_BUNDLE_ENGINE=direct
7:44aws-ucws linuxTestAccept/bundle/integration_whl/interactive_cluster_dynamic_version/DATABRICKS_BUNDLE_ENGINE=terraform/DATA_SECURITY_MODE=USER_ISOLATION
7:43gcp windowsTestAccept/bundle/integration_whl/base/DATABRICKS_BUNDLE_ENGINE=direct
7:42azure-ucws linuxTestAccept/bundle/integration_whl/wrapper_custom_params/DATABRICKS_BUNDLE_ENGINE=terraform
7:41azure-ucws linuxTestAccept/bundle/integration_whl/base/DATABRICKS_BUNDLE_ENGINE=terraform

denik pushed a commit that referenced this pull request May 20, 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 freeto 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.

5 participants

@simonfaltum@eng-dev-ecosystem-bot@pietern@denik@renaudhartert-db