[PR #63] [MERGED] feat(refresh-reviewers): recompute the reviewer expertise map from git history and open a drift PR (BE-4116) #71

Closed
opened 2026-10-26 22:35:56 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/Comfy-Org/github-workflows/pull/63
Author: @mattmillerai
Created: 7/22/2026
Status: ✅ Merged
Merged: 8/4/2026
Merged by: @mattmillerai

Base: main ← Head: matt/be-4116-refresh-reviewers


📝 Commits (2)

  • 3eb0ff3 feat(refresh-reviewers): reusable workflow — recompute the reviewer expertise map from git history, open a drift PR (BE-4116)
  • 2513caf fix(refresh-reviewers): harden per review panel — knob validation, API-failure no-op, branch guards, stale-PR reconcile, md escaping (BE-4116)

📊 Changes

7 files changed (+1870 additions, -0 deletions)

View changed files

➕ .github/refresh-reviewers/README.md (+96 -0)
➕ .github/refresh-reviewers/generate.py (+907 -0)
➕ .github/refresh-reviewers/tests/test_generate.py (+491 -0)
➕ .github/workflows/refresh-reviewers.yml (+326 -0)
➕ .github/workflows/test-refresh-reviewers.yml (+39 -0)
📝 AGENTS.md (+10 -0)
📝 README.md (+1 -0)

📄 Description

ELI-5

When someone opens a PR, assign-reviewers.yml picks owners from a hand-written map (.github/reviewers.yml) of "who knows which part of the code." That map goes stale as people join, leave, or change focus. This PR adds a sibling reusable workflow, refresh-reviewers.yml, that a repo can run on a schedule: it re-reads the repo's git history, re-scores who actually works where (recent commits count more; bots, lockfiles, and generated code don't count), and — only when the map has drifted — opens ONE small PR proposing the updated lists, with the scores shown so a human can sanity-check and merge. It never assigns anyone and never merges anything itself.

