Monorepo for Tangled tangled.org
1package models 2 3import ( 4 "fmt" 5 "slices" 6 "time" 7 8 "github.com/bluesky-social/indigo/atproto/syntax" 9 "github.com/go-git/go-git/v5/plumbing" 10 "tangled.org/core/api/tangled" 11 spindle "tangled.org/core/spindle/models" 12 "tangled.org/core/workflow" 13) 14 15type Pipeline struct { 16 Id int 17 Rkey string 18 Knot string 19 RepoOwner syntax.DID 20 RepoName string 21 TriggerId int 22 Sha string 23 Created time.Time 24 25 // populate when querying for reverse mappings 26 Trigger *Trigger 27 Statuses map[string]WorkflowStatus 28} 29 30func (p *Pipeline) AtUri() syntax.ATURI { 31 return syntax.ATURI(fmt.Sprintf("at://did:web:%s/%s/%s", p.Knot, tangled.PipelineNSID, p.Rkey)) 32} 33 34type WorkflowStatus struct { 35 Data []PipelineStatus 36} 37 38func (w WorkflowStatus) Latest() PipelineStatus { 39 return w.Data[len(w.Data)-1] 40} 41 42// time taken by this workflow to reach an "end state" 43func (w WorkflowStatus) TimeTaken() time.Duration { 44 var start, end *time.Time 45 for _, s := range w.Data { 46 if s.Status.IsStart() { 47 start = &s.Created 48 } 49 if s.Status.IsFinish() { 50 end = &s.Created 51 } 52 } 53 54 if start != nil && end != nil && end.After(*start) { 55 return end.Sub(*start) 56 } 57 58 return 0 59} 60 61func (p Pipeline) Counts() map[string]int { 62 m := make(map[string]int) 63 for _, w := range p.Statuses { 64 m[w.Latest().Status.String()] += 1 65 } 66 return m 67} 68 69func (p Pipeline) TimeTaken() time.Duration { 70 var s time.Duration 71 for _, w := range p.Statuses { 72 s += w.TimeTaken() 73 } 74 return s 75} 76 77func (p Pipeline) Workflows() []string { 78 var ws []string 79 for v := range p.Statuses { 80 ws = append(ws, v) 81 } 82 slices.Sort(ws) 83 return ws 84} 85 86// if we know that a spindle has picked up this pipeline, then it is Responding 87func (p Pipeline) IsResponding() bool { 88 return len(p.Statuses) != 0 89} 90 91type Trigger struct { 92 Id int 93 Kind workflow.TriggerKind 94 95 // push trigger fields 96 PushRef *string 97 PushNewSha *string 98 PushOldSha *string 99 100 // pull request trigger fields 101 PRSourceBranch *string 102 PRTargetBranch *string 103 PRSourceSha *string 104 PRAction *string 105} 106 107func (t *Trigger) IsPush() bool { 108 return t != nil && t.Kind == workflow.TriggerKindPush 109} 110 111func (t *Trigger) IsPullRequest() bool { 112 return t != nil && t.Kind == workflow.TriggerKindPullRequest 113} 114 115func (t *Trigger) TargetRef() string { 116 if t.IsPush() { 117 return plumbing.ReferenceName(*t.PushRef).Short() 118 } else if t.IsPullRequest() { 119 return *t.PRTargetBranch 120 } 121 122 return "" 123} 124 125type PipelineStatus struct { 126 ID int 127 Spindle string 128 Rkey string 129 PipelineKnot string 130 PipelineRkey string 131 Created time.Time 132 Workflow string 133 Status spindle.StatusKind 134 Error *string 135 ExitCode int 136} 137 138func (ps *PipelineStatus) PipelineAt() syntax.ATURI { 139 return syntax.ATURI(fmt.Sprintf("at://did:web:%s/%s/%s", ps.PipelineKnot, tangled.PipelineNSID, ps.PipelineRkey)) 140}