Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@BagToad
Copy link
Member

@BagToad BagToad commented Sep 30, 2025

Description

This pull request refactors how pull request reviewer updates are handled, switching from the GraphQL API to the REST API for adding and removing reviewers. It also improves the logic for managing reviewer lists, especially in non-interactive and interactive editing modes, and updates the test suite to cover these changes and edge cases.

Also fixes a bug where the PR author was included in the interactive list of reviewers. With GraphQL this selection would be ignored, but the REST API actually returns an error if the PR author is provided, so we need to fix that now to avoid confusion.

fixes #4844

Considerations

Moving to the REST API with this allows us to add/remove as separate operations, eliminating the need to fetch org teams and org team IDs. This is good, because it allows the GITHUB_TOKEN and other repo scoped authentication types to proceed with requesting a user review.

However, there's a drawback that we now will require two operations, one for adding reviewers and one for removing.

I am fine with this trade-off because I suspect the typical use-case will only involve either requesting a reviewer or removing a reviewer as discrete operations. Meaning, in most cases we'll never actually perform two API calls. Nonetheless the risk is there.

This implementation also proposes that these two API requests be performed concurrently. I suspect this is optimal, but I am unsure of any sort of race-condition that could arise. In particular in the case of removing and adding the same reviewer, but that could be seen as user error.

Testing

This was tested in Actions to prove that it will allow requesting a user reviewer without requiring access to teams, meaning the GITHUB_TOKEN could be used where currently gh will fail.

Test workflow

name: Test Team Reviewer

on:
  workflow_dispatch:
    inputs:
      pr_number:
        description: 'PR number to add reviewer to'
        required: true
        type: string

jobs:
  add-individual-reviewer-local-gh:
    runs-on: self-hosted
    continue-on-error: true
    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Add individual reviewer using local gh binary (should pass if permissions allow)
        env:
            GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          <LOCAL_GH_PATH>/gh pr edit ${{ github.event.inputs.pr_number }} --add-reviewer "<INDIVIDUAL_REVIEWER_USERNAME>"

  add-team-reviewer-local-gh:
    runs-on: self-hosted
    continue-on-error: true
    needs: add-individual-reviewer-local-gh
    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Add team reviewer using local gh binary (may fail if token lacks team review permission)
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          <LOCAL_GH_PATH>/gh pr edit ${{ github.event.inputs.pr_number }} --add-reviewer "<ORG_SLUG>/<TEAM_SLUG>"

  add-team-reviewer-system-gh:
    runs-on: self-hosted
    continue-on-error: true
    needs: add-team-reviewer-local-gh
    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Add team reviewer using system gh (may fail if permissions insufficient)
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          gh pr edit ${{ github.event.inputs.pr_number }} --add-reviewer "<ORG_SLUG>/<TEAM_SLUG>"

  add-individual-reviewer-system-gh:
    runs-on: self-hosted
    continue-on-error: true
    needs: add-team-reviewer-system-gh
    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Add individual reviewer using system gh
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          gh pr edit ${{ github.event.inputs.pr_number }} --add-reviewer "<INDIVIDUAL_REVIEWER_USERNAME>"

You can see the first job is successful, which is what we're going for. We want the GITHUB_TOKEN to be able to request a review from a user as long as there isn't teams included in the review request.

image

Note

This was also tested with a team reviewer already requested to prove that we will not fetch team reviewers beyond what the PR metadata gives us already through the non-interactive flow. Therein lies the key reason to switch to the REST API here.

Further Improvements

It should be noted that the REST API doesn't return a satisfying or useful error message when you provide it a team reviewer without having access to org teams, as in the case of the GITHUB_TOKEN:

image

Perhaps there is further work to be done in the future to improve this error messaging client-side.

