Comprehensive management of GitHub issues and pull requests including creation, updates, comments, labels, milestones, assignees, reviews, and merging.
The IssuesService provides 38 methods for issue management.
type IssuesService struct{}// Get a single issue
func (s *IssuesService) Get(ctx context.Context, owner, repo string, number int) (*Issue, *Response, error)
// List issues for the authenticated user
func (s *IssuesService) List(ctx context.Context, all bool, opts *IssueListOptions) ([]*Issue, *Response, error)
// ListByRepo lists issues for the specified repository
func (s *IssuesService) ListByRepo(ctx context.Context, owner, repo string, opts *IssueListByRepoOptions) ([]*Issue, *Response, error)
// ListByOrg fetches issues for the authenticated user in the specified organization
func (s *IssuesService) ListByOrg(ctx context.Context, org string, opts *IssueListOptions) ([]*Issue, *Response, error)Usage:
// Get a specific issue
issue, _, err := client.Issues.Get(ctx, "owner", "repo", 42)
// List open issues for a repository
opts := &github.IssueListByRepoOptions{
State: "open",
ListOptions: github.ListOptions{PerPage: 100},
}
issues, _, err := client.Issues.ListByRepo(ctx, "owner", "repo", opts)
// List issues assigned to authenticated user
opts := &github.IssueListOptions{
Filter: "assigned",
State: "open",
}
issues, _, err := client.Issues.List(ctx, true, opts)// Create a new issue
func (s *IssuesService) Create(ctx context.Context, owner, repo string, issue *IssueRequest) (*Issue, *Response, error)
// Edit (update) an issue
func (s *IssuesService) Edit(ctx context.Context, owner, repo string, number int, issue *IssueRequest) (*Issue, *Response, error)
type IssueRequest struct {
Title *string
Body *string
Labels *[]string
Assignee *string
Assignees *[]string
State *string // "open" or "closed"
StateReason *string // "completed" or "not_planned"
Milestone *int
}Usage:
// Create a new issue
newIssue := &github.IssueRequest{
Title: github.Ptr("Bug: Application crashes on startup"),
Body: github.Ptr("Detailed description of the bug..."),
Labels: &[]string{"bug", "priority-high"},
Assignees: &[]string{"username1", "username2"},
}
issue, _, err := client.Issues.Create(ctx, "owner", "repo", newIssue)
// Edit an existing issue
editIssue := &github.IssueRequest{
State: github.Ptr("closed"),
StateReason: github.Ptr("completed"),
}
issue, _, err := client.Issues.Edit(ctx, "owner", "repo", 42, editIssue)// Lock an issue's conversation
func (s *IssuesService) Lock(ctx context.Context, owner, repo string, number int, opts *LockIssueOptions) (*Response, error)
// Unlock an issue's conversation
func (s *IssuesService) Unlock(ctx context.Context, owner, repo string, number int) (*Response, error)
type LockIssueOptions struct {
LockReason string // "off-topic", "too heated", "resolved", "spam"
}// ListComments lists all comments on the specified issue
func (s *IssuesService) ListComments(ctx context.Context, owner, repo string, number int, opts *IssueListCommentsOptions) ([]*IssueComment, *Response, error)
// GetComment fetches the specified issue comment
func (s *IssuesService) GetComment(ctx context.Context, owner, repo string, commentID int64) (*IssueComment, *Response, error)
// CreateComment creates a new comment on the specified issue
func (s *IssuesService) CreateComment(ctx context.Context, owner, repo string, number int, comment *IssueComment) (*IssueComment, *Response, error)
// EditComment updates an issue comment
func (s *IssuesService) EditComment(ctx context.Context, owner, repo string, commentID int64, comment *IssueComment) (*IssueComment, *Response, error)
// DeleteComment deletes an issue comment
func (s *IssuesService) DeleteComment(ctx context.Context, owner, repo string, commentID int64) (*Response, error)Usage:
// List comments
comments, _, err := client.Issues.ListComments(ctx, "owner", "repo", 42, nil)
// Create a comment
comment := &github.IssueComment{
Body: github.Ptr("This is a comment on the issue"),
}
comment, _, err := client.Issues.CreateComment(ctx, "owner", "repo", 42, comment)
// Edit a comment
editedComment := &github.IssueComment{
Body: github.Ptr("Updated comment text"),
}
comment, _, err := client.Issues.EditComment(ctx, "owner", "repo", commentID, editedComment)// ListLabels lists all labels for a repository
func (s *IssuesService) ListLabels(ctx context.Context, owner, repo string, opts *ListOptions) ([]*Label, *Response, error)
// GetLabel gets a single label
func (s *IssuesService) GetLabel(ctx context.Context, owner, repo, name string) (*Label, *Response, error)
// CreateLabel creates a new label on the specified repository
func (s *IssuesService) CreateLabel(ctx context.Context, owner, repo string, label *Label) (*Label, *Response, error)
// EditLabel edits a label
func (s *IssuesService) EditLabel(ctx context.Context, owner, repo, name string, label *Label) (*Label, *Response, error)
// DeleteLabel deletes a label
func (s *IssuesService) DeleteLabel(ctx context.Context, owner, repo, name string) (*Response, error)
// ListLabelsByIssue lists all labels for an issue
func (s *IssuesService) ListLabelsByIssue(ctx context.Context, owner, repo string, number int, opts *ListOptions) ([]*Label, *Response, error)
// AddLabelsToIssue adds labels to an issue
func (s *IssuesService) AddLabelsToIssue(ctx context.Context, owner, repo string, number int, labels []string) ([]*Label, *Response, error)
// RemoveLabelForIssue removes a label from an issue
func (s *IssuesService) RemoveLabelForIssue(ctx context.Context, owner, repo string, number int, label string) (*Response, error)
// ReplaceLabelsForIssue replaces all labels for an issue
func (s *IssuesService) ReplaceLabelsForIssue(ctx context.Context, owner, repo string, number int, labels []string) ([]*Label, *Response, error)
// RemoveLabelsForIssue removes all labels from an issue
func (s *IssuesService) RemoveLabelsForIssue(ctx context.Context, owner, repo string, number int) (*Response, error)// ListAssignees fetches all available assignees for a repository
func (s *IssuesService) ListAssignees(ctx context.Context, owner, repo string, opts *ListOptions) ([]*User, *Response, error)
// IsAssignee checks if a user is an assignee for the specified repository
func (s *IssuesService) IsAssignee(ctx context.Context, owner, repo, user string) (bool, *Response, error)
// AddAssignees adds GitHub users as assignees to the issue
func (s *IssuesService) AddAssignees(ctx context.Context, owner, repo string, number int, assignees []string) (*Issue, *Response, error)
// RemoveAssignees removes GitHub users as assignees from the issue
func (s *IssuesService) RemoveAssignees(ctx context.Context, owner, repo string, number int, assignees []string) (*Issue, *Response, error)// ListMilestones lists all milestones for a repository
func (s *IssuesService) ListMilestones(ctx context.Context, owner, repo string, opts *MilestoneListOptions) ([]*Milestone, *Response, error)
// GetMilestone gets a single milestone
func (s *IssuesService) GetMilestone(ctx context.Context, owner, repo string, number int) (*Milestone, *Response, error)
// CreateMilestone creates a new milestone on the specified repository
func (s *IssuesService) CreateMilestone(ctx context.Context, owner, repo string, milestone *Milestone) (*Milestone, *Response, error)
// EditMilestone edits a milestone
func (s *IssuesService) EditMilestone(ctx context.Context, owner, repo string, number int, milestone *Milestone) (*Milestone, *Response, error)
// DeleteMilestone deletes a milestone
func (s *IssuesService) DeleteMilestone(ctx context.Context, owner, repo string, number int) (*Response, error)
// RemoveMilestone removes a milestone from an issue
func (s *IssuesService) RemoveMilestone(ctx context.Context, owner, repo string, issueNumber int) (*Issue, *Response, error)
// ListLabelsForMilestone lists labels for every issue in a milestone
func (s *IssuesService) ListLabelsForMilestone(ctx context.Context, owner, repo string, number int, opts *ListOptions) ([]*Label, *Response, error)// ListIssueEvents lists events for the specified issue
func (s *IssuesService) ListIssueEvents(ctx context.Context, owner, repo string, number int, opts *ListOptions) ([]*IssueEvent, *Response, error)
// ListRepositoryEvents lists events for the specified repository
func (s *IssuesService) ListRepositoryEvents(ctx context.Context, owner, repo string, opts *ListOptions) ([]*IssueEvent, *Response, error)
// GetEvent returns the specified issue event
func (s *IssuesService) GetEvent(ctx context.Context, owner, repo string, id int64) (*IssueEvent, *Response, error)
// ListIssueTimeline lists events for the specified issue
func (s *IssuesService) ListIssueTimeline(ctx context.Context, owner, repo string, number int, opts *ListOptions) ([]*Timeline, *Response, error)The PullRequestsService provides comprehensive pull request management.
type PullRequestsService struct{}// Get a single pull request
func (s *PullRequestsService) Get(ctx context.Context, owner, repo string, number int) (*PullRequest, *Response, error)
// GetRaw gets a single pull request in raw (diff or patch) format
func (s *PullRequestsService) GetRaw(ctx context.Context, owner, repo string, number int, opts RawOptions) (string, *Response, error)
// List pull requests for a repository
func (s *PullRequestsService) List(ctx context.Context, owner, repo string, opts *PullRequestListOptions) ([]*PullRequest, *Response, error)
// ListPullRequestsWithCommit lists pull requests associated with a commit SHA
func (s *PullRequestsService) ListPullRequestsWithCommit(ctx context.Context, owner, repo, sha string, opts *ListOptions) ([]*PullRequest, *Response, error)// Create a new pull request
func (s *PullRequestsService) Create(ctx context.Context, owner, repo string, pull *NewPullRequest) (*PullRequest, *Response, error)
// Edit modifies a pull request
func (s *PullRequestsService) Edit(ctx context.Context, owner, repo string, number int, pull *PullRequest) (*PullRequest, *Response, error)
type NewPullRequest struct {
Title *string
Head *string // Required: branch where your changes are
Base *string // Required: branch you want changes pulled into
Body *string
Issue *int
MaintainerCanModify *bool
Draft *bool
}Usage:
// Create a pull request
newPR := &github.NewPullRequest{
Title: github.Ptr("Add new feature"),
Head: github.Ptr("feature-branch"),
Base: github.Ptr("main"),
Body: github.Ptr("This PR adds..."),
Draft: github.Ptr(false),
}
pr, _, err := client.PullRequests.Create(ctx, "owner", "repo", newPR)
// Edit a pull request
editPR := &github.PullRequest{
Title: github.Ptr("Updated title"),
Body: github.Ptr("Updated description"),
State: github.Ptr("open"),
}
pr, _, err := client.PullRequests.Edit(ctx, "owner", "repo", 42, editPR)// ListCommits lists commits in a pull request
func (s *PullRequestsService) ListCommits(ctx context.Context, owner, repo string, number int, opts *ListOptions) ([]*RepositoryCommit, *Response, error)
// ListFiles lists files in a pull request
func (s *PullRequestsService) ListFiles(ctx context.Context, owner, repo string, number int, opts *ListOptions) ([]*CommitFile, *Response, error)
// IsMerged checks if a pull request has been merged
func (s *PullRequestsService) IsMerged(ctx context.Context, owner, repo string, number int) (bool, *Response, error)// Merge a pull request
func (s *PullRequestsService) Merge(ctx context.Context, owner, repo string, number int, commitMessage string, opts *PullRequestOptions) (*PullRequestMergeResult, *Response, error)
type PullRequestOptions struct {
CommitTitle string // Title for the merge commit
SHA string // SHA that pull request head must match
MergeMethod string // "merge", "squash", or "rebase"
}
type PullRequestMergeResult struct {
SHA *string
Merged *bool
Message *string
}Usage:
// Merge with specific options
opts := &github.PullRequestOptions{
MergeMethod: "squash",
CommitTitle: "Feature: Add new functionality",
}
result, _, err := client.PullRequests.Merge(
ctx, "owner", "repo", 42, "Detailed commit message", opts)
if *result.Merged {
fmt.Printf("PR merged with SHA: %s\n", *result.SHA)
}// UpdateBranch updates the pull request branch with latest upstream changes
func (s *PullRequestsService) UpdateBranch(ctx context.Context, owner, repo string, number int, opts *PullRequestBranchUpdateOptions) (*PullRequestBranchUpdateResponse, *Response, error)
type PullRequestBranchUpdateOptions struct {
ExpectedHeadSHA *string // Expected SHA of the pull request's HEAD ref
}// ListReviews lists reviews on a specified pull request
func (s *PullRequestsService) ListReviews(ctx context.Context, owner, repo string, number int, opts *ListOptions) ([]*PullRequestReview, *Response, error)
// GetReview gets a specific review of a pull request
func (s *PullRequestsService) GetReview(ctx context.Context, owner, repo string, number int, reviewID int64) (*PullRequestReview, *Response, error)// CreateReview creates a new review on the specified pull request
func (s *PullRequestsService) CreateReview(ctx context.Context, owner, repo string, number int, review *PullRequestReviewRequest) (*PullRequestReview, *Response, error)
// SubmitReview submits a pending review
func (s *PullRequestsService) SubmitReview(ctx context.Context, owner, repo string, number int, reviewID int64, review *PullRequestReviewRequest) (*PullRequestReview, *Response, error)
// UpdateReview updates a review on a pull request
func (s *PullRequestsService) UpdateReview(ctx context.Context, owner, repo string, number int, reviewID int64, body string) (*PullRequestReview, *Response, error)
// DeletePendingReview deletes a pending review
func (s *PullRequestsService) DeletePendingReview(ctx context.Context, owner, repo string, number int, reviewID int64) (*PullRequestReview, *Response, error)
type PullRequestReviewRequest struct {
NodeID *string
CommitID *string
Body *string
Event *string // "APPROVE", "REQUEST_CHANGES", "COMMENT", "PENDING"
Comments []*DraftReviewComment
}
type DraftReviewComment struct {
Path *string
Position *int
Body *string
StartLine *int
Line *int
StartSide *string // "LEFT" or "RIGHT"
Side *string // "LEFT" or "RIGHT"
}Usage:
// Create a review with comments
review := &github.PullRequestReviewRequest{
Body: github.Ptr("Overall looks good with a few suggestions"),
Event: github.Ptr("REQUEST_CHANGES"),
Comments: []*github.DraftReviewComment{
{
Path: github.Ptr("main.go"),
Position: github.Ptr(10),
Body: github.Ptr("Consider using a more descriptive variable name"),
},
},
}
review, _, err := client.PullRequests.CreateReview(ctx, "owner", "repo", 42, review)
// Submit a pending review
submitReview := &github.PullRequestReviewRequest{
Body: github.Ptr("Approved after changes"),
Event: github.Ptr("APPROVE"),
}
review, _, err := client.PullRequests.SubmitReview(
ctx, "owner", "repo", 42, reviewID, submitReview)// DismissReview dismisses a specified review on a pull request
func (s *PullRequestsService) DismissReview(ctx context.Context, owner, repo string, number int, reviewID int64, review *PullRequestReviewDismissalRequest) (*PullRequestReview, *Response, error)
type PullRequestReviewDismissalRequest struct {
Message *string // Required: message explaining why the review was dismissed
}// ListComments lists all comments on the specified pull request
func (s *PullRequestsService) ListComments(ctx context.Context, owner, repo string, number int, opts *PullRequestListCommentsOptions) ([]*PullRequestComment, *Response, error)
// ListReviewComments lists all review comments for a specified review
func (s *PullRequestsService) ListReviewComments(ctx context.Context, owner, repo string, number int, reviewID int64, opts *ListOptions) ([]*PullRequestComment, *Response, error)
// GetComment gets a single comment
func (s *PullRequestsService) GetComment(ctx context.Context, owner, repo string, commentID int64) (*PullRequestComment, *Response, error)
// CreateComment creates a new comment on a pull request
func (s *PullRequestsService) CreateComment(ctx context.Context, owner, repo string, number int, comment *PullRequestComment) (*PullRequestComment, *Response, error)
// CreateCommentInReplyTo creates a new comment as a reply to another comment
func (s *PullRequestsService) CreateCommentInReplyTo(ctx context.Context, owner, repo string, number int, body string, commentID int64) (*PullRequestComment, *Response, error)
// EditComment updates a pull request comment
func (s *PullRequestsService) EditComment(ctx context.Context, owner, repo string, commentID int64, comment *PullRequestComment) (*PullRequestComment, *Response, error)
// DeleteComment deletes a pull request comment
func (s *PullRequestsService) DeleteComment(ctx context.Context, owner, repo string, commentID int64) (*Response, error)// ListReviewers lists reviewers whose reviews have been requested on a pull request
func (s *PullRequestsService) ListReviewers(ctx context.Context, owner, repo string, number int, opts *ListOptions) (*Reviewers, *Response, error)
// RequestReviewers creates a review request for the provided reviewers
func (s *PullRequestsService) RequestReviewers(ctx context.Context, owner, repo string, number int, reviewers ReviewersRequest) (*PullRequest, *Response, error)
// RemoveReviewers removes review requests for the provided reviewers
func (s *PullRequestsService) RemoveReviewers(ctx context.Context, owner, repo string, number int, reviewers ReviewersRequest) (*Response, error)
type ReviewersRequest struct {
NodeID *string
Reviewers []string
TeamReviewers []string
}type Issue struct {
ID *int64 `json:"id,omitempty"`
Number *int `json:"number,omitempty"`
State *string `json:"state,omitempty"`
StateReason *string `json:"state_reason,omitempty"` // Can be: "completed", "not_planned", "reopened"
Locked *bool `json:"locked,omitempty"`
Title *string `json:"title,omitempty"`
Body *string `json:"body,omitempty"`
AuthorAssociation *string `json:"author_association,omitempty"` // Deprecated: Will be removed from Events API Oct 7, 2025
User *User `json:"user,omitempty"`
Labels []*Label `json:"labels,omitempty"`
Assignee *User `json:"assignee,omitempty"`
Assignees []*User `json:"assignees,omitempty"`
Comments *int `json:"comments,omitempty"`
ClosedAt *Timestamp `json:"closed_at,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
ClosedBy *User `json:"closed_by,omitempty"`
URL *string `json:"url,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
CommentsURL *string `json:"comments_url,omitempty"`
EventsURL *string `json:"events_url,omitempty"`
LabelsURL *string `json:"labels_url,omitempty"`
RepositoryURL *string `json:"repository_url,omitempty"`
Milestone *Milestone `json:"milestone,omitempty"`
PullRequestLinks *PullRequestLinks `json:"pull_request,omitempty"`
Repository *Repository `json:"repository,omitempty"`
Reactions *Reactions `json:"reactions,omitempty"`
NodeID *string `json:"node_id,omitempty"`
Draft *bool `json:"draft,omitempty"`
Type *IssueType `json:"type,omitempty"`
TextMatches []*TextMatch `json:"text_matches,omitempty"` // Only populated from search results
ActiveLockReason *string `json:"active_lock_reason,omitempty"` // Possible values: "off-topic", "too heated", "resolved", "spam"
}type PullRequest struct {
ID *int64 `json:"id,omitempty"`
Number *int `json:"number,omitempty"`
State *string `json:"state,omitempty"`
Locked *bool `json:"locked,omitempty"`
Title *string `json:"title,omitempty"`
Body *string `json:"body,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
ClosedAt *Timestamp `json:"closed_at,omitempty"`
MergedAt *Timestamp `json:"merged_at,omitempty"`
Labels []*Label `json:"labels,omitempty"`
User *User `json:"user,omitempty"`
Draft *bool `json:"draft,omitempty"`
URL *string `json:"url,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
IssueURL *string `json:"issue_url,omitempty"`
StatusesURL *string `json:"statuses_url,omitempty"`
DiffURL *string `json:"diff_url,omitempty"`
PatchURL *string `json:"patch_url,omitempty"`
CommitsURL *string `json:"commits_url,omitempty"`
CommentsURL *string `json:"comments_url,omitempty"`
ReviewCommentsURL *string `json:"review_comments_url,omitempty"`
ReviewCommentURL *string `json:"review_comment_url,omitempty"`
Assignee *User `json:"assignee,omitempty"`
Assignees []*User `json:"assignees,omitempty"`
Milestone *Milestone `json:"milestone,omitempty"`
AuthorAssociation *string `json:"author_association,omitempty"` // Deprecated: Will be removed from Events API Oct 7, 2025
NodeID *string `json:"node_id,omitempty"`
RequestedReviewers []*User `json:"requested_reviewers,omitempty"`
AutoMerge *PullRequestAutoMerge `json:"auto_merge,omitempty"`
// These fields are not populated by the List operation
Merged *bool `json:"merged,omitempty"`
Mergeable *bool `json:"mergeable,omitempty"`
MergeableState *string `json:"mergeable_state,omitempty"`
Rebaseable *bool `json:"rebaseable,omitempty"`
MergedBy *User `json:"merged_by,omitempty"`
MergeCommitSHA *string `json:"merge_commit_sha,omitempty"`
Comments *int `json:"comments,omitempty"`
Commits *int `json:"commits,omitempty"`
Additions *int `json:"additions,omitempty"`
Deletions *int `json:"deletions,omitempty"`
ChangedFiles *int `json:"changed_files,omitempty"`
MaintainerCanModify *bool `json:"maintainer_can_modify,omitempty"`
ReviewComments *int `json:"review_comments,omitempty"`
// RequestedTeams is populated as part of PullRequestEvent
RequestedTeams []*Team `json:"requested_teams,omitempty"`
Links *PRLinks `json:"_links,omitempty"`
Head *PullRequestBranch `json:"head,omitempty"`
Base *PullRequestBranch `json:"base,omitempty"`
ActiveLockReason *string `json:"active_lock_reason,omitempty"` // Possible values: "off-topic", "too heated", "resolved", "spam"
}type PullRequestReview struct {
ID *int64
NodeID *string
User *User
Body *string
SubmittedAt *Timestamp
CommitID *string
HTMLURL *string
PullRequestURL *string
State *string
AuthorAssociation *string
}type Label struct {
ID *int64
NodeID *string
URL *string
Name *string
Description *string
Color *string
Default *bool
}type Milestone struct {
URL *string
HTMLURL *string
LabelsURL *string
ID *int64
Number *int
State *string
Title *string
Description *string
Creator *User
OpenIssues *int
ClosedIssues *int
CreatedAt *Timestamp
UpdatedAt *Timestamp
ClosedAt *Timestamp
DueOn *Timestamp
NodeID *string
}type IssueComment struct {
ID *int64
NodeID *string
Body *string
User *User
Reactions *Reactions
CreatedAt *Timestamp
UpdatedAt *Timestamp
AuthorAssociation *string
URL *string
HTMLURL *string
IssueURL *string
}type PullRequestComment struct {
ID *int64
NodeID *string
InReplyTo *int64
Body *string
Path *string
DiffHunk *string
PullRequestReviewID *int64
Position *int
OriginalPosition *int
StartLine *int
Line *int
OriginalLine *int
OriginalStartLine *int
Side *string
StartSide *string
CommitID *string
OriginalCommitID *string
User *User
Reactions *Reactions
CreatedAt *Timestamp
UpdatedAt *Timestamp
AuthorAssociation *string
URL *string
HTMLURL *string
PullRequestURL *string
}type IssueListOptions struct {
Filter string // "assigned", "created", "mentioned", "subscribed", "all"
State string // "open", "closed", "all"
Labels []string
Sort string // "created", "updated", "comments"
Direction string // "asc", "desc"
Since time.Time
ListOptions
}
type IssueListByRepoOptions struct {
Milestone string // "*", "none", or milestone number
State string
Assignee string
Creator string
Mentioned string
Labels []string
Sort string
Direction string
Since time.Time
ListOptions
}
type PullRequestListOptions struct {
State string // "open", "closed", "all"
Head string // Filter by head user and branch name
Base string // Filter by base branch name
Sort string // "created", "updated", "popularity", "long-running"
Direction string
ListOptions
}
type MilestoneListOptions struct {
State string // "open", "closed", "all"
Sort string // "due_on", "completeness"
Direction string
ListOptions
}