mirror of
https://git.vectorsigma.ru/public/atlantis.git
synced 2026-07-29 12:38:17 +00:00
93 lines
2.9 KiB
Go
93 lines
2.9 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/google/go-github/github"
|
|
"context"
|
|
)
|
|
|
|
type GithubClient struct {
|
|
client *github.Client
|
|
ctx context.Context
|
|
}
|
|
|
|
const (
|
|
statusContext = "Atlantis"
|
|
PendingStatus = "pending"
|
|
SuccessStatus = "success"
|
|
ErrorStatus = "error"
|
|
FailureStatus = "failure"
|
|
)
|
|
|
|
func (g *GithubClient) UpdateStatus(ctx *PullRequestContext, status string, description string) {
|
|
repoStatus := github.RepoStatus{State: github.String(status), Description: github.String(description), Context: github.String(statusContext)}
|
|
g.client.Repositories.CreateStatus(g.ctx, ctx.owner, ctx.repoName, ctx.head, &repoStatus)
|
|
// todo: deal with error updating status
|
|
}
|
|
|
|
func (g *GithubClient) GetModifiedFiles(ctx *PullRequestContext) ([]string, error) {
|
|
var files = []string{}
|
|
comparison, _, err := g.client.Repositories.CompareCommits(g.ctx, ctx.owner, ctx.repoName, ctx.base, ctx.head)
|
|
if err != nil {
|
|
return files, err
|
|
}
|
|
for _, file := range comparison.Files {
|
|
files = append(files, *file.Filename)
|
|
}
|
|
return files, nil
|
|
}
|
|
|
|
func (g *GithubClient) CreateComment(ctx *PullRequestContext, comment string) error {
|
|
_, _, err := g.client.Issues.CreateComment(g.ctx, ctx.owner, ctx.repoName, ctx.number, &github.IssueComment{Body: &comment})
|
|
return err
|
|
}
|
|
|
|
// CommentExists searches through comments on a pull request and returns true if one matches matcher
|
|
func (g *GithubClient) CommentExists(ctx *PullRequestContext, matcher func(*github.IssueComment) bool) (bool, error) {
|
|
opt := &github.IssueListCommentsOptions{}
|
|
// need to loop since there may be multiple pages of comments
|
|
for {
|
|
comments, resp, err := g.client.Issues.ListComments(g.ctx, ctx.owner, ctx.repoName, ctx.number, opt)
|
|
if err != nil {
|
|
return false, fmt.Errorf("failed to retrieve comments: %v", err)
|
|
}
|
|
for _, comment := range comments {
|
|
if matcher(comment) {
|
|
return true, nil
|
|
}
|
|
}
|
|
if resp.NextPage == 0 {
|
|
break
|
|
}
|
|
opt.ListOptions.Page = resp.NextPage
|
|
}
|
|
return false, nil
|
|
}
|
|
|
|
func (g *GithubClient) PullIsApproved(ctx *PullRequestContext) (bool, error) {
|
|
// todo: move back to using g.client.PullRequests.ListReviews when we update our GitHub enterprise version
|
|
// to where we don't need to include the custom accept header
|
|
u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews", ctx.owner, ctx.repoName, ctx.number)
|
|
req, err := g.client.NewRequest("GET", u, nil)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
req.Header.Set("Accept", "application/vnd.github.black-cat-preview+json")
|
|
|
|
var reviews []*github.PullRequestReview
|
|
_, err = g.client.Do(g.ctx, req, &reviews)
|
|
if err != nil {
|
|
return false, fmt.Errorf("failed to retrieve reviews: %v", err)
|
|
}
|
|
for _, review := range reviews {
|
|
if review != nil && review.State != nil && *review.State == "APPROVED" {
|
|
return true, nil
|
|
}
|
|
}
|
|
return false, nil
|
|
}
|
|
|
|
func (g *GithubClient) GetPullRequest(owner string, repo string, number int) (*github.PullRequest, *github.Response, error) {
|
|
return g.client.PullRequests.Get(g.ctx, owner, repo, number)
|
|
}
|