github.com/mongodb/grip@v0.0.0-20240213223901-f906268d82b9/message/github_status.go (about) 1 package message 2 3 import ( 4 "fmt" 5 "net/url" 6 7 "github.com/mongodb/grip/level" 8 ) 9 10 // GithubState represents the 4 valid states for the Github State API in 11 // a safer way 12 type GithubState string 13 14 // The list of valid states for Github Status API requests 15 const ( 16 GithubStatePending = GithubState("pending") 17 GithubStateSuccess = GithubState("success") 18 GithubStateError = GithubState("error") 19 GithubStateFailure = GithubState("failure") 20 ) 21 22 // GithubStatus is a message to be posted to Github's Status API 23 type GithubStatus struct { 24 Owner string `bson:"owner,omitempty" json:"owner,omitempty" yaml:"owner,omitempty"` 25 Repo string `bson:"repo,omitempty" json:"repo,omitempty" yaml:"repo,omitempty"` 26 Ref string `bson:"ref,omitempty" json:"ref,omitempty" yaml:"ref,omitempty"` 27 28 Context string `bson:"context" json:"context" yaml:"context"` 29 State GithubState `bson:"state" json:"state" yaml:"state"` 30 URL string `bson:"url" json:"url" yaml:"url"` 31 Description string `bson:"description" json:"description" yaml:"description"` 32 } 33 34 // Valid returns true if the message is well formed 35 func (p *GithubStatus) Valid() bool { 36 // owner, repo and ref must be empty or must be set 37 ownerEmpty := len(p.Owner) == 0 38 repoEmpty := len(p.Repo) == 0 39 refLen := len(p.Ref) == 0 40 if ownerEmpty != repoEmpty || repoEmpty != refLen { 41 return false 42 } 43 44 switch p.State { 45 case GithubStatePending, GithubStateSuccess, GithubStateError, GithubStateFailure: 46 default: 47 return false 48 } 49 50 _, err := url.Parse(p.URL) 51 if err != nil || len(p.Context) == 0 { 52 return false 53 } 54 55 return true 56 } 57 58 type githubStatusMessage struct { 59 raw GithubStatus 60 str string 61 62 Base `bson:"metadata" json:"metadata" yaml:"metadata"` 63 } 64 65 // NewGithubStatusMessageWithRepo creates a composer for sending payloads to the Github Status 66 // API, with the repository and ref stored in the composer 67 func NewGithubStatusMessageWithRepo(p level.Priority, status GithubStatus) Composer { 68 s := MakeGithubStatusMessageWithRepo(status) 69 _ = s.SetPriority(p) 70 71 return s 72 } 73 74 // MakeGithubStatusMessageWithRepo creates a composer for sending payloads to the Github Status 75 // API, with the repository and ref stored in the composer 76 func MakeGithubStatusMessageWithRepo(status GithubStatus) Composer { 77 return &githubStatusMessage{ 78 raw: status, 79 } 80 } 81 82 // NewGithubStatusMessage creates a composer for sending payloads to the Github Status 83 // API. 84 func NewGithubStatusMessage(p level.Priority, context string, state GithubState, URL, description string) Composer { 85 s := MakeGithubStatusMessage(context, state, URL, description) 86 _ = s.SetPriority(p) 87 88 return s 89 } 90 91 // MakeGithubStatusMessage creates a composer for sending payloads to the Github Status 92 // API without setting a priority 93 func MakeGithubStatusMessage(context string, state GithubState, URL, description string) Composer { 94 return &githubStatusMessage{ 95 raw: GithubStatus{ 96 Context: context, 97 State: state, 98 URL: URL, 99 Description: description, 100 }, 101 } 102 } 103 104 func (c *githubStatusMessage) Loggable() bool { 105 return c.raw.Valid() 106 } 107 108 func (c *githubStatusMessage) String() string { 109 if len(c.str) != 0 { 110 return c.str 111 } 112 113 base := c.raw.Ref 114 if len(c.raw.Owner) > 0 { 115 base = fmt.Sprintf("%s/%s@%s ", c.raw.Owner, c.raw.Repo, c.raw.Ref) 116 } 117 if len(c.raw.Description) == 0 { 118 // looks like: evergreen failed (https://evergreen.mongodb.com) 119 c.str = base + fmt.Sprintf("%s %s (%s)", c.raw.Context, string(c.raw.State), c.raw.URL) 120 } else { 121 // looks like: evergreen failed: 1 task failed (https://evergreen.mongodb.com) 122 c.str = base + fmt.Sprintf("%s %s: %s (%s)", c.raw.Context, string(c.raw.State), c.raw.Description, c.raw.URL) 123 } 124 125 return c.str 126 } 127 128 func (c *githubStatusMessage) Raw() interface{} { 129 return &c.raw 130 }