mirror of
https://github.com/HDFGroup/hdf5.git
synced 2026-09-25 04:09:44 +03:00
review-checklist.js previously tried to enforce a single load-balanced reviewer per area by actively stripping anyone else who showed up, using a checklist-comment-existence heuristic (isOpeningRace) to decide when it was safe to do so. Walking through real PR timelines surfaced several cases where that heuristic and that stripping behavior did the wrong thing: - An old PR's first encounter with the bot (or one whose checklist comment was deleted) was misdiagnosed as a brand-new PR, forcibly reselecting a human-curated reviewer list. - A CODEOWNER for areas this PR doesn't touch (e.g. a project lead added by hand for their judgment) was swept by the same logic as junk auto-assignment, with no protection for an existing approval. - A reviewer who isn't an owner of any touched area was invisible in the checklist and untouched by any cleanup path either way. - A PR that picked up reviewers while non-draft, then was converted to draft, had those reviewers wiped out by the next push — converted_to_draft isn't in this workflow's trigger list, so there's no event at the actual transition to distinguish "noise from this PR's creation" from "a real assignment from before it became a draft." - A reviewer removed via the PR UI could be silently re-added by GitHub's own CODEOWNERS engine on a later push, since there was no memory of the removal across runs. Redesign around one principle: the bot should never automatically strip a reviewer who's already on the PR, manually added or auto-assigned, except where the policy explicitly calls for it. Concretely: - coordinateReviewers is now purely additive for non-draft PRs: chooseReviewers runs against the *real* existingRequested, so it naturally skips any area that already has someone and only fills gaps. This is idempotent and safe on every event, eliminating the need for the old race-detection heuristic entirely (isOpeningRace, the new-PR/synchronize distinction, and the post-request 15s delayed re-clear are all removed as dead weight). - Pruning — used only where the bot still clears reviewers — is scoped to touchedAreaOwners (owners of areas this PR touches, plus catch-all "*" owners) instead of the repo-wide allCodeOwners, so a CODEOWNER for unrelated areas is never touched. - Draft handling clears auto-assigned reviewers only at the literal opened/reopened-as-draft moment — the one point where "CODEOWNERS noise from this PR's creation" and "this PR's actual reviewer state" are mechanically the same thing. Every other event while draft leaves existing reviewers alone. - An explicit review_request_removed persists that login to an exclusion list embedded as a second hidden marker in the checklist comment (the only durable storage available), and every run strips anyone in that list who reappears — covering GitHub re-assigning them on a later push. A direct review_requested for that exact login overrides the exclusion, since it's the strongest available signal that someone individually decided that person should be back right now. - buildBody adds a catch-all "Additional reviewers" line for anyone requested who isn't an owner of any touched area, so they're visible and their approval is shown (informationally — it doesn't gate any area's sign-off), and accepts any owner's approval for an area's sign-off rather than only the specifically-assigned one's. 12 new tests cover the buildBody changes and the parseExcluded/serializeExcluded round-trip; all existing pure-function tests are unchanged. Co-authored-by: H. Joe Lee <hyoklee@hdfgroup.org>