Skip to content

Commit 24fb765

Browse files
BagToadCopilot
andcommitted
Exclude PR author from reviewer candidates in SuggestedReviewerActors
Add author { login } to the SuggestedReviewerActors GraphQL query and pre-seed the seen map with the author login so they are excluded from all sources (suggestions, collaborators, teams). Previously the author was only skipped via the isAuthor flag in the suggestions loop but could still appear as a collaborator. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 1bba50b commit 24fb765

2 files changed

Lines changed: 40 additions & 5 deletions

File tree

api/queries_pr_review.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,9 @@ func SuggestedReviewerActors(client *Client, repo ghrepo.Interface, prID string,
413413
type responseData struct {
414414
Node struct {
415415
PullRequest struct {
416+
Author struct {
417+
Login string
418+
}
416419
SuggestedActors struct {
417420
Nodes []struct {
418421
IsAuthor bool
@@ -472,7 +475,11 @@ func SuggestedReviewerActors(client *Client, repo ghrepo.Interface, prID string,
472475
// Build candidates using cascading quota logic:
473476
// Each source has a base quota of 5, plus any unfilled quota from previous sources.
474477
// This ensures we show up to 15 total candidates, filling gaps when earlier sources have fewer.
478+
// Pre-seed seen with the PR author since you cannot review your own PR.
475479
seen := make(map[string]bool)
480+
if authorLogin := result.Node.PullRequest.Author.Login; authorLogin != "" {
481+
seen[authorLogin] = true
482+
}
476483
var candidates []ReviewerCandidate
477484
const baseQuota = 5
478485

api/queries_pr_test.go

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ func mockReviewerResponse(suggestions, collabs, teams, totalCollabs, totalTeams
160160

161161
return fmt.Sprintf(`{
162162
"data": {
163-
"node": {"suggestedReviewerActors": {"nodes": [%s]}},
163+
"node": {"author": {"login": "testauthor"}, "suggestedReviewerActors": {"nodes": [%s]}},
164164
"repository": {
165165
"collaborators": {"nodes": [%s]},
166166
"collaboratorsTotalCount": {"totalCount": %d}
@@ -235,7 +235,7 @@ func TestSuggestedReviewerActors(t *testing.T) {
235235
httpmock.GraphQL(`query SuggestedReviewerActors\b`),
236236
httpmock.StringResponse(`{
237237
"data": {
238-
"node": {"suggestedReviewerActors": {"nodes": [
238+
"node": {"author": {"login": "testauthor"}, "suggestedReviewerActors": {"nodes": [
239239
{"isAuthor": true, "reviewer": {"__typename": "User", "login": "author", "name": "Author"}},
240240
{"isAuthor": false, "reviewer": {"__typename": "User", "login": "s1", "name": "S1"}},
241241
{"isAuthor": false, "reviewer": {"__typename": "User", "login": "s2", "name": "S2"}}
@@ -255,6 +255,34 @@ func TestSuggestedReviewerActors(t *testing.T) {
255255
expectedLogins: []string{"s1", "s2", "c1", "OWNER/team1"},
256256
expectedMore: 8,
257257
},
258+
{
259+
name: "author excluded from collaborators",
260+
httpStubs: func(reg *httpmock.Registry) {
261+
reg.Register(
262+
httpmock.GraphQL(`query SuggestedReviewerActors\b`),
263+
httpmock.StringResponse(`{
264+
"data": {
265+
"node": {"author": {"login": "theauthor"}, "suggestedReviewerActors": {"nodes": [
266+
{"isAuthor": false, "reviewer": {"__typename": "User", "login": "s1", "name": "S1"}}
267+
]}},
268+
"repository": {
269+
"collaborators": {"nodes": [
270+
{"login": "theauthor", "name": "The Author"},
271+
{"login": "c1", "name": "C1"}
272+
]},
273+
"collaboratorsTotalCount": {"totalCount": 5}
274+
},
275+
"organization": {
276+
"teams": {"nodes": []},
277+
"teamsTotalCount": {"totalCount": 0}
278+
}
279+
}
280+
}`))
281+
},
282+
expectedCount: 2,
283+
expectedLogins: []string{"s1", "c1"},
284+
expectedMore: 5,
285+
},
258286
{
259287
name: "deduplication across sources",
260288
httpStubs: func(reg *httpmock.Registry) {
@@ -263,7 +291,7 @@ func TestSuggestedReviewerActors(t *testing.T) {
263291
httpmock.GraphQL(`query SuggestedReviewerActors\b`),
264292
httpmock.StringResponse(`{
265293
"data": {
266-
"node": {"suggestedReviewerActors": {"nodes": [
294+
"node": {"author": {"login": "testauthor"}, "suggestedReviewerActors": {"nodes": [
267295
{"isAuthor": false, "reviewer": {"__typename": "User", "login": "shareduser", "name": "Shared"}}
268296
]}},
269297
"repository": {
@@ -291,7 +319,7 @@ func TestSuggestedReviewerActors(t *testing.T) {
291319
httpmock.GraphQL(`query SuggestedReviewerActors\b`),
292320
httpmock.StringResponse(`{
293321
"data": {
294-
"node": {"suggestedReviewerActors": {"nodes": [
322+
"node": {"author": {"login": "testauthor"}, "suggestedReviewerActors": {"nodes": [
295323
{"isAuthor": false, "reviewer": {"__typename": "User", "login": "s1", "name": "S1"}}
296324
]}},
297325
"repository": {
@@ -314,7 +342,7 @@ func TestSuggestedReviewerActors(t *testing.T) {
314342
httpmock.GraphQL(`query SuggestedReviewerActors\b`),
315343
httpmock.StringResponse(`{
316344
"data": {
317-
"node": {"suggestedReviewerActors": {"nodes": [
345+
"node": {"author": {"login": "testauthor"}, "suggestedReviewerActors": {"nodes": [
318346
{"isAuthor": false, "reviewer": {"__typename": "Bot", "login": "copilot-pull-request-reviewer"}},
319347
{"isAuthor": false, "reviewer": {"__typename": "User", "login": "s1", "name": "S1"}}
320348
]}},

0 commit comments

Comments
 (0)