Switches pull request reviewer add/remove operations from GraphQL to the REST API, enabling separate add and remove calls for reviewers and teams. Refactors reviewer editing logic to avoid fetching organization teams unless required for interactive editing, improving performance for non-interactive flows. Updates tests and supporting code to reflect the new reviewer management and metadata fetching behavior.
@BagToad BagToad requested a review from a team as a code owner September 30, 2025 18:09
@BagToad BagToad requested review from babakks and Copilot September 30, 2025 18:09
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR refactors the gh pr edit command to optimize team fetching behavior and switch from GraphQL to REST API for reviewer management. It improves performance by only fetching organization teams when actually needed and fixes a bug where PR authors could be incorrectly included in reviewer selections.

  • Refactored reviewer API calls from GraphQL to REST endpoints
  • Added conditional team fetching logic to avoid unnecessary API calls
  • Fixed PR author inclusion bug in interactive reviewer selection

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
pkg/cmd/pr/shared/editable.go Removed ReviewerIds method and optimized team fetching logic
pkg/cmd/pr/edit/edit_test.go Updated test suite with new REST API mocks and conditional team fetching test cases
pkg/cmd/pr/edit/edit.go Implemented REST API reviewer updates and PR author filtering
api/queries_pr.go Added new REST API functions for adding/removing reviewers

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Copy link
Member

@babakks babakks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, bar a few necessary fixes (e.g. url.PathEscape).

Deleted the unused ghIds helper function and the associated githubv4 import from edit.go to clean up the codebase.
Updated AddPullRequestReviews and RemovePullRequestReviews to use url.PathEscape for repo owner and name in API paths. This ensures correct handling of special characters in repository identifiers.
Extracted logic for splitting reviewer identifiers into users and teams into a new helper function, partitionUsersAndTeams. Updated updatePullRequestReviews to use this function for both adding and removing reviewers, improving code clarity and maintainability. Also clarified comments regarding PR author handling.
Corrected '--tile' to '--title' in the error message shown when required flags are missing in non-interactive mode.
Eliminates unnecessary initialization of users and teams to empty slices in RemovePullRequestReviews. Also updates the request body struct to use 'omitempty' for reviewers and team_reviewers, ensuring empty fields are omitted from the JSON payload.
BagToad and others added 3 commits October 2, 2025 09:54
Swaps the argument order of the httpStubs functions in edit_test.go to match the expected (t *testing.T, reg *httpmock.Registry) signature. This improves consistency and prevents potential confusion or errors when calling these test helpers.
Co-authored-by: Babak K. Shandiz <[email protected]>
Co-authored-by: Babak K. Shandiz <[email protected]>
@BagToad BagToad merged commit 67bf27b into trunk Oct 3, 2025
11 checks passed
@BagToad BagToad deleted the kw/do-not-request-org-teams-for-reviewer-set branch October 3, 2025 18:25
@mishu0

This comment was marked as spam.

@mishu0

This comment was marked as spam.

tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request Oct 17, 2025
This MR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [cli/cli](https://github.com/cli/cli) | minor | `v2.81.0` -> `v2.82.0` |

MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot).

**Proposed changes to behavior should be submitted there as MRs.**

---

### Release Notes

<details>
<summary>cli/cli (cli/cli)</summary>

### [`v2.82.0`](https://github.com/cli/cli/releases/tag/v2.82.0): GitHub CLI 2.82.0

[Compare Source](cli/cli@v2.81.0...v2.82.0)

##### ✨ Features

- `gh pr edit`: Only fetch org teams for reviewers when required by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;11835](cli/cli#11835)

##### 🐛 Fixes

- fix(cache delete): report correct deleted count for key and key+ref deletions by [@&#8203;luxass](https://github.com/luxass) in [#&#8203;11838](cli/cli#11838)
- `gh agent-task create`: Fix `--follow` not killing the progress indicator by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;11879](cli/cli#11879)
- `gh agent-task create`: Fix targetting upstream instead of default repo by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;11896](cli/cli#11896)
- Fix `auth login` and `auth refresh` to use UNIX socket by [@&#8203;babakks](https://github.com/babakks) in [#&#8203;11922](cli/cli#11922)

**Full Changelog**: <cli/cli@v2.81.0...v2.82.0>

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this MR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MS4xNDguNiIsInVwZGF0ZWRJblZlciI6IjQxLjE0OC42IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJSZW5vdmF0ZSBCb3QiXX0=-->
Sign up for free to 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.

gh pr edit --add-reviewer Don't acquire organizational teams if it's not necessary

5 participants