What's here

  • .github/workflows/refresh-reviewers.yml — the reusable workflow_call engine, following assign-reviewers.yml's conventions: app-token auth (vars.APP_ID + CLOUD_CODE_BOT_PRIVATE_KEY), caller-side config, never-fail defensive handling. The workflow's own permissions: stay contents: read; the branch push + PR open go through the app token. Generator script is loaded from a pinned workflows_ref of this repo (tamper-proofing convention), never the caller's checkout.
  • .github/refresh-reviewers/generate.py — the engine, ported from the validated BE-4114 prototype (not redesigned): decayed commit-touch scoring (0.5^(age/half_life), line counts intentionally unused), bot-author + generated/churn-path + rename-syntax filtering, noreply-email decoding (incl. digits+login@) with per-run-cached commits-API fallback, collaborator (not org-member) eligibility, per-rule threshold/floor/backfill selection with the under-floor leave-unchanged cold-start fallback, default_pool = top-5 overall minus ≥2-rule anchors minus map_exclude, a surgical rewrite that touches only the reviewers:/default_pool: sequences (flow AND block) and preserves every comment byte-for-byte, plus the report-only taxonomy-gap section.
  • Drift gate + idempotent PR: no drift → quiet exit. Drift → reset bot/refresh-reviewers from the default branch, commit the single file, force-push, and create the PR or edit the existing open one's body — duplicates never stack.
  • .github/refresh-reviewers/tests/test_generate.py — 38 pure-python tests (repo .github/<tool>/tests/ pattern): glob parity with globToRegExp (**/inference/** vs services/ingest/** cases), decay math, threshold/floor/backfill/under-floor selection, bot/path/rename filtering, noreply decoding, byte-preserving rewrite (flow + block + scalar), PR-body content. Plus test-refresh-reviewers.yml (path-filtered CI, mirrors test-cursor-review-scripts.yml).
  • Docs: .github/refresh-reviewers/README.md (contract, knob defaults + BE-4114 rationale, map_exclude guidance), root README table row, AGENTS.md entries (137/200 lines, integrity checker passes).

Verification

  • python3 -m unittest discover -s .github/refresh-reviewers/tests — 38/38 pass; all other suites (cursor-review, agents-md-integrity, groom, bump-callers) still green; actionlint clean on both new workflows.
  • End-to-end smoke against a synthetic git repo with a stubbed API: correct drift detection, comment-preserving rewrite, under-floor rule left unchanged, bot/unresolved counts right, idempotent outputs.

Judgment calls

  • workflows_ref input added (not in the ticket contract): required by this repo's "scripts are the single source of truth, loaded from a pinned ref" convention — same shape as agents-md-integrity.yml/pr-size.yml.
  • Never-fail scope: environmental failures (missing config, unreachable collaborators API, no history) exit 0 with a ::warning::; genuine bugs still raise so they're visible. Collaborator-API-down aborts quietly rather than emitting a map with unvalidated eligibility.
  • Login-case canonicalization: noreply decode preserves email casing and membership matching is case-insensitive against the collaborator list's canonical casing — without this, mixed-case logins (e.g. DrJKL-style) would be silently dropped. Regression-tested.
  • Whole-path rename form (old => new without braces) is normalized too, not just the ticket's brace form — git emits both.
  • Force-push on bot/refresh-reviewers is per the ticket's reset-branch idempotency spec; the branch is bot-owned by contract. No concurrency: group (siblings don't set one; weekly-schedule overlap is negligible).
  • No consumer wiring here — the cloud caller is the separate blocked follow-up, per the ticket.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/Comfy-Org/github-workflows/pull/63 **Author:** [@mattmillerai](https://github.com/mattmillerai) **Created:** 7/22/2026 **Status:** ✅ Merged **Merged:** 8/4/2026 **Merged by:** [@mattmillerai](https://github.com/mattmillerai) **Base:** `main` ← **Head:** `matt/be-4116-refresh-reviewers` --- ### 📝 Commits (2) - [`3eb0ff3`](https://github.com/Comfy-Org/github-workflows/commit/3eb0ff3230294eac8f05a03e97f8ea968c490d1f) feat(refresh-reviewers): reusable workflow — recompute the reviewer expertise map from git history, open a drift PR (BE-4116) - [`2513caf`](https://github.com/Comfy-Org/github-workflows/commit/2513caf6d74514787a231c87af2801887015afbe) fix(refresh-reviewers): harden per review panel — knob validation, API-failure no-op, branch guards, stale-PR reconcile, md escaping (BE-4116) ### 📊 Changes **7 files changed** (+1870 additions, -0 deletions) <details> <summary>View changed files</summary> ➕ `.github/refresh-reviewers/README.md` (+96 -0) ➕ `.github/refresh-reviewers/generate.py` (+907 -0) ➕ `.github/refresh-reviewers/tests/test_generate.py` (+491 -0) ➕ `.github/workflows/refresh-reviewers.yml` (+326 -0) ➕ `.github/workflows/test-refresh-reviewers.yml` (+39 -0) 📝 `AGENTS.md` (+10 -0) 📝 `README.md` (+1 -0) </details> ### 📄 Description ## ELI-5 When someone opens a PR, `assign-reviewers.yml` picks owners from a hand-written map (`.github/reviewers.yml`) of "who knows which part of the code." That map goes stale as people join, leave, or change focus. This PR adds a sibling reusable workflow, `refresh-reviewers.yml`, that a repo can run on a schedule: it re-reads the repo's git history, re-scores who actually works where (recent commits count more; bots, lockfiles, and generated code don't count), and — only when the map has drifted — opens ONE small PR proposing the updated lists, with the scores shown so a human can sanity-check and merge. It never assigns anyone and never merges anything itself. ## What's here - **`.github/workflows/refresh-reviewers.yml`** — the reusable `workflow_call` engine, following `assign-reviewers.yml`'s conventions: app-token auth (`vars.APP_ID` + `CLOUD_CODE_BOT_PRIVATE_KEY`), caller-side config, never-fail defensive handling. The workflow's own `permissions:` stay `contents: read`; the branch push + PR open go through the app token. Generator script is loaded from a pinned `workflows_ref` of this repo (tamper-proofing convention), never the caller's checkout. - **`.github/refresh-reviewers/generate.py`** — the engine, ported from the validated BE-4114 prototype (not redesigned): decayed commit-touch scoring (`0.5^(age/half_life)`, line counts intentionally unused), bot-author + generated/churn-path + rename-syntax filtering, noreply-email decoding (incl. `digits+login@`) with per-run-cached commits-API fallback, **collaborator** (not org-member) eligibility, per-rule threshold/floor/backfill selection with the under-floor leave-unchanged cold-start fallback, `default_pool` = top-5 overall minus ≥2-rule anchors minus `map_exclude`, a **surgical rewrite** that touches only the `reviewers:`/`default_pool:` sequences (flow AND block) and preserves every comment byte-for-byte, plus the report-only taxonomy-gap section. - **Drift gate + idempotent PR**: no drift → quiet exit. Drift → reset `bot/refresh-reviewers` from the default branch, commit the single file, force-push, and create the PR or edit the existing open one's body — duplicates never stack. - **`.github/refresh-reviewers/tests/test_generate.py`** — 38 pure-python tests (repo `.github/<tool>/tests/` pattern): glob parity with `globToRegExp` (`**/inference/**` vs `services/ingest/**` cases), decay math, threshold/floor/backfill/under-floor selection, bot/path/rename filtering, noreply decoding, byte-preserving rewrite (flow + block + scalar), PR-body content. Plus `test-refresh-reviewers.yml` (path-filtered CI, mirrors `test-cursor-review-scripts.yml`). - **Docs**: `.github/refresh-reviewers/README.md` (contract, knob defaults + BE-4114 rationale, `map_exclude` guidance), root README table row, AGENTS.md entries (137/200 lines, integrity checker passes). ## Verification - `python3 -m unittest discover -s .github/refresh-reviewers/tests` — 38/38 pass; all other suites (cursor-review, agents-md-integrity, groom, bump-callers) still green; `actionlint` clean on both new workflows. - End-to-end smoke against a synthetic git repo with a stubbed API: correct drift detection, comment-preserving rewrite, under-floor rule left unchanged, bot/unresolved counts right, idempotent outputs. ## Judgment calls - **`workflows_ref` input added** (not in the ticket contract): required by this repo's "scripts are the single source of truth, loaded from a pinned ref" convention — same shape as `agents-md-integrity.yml`/`pr-size.yml`. - **Never-fail scope**: *environmental* failures (missing config, unreachable collaborators API, no history) exit 0 with a `::warning::`; genuine bugs still raise so they're visible. Collaborator-API-down aborts quietly rather than emitting a map with unvalidated eligibility. - **Login-case canonicalization**: noreply decode preserves email casing and membership matching is case-insensitive against the collaborator list's canonical casing — without this, mixed-case logins (e.g. `DrJKL`-style) would be silently dropped. Regression-tested. - **Whole-path rename form** (`old => new` without braces) is normalized too, not just the ticket's brace form — git emits both. - **Force-push on `bot/refresh-reviewers`** is per the ticket's reset-branch idempotency spec; the branch is bot-owned by contract. No `concurrency:` group (siblings don't set one; weekly-schedule overlap is negligible). - No consumer wiring here — the cloud caller is the separate blocked follow-up, per the ticket. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-26 22:35:56 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Comfy-Org/github-workflows#71
No description provided.