cloudflare-native port of the tangled knot server
0

Configure Feed

Select the types of activity you want to include in your feed.

aerie / types / pipeline.go
5.6 kB 253 lines
1package types 2 3import ( 4 "fmt" 5 "strings" 6 "time" 7 8 "tangled.org/core/api/tangled" 9) 10 11type StatusKind string 12 13func (s StatusKind) String() string { 14 return string(s) 15} 16 17func (s StatusKind) IsFinish() bool { 18 switch string(s) { 19 case "failed", "timeout", "cancelled", "success": 20 return true 21 } 22 return false 23} 24 25func (s StatusKind) IsStart() bool { 26 switch string(s) { 27 case "pending", "running": 28 return true 29 } 30 return false 31} 32 33type WorkflowStatus struct { 34 *tangled.CiPipeline_Workflow 35 PipelineCreatedAt *string 36} 37 38func (w WorkflowStatus) Latest() WorkflowStatus { 39 return w 40} 41 42func (w WorkflowStatus) Error() string { 43 if w.CiPipeline_Workflow == nil || w.CiPipeline_Workflow.Error == nil { 44 return "" 45 } 46 return *w.CiPipeline_Workflow.Error 47} 48 49func (w WorkflowStatus) Status() StatusKind { 50 if w.CiPipeline_Workflow == nil { 51 return "" 52 } 53 return StatusKind(w.CiPipeline_Workflow.Status) 54} 55 56func (w WorkflowStatus) TimeTaken() time.Duration { 57 if w.CiPipeline_Workflow == nil || w.StartedAt == nil || w.FinishedAt == nil || *w.StartedAt == "" || *w.FinishedAt == "" { 58 return 0 59 } 60 t1, err1 := time.Parse(time.RFC3339, *w.StartedAt) 61 t2, err2 := time.Parse(time.RFC3339, *w.FinishedAt) 62 if err1 == nil && err2 == nil && t2.After(t1) { 63 return t2.Sub(t1) 64 } 65 return 0 66} 67 68func (w WorkflowStatus) Created() time.Time { 69 var timeStr string 70 if w.CiPipeline_Workflow != nil && w.StartedAt != nil && *w.StartedAt != "" { 71 timeStr = *w.StartedAt 72 } else if w.CiPipeline_Workflow != nil && w.FinishedAt != nil && *w.FinishedAt != "" { 73 timeStr = *w.FinishedAt 74 } else if w.PipelineCreatedAt != nil && *w.PipelineCreatedAt != "" { 75 timeStr = *w.PipelineCreatedAt 76 } else { 77 return time.Time{} 78 } 79 80 t, err := time.Parse(time.RFC3339, timeStr) 81 if err != nil { 82 return time.Time{} 83 } 84 return t 85} 86 87type Trigger struct { 88 *tangled.CiPipeline_Trigger 89} 90 91func (t Trigger) IsPush() bool { 92 return t.CiPipeline_Trigger != nil && t.CiPipeline_Trigger.CiTrigger_Push != nil 93} 94 95func (t Trigger) IsPullRequest() bool { 96 return t.CiPipeline_Trigger != nil && t.CiPipeline_Trigger.CiTrigger_PullRequest != nil 97} 98 99func (t Trigger) IsManual() bool { 100 return t.CiPipeline_Trigger != nil && t.CiPipeline_Trigger.CiTrigger_Manual != nil 101} 102 103func (t Trigger) TargetRef() string { 104 if t.CiPipeline_Trigger == nil { 105 return "" 106 } 107 if t.CiPipeline_Trigger.CiTrigger_Push != nil { 108 ref := t.CiPipeline_Trigger.CiTrigger_Push.Ref 109 if strings.HasPrefix(ref, "refs/heads/") { 110 return strings.TrimPrefix(ref, "refs/heads/") 111 } 112 if strings.HasPrefix(ref, "refs/tags/") { 113 return strings.TrimPrefix(ref, "refs/tags/") 114 } 115 return ref 116 } 117 if t.CiPipeline_Trigger.CiTrigger_PullRequest != nil { 118 return t.CiPipeline_Trigger.CiTrigger_PullRequest.TargetBranch 119 } 120 return "" 121} 122 123func (t Trigger) PRSourceBranch() string { 124 if t.CiPipeline_Trigger == nil || t.CiPipeline_Trigger.CiTrigger_PullRequest == nil { 125 return "" 126 } 127 sb := t.CiPipeline_Trigger.CiTrigger_PullRequest.SourceBranch 128 if sb == nil { 129 return "" 130 } 131 return *sb 132} 133 134type Pipeline struct { 135 *tangled.CiPipeline 136} 137 138func (p Pipeline) Valid() bool { 139 return p.CiPipeline != nil 140} 141 142func (p Pipeline) Id() string { 143 if p.CiPipeline == nil { 144 return "" 145 } 146 return p.CiPipeline.Id 147} 148 149func (p Pipeline) Statuses() map[string]WorkflowStatus { 150 m := make(map[string]WorkflowStatus) 151 if p.CiPipeline != nil { 152 for _, w := range p.CiPipeline.Workflows { 153 m[w.Name] = WorkflowStatus{ 154 CiPipeline_Workflow: w, 155 PipelineCreatedAt: p.CreatedAt, 156 } 157 } 158 } 159 return m 160} 161 162func (p Pipeline) Counts() map[string]int { 163 m := make(map[string]int) 164 if p.CiPipeline != nil { 165 for _, w := range p.CiPipeline.Workflows { 166 m[w.Status]++ 167 } 168 } 169 return m 170} 171 172// InProgress reports whether any workflow in the pipeline is still pending or 173// running (i.e. the pipeline has not fully settled). 174func (p Pipeline) InProgress() bool { 175 counts := p.Counts() 176 return counts["pending"] > 0 || counts["running"] > 0 177} 178 179func (p Pipeline) ShortStatusSummary() string { 180 if p.CiPipeline == nil { 181 return "" 182 } 183 counts := p.Counts() 184 total := len(p.CiPipeline.Workflows) 185 successes := counts["success"] 186 return fmt.Sprintf("%d/%d", successes, total) 187} 188 189func (p Pipeline) LongStatusSummary() string { 190 if p.CiPipeline == nil { 191 return "" 192 } 193 counts := p.Counts() 194 total := len(p.CiPipeline.Workflows) 195 var parts []string 196 states := []string{"success", "failed", "timeout", "cancelled", "running", "pending"} 197 for _, state := range states { 198 if c, ok := counts[state]; ok { 199 parts = append(parts, fmt.Sprintf("%d/%d %s", c, total, state)) 200 } 201 } 202 return strings.Join(parts, ", ") 203} 204 205func (p Pipeline) TimeTaken() time.Duration { 206 if p.CiPipeline == nil { 207 return 0 208 } 209 var s time.Duration 210 for _, w := range p.CiPipeline.Workflows { 211 s += WorkflowStatus{CiPipeline_Workflow: w}.TimeTaken() 212 } 213 return s 214} 215 216func (p Pipeline) Created() time.Time { 217 if p.CiPipeline == nil || p.CreatedAt == nil || *p.CreatedAt == "" { 218 return time.Time{} 219 } 220 t, err := time.Parse(time.RFC3339, *p.CreatedAt) 221 if err != nil { 222 return time.Time{} 223 } 224 return t 225} 226 227func (p Pipeline) Trigger() Trigger { 228 if p.CiPipeline == nil { 229 return Trigger{nil} 230 } 231 return Trigger{p.CiPipeline.Trigger} 232} 233 234func (p Pipeline) IsResponding() bool { 235 return p.CiPipeline != nil && len(p.CiPipeline.Workflows) > 0 236} 237 238func (p Pipeline) Sha() string { 239 if p.CiPipeline == nil { 240 return "" 241 } 242 return p.CiPipeline.Commit 243} 244 245func (p Pipeline) Workflows() []string { 246 var ws []string 247 if p.CiPipeline != nil { 248 for _, w := range p.CiPipeline.Workflows { 249 ws = append(ws, w.Name) 250 } 251 } 252 return ws 253}