/
github_status.go
130 lines (107 loc) · 3.68 KB
/
github_status.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
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
package message
import (
"fmt"
"net/url"
"github.com/cdr/grip/level"
)
// GithubState represents the 4 valid states for the Github State API in
// a safer way
type GithubState string
// The list of valid states for Github Status API requests
const (
GithubStatePending = GithubState("pending")
GithubStateSuccess = GithubState("success")
GithubStateError = GithubState("error")
GithubStateFailure = GithubState("failure")
)
// GithubStatus is a message to be posted to Github's Status API
type GithubStatus struct {
Owner string `bson:"owner,omitempty" json:"owner,omitempty" yaml:"owner,omitempty"`
Repo string `bson:"repo,omitempty" json:"repo,omitempty" yaml:"repo,omitempty"`
Ref string `bson:"ref,omitempty" json:"ref,omitempty" yaml:"ref,omitempty"`
Context string `bson:"context" json:"context" yaml:"context"`
State GithubState `bson:"state" json:"state" yaml:"state"`
URL string `bson:"url" json:"url" yaml:"url"`
Description string `bson:"description" json:"description" yaml:"description"`
}
// Valid returns true if the message is well formed
func (p *GithubStatus) Valid() bool {
// owner, repo and ref must be empty or must be set
ownerEmpty := len(p.Owner) == 0
repoEmpty := len(p.Repo) == 0
refLen := len(p.Ref) == 0
if ownerEmpty != repoEmpty || repoEmpty != refLen {
return false
}
switch p.State {
case GithubStatePending, GithubStateSuccess, GithubStateError, GithubStateFailure:
default:
return false
}
_, err := url.Parse(p.URL)
if err != nil || len(p.Context) == 0 {
return false
}
return true
}
type githubStatusMessage struct {
raw GithubStatus
str string
Base `bson:"metadata" json:"metadata" yaml:"metadata"`
}
// NewGithubStatusMessageWithRepo creates a composer for sending payloads to the Github Status
// API, with the repository and ref stored in the composer
func NewGithubStatusMessageWithRepo(p level.Priority, status GithubStatus) Composer {
s := MakeGithubStatusMessageWithRepo(status)
_ = s.SetPriority(p)
return s
}
// MakeGithubStatusMessageWithRepo creates a composer for sending payloads to the Github Status
// API, with the repository and ref stored in the composer
func MakeGithubStatusMessageWithRepo(status GithubStatus) Composer {
return &githubStatusMessage{
raw: status,
}
}
// NewGithubStatusMessage creates a composer for sending payloads to the Github Status
// API.
func NewGithubStatusMessage(p level.Priority, context string, state GithubState, URL, description string) Composer {
s := MakeGithubStatusMessage(context, state, URL, description)
_ = s.SetPriority(p)
return s
}
// MakeGithubStatusMessage creates a composer for sending payloads to the Github Status
// API without setting a priority
func MakeGithubStatusMessage(context string, state GithubState, URL, description string) Composer {
return &githubStatusMessage{
raw: GithubStatus{
Context: context,
State: state,
URL: URL,
Description: description,
},
}
}
func (c *githubStatusMessage) Loggable() bool {
return c.raw.Valid()
}
func (c *githubStatusMessage) String() string {
if len(c.str) != 0 {
return c.str
}
base := c.raw.Ref
if len(c.raw.Owner) > 0 {
base = fmt.Sprintf("%s/%s@%s ", c.raw.Owner, c.raw.Repo, c.raw.Ref)
}
if len(c.raw.Description) == 0 {
// looks like: evergreen failed (https://evergreen.cdr.com)
c.str = base + fmt.Sprintf("%s %s (%s)", c.raw.Context, string(c.raw.State), c.raw.URL)
} else {
// looks like: evergreen failed: 1 task failed (https://evergreen.cdr.com)
c.str = base + fmt.Sprintf("%s %s: %s (%s)", c.raw.Context, string(c.raw.State), c.raw.Description, c.raw.URL)
}
return c.str
}
func (c *githubStatusMessage) Raw() interface{} {
return &c.raw
}