Repository: GoogleCloudPlatform/magic-modules
Pull request #14031: Convert review functions to go-gh
Author: login: ScottSuarez
Created: 2025-05-19T18:13:42Z | Merged: 2025-05-22T18:38:29Z

closes https://github.com/hashicorp/terraform-provider-google/issues/17191
<!--
Complete the self-review checklist to help speed up the review process: https://googlecloudplatform.github.io/magic-modules/contribute/review-pr/

If your PR is still work in progress, please create it in draft mode.

Put a description of what this PR is for here, along with any references to issues that this resolves or contributes to.
For example: Fixes https://github.com/hashicorp/terraform-provider-google/issues/ISSUE_ID
-->

**Release Note Template for Downstream PRs (will be copied)**

See [Write release notes](https://googlecloudplatform.github.io/magic-modules/contribute/release-notes/) for guidance.

```release-note:none

```



Diff:
diff --git a/.ci/magician/github/get.go b/.ci/magician/github/get.go
index 667c8b498f0d..8df94827a5f9 100644
--- a/.ci/magician/github/get.go
+++ b/.ci/magician/github/get.go
@@ -17,7 +17,6 @@ package github
 
 import (
 	"fmt"
-	utils "magician/utility"
 	"strconv"
 	"time"
 
@@ -94,45 +93,48 @@ func (c *Client) GetPullRequests(state, base, sort, direction string) ([]PullReq
 }
 
 // GetPullRequestRequestedReviewers gets requested reviewers for a PR
-func (gh *Client) GetPullRequestRequestedReviewers(prNumber string) ([]User, error) {
-	url := fmt.Sprintf("https://api.github.com/repos/GoogleCloudPlatform/magic-modules/pulls/%s/requested_reviewers", prNumber)
-
-	var requestedReviewers struct {
-		Users []User `json:"users"`
+func (c *Client) GetPullRequestRequestedReviewers(prNumber string) ([]User, error) {
+	num, err := strconv.Atoi(prNumber)
+	if err != nil {
+		return nil, err
 	}
 
-	err := utils.RequestCallWithRetry(url, "GET", gh.token, &requestedReviewers, nil)
+	reviewers, _, err := c.gh.PullRequests.ListReviewers(c.ctx, defaultOwner, defaultRepo, num, nil)
 	if err != nil {
 		return nil, err
 	}
 
-	return requestedReviewers.Users, nil
+	return convertGHUsers(reviewers.Users), nil
 }
 
 // GetPullRequestPreviousReviewers gets previous reviewers for a PR
-func (gh *Client) GetPullRequestPreviousReviewers(prNumber string) ([]User, error) {
-	url := fmt.Sprintf("https://api.github.com/repos/GoogleCloudPlatform/magic-modules/pulls/%s/reviews", prNumber)
-
-	var reviews []struct {
-		User User `json:"user"`
+func (c *Client) GetPullRequestPreviousReviewers(prNumber string) ([]User, error) {
+	num, err := strconv.Atoi(prNumber)
+	if err != nil {
+		return nil, err
 	}
-
-	err := utils.RequestCallWithRetry(url, "GET", gh.token, &reviews, nil)
+	reviews, _, err := c.gh.PullRequests.ListReviews(c.ctx, defaultOwner, defaultRepo, num, nil)
 	if err != nil {
 		return nil, err
 	}
 
-	previousAssignedReviewers := map[string]User{}
+	// Use a map to deduplicate reviewers
+	reviewerMap := make(map[string]*gh.User)
+
 	for _, review := range reviews {
-		previousAssignedReviewers[review.User.Login] = review.User
+		if review.User != nil && review.User.Login != nil {
+			login := review.User.GetLogin()
+			reviewerMap[login] = review.User
+		}
 	}
 
-	result := []User{}
-	for _, user := range previousAssignedReviewers {
-		result = append(result, user)
+	// Convert map to slice
+	reviewers := make([]*gh.User, 0, len(reviewerMap))
+	for _, user := range reviewerMap {
+		reviewers = append(reviewers, user)
 	}
 
-	return result, nil
+	return convertGHUsers(reviewers), nil
 }
 
 // GetCommitMessage gets a commit message
diff --git a/.ci/magician/github/integration_test.go b/.ci/magician/github/integration_test.go
index bf5a649f27a1..64ed13e0ba64 100644
--- a/.ci/magician/github/integration_test.go
+++ b/.ci/magician/github/integration_test.go
@@ -37,7 +37,9 @@ const (
 	testNonMember     = "bananaman5000"
 	testRepo          = "magic-modules"
 	testOwner         = "GoogleCloudPlatform"
-	testPRNumber      = "13969"                                    // replace this with an actual PR Number
+	testReviewer      = "melinath"
+	testPRNumber      = "14031"
+	testOldPRNumber   = "13969"                                    // replace this with an actual PR Number
 	testPRCommitSha   = "4a8409686810551655eea2533e939cc5344e83e2" // replace this with an actual SHA
 	testMainCommitSha = "fd910977cf24595d2c04e3f0a369a82c79fdb8f8" // replace this with an actual SHA
 	testLabel         = "terraform-3.0"
@@ -276,27 +278,70 @@ func TestIntegrationCreateWorkflowDispatchEvent(t *testing.T) {
 	t.Logf("Successfully triggered workflow dispatch event")
 }
 
+func TestIntegrationRequestAndRemovePullRequestReviewers(t *testing.T) {
+	client := skipIfNoToken(t)
+
+	// Request a reviewer
+	reviewers := []string{testReviewer} // Request the owner to review their own PR
+	err := client.RequestPullRequestReviewers(testPRNumber, reviewers)
+	if err != nil {
+		t.Fatalf("RequestPullRequestReviewers failed: %v", err)
+	}
+
+	// Remove the reviewer
+	err = client.RemovePullRequestReviewers(testPRNumber, reviewers)
+	if err != nil {
+		t.Fatalf("RemovePullRequestReviewers failed: %v", err)
+	}
+
+	t.Logf("Successfully requested and removed reviewers: %v", reviewers)
+}
+
+func TestIntegrationGetPullRequestRequestedReviewers(t *testing.T) {
+	client := skipIfNoToken(t)
+
+	reviewers, err := client.GetPullRequestRequestedReviewers(testPRNumber)
+	if err != nil {
+		t.Fatalf("GetPullRequestRequestedReviewers failed: %v", err)
+	}
+
+	t.Logf("Found %d requested reviewers", len(reviewers))
+	for i, reviewer := range reviewers {
+		t.Logf("Reviewer %d: %s", i+1, reviewer.Login)
+	}
+}
+
+func TestIntegrationGetPullRequestPreviousReviewers(t *testing.T) {
+	client := skipIfNoToken(t)
+
+	reviewers, err := client.GetPullRequestPreviousReviewers(testOldPRNumber)
+	if err != nil {
+		t.Fatalf("GetPullRequestPreviousReviewers failed: %v", err)
+	}
+
+	t.Logf("Found %d previous reviewers", len(reviewers))
+	for i, reviewer := range reviewers {
+		t.Logf("Previous reviewer %d: %s", i+1, reviewer.Login)
+	}
+}
+
 // TestIntegrationMergePullRequest is commented out as it has permanent effects
 // Uncomment and run only if you're sure you want to merge the PR
 /*
  func TestIntegrationMergePullRequest(t *testing.T) {
 	 client := skipIfNoToken(t)
-
 	 // Skip this test by default as it has permanent effects
 	 if os.Getenv("RUN_MERGE_PR_TEST") != "true" {
 		 t.Skip("Skipping merge PR test: set RUN_MERGE_PR_TEST=true to run")
 	 }
-
 	 // You'll need a valid commit SHA for this test
 	 if testPRCommitSha == "HEAD" {
 		 t.Skip("Skipping MergePullRequest test: need a valid commit SHA")
 	 }
-
 	 err := client.MergePullRequest(testOwner, testRepo, testPRNumber, testPRCommitSha)
 	 if err != nil {
 		 t.Fatalf("MergePullRequest failed: %v", err)
 	 }
-
 	 t.Logf("Successfully merged pull request")
  }
 */
diff --git a/.ci/magician/github/set.go b/.ci/magician/github/set.go
index e56b5a03f5b5..c04e7daf936b 100644
--- a/.ci/magician/github/set.go
+++ b/.ci/magician/github/set.go
@@ -78,39 +78,52 @@ func (c *Client) UpdateComment(prNumber, comment string, id int) error {
 	return nil
 }
 
-func (gh *Client) RequestPullRequestReviewers(prNumber string, reviewers []string) error {
-	url := fmt.Sprintf("https://api.github.com/repos/GoogleCloudPlatform/magic-modules/pulls/%s/requested_reviewers", prNumber)
+// RequestPullRequestReviewers adds reviewers to a pull request
+func (c *Client) RequestPullRequestReviewers(prNumber string, reviewers []string) error {
+	if len(reviewers) == 0 {
+		return nil
+	}
 
-	body := map[string][]string{
-		"reviewers":      reviewers,
-		"team_reviewers": {},
+	num, err := strconv.Atoi(prNumber)
+	if err != nil {
+		return err
 	}
 
-	err := utils.RequestCallWithRetry(url, "POST", gh.token, nil, body)
+	// Create the reviewers request
+	reviewersRequest := gh.ReviewersRequest{
+		Reviewers: reviewers,
+	}
+
+	_, _, err = c.gh.PullRequests.RequestReviewers(c.ctx, defaultOwner, defaultRepo, num, reviewersRequest)
 	if err != nil {
 		return err
 	}
 
 	fmt.Printf("Successfully added reviewers %v to pull request %s\n", reviewers, prNumber)
-
 	return nil
 }
 
-func (gh *Client) RemovePullRequestReviewers(prNumber string, reviewers []string) error {
-	url := fmt.Sprintf("https://api.github.com/repos/GoogleCloudPlatform/magic-modules/pulls/%s/requested_reviewers", prNumber)
-
-	body := map[string][]string{
-		"reviewers":      reviewers,
-		"team_reviewers": {},
+// RemovePullRequestReviewers removes reviewers from a pull request
+func (c *Client) RemovePullRequestReviewers(prNumber string, reviewers []string) error {
+	if len(reviewers) == 0 {
+		return nil
 	}
 
-	err := utils.RequestCall(url, "DELETE", gh.token, nil, body)
+	num, err := strconv.Atoi(prNumber)
 	if err != nil {
 		return err
 	}
 
-	fmt.Printf("Successfully removed reviewers %v to pull request %s\n", reviewers, prNumber)
+	reviewersRequest := gh.ReviewersRequest{
+		Reviewers: reviewers,
+	}
+
+	_, err = c.gh.PullRequests.RemoveReviewers(c.ctx, defaultOwner, defaultRepo, num, reviewersRequest)
+	if err != nil {
+		return err
+	}
 
+	fmt.Printf("Successfully removed reviewers %v from pull request %s\n", reviewers, prNumber)
 	return nil
 }
 


Reviews:
user: login: melinath
body: LGTM apart from the failure requesting service team reviewers.
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-22T16:55:12Z

Review comments:
diff_hunk: @@ -78,39 +78,46 @@ func (c *Client) UpdateComment(prNumber, comment string, id int) error {
 	return nil
 }
 
-func (gh *Client) RequestPullRequestReviewers(prNumber string, reviewers []string) error {
-	url := fmt.Sprintf("https://api.github.com/repos/GoogleCloudPlatform/magic-modules/pulls/%s/requested_reviewers", prNumber)
+// RequestPullRequestReviewers adds reviewers to a pull request
+func (c *Client) RequestPullRequestReviewers(prNumber string, reviewers []string) error {
+	num, err := strconv.Atoi(prNumber)
+	if err != nil {
+		return err
+	}
 
-	body := map[string][]string{
-		"reviewers":      reviewers,
-		"team_reviewers": {},
+	// Create the reviewers request
+	reviewersRequest := gh.ReviewersRequest{
+		Reviewers:     reviewers,
+		TeamReviewers: nil,
 	}
 
-	err := utils.RequestCallWithRetry(url, "POST", gh.token, nil, body)
+	_, _, err = c.gh.PullRequests.RequestReviewers(c.ctx, defaultOwner, defaultRepo, num, reviewersRequest)
path: .ci/magician/github/set.go
user: login: melinath
body: It looks like this line is causing a failure because it doesn't match the schema GitHub expects:

```
422 Invalid request.

No subschema in "anyOf" matched.
"reviewers" wasn't supplied.
"team_reviewers" wasn't supplied.
```


I think previously we were getting around this by accident because we were sending an empty object for team_reviewers - now we probably need to make this function a no-op if the list of reviewers is empty. (And we don't need to set TeamReviewers at all.)
created_at: 2025-05-22T16:53:27Z
author_association: MEMBER
diff_hunk: @@ -78,39 +78,46 @@ func (c *Client) UpdateComment(prNumber, comment string, id int) error {
 	return nil
 }
 
-func (gh *Client) RequestPullRequestReviewers(prNumber string, reviewers []string) error {
-	url := fmt.Sprintf("https://api.github.com/repos/GoogleCloudPlatform/magic-modules/pulls/%s/requested_reviewers", prNumber)
+// RequestPullRequestReviewers adds reviewers to a pull request
+func (c *Client) RequestPullRequestReviewers(prNumber string, reviewers []string) error {
+	num, err := strconv.Atoi(prNumber)
+	if err != nil {
+		return err
+	}
 
-	body := map[string][]string{
-		"reviewers":      reviewers,
-		"team_reviewers": {},
+	// Create the reviewers request
+	reviewersRequest := gh.ReviewersRequest{
+		Reviewers:     reviewers,
+		TeamReviewers: nil,
 	}
 
-	err := utils.RequestCallWithRetry(url, "POST", gh.token, nil, body)
+	_, _, err = c.gh.PullRequests.RequestReviewers(c.ctx, defaultOwner, defaultRepo, num, reviewersRequest)
 	if err != nil {
 		return err
 	}
 
 	fmt.Printf("Successfully added reviewers %v to pull request %s\n", reviewers, prNumber)
-
 	return nil
 }
 
-func (gh *Client) RemovePullRequestReviewers(prNumber string, reviewers []string) error {
-	url := fmt.Sprintf("https://api.github.com/repos/GoogleCloudPlatform/magic-modules/pulls/%s/requested_reviewers", prNumber)
+// RemovePullRequestReviewers removes reviewers from a pull request
+func (c *Client) RemovePullRequestReviewers(prNumber string, reviewers []string) error {
+	num, err := strconv.Atoi(prNumber)
+	if err != nil {
+		return err
+	}
 
-	body := map[string][]string{
-		"reviewers":      reviewers,
-		"team_reviewers": {},
+	reviewersRequest := gh.ReviewersRequest{
+		Reviewers:     reviewers,
+		TeamReviewers: nil,
 	}
 
-	err := utils.RequestCall(url, "DELETE", gh.token, nil, body)
+	_, err = c.gh.PullRequests.RemoveReviewers(c.ctx, defaultOwner, defaultRepo, num, reviewersRequest)
path: .ci/magician/github/set.go
user: login: melinath
body: I bet we need the same logic here.
created_at: 2025-05-22T16:53:49Z
author_association: MEMBER

PR comments:
user: login: modular-magician
created_at: 2025-05-19T18:23:00Z
body: Hi there, I'm the Modular magician. I've detected the following information about your changes:

## Diff report

Your PR hasn't generated any diffs, but I'll let you know if a future commit does.





author_association: COLLABORATOR
user: login: ScottSuarez
created_at: 2025-05-19T18:37:16Z
body: Not sure if we want to close https://github.com/hashicorp/terraform-provider-google/issues/17191 after this gets merge.

There is still one function, (MergePullRequest) that I have not converted and won't be as part of this fixit.
author_association: CONTRIBUTOR
user: login: modular-magician
created_at: 2025-05-19T18:37:37Z
body: Hi there, I'm the Modular magician. I've detected the following information about your changes:

## Diff report

Your PR hasn't generated any diffs, but I'll let you know if a future commit does.





author_association: COLLABORATOR
user: login: modular-magician
created_at: 2025-05-19T18:38:17Z
body: Hi there, I'm the Modular magician. I've detected the following information about your changes:

## Diff report

Your PR hasn't generated any diffs, but I'll let you know if a future commit does.





author_association: COLLABORATOR
user: login: modular-magician
created_at: 2025-05-19T18:40:14Z
body: Hi there, I'm the Modular magician. I've detected the following information about your changes:

## Diff report

Your PR hasn't generated any diffs, but I'll let you know if a future commit does.





author_association: COLLABORATOR
user: login: github-actions[bot]
created_at: 2025-05-22T09:43:14Z
body: @melinath This PR has been waiting for review for 3 weekdays. Please take a look! Use the label `disable-review-reminders` to disable these notifications.
author_association: NONE
user: login: melinath
created_at: 2025-05-22T16:30:20Z
body: > Not sure if we want to close [hashicorp/terraform-provider-google#17191](https://github.com/hashicorp/terraform-provider-google/issues/17191) after this gets merge.
> 
> There is still one function, (MergePullRequest) that I have not converted and won't be as part of this fixit.

sure, let's close it. We can open a new ticket in the future if needed.
author_association: MEMBER
user: login: modular-magician
created_at: 2025-05-22T18:05:53Z
body: Hi there, I'm the Modular magician. I've detected the following information about your changes:

## Diff report

Your PR hasn't generated any diffs, but I'll let you know if a future commit does.





author_association: COLLABORATOR