Add resolve and reply support
This commit is contained in:
112
github.go
112
github.go
@@ -20,6 +20,11 @@ type GitHubService interface {
|
||||
GetPullRequest(context.Context, string, string, int) (PRDetails, error)
|
||||
}
|
||||
|
||||
type GitHubWriteService interface {
|
||||
SetThreadResolved(context.Context, string, bool) (ReviewThread, error)
|
||||
ReplyToThread(context.Context, string, string) (ReviewComment, error)
|
||||
}
|
||||
|
||||
type GitHubClient struct {
|
||||
endpoint string
|
||||
token string
|
||||
@@ -422,6 +427,38 @@ query CheckAnnotationsPage($id: ID!, $after: String) {
|
||||
}
|
||||
}`
|
||||
|
||||
const resolveThreadMutation = `
|
||||
mutation ResolveReviewThread($input: ResolveReviewThreadInput!) {
|
||||
resolveReviewThread(input: $input) {
|
||||
thread {
|
||||
id isResolved isOutdated viewerCanResolve viewerCanUnresolve viewerCanReply path
|
||||
line originalLine diffSide startLine originalStartLine startDiffSide
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
const unresolveThreadMutation = `
|
||||
mutation UnresolveReviewThread($input: UnresolveReviewThreadInput!) {
|
||||
unresolveReviewThread(input: $input) {
|
||||
thread {
|
||||
id isResolved isOutdated viewerCanResolve viewerCanUnresolve viewerCanReply path
|
||||
line originalLine diffSide startLine originalStartLine startDiffSide
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
const replyToThreadMutation = `
|
||||
mutation ReplyToReviewThread($input: AddPullRequestReviewThreadReplyInput!) {
|
||||
addPullRequestReviewThreadReply(input: $input) {
|
||||
comment {
|
||||
id body diffHunk createdAt url outdated
|
||||
line startLine originalLine originalStartLine
|
||||
originalCommit { oid }
|
||||
author { login }
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
type githubActor struct {
|
||||
Login string `json:"login"`
|
||||
Name string `json:"name"`
|
||||
@@ -1047,6 +1084,63 @@ func (c *GitHubClient) GetPullRequest(ctx context.Context, owner, name string, n
|
||||
return details, nil
|
||||
}
|
||||
|
||||
func (c *GitHubClient) SetThreadResolved(
|
||||
ctx context.Context, threadID string, resolved bool,
|
||||
) (ReviewThread, error) {
|
||||
query := resolveThreadMutation
|
||||
variables := map[string]any{"input": map[string]any{"threadId": threadID}}
|
||||
if resolved {
|
||||
var data struct {
|
||||
ResolveReviewThread *struct {
|
||||
Thread *githubReviewThread
|
||||
}
|
||||
}
|
||||
if err := c.query(ctx, query, variables, &data); err != nil {
|
||||
return ReviewThread{}, err
|
||||
}
|
||||
if data.ResolveReviewThread == nil || data.ResolveReviewThread.Thread == nil {
|
||||
return ReviewThread{}, errors.New("GitHub returned no resolved review thread")
|
||||
}
|
||||
return convertReviewThread(*data.ResolveReviewThread.Thread), nil
|
||||
}
|
||||
|
||||
var data struct {
|
||||
UnresolveReviewThread *struct {
|
||||
Thread *githubReviewThread
|
||||
}
|
||||
}
|
||||
if err := c.query(ctx, unresolveThreadMutation, variables, &data); err != nil {
|
||||
return ReviewThread{}, err
|
||||
}
|
||||
if data.UnresolveReviewThread == nil || data.UnresolveReviewThread.Thread == nil {
|
||||
return ReviewThread{}, errors.New("GitHub returned no unresolved review thread")
|
||||
}
|
||||
return convertReviewThread(*data.UnresolveReviewThread.Thread), nil
|
||||
}
|
||||
|
||||
func (c *GitHubClient) ReplyToThread(
|
||||
ctx context.Context, threadID, body string,
|
||||
) (ReviewComment, error) {
|
||||
var data struct {
|
||||
AddPullRequestReviewThreadReply *struct {
|
||||
Comment *githubReviewComment
|
||||
}
|
||||
}
|
||||
if err := c.query(ctx, replyToThreadMutation, map[string]any{
|
||||
"input": map[string]any{
|
||||
"pullRequestReviewThreadId": threadID,
|
||||
"body": body,
|
||||
},
|
||||
}, &data); err != nil {
|
||||
return ReviewComment{}, err
|
||||
}
|
||||
if data.AddPullRequestReviewThreadReply == nil ||
|
||||
data.AddPullRequestReviewThreadReply.Comment == nil {
|
||||
return ReviewComment{}, errors.New("GitHub returned no review reply")
|
||||
}
|
||||
return convertReviewComment(*data.AddPullRequestReviewThreadReply.Comment), nil
|
||||
}
|
||||
|
||||
func convertReviewThread(thread githubReviewThread) ReviewThread {
|
||||
item := ReviewThread{
|
||||
ID: thread.ID, Path: thread.Path, DiffSide: thread.DiffSide,
|
||||
@@ -1068,17 +1162,21 @@ func convertReviewThread(thread githubReviewThread) ReviewThread {
|
||||
item.DiffSide = thread.StartDiffSide
|
||||
}
|
||||
for _, comment := range thread.Comments.Nodes {
|
||||
item.Comments = append(item.Comments, ReviewComment{
|
||||
ID: comment.ID, Author: actorLogin(comment.Author), Body: comment.Body,
|
||||
DiffHunk: comment.DiffHunk, CreatedAt: comment.CreatedAt, URL: comment.URL,
|
||||
Line: intValue(comment.Line), StartLine: intValue(comment.StartLine),
|
||||
OriginalLine: intValue(comment.OriginalLine), OriginalStartLine: intValue(comment.OriginalStartLine),
|
||||
OriginalCommitOID: commitOID(comment.OriginalCommit), Outdated: comment.Outdated,
|
||||
})
|
||||
item.Comments = append(item.Comments, convertReviewComment(comment))
|
||||
}
|
||||
return item
|
||||
}
|
||||
|
||||
func convertReviewComment(comment githubReviewComment) ReviewComment {
|
||||
return ReviewComment{
|
||||
ID: comment.ID, Author: actorLogin(comment.Author), Body: comment.Body,
|
||||
DiffHunk: comment.DiffHunk, CreatedAt: comment.CreatedAt, URL: comment.URL,
|
||||
Line: intValue(comment.Line), StartLine: intValue(comment.StartLine),
|
||||
OriginalLine: intValue(comment.OriginalLine), OriginalStartLine: intValue(comment.OriginalStartLine),
|
||||
OriginalCommitOID: commitOID(comment.OriginalCommit), Outdated: comment.Outdated,
|
||||
}
|
||||
}
|
||||
|
||||
func actorLogin(actor *githubActor) string {
|
||||
if actor == nil || actor.Login == "" {
|
||||
return "[ghost]"
|
||||
|
||||
Reference in New Issue
Block a user