Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1155,7 +1155,7 @@ The following sets of tools are available:
- `owner`: Repository owner (string, required)
- `pullNumber`: Pull request number to update (number, required)
- `repo`: Repository name (string, required)
- `reviewers`: GitHub usernames to request reviews from (string[], optional)
- `reviewers`: GitHub usernames or ORG/team-slug team reviewers to request reviews from (string[], optional)
- `state`: New state (string, optional)
- `title`: New title (string, optional)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"type": "string"
},
"reviewers": {
"description": "GitHub usernames to request reviews from",
"description": "GitHub usernames or ORG/team-slug team reviewers to request reviews from",
"items": {
"type": "string"
},
Expand All @@ -37,4 +37,4 @@
"type": "object"
},
"name": "request_pull_request_reviewers"
}
}
4 changes: 2 additions & 2 deletions pkg/github/__toolsnaps__/update_pull_request.snap
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"type": "string"
},
"reviewers": {
"description": "GitHub usernames to request reviews from",
"description": "GitHub usernames or ORG/team-slug team reviewers to request reviews from",
"items": {
"type": "string"
},
Expand All @@ -61,4 +61,4 @@
"type": "object"
},
"name": "update_pull_request"
}
}
7 changes: 5 additions & 2 deletions pkg/github/granular_tools_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,10 @@ func TestGranularUpdatePullRequestState(t *testing.T) {

func TestGranularRequestPullRequestReviewers(t *testing.T) {
client := mustNewGHClient(t, MockHTTPClientWithHandlers(map[string]http.HandlerFunc{
PostReposPullsRequestedReviewersByOwnerByRepoByPullNumber: mockResponse(t, http.StatusOK, &gogithub.PullRequest{Number: gogithub.Ptr(1)}),
PostReposPullsRequestedReviewersByOwnerByRepoByPullNumber: expectRequestBody(t, map[string]any{
"reviewers": []any{"user1"},
"team_reviewers": []any{"team1"},
}).andThen(mockResponse(t, http.StatusOK, &gogithub.PullRequest{Number: gogithub.Ptr(1)})),
}))
deps := BaseDeps{Client: client}
serverTool := GranularRequestPullRequestReviewers(translations.NullTranslationHelper)
Expand All @@ -645,7 +648,7 @@ func TestGranularRequestPullRequestReviewers(t *testing.T) {
"owner": "owner",
"repo": "repo",
"pullNumber": float64(1),
"reviewers": []string{"user1", "user2"},
"reviewers": []string{"user1", "owner/team1"},
})
result, err := handler(ContextWithDeps(context.Background(), deps), &request)
require.NoError(t, err)
Expand Down
6 changes: 4 additions & 2 deletions pkg/github/pullrequests.go
Original file line number Diff line number Diff line change
Expand Up @@ -752,7 +752,7 @@ func UpdatePullRequest(t translations.TranslationHelperFunc) inventory.ServerToo
},
"reviewers": {
Type: "array",
Description: "GitHub usernames to request reviews from",
Description: "GitHub usernames or ORG/team-slug team reviewers to request reviews from",
Items: &jsonschema.Schema{
Type: "string",
},
Expand Down Expand Up @@ -944,8 +944,10 @@ func UpdatePullRequest(t translations.TranslationHelperFunc) inventory.ServerToo
return utils.NewToolResultErrorFromErr("failed to get GitHub client", err), nil, nil
}

userReviewers, teamReviewers := splitPullRequestReviewers(reviewers)
reviewersRequest := github.ReviewersRequest{
Reviewers: reviewers,
Reviewers: userReviewers,
TeamReviewers: teamReviewers,
}

_, resp, err := client.PullRequests.RequestReviewers(ctx, owner, repo, pullNumber, reviewersRequest)
Expand Down
24 changes: 22 additions & 2 deletions pkg/github/pullrequests_granular.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ func GranularRequestPullRequestReviewers(t translations.TranslationHelperFunc) i
"pullNumber": {Type: "number", Description: "The pull request number", Minimum: jsonschema.Ptr(1.0)},
"reviewers": {
Type: "array",
Description: "GitHub usernames to request reviews from",
Description: "GitHub usernames or ORG/team-slug team reviewers to request reviews from",
Items: &jsonschema.Schema{Type: "string"},
},
},
Expand Down Expand Up @@ -325,13 +325,17 @@ func GranularRequestPullRequestReviewers(t translations.TranslationHelperFunc) i
if len(reviewers) == 0 {
return utils.NewToolResultError("missing required parameter: reviewers"), nil, nil
}
userReviewers, teamReviewers := splitPullRequestReviewers(reviewers)

client, err := deps.GetClient(ctx)
if err != nil {
return utils.NewToolResultErrorFromErr("failed to get GitHub client", err), nil, nil
}

pr, resp, err := client.PullRequests.RequestReviewers(ctx, owner, repo, pullNumber, gogithub.ReviewersRequest{Reviewers: reviewers})
pr, resp, err := client.PullRequests.RequestReviewers(ctx, owner, repo, pullNumber, gogithub.ReviewersRequest{
Reviewers: userReviewers,
TeamReviewers: teamReviewers,
})
if err != nil {
return ghErrors.NewGitHubAPIErrorResponse(ctx, "failed to request reviewers", resp, err), nil, nil
}
Expand All @@ -351,6 +355,22 @@ func GranularRequestPullRequestReviewers(t translations.TranslationHelperFunc) i
return st
}

func splitPullRequestReviewers(reviewers []string) ([]string, []string) {
userReviewers := make([]string, 0, len(reviewers))
teamReviewers := make([]string, 0)

for _, reviewer := range reviewers {
org, team, ok := strings.Cut(reviewer, "/")
if ok && org != "" && team != "" && !strings.Contains(team, "/") {
teamReviewers = append(teamReviewers, team)
continue
}
userReviewers = append(userReviewers, reviewer)
}

return userReviewers, teamReviewers
}

// GranularCreatePullRequestReview creates a tool to create a PR review.
func GranularCreatePullRequestReview(t translations.TranslationHelperFunc) inventory.ServerTool {
st := NewTool(
Expand Down
18 changes: 18 additions & 0 deletions pkg/github/pullrequests_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,24 @@ func Test_UpdatePullRequest(t *testing.T) {
expectError: false,
expectedPR: mockPRWithReviewers,
},
{
name: "successful PR update with user and team reviewers",
mockedClient: MockHTTPClientWithHandlers(map[string]http.HandlerFunc{
PostReposPullsRequestedReviewersByOwnerByRepoByPullNumber: expectRequestBody(t, map[string]any{
"reviewers": []any{"reviewer1"},
"team_reviewers": []any{"platform"},
}).andThen(mockResponse(t, http.StatusOK, mockPRWithReviewers)),
GetReposPullsByOwnerByRepoByPullNumber: mockResponse(t, http.StatusOK, mockPRWithReviewers),
}),
requestArgs: map[string]any{
"owner": "owner",
"repo": "repo",
"pullNumber": float64(42),
"reviewers": []any{"reviewer1", "owner/platform"},
},
expectError: false,
expectedPR: mockPRWithReviewers,
},
{
name: "successful PR update (title only)",
mockedClient: MockHTTPClientWithHandlers(map[string]http.HandlerFunc{
Expand Down