github.com/ungtb10d/cli/v2@v2.0.0-20221110210412-98537dd9d6a1/pkg/cmd/pr/checks/aggregate.go (about) 1 package checks 2 3 import ( 4 "fmt" 5 "sort" 6 "time" 7 8 "github.com/ungtb10d/cli/v2/api" 9 ) 10 11 type check struct { 12 Name string `json:"name"` 13 State string `json:"state"` 14 StartedAt time.Time `json:"startedAt"` 15 CompletedAt time.Time `json:"completedAt"` 16 Link string `json:"link"` 17 Bucket string `json:"bucket"` 18 } 19 20 type checkCounts struct { 21 Failed int 22 Passed int 23 Pending int 24 Skipping int 25 } 26 27 func aggregateChecks(checkContexts []api.CheckContext, requiredChecks bool) (checks []check, counts checkCounts) { 28 for _, c := range eliminateDuplicates(checkContexts) { 29 if requiredChecks && !c.IsRequired { 30 continue 31 } 32 33 state := c.State 34 if state == "" { 35 if c.Status == "COMPLETED" { 36 state = c.Conclusion 37 } else { 38 state = c.Status 39 } 40 } 41 42 link := c.DetailsURL 43 if link == "" { 44 link = c.TargetURL 45 } 46 47 name := c.Name 48 if name == "" { 49 name = c.Context 50 } 51 52 item := check{ 53 Name: name, 54 State: state, 55 StartedAt: c.StartedAt, 56 CompletedAt: c.CompletedAt, 57 Link: link, 58 } 59 switch state { 60 case "SUCCESS": 61 item.Bucket = "pass" 62 counts.Passed++ 63 case "SKIPPED", "NEUTRAL": 64 item.Bucket = "skipping" 65 counts.Skipping++ 66 case "ERROR", "FAILURE", "CANCELLED", "TIMED_OUT", "ACTION_REQUIRED": 67 item.Bucket = "fail" 68 counts.Failed++ 69 default: // "EXPECTED", "REQUESTED", "WAITING", "QUEUED", "PENDING", "IN_PROGRESS", "STALE" 70 item.Bucket = "pending" 71 counts.Pending++ 72 } 73 74 checks = append(checks, item) 75 } 76 return 77 } 78 79 // eliminateDuplicates filters a set of checks to only the most recent ones if the set includes repeated runs 80 func eliminateDuplicates(checkContexts []api.CheckContext) []api.CheckContext { 81 sort.Slice(checkContexts, func(i, j int) bool { return checkContexts[i].StartedAt.After(checkContexts[j].StartedAt) }) 82 83 mapChecks := make(map[string]struct{}) 84 mapContexts := make(map[string]struct{}) 85 unique := make([]api.CheckContext, 0, len(checkContexts)) 86 87 for _, ctx := range checkContexts { 88 if ctx.Context != "" { 89 if _, exists := mapContexts[ctx.Context]; exists { 90 continue 91 } 92 mapContexts[ctx.Context] = struct{}{} 93 } else { 94 key := fmt.Sprintf("%s/%s", ctx.Name, ctx.CheckSuite.WorkflowRun.Workflow.Name) 95 if _, exists := mapChecks[key]; exists { 96 continue 97 } 98 mapChecks[key] = struct{}{} 99 } 100 unique = append(unique, ctx) 101 } 102 103 return unique 104 }