cloudflare/pint

Public

mirrored from https://github.com/cloudflare/pintAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v0.3.1

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

internal/reporter/github.go

120lines · modecode

1package reporter
2
3import (
4 "fmt"
5 "time"
6
7 "context"
8
9 "github.com/cloudflare/pint/internal/git"
10 "github.com/google/go-github/v37/github"
11 "golang.org/x/oauth2"
12)
13
14type GithubReporter struct {
15 baseURL *string
16 uploadURL *string
17 timeout time.Duration
18 authToken string
19 owner string
20 repo string
21 prNum int
22 gitCmd git.CommandRunner
23}
24
25// NewGithubReporter creates a new GitHub reporter that reports
26// problems via comments on a given pull request number (integer).
27func NewGithubReporter(baseURL, uploadURL *string, timeout time.Duration, token, owner, repo string, prNum int, gitCmd git.CommandRunner) GithubReporter {
28 return GithubReporter{
29 baseURL: baseURL,
30 uploadURL: uploadURL,
31 timeout: timeout,
32 authToken: token,
33 owner: owner,
34 repo: repo,
35 prNum: prNum,
36 gitCmd: gitCmd,
37 }
38}
39
40// Submit submits the summary to GitHub.
41func (gr GithubReporter) Submit(summary Summary) error {
42 ctx, cancel := context.WithTimeout(context.Background(), gr.timeout)
43 defer cancel()
44
45 ts := oauth2.StaticTokenSource(
46 &oauth2.Token{AccessToken: gr.authToken},
47 )
48 tc := oauth2.NewClient(ctx, ts)
49
50 var client *github.Client
51
52 if (gr.uploadURL != nil && *gr.uploadURL != "") &&
53 (gr.baseURL != nil && *gr.baseURL != "") {
54 ec, err := github.NewEnterpriseClient(*gr.baseURL, *gr.uploadURL, tc)
55 if err != nil {
56 return fmt.Errorf("creating new GitHub client: %w", err)
57 }
58 client = ec
59 } else {
60 client = github.NewClient(tc)
61 }
62
63 pb, err := blameReports(summary.Reports, gr.gitCmd)
64 if err != nil {
65 return fmt.Errorf("failed to run git blame: %w", err)
66 }
67
68 comments := []*github.DraftReviewComment{}
69 for _, rep := range summary.Reports {
70 rep := rep
71
72 gitBlames, ok := pb[rep.Path]
73 if !ok {
74 continue
75 }
76
77 linesWithBlame := []int{}
78 for _, pl := range rep.Problem.Lines {
79 commit := gitBlames.GetCommit(pl)
80 if summary.FileChanges.HasCommit(commit) {
81 linesWithBlame = append(linesWithBlame, pl)
82 }
83 }
84
85 if len(linesWithBlame) == 0 {
86 continue
87 }
88
89 var comment *github.DraftReviewComment
90
91 if len(linesWithBlame) == 1 {
92 comment = &github.DraftReviewComment{
93 Path: github.String(rep.Path),
94 Body: github.String(rep.Problem.Text),
95 Line: github.Int(linesWithBlame[0]),
96 }
97 } else if len(linesWithBlame) > 1 {
98 start, end := linesWithBlame[0], linesWithBlame[len(linesWithBlame)-1]
99 comment = &github.DraftReviewComment{
100 Path: github.String(rep.Path),
101 Body: github.String(rep.Problem.Text),
102 Line: github.Int(end),
103 StartLine: github.Int(start),
104 }
105 }
106
107 comments = append(comments, comment)
108 }
109
110 if len(comments) > 0 {
111 if _, _, err := client.PullRequests.CreateReview(ctx, gr.owner, gr.repo, gr.prNum, &github.PullRequestReviewRequest{
112 Event: github.String("COMMENT"),
113 Comments: comments,
114 }); err != nil {
115 return fmt.Errorf("creating review: %w", err)
116 }
117 }
118
119 return nil
120}