-
Notifications
You must be signed in to change notification settings - Fork 79
/
Copy pathscanallpullrequests.go
79 lines (70 loc) · 2.81 KB
/
scanallpullrequests.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package scanpullrequest
import (
"context"
"errors"
"fmt"
"github.com/jfrog/frogbot/v2/utils"
"github.com/jfrog/frogbot/v2/utils/outputwriter"
"github.com/jfrog/jfrog-client-go/utils/log"
"github.com/jfrog/froggit-go/vcsclient"
)
var errPullRequestScan = "pull request #%d scan in the '%s' repository returned the following error:\n%s"
type ScanAllPullRequestsCmd struct {
}
func (cmd ScanAllPullRequestsCmd) Run(configAggregator utils.RepoAggregator, client vcsclient.VcsClient, frogbotRepoConnection *utils.UrlAccessChecker) error {
for _, config := range configAggregator {
log.Info("Scanning all open pull requests for repository:", config.RepoName)
log.Info("-----------------------------------------------------------")
config.OutputWriter.SetHasInternetConnection(frogbotRepoConnection.IsConnected())
err := scanAllPullRequests(config, client)
if err != nil {
return err
}
}
return nil
}
// Scan pull requests as follows:
// a. Retrieve all open pull requests
// b. Find the ones that should be scanned (new PRs or PRs with a 're-scan' comment)
// c. Audit the dependencies of the source and the target branches.
// d. Compare the vulnerabilities found in source and target branches, and show only the new vulnerabilities added by the pull request.
func scanAllPullRequests(repo utils.Repository, client vcsclient.VcsClient) (err error) {
openPullRequests, err := client.ListOpenPullRequests(context.Background(), repo.RepoOwner, repo.RepoName)
if err != nil {
return err
}
for _, pr := range openPullRequests {
shouldScan, e := shouldScanPullRequest(repo, client, int(pr.ID))
if e != nil {
err = errors.Join(err, fmt.Errorf(errPullRequestScan, int(pr.ID), repo.RepoName, e.Error()))
}
if !shouldScan {
log.Info("Pull Request", pr.ID, "has already been scanned before. If you wish to scan it again, please comment \"rescan\".")
continue
}
repo.PullRequestDetails = pr
if e = scanPullRequest(&repo, client); e != nil {
// If error, write it in errList and continue to the next PR.
err = errors.Join(err, fmt.Errorf(errPullRequestScan, int(pr.ID), repo.RepoName, e.Error()))
}
}
return
}
func shouldScanPullRequest(repo utils.Repository, client vcsclient.VcsClient, prID int) (shouldScan bool, err error) {
pullRequestsComments, err := utils.GetSortedPullRequestComments(client, repo.RepoOwner, repo.RepoName, prID)
if err != nil {
return
}
for _, comment := range pullRequestsComments {
// If this a 're-scan' request comment
if utils.IsFrogbotRescanComment(comment.Content) {
return true, nil
}
// if this is a Frogbot 'scan results' comment and not 're-scan' request comment, do not scan this pull request.
if outputwriter.IsFrogbotComment(comment.Content) {
return false, nil
}
}
// This is a new pull request, and it therefore should be scanned.
return true, nil
}