Skip to content

Commit

Permalink
Use enum for conclusions
Browse files Browse the repository at this point in the history
  • Loading branch information
Kuixz committed Aug 20, 2024
1 parent c755960 commit 73f20a7
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 29 deletions.
21 changes: 16 additions & 5 deletions pkg/slack/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,15 @@ func (f ChannelInfo) String() string {
return fmt.Sprintf("%s with %s", f.ChannelID, f.Filter)
}

func (f ChannelInfo) ShouldSend(run *jobs.WorkflowRun) bool {
return f.Filter.Length() == 0 || f.Filter.Any(run)
func (f ChannelInfo) ShouldSend(run *jobs.WorkflowRun) (bool, error) {
if f.Filter.Length() == 0 {
return true, nil
}
result, err := f.Filter.Any(run)
if err != nil {
return false, err
}
return result, nil
}

func NewApp(logger *zap.Logger, config *Config, store kv.Store) *App {
Expand Down Expand Up @@ -81,9 +88,13 @@ func (a *App) GetChannels(ctx context.Context, repo string) ([]ChannelInfo, erro

for _, channelString := range channelInfoStrings {
channelID, conclusionsString, _ := strings.Cut(channelString, ":")
var conclusions []string
for _, conclusion := range strings.Split(conclusionsString, ",") {
if len(conclusion) > 0 {
var conclusions []Conclusion
for _, conclusionString := range strings.Split(conclusionsString, ",") {
if len(conclusionString) > 0 {
conclusion, err := NewConclusionFromString(conclusionString)
if err != nil {
return nil, err
}
conclusions = append(conclusions, conclusion)
}
}
Expand Down
81 changes: 59 additions & 22 deletions pkg/slack/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,23 @@ import (
"k8s.io/utils/strings/slices"
)

type Conclusion string

const (
ConclusionActionRequired Conclusion = "action_required"
ConclusionCancelled Conclusion = "cancelled"
ConclusionFailure Conclusion = "failure"
ConclusionNeutral Conclusion = "neutral"
ConclusionSuccess Conclusion = "success"
ConclusionSkipped Conclusion = "skipped"
ConclusionStale Conclusion = "stale"
ConclusionTimedOut Conclusion = "timed_out"
)

type MessageFilterRule struct {
Conclusions []string `json:"conclusions"`
Branches []string `json:"branches"`
Workflows []string `json:"workflows"`
Conclusions []Conclusion `json:"conclusions"`
Branches []string `json:"branches"`
Workflows []string `json:"workflows"`
}

type MessageFilter struct {
Expand Down Expand Up @@ -42,8 +55,8 @@ func (mf MessageFilter) Length() int {
return len(mf.Whitelists)
}

func (rule MessageFilterRule) Pass(run *jobs.WorkflowRun) bool {
if len(rule.Conclusions) > 0 && !slices.Contains(rule.Conclusions, run.Conclusion) {
func (rule MessageFilterRule) Pass(run *jobs.WorkflowRun, conclusion Conclusion) bool {
if len(rule.Conclusions) > 0 && !lo.Contains(rule.Conclusions, conclusion) {
return false
}
if len(rule.Branches) > 0 && !slices.Contains(rule.Branches, run.Branch) {
Expand All @@ -55,23 +68,39 @@ func (rule MessageFilterRule) Pass(run *jobs.WorkflowRun) bool {
return true
}

func (mf MessageFilter) Any(run *jobs.WorkflowRun) bool {
func (mf MessageFilter) Any(run *jobs.WorkflowRun) (bool, error) {
conclusion, err := NewConclusionFromString(run.Conclusion)
if err != nil {
return false, fmt.Errorf("Workflow run yielded invalid conclusion: %s", conclusion)
}
for _, rule := range mf.Whitelists {
if rule.Pass(run) {
return true
if rule.Pass(run, conclusion) {
return true, nil
}
}
return false
return false, nil
}

func NewConclusionFromString(str string) (Conclusion, error) {
switch str {
case "action_required":
return ConclusionActionRequired, nil
default:
return "", fmt.Errorf("unknown conclusion: %s", str)
}
}

func ParseConclusions(conclusions []string) ([]string, error) {
func ParseConclusions(conclusionStrings []string) ([]Conclusion, error) {
// Ref: https://docs.github.com/en/rest/checks/runs?apiVersion=2022-11-28#create-a-check-run--parameters
conclusionsEnum := []string{"action_required", "cancelled", "failure", "neutral", "success", "skipped", "stale", "timed_out"}
// conclusionsEnum := []string{"action_required", "cancelled", "failure", "neutral", "success", "skipped", "stale", "timed_out"}
var conclusions []Conclusion
var unsupportedConclusions []string
for _, c := range conclusions {
if !slices.Contains(conclusionsEnum, c) {
unsupportedConclusions = append(unsupportedConclusions, c)
for _, c := range conclusionStrings {
conclusion, err := NewConclusionFromString(c)
if err != nil {
return nil, err
}
conclusions = append(conclusions, conclusion)
}

if len(unsupportedConclusions) > 0 {
Expand All @@ -81,7 +110,7 @@ func ParseConclusions(conclusions []string) ([]string, error) {
return conclusions, nil
}

func NewFilterRule(key string, values []string, conclusions []string) (*MessageFilterRule, error) {
func NewFilterRule(key string, values []string, conclusions []Conclusion) (*MessageFilterRule, error) {
mfr := &MessageFilterRule{}
switch key {
case "conclusions":
Expand All @@ -92,10 +121,6 @@ func NewFilterRule(key string, values []string, conclusions []string) (*MessageF
default:
return nil, fmt.Errorf("unsupported filter type: %s", key)
}
conclusions, err := ParseConclusions(conclusions)
if err != nil {
return nil, err
}

mfr.Conclusions = conclusions
return mfr, nil
Expand All @@ -119,7 +144,13 @@ func ParseAsFilter(filterRuleStrings []string) (*MessageFilter, error) {
return nil, fmt.Errorf("duplicated conclusion strings; use commas to separate conclusions")
}

conclusions := strings.Split(definition[0], ",")
conclusionStrings := strings.Split(definition[0], ",")

conclusions, err := ParseConclusions(conclusionStrings)
if err != nil {
return nil, err
}

rule, err := NewFilterRule("conclusions", []string{}, conclusions)
if err != nil {
return nil, err
Expand All @@ -134,7 +165,7 @@ func ParseAsFilter(filterRuleStrings []string) (*MessageFilter, error) {
}

values := strings.Split(definition[1], ",")
rule, err := NewFilterRule(filterType, values, []string{})
rule, err := NewFilterRule(filterType, values, []Conclusion{})
if err != nil {
return nil, err
}
Expand All @@ -148,7 +179,13 @@ func ParseAsFilter(filterRuleStrings []string) (*MessageFilter, error) {
}

values := strings.Split(definition[1], ",")
conclusions := strings.Split(definition[2], ",")
conclusionStrings := strings.Split(definition[2], ",")

conclusions, err := ParseConclusions(conclusionStrings)
if err != nil {
return nil, err
}

rule, err := NewFilterRule(filterType, values, conclusions)
if err != nil {
return nil, err
Expand Down
13 changes: 11 additions & 2 deletions pkg/slack/notifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,19 @@ func (n *Notifier) notify(ctx context.Context, run *jobs.WorkflowRun) {
}

for _, channel := range channels {
if channel.ShouldSend(run) {
result, err := channel.ShouldSend(run)
if err != nil {
n.logger.Warn("failed to send message",
zap.Error(err),
zap.String("channelID", channel.ChannelID),
)
return
}
if !result {
return
}
err := n.app.SendMessage(ctx, channel.ChannelID, slack.MsgOptionAttachments(slackMsg))

err = n.app.SendMessage(ctx, channel.ChannelID, slack.MsgOptionAttachments(slackMsg))
if err != nil {
n.logger.Warn("failed to send message",
zap.Error(err),
Expand Down

0 comments on commit 73f20a7

Please sign in to comment.