From 3d99db714966b8ddbdfec0856a9f65569f8d8e3e Mon Sep 17 00:00:00 2001 From: JamBalaya56562 Date: Sun, 9 Aug 2026 07:38:20 +0900 Subject: [PATCH 1/2] refactor!: Rename `EditComment` to `UpdateComment` on `IssuesService`, and pass a new `IssueCommentRequest` by value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CreateComment and EditComment reused the 11-field IssueComment response type as their request bodies, but both endpoints accept exactly one parameter, body, and it is required in both schemas. EditComment's doc comment even had to warn "A non-nil comment.Body must be provided. Other comment fields should be left nil" — the new shared IssueCommentRequest makes that warning unnecessary by construction. Since the create and update schemas are identical, a single shared request type is used rather than a split. EditComment is renamed to UpdateComment to match the docs operation name. The IssueComment response type stays unchanged, and its entry is removed from the .golangci.yml allowlist. BREAKING CHANGE: IssuesService.CreateComment now takes a new IssueCommentRequest (with non-pointer Body) by value, and IssuesService.EditComment is renamed to UpdateComment and takes the same IssueCommentRequest by value, instead of *IssueComment. --- .golangci.yml | 1 - github/github-accessors.go | 8 ++++++++ github/github-accessors_test.go | 8 ++++++++ github/issues_comments.go | 12 ++++++++---- github/issues_comments_test.go | 24 ++++++++++++------------ 5 files changed, 36 insertions(+), 17 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index adb297b6ebd..6c9b3d623d2 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -227,7 +227,6 @@ linters: - Import - InstallationTokenListRepoOptions - InstallationTokenOptions - - IssueComment - IssueImportRequest - Key - LockIssueOptions diff --git a/github/github-accessors.go b/github/github-accessors.go index a4215e8fbc7..8b418d8a8c8 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -20854,6 +20854,14 @@ func (i *IssueCommentEvent) GetSender() *User { return i.Sender } +// GetBody returns the Body field. +func (i *IssueCommentRequest) GetBody() string { + if i == nil { + return "" + } + return i.Body +} + // GetBlockedBy returns the BlockedBy field if it's non-nil, zero value otherwise. func (i *IssueDependenciesSummary) GetBlockedBy() int { if i == nil || i.BlockedBy == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 04b0e9c8b2a..b4d730d82ac 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -26288,6 +26288,14 @@ func TestIssueCommentEvent_GetSender(tt *testing.T) { i.GetSender() } +func TestIssueCommentRequest_GetBody(tt *testing.T) { + tt.Parallel() + i := &IssueCommentRequest{} + i.GetBody() + i = nil + i.GetBody() +} + func TestIssueDependenciesSummary_GetBlockedBy(tt *testing.T) { tt.Parallel() var zeroValue int diff --git a/github/issues_comments.go b/github/issues_comments.go index 453ad70ad97..b96167f45fa 100644 --- a/github/issues_comments.go +++ b/github/issues_comments.go @@ -36,6 +36,11 @@ func (i IssueComment) String() string { return Stringify(i) } +// IssueCommentRequest represents a request to create or update an issue comment. +type IssueCommentRequest struct { + Body string `json:"body"` +} + // IssueListCommentsOptions specifies the optional parameters to the // IssuesService.ListComments method. type IssueListCommentsOptions struct { @@ -117,7 +122,7 @@ func (s *IssuesService) GetComment(ctx context.Context, owner, repo string, comm // GitHub API docs: https://docs.github.com/rest/issues/comments?apiVersion=2022-11-28#create-an-issue-comment // //meta:operation POST /repos/{owner}/{repo}/issues/{issue_number}/comments -func (s *IssuesService) CreateComment(ctx context.Context, owner, repo string, number int, body *IssueComment) (*IssueComment, *Response, error) { +func (s *IssuesService) CreateComment(ctx context.Context, owner, repo string, number int, body IssueCommentRequest) (*IssueComment, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/%v/comments", owner, repo, number) req, err := s.client.NewRequest(ctx, "POST", u, body) if err != nil { @@ -132,13 +137,12 @@ func (s *IssuesService) CreateComment(ctx context.Context, owner, repo string, n return c, resp, nil } -// EditComment updates an issue comment. -// A non-nil comment.Body must be provided. Other comment fields should be left nil. +// UpdateComment updates an issue comment. // // GitHub API docs: https://docs.github.com/rest/issues/comments?apiVersion=2022-11-28#update-an-issue-comment // //meta:operation PATCH /repos/{owner}/{repo}/issues/comments/{comment_id} -func (s *IssuesService) EditComment(ctx context.Context, owner, repo string, commentID int64, body *IssueComment) (*IssueComment, *Response, error) { +func (s *IssuesService) UpdateComment(ctx context.Context, owner, repo string, commentID int64, body IssueCommentRequest) (*IssueComment, *Response, error) { u := fmt.Sprintf("repos/%v/%v/issues/comments/%v", owner, repo, commentID) req, err := s.client.NewRequest(ctx, "PATCH", u, body) if err != nil { diff --git a/github/issues_comments_test.go b/github/issues_comments_test.go index 70a317b5308..a91cc756ca6 100644 --- a/github/issues_comments_test.go +++ b/github/issues_comments_test.go @@ -155,7 +155,7 @@ func TestIssuesService_CreateComment(t *testing.T) { t.Parallel() client, mux, _ := setup(t) - input := &IssueComment{Body: Ptr("b")} + input := IssueCommentRequest{Body: "b"} mux.HandleFunc("/repos/o/r/issues/1/comments", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "POST") @@ -194,15 +194,15 @@ func TestIssuesService_CreateComment_invalidOrg(t *testing.T) { client, _, _ := setup(t) ctx := t.Context() - _, _, err := client.Issues.CreateComment(ctx, "%", "r", 1, nil) + _, _, err := client.Issues.CreateComment(ctx, "%", "r", 1, IssueCommentRequest{}) testURLParseError(t, err) } -func TestIssuesService_EditComment(t *testing.T) { +func TestIssuesService_UpdateComment(t *testing.T) { t.Parallel() client, mux, _ := setup(t) - input := &IssueComment{Body: Ptr("b")} + input := IssueCommentRequest{Body: "b"} mux.HandleFunc("/repos/o/r/issues/comments/1", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "PATCH") @@ -211,24 +211,24 @@ func TestIssuesService_EditComment(t *testing.T) { }) ctx := t.Context() - comment, _, err := client.Issues.EditComment(ctx, "o", "r", 1, input) + comment, _, err := client.Issues.UpdateComment(ctx, "o", "r", 1, input) if err != nil { - t.Errorf("Issues.EditComment returned error: %v", err) + t.Errorf("Issues.UpdateComment returned error: %v", err) } want := &IssueComment{ID: Ptr(int64(1))} if !cmp.Equal(comment, want) { - t.Errorf("Issues.EditComment returned %+v, want %+v", comment, want) + t.Errorf("Issues.UpdateComment returned %+v, want %+v", comment, want) } - const methodName = "EditComment" + const methodName = "UpdateComment" testBadOptions(t, methodName, func() (err error) { - _, _, err = client.Issues.EditComment(ctx, "\n", "\n", -1, input) + _, _, err = client.Issues.UpdateComment(ctx, "\n", "\n", -1, input) return err }) testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Issues.EditComment(ctx, "o", "r", 1, input) + got, resp, err := client.Issues.UpdateComment(ctx, "o", "r", 1, input) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -236,12 +236,12 @@ func TestIssuesService_EditComment(t *testing.T) { }) } -func TestIssuesService_EditComment_invalidOwner(t *testing.T) { +func TestIssuesService_UpdateComment_invalidOwner(t *testing.T) { t.Parallel() client, _, _ := setup(t) ctx := t.Context() - _, _, err := client.Issues.EditComment(ctx, "%", "r", 1, nil) + _, _, err := client.Issues.UpdateComment(ctx, "%", "r", 1, IssueCommentRequest{}) testURLParseError(t, err) } From 96e0bc162e7243e1b0cedfebcb7aaaa1ff8bfd24 Mon Sep 17 00:00:00 2001 From: JamBalaya56562 Date: Sun, 9 Aug 2026 13:11:25 +0900 Subject: [PATCH 2/2] feat: Add `PerformedViaGithubApp`, `Pin` and `Minimized` to `IssueComment` The issue-comment response schema includes performed_via_github_app, pin and minimized, which were missing from the Go struct. pin and minimized are modeled with the new PinnedIssueComment and MinimizedIssueComment types matching their schemas. --- github/github-accessors.go | 48 +++++++++++++++++++++++++++++ github/github-accessors_test.go | 54 +++++++++++++++++++++++++++++++++ github/github-stringify_test.go | 29 ++++++++++-------- github/issues_comments.go | 22 +++++++++++--- 4 files changed, 136 insertions(+), 17 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 8b418d8a8c8..a46623d82ba 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -20750,6 +20750,14 @@ func (i *IssueComment) GetIssueURL() string { return *i.IssueURL } +// GetMinimized returns the Minimized field. +func (i *IssueComment) GetMinimized() *MinimizedIssueComment { + if i == nil { + return nil + } + return i.Minimized +} + // GetNodeID returns the NodeID field if it's non-nil, zero value otherwise. func (i *IssueComment) GetNodeID() string { if i == nil || i.NodeID == nil { @@ -20758,6 +20766,22 @@ func (i *IssueComment) GetNodeID() string { return *i.NodeID } +// GetPerformedViaGithubApp returns the PerformedViaGithubApp field. +func (i *IssueComment) GetPerformedViaGithubApp() *App { + if i == nil { + return nil + } + return i.PerformedViaGithubApp +} + +// GetPin returns the Pin field. +func (i *IssueComment) GetPin() *PinnedIssueComment { + if i == nil { + return nil + } + return i.Pin +} + // GetReactions returns the Reactions field. func (i *IssueComment) GetReactions() *Reactions { if i == nil { @@ -24926,6 +24950,14 @@ func (m *MilestoneStats) GetTotalMilestones() int { return *m.TotalMilestones } +// GetReason returns the Reason field if it's non-nil, zero value otherwise. +func (m *MinimizedIssueComment) GetReason() string { + if m == nil || m.Reason == nil { + return "" + } + return *m.Reason +} + // GetAnalysisKey returns the AnalysisKey field if it's non-nil, zero value otherwise. func (m *MostRecentInstance) GetAnalysisKey() string { if m == nil || m.AnalysisKey == nil { @@ -28486,6 +28518,22 @@ func (p *PingEvent) GetZen() string { return *p.Zen } +// GetPinnedAt returns the PinnedAt field if it's non-nil, zero value otherwise. +func (p *PinnedIssueComment) GetPinnedAt() Timestamp { + if p == nil || p.PinnedAt == nil { + return Timestamp{} + } + return *p.PinnedAt +} + +// GetPinnedBy returns the PinnedBy field. +func (p *PinnedIssueComment) GetPinnedBy() *User { + if p == nil { + return nil + } + return p.PinnedBy +} + // GetCollaborators returns the Collaborators field if it's non-nil, zero value otherwise. func (p *Plan) GetCollaborators() int { if p == nil || p.Collaborators == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index b4d730d82ac..a823937f05c 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -26172,6 +26172,14 @@ func TestIssueComment_GetIssueURL(tt *testing.T) { i.GetIssueURL() } +func TestIssueComment_GetMinimized(tt *testing.T) { + tt.Parallel() + i := &IssueComment{} + i.GetMinimized() + i = nil + i.GetMinimized() +} + func TestIssueComment_GetNodeID(tt *testing.T) { tt.Parallel() var zeroValue string @@ -26183,6 +26191,22 @@ func TestIssueComment_GetNodeID(tt *testing.T) { i.GetNodeID() } +func TestIssueComment_GetPerformedViaGithubApp(tt *testing.T) { + tt.Parallel() + i := &IssueComment{} + i.GetPerformedViaGithubApp() + i = nil + i.GetPerformedViaGithubApp() +} + +func TestIssueComment_GetPin(tt *testing.T) { + tt.Parallel() + i := &IssueComment{} + i.GetPin() + i = nil + i.GetPin() +} + func TestIssueComment_GetReactions(tt *testing.T) { tt.Parallel() i := &IssueComment{} @@ -31233,6 +31257,17 @@ func TestMilestoneStats_GetTotalMilestones(tt *testing.T) { m.GetTotalMilestones() } +func TestMinimizedIssueComment_GetReason(tt *testing.T) { + tt.Parallel() + var zeroValue string + m := &MinimizedIssueComment{Reason: &zeroValue} + m.GetReason() + m = &MinimizedIssueComment{} + m.GetReason() + m = nil + m.GetReason() +} + func TestMostRecentInstance_GetAnalysisKey(tt *testing.T) { tt.Parallel() var zeroValue string @@ -35852,6 +35887,25 @@ func TestPingEvent_GetZen(tt *testing.T) { p.GetZen() } +func TestPinnedIssueComment_GetPinnedAt(tt *testing.T) { + tt.Parallel() + var zeroValue Timestamp + p := &PinnedIssueComment{PinnedAt: &zeroValue} + p.GetPinnedAt() + p = &PinnedIssueComment{} + p.GetPinnedAt() + p = nil + p.GetPinnedAt() +} + +func TestPinnedIssueComment_GetPinnedBy(tt *testing.T) { + tt.Parallel() + p := &PinnedIssueComment{} + p.GetPinnedBy() + p = nil + p.GetPinnedBy() +} + func TestPlan_GetCollaborators(tt *testing.T) { tt.Parallel() var zeroValue int diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go index 73dcc09fa17..f1eb048f4d1 100644 --- a/github/github-stringify_test.go +++ b/github/github-stringify_test.go @@ -983,19 +983,22 @@ func TestIssue_String(t *testing.T) { func TestIssueComment_String(t *testing.T) { t.Parallel() v := IssueComment{ - ID: Ptr(int64(0)), - NodeID: Ptr(""), - Body: Ptr(""), - User: &User{}, - Reactions: &Reactions{}, - CreatedAt: &Timestamp{}, - UpdatedAt: &Timestamp{}, - AuthorAssociation: Ptr(""), - URL: Ptr(""), - HTMLURL: Ptr(""), - IssueURL: Ptr(""), - } - want := `github.IssueComment{ID:0, NodeID:"", Body:"", User:github.User{}, Reactions:github.Reactions{}, CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, AuthorAssociation:"", URL:"", HTMLURL:"", IssueURL:""}` + ID: Ptr(int64(0)), + NodeID: Ptr(""), + Body: Ptr(""), + User: &User{}, + Reactions: &Reactions{}, + CreatedAt: &Timestamp{}, + UpdatedAt: &Timestamp{}, + AuthorAssociation: Ptr(""), + PerformedViaGithubApp: &App{}, + Pin: &PinnedIssueComment{}, + Minimized: &MinimizedIssueComment{}, + URL: Ptr(""), + HTMLURL: Ptr(""), + IssueURL: Ptr(""), + } + want := `github.IssueComment{ID:0, NodeID:"", Body:"", User:github.User{}, Reactions:github.Reactions{}, CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, AuthorAssociation:"", PerformedViaGithubApp:github.App{}, Pin:github.PinnedIssueComment{}, Minimized:github.MinimizedIssueComment{}, URL:"", HTMLURL:"", IssueURL:""}` if got := v.String(); got != want { t.Errorf("IssueComment.String = %v, want %v", got, want) } diff --git a/github/issues_comments.go b/github/issues_comments.go index b96167f45fa..23bf0e1c7b3 100644 --- a/github/issues_comments.go +++ b/github/issues_comments.go @@ -26,10 +26,24 @@ type IssueComment struct { // Deprecated: GitHub will remove this field from Events API payloads on October 7, 2025. // Use the Issue Comments REST API endpoint to retrieve this information. // See: https://docs.github.com/rest/issues/comments?apiVersion=2022-11-28#get-an-issue-comment - AuthorAssociation *string `json:"author_association,omitempty"` - URL *string `json:"url,omitempty"` - HTMLURL *string `json:"html_url,omitempty"` - IssueURL *string `json:"issue_url,omitempty"` + AuthorAssociation *string `json:"author_association,omitempty"` + PerformedViaGithubApp *App `json:"performed_via_github_app,omitempty"` + Pin *PinnedIssueComment `json:"pin,omitempty"` + Minimized *MinimizedIssueComment `json:"minimized,omitempty"` + URL *string `json:"url,omitempty"` + HTMLURL *string `json:"html_url,omitempty"` + IssueURL *string `json:"issue_url,omitempty"` +} + +// PinnedIssueComment represents the pin details of a pinned issue comment. +type PinnedIssueComment struct { + PinnedAt *Timestamp `json:"pinned_at,omitempty"` + PinnedBy *User `json:"pinned_by,omitempty"` +} + +// MinimizedIssueComment represents the minimized details of a minimized issue comment. +type MinimizedIssueComment struct { + Reason *string `json:"reason,omitempty"` } func (i IssueComment) String() string {