This repository was archived by the owner on Dec 17, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathcontext.go
More file actions
154 lines (139 loc) · 4.52 KB
/
Copy pathcontext.go
File metadata and controls
154 lines (139 loc) · 4.52 KB
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package validator
import (
"context"
"log"
"reflect"
"time"
"github.com/google/go-github/github"
"github.com/pkg/errors"
)
// Context contains an event payload an a configured client
type Context struct {
Event interface{}
Github *github.Client
Ctx *context.Context
AppID *int
AppGitHub *github.Client
}
// Process handles webhook events kinda like Probot does
func (c *Context) Process() bool {
switch e := c.Event.(type) {
case *github.CheckSuiteEvent:
c.ProcessCheckSuite(c.Event.(*github.CheckSuiteEvent))
return true
case *github.PullRequestEvent:
return c.ProcessPrEvent(c.Event.(*github.PullRequestEvent))
case *github.CheckRunEvent:
return c.ProcessCheckRunEvent(c.Event.(*github.CheckRunEvent))
case *github.InstallationEvent:
err := c.LogInstallationCount()
if err != nil {
log.Printf("%+v\n", err)
return false
}
return true
case *github.InstallationRepositoriesEvent:
err := c.LogInstallationCount()
if err != nil {
log.Printf("%+v\n", err)
return false
}
return true
default:
log.Printf("ignoring %s\n", reflect.TypeOf(e).String())
}
return false
}
// ProcessCheckSuite validates the Kubernetes YAML that has changed on checks
// associated with PRs.
func (c *Context) ProcessCheckSuite(e *github.CheckSuiteEvent) {
if *e.Action == "created" || *e.Action == "requested" || *e.Action == "rerequested" {
createCheckRunErr := c.createInitialCheckRun(e)
if createCheckRunErr != nil {
// TODO return a 500 to signal that retry is preferred
log.Println(errors.Wrap(createCheckRunErr, "Couldn't create check run"))
return
}
checkRunStart := time.Now()
var annotations []*github.CheckRunAnnotation
var candidates Candidates
config, configAnnotation, err := c.kubeValidatorConfigOrAnnotation(e)
if err != nil {
c.createConfigMissingCheckRun(&checkRunStart, e)
return
}
if configAnnotation != nil {
annotations = append(annotations, configAnnotation)
c.createConfigInvalidCheckRun(&checkRunStart, e, annotations)
return
}
// Determine which files to validate
changedFileList, fileListError := c.changedFileList(e)
if fileListError != nil {
// TODO fail the checkrun instead
log.Println(fileListError)
return
}
candidates = config.matchingCandidates(c, changedFileList)
annotations = append(annotations, candidates.LoadBytes()...)
annotations = append(annotations, candidates.Validate()...)
// Annotate the PR
finalCheckRunErr := c.createFinalCheckRun(&checkRunStart, e, candidates, annotations)
if finalCheckRunErr != nil {
// TODO return a 500 to signal that retry is preferred
log.Println(errors.Wrap(finalCheckRunErr, "Couldn't create check run"))
return
}
}
return
}
// ProcessPrEvent re-requests check suites on PRs when they're opened or re-opened
func (c *Context) ProcessPrEvent(e *github.PullRequestEvent) bool {
if *e.Action == "opened" || *e.Action == "reopened" {
results, _, err := c.Github.Checks.ListCheckSuitesForRef(*c.Ctx, e.Repo.GetOwner().GetLogin(), e.Repo.GetName(), e.PullRequest.Head.GetRef(), &github.ListCheckSuiteOptions{
AppID: c.AppID,
})
if err != nil {
log.Printf("%+v\n", err)
}
if results.GetTotal() == 1 {
suite := results.CheckSuites[0]
_, err := c.Github.Checks.ReRequestCheckSuite(*c.Ctx, e.Repo.GetOwner().GetLogin(), e.Repo.GetName(), suite.GetID())
if err != nil {
log.Printf("%+v\n", err)
}
return true
}
}
return false
}
// ProcessCheckRunEvent re-requests CheckSuites when a conatined CheckRun is rerequested
func (c *Context) ProcessCheckRunEvent(e *github.CheckRunEvent) bool {
if *e.Action == "rerequested" {
_, err := c.Github.Checks.ReRequestCheckSuite(*c.Ctx, e.Repo.GetOwner().GetLogin(), e.Repo.GetName(), e.CheckRun.CheckSuite.GetID())
if err != nil {
log.Printf("%+v\n", err)
return false
}
return true
}
return false
}
// LogInstallationCount logs the number of installations to help keep track of
// eligibility for inclusion in the GitHub Marketplace.
// https://developer.github.com/apps/marketplace/creating-and-submitting-your-app-for-approval/requirements-for-listing-an-app-on-github-marketplace/
func (c *Context) LogInstallationCount() error {
installations, _, err := c.AppGitHub.Apps.ListInstallations(*c.Ctx, &github.ListOptions{
PerPage: 251,
})
if err != nil {
return err
}
installationCount := len(installations)
if installationCount > 250 {
log.Printf("%+v installations. get thee to the market!", installationCount)
} else {
log.Printf("%+v installations. keep it up!", installationCount)
}
return nil
}