Repository: google/go-github
Pull request #3532 (2025-03-25 05:07:41)

feat!: Add ListReactionOptions to all ListxxReactions functions to enable filter by content
BREAKING CHANGE: `ListCommentReactionOptions` => `ListReactionOptions` and all `List*Reactions` methods now use it.

All list reactions endpoint now suppor the `content` query parameters to filter the returned results by content (`+1`, `eyes`, etc.). Including:

- [List reactions for a commit comment](https://docs.github.com/rest/reactions/reactions#list-reactions-for-a-commit-comment)
- [List reactions for an issue](https://docs.github.com/rest/reactions/reactions#list-reactions-for-an-issue)
- [List reactions for an issue comment](https://docs.github.com/rest/reactions/reactions#list-reactions-for-an-issue-comment)
- [List reactions for a pull request review comment](https://docs.github.com/rest/reactions/reactions#list-reactions-for-a-pull-request-review-comment)
- [List reactions for a team discussion legacy](https://docs.github.com/rest/reactions/reactions#list-reactions-for-a-team-discussion-legacy)
- [List reactions for a team discussion comment legacy](https://docs.github.com/rest/reactions/reactions#list-reactions-for-a-team-discussion-comment-legacy)

This PR updates all `ListxxReactions` functions corresponding to the APIs above, replacing the generic `ListOptions` with `ListReactionOptions` which contains the `Content` field.

**Note on breaking changes**: `ListCommentReactions` already utilzed a options param struct: `ListCommentReactionOptions`.  This PR replaces that with `ListReactionOptions` to maintain consistency.  This change and all the `ListOptions` should be considered breaking.


google-cla[bot]: Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this [failed invocation](https://github.com/google/go-github/pull/3532/checks?check_run_id=39344295837) of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.
codecov[bot]: ## [Codecov](https://app.codecov.io/gh/google/go-github/pull/3532?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 91.30%. Comparing base [(`3cac18b`)](https://app.codecov.io/gh/google/go-github/commit/3cac18b40cf29fc1a8ca9d192cd6d78e1e1c7b98?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) to head [(`9c28048`)](https://app.codecov.io/gh/google/go-github/commit/9c280488e2ac0dddf2533240866ab09c65c5c2f2?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google).

<details><summary>Additional details and impacted files</summary>


```diff
@@           Coverage Diff           @@
##           master    #3532   +/-   ##
=======================================
  Coverage   91.30%   91.30%           
=======================================
  Files         184      184           
  Lines       16143    16143           
=======================================
  Hits        14739    14739           
  Misses       1230     1230           
  Partials      174      174           
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/google/go-github/pull/3532?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google).

<details><summary> :rocket: New features to boost your workflow: </summary>

- :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
</details>
gmlewis: Thank you, @stevehipwell!
Merging.

Patch:
diff --git a/github/reactions.go b/github/reactions.go
index e9823220..71dd611d 100644
--- a/github/reactions.go
+++ b/github/reactions.go
@@ -48,9 +48,8 @@ func (r Reaction) String() string {
 	return Stringify(r)
 }
 
-// ListCommentReactionOptions specifies the optional parameters to the
-// ReactionsService.ListCommentReactions method.
-type ListCommentReactionOptions struct {
+// ListReactionOptions specifies the optional parameters to the list reactions endpoints.
+type ListReactionOptions struct {
 	// Content restricts the returned comment reactions to only those with the given type.
 	// Omit this parameter to list all reactions to a commit comment.
 	// Possible values are: "+1", "-1", "laugh", "confused", "heart", "hooray", "rocket", or "eyes".
@@ -64,7 +63,7 @@ type ListCommentReactionOptions struct {
 // GitHub API docs: https://docs.github.com/rest/reactions/reactions#list-reactions-for-a-commit-comment
 //
 //meta:operation GET /repos/{owner}/{repo}/comments/{comment_id}/reactions
-func (s *ReactionsService) ListCommentReactions(ctx context.Context, owner, repo string, id int64, opts *ListCommentReactionOptions) ([]*Reaction, *Response, error) {
+func (s *ReactionsService) ListCommentReactions(ctx context.Context, owner, repo string, id int64, opts *ListReactionOptions) ([]*Reaction, *Response, error) {
 	u := fmt.Sprintf("repos/%v/%v/comments/%v/reactions", owner, repo, id)
 	u, err := addOptions(u, opts)
 	if err != nil {
@@ -144,7 +143,7 @@ func (s *ReactionsService) DeleteCommentReactionByID(ctx context.Context, repoID
 // GitHub API docs: https://docs.github.com/rest/reactions/reactions#list-reactions-for-an-issue
 //
 //meta:operation GET /repos/{owner}/{repo}/issues/{issue_number}/reactions
-func (s *ReactionsService) ListIssueReactions(ctx context.Context, owner, repo string, number int, opts *ListOptions) ([]*Reaction, *Response, error) {
+func (s *ReactionsService) ListIssueReactions(ctx context.Context, owner, repo string, number int, opts *ListReactionOptions) ([]*Reaction, *Response, error) {
 	u := fmt.Sprintf("repos/%v/%v/issues/%v/reactions", owner, repo, number)
 	u, err := addOptions(u, opts)
 	if err != nil {
@@ -224,7 +223,7 @@ func (s *ReactionsService) DeleteIssueReactionByID(ctx context.Context, repoID,
 // GitHub API docs: https://docs.github.com/rest/reactions/reactions#list-reactions-for-an-issue-comment
 //
 //meta:operation GET /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions
-func (s *ReactionsService) ListIssueCommentReactions(ctx context.Context, owner, repo string, id int64, opts *ListOptions) ([]*Reaction, *Response, error) {
+func (s *ReactionsService) ListIssueCommentReactions(ctx context.Context, owner, repo string, id int64, opts *ListReactionOptions) ([]*Reaction, *Response, error) {
 	u := fmt.Sprintf("repos/%v/%v/issues/comments/%v/reactions", owner, repo, id)
 	u, err := addOptions(u, opts)
 	if err != nil {
@@ -304,7 +303,7 @@ func (s *ReactionsService) DeleteIssueCommentReactionByID(ctx context.Context, r
 // GitHub API docs: https://docs.github.com/rest/reactions/reactions#list-reactions-for-a-pull-request-review-comment
 //
 //meta:operation GET /repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions
-func (s *ReactionsService) ListPullRequestCommentReactions(ctx context.Context, owner, repo string, id int64, opts *ListOptions) ([]*Reaction, *Response, error) {
+func (s *ReactionsService) ListPullRequestCommentReactions(ctx context.Context, owner, repo string, id int64, opts *ListReactionOptions) ([]*Reaction, *Response, error) {
 	u := fmt.Sprintf("repos/%v/%v/pulls/comments/%v/reactions", owner, repo, id)
 	u, err := addOptions(u, opts)
 	if err != nil {
@@ -384,7 +383,7 @@ func (s *ReactionsService) DeletePullRequestCommentReactionByID(ctx context.Cont
 // GitHub API docs: https://docs.github.com/rest/reactions/reactions#list-reactions-for-a-team-discussion-legacy
 //
 //meta:operation GET /teams/{team_id}/discussions/{discussion_number}/reactions
-func (s *ReactionsService) ListTeamDiscussionReactions(ctx context.Context, teamID int64, discussionNumber int, opts *ListOptions) ([]*Reaction, *Response, error) {
+func (s *ReactionsService) ListTeamDiscussionReactions(ctx context.Context, teamID int64, discussionNumber int, opts *ListReactionOptions) ([]*Reaction, *Response, error) {
 	u := fmt.Sprintf("teams/%v/discussions/%v/reactions", teamID, discussionNumber)
 	u, err := addOptions(u, opts)
 	if err != nil {
@@ -460,7 +459,7 @@ func (s *ReactionsService) DeleteTeamDiscussionReactionByOrgIDAndTeamID(ctx cont
 // GitHub API docs: https://docs.github.com/rest/reactions/reactions#list-reactions-for-a-team-discussion-comment-legacy
 //
 //meta:operation GET /teams/{team_id}/discussions/{discussion_number}/comments/{comment_number}/reactions
-func (s *ReactionsService) ListTeamDiscussionCommentReactions(ctx context.Context, teamID int64, discussionNumber, commentNumber int, opts *ListOptions) ([]*Reaction, *Response, error) {
+func (s *ReactionsService) ListTeamDiscussionCommentReactions(ctx context.Context, teamID int64, discussionNumber, commentNumber int, opts *ListReactionOptions) ([]*Reaction, *Response, error) {
 	u := fmt.Sprintf("teams/%v/discussions/%v/comments/%v/reactions", teamID, discussionNumber, commentNumber)
 	u, err := addOptions(u, opts)
 	if err != nil {


Test patch:
diff --git a/github/reactions_test.go b/github/reactions_test.go
index 5758a705..71e8efc0 100644
--- a/github/reactions_test.go
+++ b/github/reactions_test.go
@@ -79,7 +79,7 @@ func TestReactionsService_ListCommentReactions(t *testing.T) {
 		fmt.Fprint(w, `[{"id":1,"user":{"login":"l","id":2},"content":"+1"}]`)
 	})
 
-	opt := &ListCommentReactionOptions{Content: "+1"}
+	opt := &ListReactionOptions{Content: "+1"}
 	ctx := context.Background()
 	reactions, _, err := client.Reactions.ListCommentReactions(ctx, "o", "r", 1, opt)
 	if err != nil {
@@ -149,13 +149,15 @@ func TestReactionsService_ListIssueReactions(t *testing.T) {
 	mux.HandleFunc("/repos/o/r/issues/1/reactions", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		testHeader(t, r, "Accept", mediaTypeReactionsPreview)
+		testFormValues(t, r, values{"content": "+1"})
 
 		w.WriteHeader(http.StatusOK)
 		assertWrite(t, w, []byte(`[{"id":1,"user":{"login":"l","id":2},"content":"+1"}]`))
 	})
 
+	opt := &ListReactionOptions{Content: "+1"}
 	ctx := context.Background()
-	got, _, err := client.Reactions.ListIssueReactions(ctx, "o", "r", 1, nil)
+	got, _, err := client.Reactions.ListIssueReactions(ctx, "o", "r", 1, opt)
 	if err != nil {
 		t.Errorf("ListIssueReactions returned error: %v", err)
 	}
@@ -173,7 +175,7 @@ func TestReactionsService_ListIssueReactions_coverage(t *testing.T) {
 
 	const methodName = "ListIssueReactions"
 	testBadOptions(t, methodName, func() (err error) {
-		_, _, err = client.Reactions.ListIssueReactions(ctx, "\n", "\n", -1, &ListOptions{})
+		_, _, err = client.Reactions.ListIssueReactions(ctx, "\n", "\n", -1, &ListReactionOptions{})
 		return err
 	})
 
@@ -230,13 +232,15 @@ func TestReactionsService_ListIssueCommentReactions(t *testing.T) {
 	mux.HandleFunc("/repos/o/r/issues/comments/1/reactions", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		testHeader(t, r, "Accept", mediaTypeReactionsPreview)
+		testFormValues(t, r, values{"content": "+1"})
 
 		w.WriteHeader(http.StatusOK)
 		assertWrite(t, w, []byte(`[{"id":1,"user":{"login":"l","id":2},"content":"+1"}]`))
 	})
 
+	opt := &ListReactionOptions{Content: "+1"}
 	ctx := context.Background()
-	got, _, err := client.Reactions.ListIssueCommentReactions(ctx, "o", "r", 1, nil)
+	got, _, err := client.Reactions.ListIssueCommentReactions(ctx, "o", "r", 1, opt)
 	if err != nil {
 		t.Errorf("ListIssueCommentReactions returned error: %v", err)
 	}
@@ -254,7 +258,7 @@ func TestReactionsService_ListIssueCommentReactions_coverage(t *testing.T) {
 
 	const methodName = "ListIssueCommentReactions"
 	testBadOptions(t, methodName, func() (err error) {
-		_, _, err = client.Reactions.ListIssueCommentReactions(ctx, "\n", "\n", -1, &ListOptions{})
+		_, _, err = client.Reactions.ListIssueCommentReactions(ctx, "\n", "\n", -1, &ListReactionOptions{})
 		return err
 	})
 
@@ -311,13 +315,15 @@ func TestReactionsService_ListPullRequestCommentReactions(t *testing.T) {
 	mux.HandleFunc("/repos/o/r/pulls/comments/1/reactions", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		testHeader(t, r, "Accept", mediaTypeReactionsPreview)
+		testFormValues(t, r, values{"content": "+1"})
 
 		w.WriteHeader(http.StatusOK)
 		assertWrite(t, w, []byte(`[{"id":1,"user":{"login":"l","id":2},"content":"+1"}]`))
 	})
 
+	opt := &ListReactionOptions{Content: "+1"}
 	ctx := context.Background()
-	got, _, err := client.Reactions.ListPullRequestCommentReactions(ctx, "o", "r", 1, nil)
+	got, _, err := client.Reactions.ListPullRequestCommentReactions(ctx, "o", "r", 1, opt)
 	if err != nil {
 		t.Errorf("ListPullRequestCommentReactions returned error: %v", err)
 	}
@@ -335,7 +341,7 @@ func TestReactionsService_ListPullRequestCommentReactions_coverage(t *testing.T)
 
 	const methodName = "ListPullRequestCommentReactions"
 	testBadOptions(t, methodName, func() (err error) {
-		_, _, err = client.Reactions.ListPullRequestCommentReactions(ctx, "\n", "\n", -1, &ListOptions{})
+		_, _, err = client.Reactions.ListPullRequestCommentReactions(ctx, "\n", "\n", -1, &ListReactionOptions{})
 		return err
 	})
 
@@ -392,13 +398,15 @@ func TestReactionsService_ListTeamDiscussionReactions(t *testing.T) {
 	mux.HandleFunc("/teams/1/discussions/2/reactions", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		testHeader(t, r, "Accept", mediaTypeReactionsPreview)
+		testFormValues(t, r, values{"content": "+1"})
 
 		w.WriteHeader(http.StatusOK)
 		assertWrite(t, w, []byte(`[{"id":1,"user":{"login":"l","id":2},"content":"+1"}]`))
 	})
 
+	opt := &ListReactionOptions{Content: "+1"}
 	ctx := context.Background()
-	got, _, err := client.Reactions.ListTeamDiscussionReactions(ctx, 1, 2, nil)
+	got, _, err := client.Reactions.ListTeamDiscussionReactions(ctx, 1, 2, opt)
 	if err != nil {
 		t.Errorf("ListTeamDiscussionReactions returned error: %v", err)
 	}
@@ -416,7 +424,7 @@ func TestReactionsService_ListTeamDiscussionReactions_coverage(t *testing.T) {
 
 	const methodName = "ListTeamDiscussionReactions"
 	testBadOptions(t, methodName, func() (err error) {
-		_, _, err = client.Reactions.ListTeamDiscussionReactions(ctx, -1, -2, &ListOptions{})
+		_, _, err = client.Reactions.ListTeamDiscussionReactions(ctx, -1, -2, &ListReactionOptions{})
 		return err
 	})
 
@@ -473,13 +481,15 @@ func TestReactionService_ListTeamDiscussionCommentReactions(t *testing.T) {
 	mux.HandleFunc("/teams/1/discussions/2/comments/3/reactions", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		testHeader(t, r, "Accept", mediaTypeReactionsPreview)
+		testFormValues(t, r, values{"content": "+1"})
 
 		w.WriteHeader(http.StatusOK)
 		assertWrite(t, w, []byte(`[{"id":1,"user":{"login":"l","id":2},"content":"+1"}]`))
 	})
 
+	opt := &ListReactionOptions{Content: "+1"}
 	ctx := context.Background()
-	got, _, err := client.Reactions.ListTeamDiscussionCommentReactions(ctx, 1, 2, 3, nil)
+	got, _, err := client.Reactions.ListTeamDiscussionCommentReactions(ctx, 1, 2, 3, opt)
 	if err != nil {
 		t.Errorf("ListTeamDiscussionCommentReactions returned error: %v", err)
 	}
@@ -497,7 +507,7 @@ func TestReactionService_ListTeamDiscussionCommentReactions_coverage(t *testing.
 
 	const methodName = "ListTeamDiscussionCommentReactions"
 	testBadOptions(t, methodName, func() (err error) {
-		_, _, err = client.Reactions.ListTeamDiscussionCommentReactions(ctx, -1, -2, -3, &ListOptions{})
+		_, _, err = client.Reactions.ListTeamDiscussionCommentReactions(ctx, -1, -2, -3, &ListReactionOptions{})
 		return err
 	})