···66 "strings"77 "time"8899- "github.com/bluesky-social/indigo/atproto/syntax"1010- "github.com/go-git/go-git/v5/plumbing"1111- spindle "tangled.org/core/spindle/models"1212- "tangled.org/core/workflow"99+ "tangled.org/core/appview/models"1310)14111515-type Pipeline struct {1616- Id int1717- Rkey string1818- Knot string1919- RepoOwner syntax.DID2020- RepoName string2121- TriggerId int2222- Sha string2323- Created time.Time2424-2525- // populate when querying for reverse mappings2626- Trigger *Trigger2727- Statuses map[string]WorkflowStatus2828-}2929-3030-type WorkflowStatus struct {3131- Data []PipelineStatus3232-}3333-3434-func (w WorkflowStatus) Latest() PipelineStatus {3535- return w.Data[len(w.Data)-1]3636-}3737-3838-// time taken by this workflow to reach an "end state"3939-func (w WorkflowStatus) TimeTaken() time.Duration {4040- var start, end *time.Time4141- for _, s := range w.Data {4242- if s.Status.IsStart() {4343- start = &s.Created4444- }4545- if s.Status.IsFinish() {4646- end = &s.Created4747- }4848- }4949-5050- if start != nil && end != nil && end.After(*start) {5151- return end.Sub(*start)5252- }5353-5454- return 05555-}5656-5757-func (p Pipeline) Counts() map[string]int {5858- m := make(map[string]int)5959- for _, w := range p.Statuses {6060- m[w.Latest().Status.String()] += 16161- }6262- return m6363-}6464-6565-func (p Pipeline) TimeTaken() time.Duration {6666- var s time.Duration6767- for _, w := range p.Statuses {6868- s += w.TimeTaken()6969- }7070- return s7171-}7272-7373-func (p Pipeline) Workflows() []string {7474- var ws []string7575- for v := range p.Statuses {7676- ws = append(ws, v)7777- }7878- slices.Sort(ws)7979- return ws8080-}8181-8282-// if we know that a spindle has picked up this pipeline, then it is Responding8383-func (p Pipeline) IsResponding() bool {8484- return len(p.Statuses) != 08585-}8686-8787-type Trigger struct {8888- Id int8989- Kind workflow.TriggerKind9090-9191- // push trigger fields9292- PushRef *string9393- PushNewSha *string9494- PushOldSha *string9595-9696- // pull request trigger fields9797- PRSourceBranch *string9898- PRTargetBranch *string9999- PRSourceSha *string100100- PRAction *string101101-}102102-103103-func (t *Trigger) IsPush() bool {104104- return t != nil && t.Kind == workflow.TriggerKindPush105105-}106106-107107-func (t *Trigger) IsPullRequest() bool {108108- return t != nil && t.Kind == workflow.TriggerKindPullRequest109109-}110110-111111-func (t *Trigger) TargetRef() string {112112- if t.IsPush() {113113- return plumbing.ReferenceName(*t.PushRef).Short()114114- } else if t.IsPullRequest() {115115- return *t.PRTargetBranch116116- }117117-118118- return ""119119-}120120-121121-type PipelineStatus struct {122122- ID int123123- Spindle string124124- Rkey string125125- PipelineKnot string126126- PipelineRkey string127127- Created time.Time128128- Workflow string129129- Status spindle.StatusKind130130- Error *string131131- ExitCode int132132-}133133-134134-func GetPipelines(e Execer, filters ...filter) ([]Pipeline, error) {135135- var pipelines []Pipeline1212+func GetPipelines(e Execer, filters ...filter) ([]models.Pipeline, error) {1313+ var pipelines []models.Pipeline1361413715 var conditions []string13816 var args []any···34156 defer rows.Close()3515736158 for rows.Next() {3737- var pipeline Pipeline159159+ var pipeline models.Pipeline38160 var createdAt string39161 err = rows.Scan(40162 &pipeline.Id,···63185 return pipelines, nil64186}651876666-func AddPipeline(e Execer, pipeline Pipeline) error {188188+func AddPipeline(e Execer, pipeline models.Pipeline) error {67189 args := []any{68190 pipeline.Rkey,69191 pipeline.Knot,···94216 return err95217}962189797-func AddTrigger(e Execer, trigger Trigger) (int64, error) {219219+func AddTrigger(e Execer, trigger models.Trigger) (int64, error) {98220 args := []any{99221 trigger.Kind,100222 trigger.PushRef,···130252 return res.LastInsertId()131253}132254133133-func AddPipelineStatus(e Execer, status PipelineStatus) error {255255+func AddPipelineStatus(e Execer, status models.PipelineStatus) error {134256 args := []any{135257 status.Spindle,136258 status.Rkey,···168290169291// this is a mega query, but the most useful one:170292// get N pipelines, for each one get the latest status of its N workflows171171-func GetPipelineStatuses(e Execer, filters ...filter) ([]Pipeline, error) {293293+func GetPipelineStatuses(e Execer, filters ...filter) ([]models.Pipeline, error) {172294 var conditions []string173295 var args []any174296 for _, filter := range filters {···213335 }214336 defer rows.Close()215337216216- pipelines := make(map[string]Pipeline)338338+ pipelines := make(map[string]models.Pipeline)217339 for rows.Next() {218218- var p Pipeline219219- var t Trigger340340+ var p models.Pipeline341341+ var t models.Trigger220342 var created string221343222344 err := rows.Scan(···248370249371 t.Id = p.TriggerId250372 p.Trigger = &t251251- p.Statuses = make(map[string]WorkflowStatus)373373+ p.Statuses = make(map[string]models.WorkflowStatus)252374253375 k := fmt.Sprintf("%s/%s", p.Knot, p.Rkey)254376 pipelines[k] = p···287409 defer rows.Close()288410289411 for rows.Next() {290290- var ps PipelineStatus412412+ var ps models.PipelineStatus291413 var created string292414293415 err := rows.Scan(···320442 }321443 statuses, _ := pipeline.Statuses[ps.Workflow]322444 if !ok {323323- pipeline.Statuses[ps.Workflow] = WorkflowStatus{}445445+ pipeline.Statuses[ps.Workflow] = models.WorkflowStatus{}324446 }325447326448 // append···331453 pipelines[key] = pipeline332454 }333455334334- var all []Pipeline456456+ var all []models.Pipeline335457 for _, p := range pipelines {336458 for _, s := range p.Statuses {337337- slices.SortFunc(s.Data, func(a, b PipelineStatus) int {459459+ slices.SortFunc(s.Data, func(a, b models.PipelineStatus) int {338460 if a.Created.After(b.Created) {339461 return 1340462 }···354476 }355477356478 // sort pipelines by date357357- slices.SortFunc(all, func(a, b Pipeline) int {479479+ slices.SortFunc(all, func(a, b models.Pipeline) int {358480 if a.Created.After(b.Created) {359481 return -1360482 }
+130
appview/models/pipeline.go
···11+package models22+33+import (44+ "slices"55+ "time"66+77+ "github.com/bluesky-social/indigo/atproto/syntax"88+ "github.com/go-git/go-git/v5/plumbing"99+ spindle "tangled.org/core/spindle/models"1010+ "tangled.org/core/workflow"1111+)1212+1313+type Pipeline struct {1414+ Id int1515+ Rkey string1616+ Knot string1717+ RepoOwner syntax.DID1818+ RepoName string1919+ TriggerId int2020+ Sha string2121+ Created time.Time2222+2323+ // populate when querying for reverse mappings2424+ Trigger *Trigger2525+ Statuses map[string]WorkflowStatus2626+}2727+2828+type WorkflowStatus struct {2929+ Data []PipelineStatus3030+}3131+3232+func (w WorkflowStatus) Latest() PipelineStatus {3333+ return w.Data[len(w.Data)-1]3434+}3535+3636+// time taken by this workflow to reach an "end state"3737+func (w WorkflowStatus) TimeTaken() time.Duration {3838+ var start, end *time.Time3939+ for _, s := range w.Data {4040+ if s.Status.IsStart() {4141+ start = &s.Created4242+ }4343+ if s.Status.IsFinish() {4444+ end = &s.Created4545+ }4646+ }4747+4848+ if start != nil && end != nil && end.After(*start) {4949+ return end.Sub(*start)5050+ }5151+5252+ return 05353+}5454+5555+func (p Pipeline) Counts() map[string]int {5656+ m := make(map[string]int)5757+ for _, w := range p.Statuses {5858+ m[w.Latest().Status.String()] += 15959+ }6060+ return m6161+}6262+6363+func (p Pipeline) TimeTaken() time.Duration {6464+ var s time.Duration6565+ for _, w := range p.Statuses {6666+ s += w.TimeTaken()6767+ }6868+ return s6969+}7070+7171+func (p Pipeline) Workflows() []string {7272+ var ws []string7373+ for v := range p.Statuses {7474+ ws = append(ws, v)7575+ }7676+ slices.Sort(ws)7777+ return ws7878+}7979+8080+// if we know that a spindle has picked up this pipeline, then it is Responding8181+func (p Pipeline) IsResponding() bool {8282+ return len(p.Statuses) != 08383+}8484+8585+type Trigger struct {8686+ Id int8787+ Kind workflow.TriggerKind8888+8989+ // push trigger fields9090+ PushRef *string9191+ PushNewSha *string9292+ PushOldSha *string9393+9494+ // pull request trigger fields9595+ PRSourceBranch *string9696+ PRTargetBranch *string9797+ PRSourceSha *string9898+ PRAction *string9999+}100100+101101+func (t *Trigger) IsPush() bool {102102+ return t != nil && t.Kind == workflow.TriggerKindPush103103+}104104+105105+func (t *Trigger) IsPullRequest() bool {106106+ return t != nil && t.Kind == workflow.TriggerKindPullRequest107107+}108108+109109+func (t *Trigger) TargetRef() string {110110+ if t.IsPush() {111111+ return plumbing.ReferenceName(*t.PushRef).Short()112112+ } else if t.IsPullRequest() {113113+ return *t.PRTargetBranch114114+ }115115+116116+ return ""117117+}118118+119119+type PipelineStatus struct {120120+ ID int121121+ Spindle string122122+ Rkey string123123+ PipelineKnot string124124+ PipelineRkey string125125+ Created time.Time126126+ Workflow string127127+ Status spindle.StatusKind128128+ Error *string129129+ ExitCode int130130+}
···160160161161 repoInfo := f.RepoInfo(user)162162163163- m := make(map[string]db.Pipeline)163163+ m := make(map[string]models.Pipeline)164164165165 var shas []string166166 for _, s := range pull.Submissions {···552552 log.Printf("failed to fetch pipeline statuses: %s", err)553553 // non-fatal554554 }555555- m := make(map[string]db.Pipeline)555555+ m := make(map[string]models.Pipeline)556556 for _, p := range ps {557557 m[p.Sha] = p558558 }
+1-1
appview/repo/repo.go
···400400 log.Println(err)401401 // non-fatal402402 }403403- var pipeline *db.Pipeline403403+ var pipeline *models.Pipeline404404 if p, ok := pipelines[result.Diff.Commit.This]; ok {405405 pipeline = &p406406 }
+3-2
appview/repo/repo_util.go
···1010 "strings"11111212 "tangled.org/core/appview/db"1313+ "tangled.org/core/appview/models"1314 "tangled.org/core/appview/pages/repoinfo"1415 "tangled.org/core/types"1516···144143 d *db.DB,145144 repoInfo repoinfo.RepoInfo,146145 shas []string,147147-) (map[string]db.Pipeline, error) {148148- m := make(map[string]db.Pipeline)146146+) (map[string]models.Pipeline, error) {147147+ m := make(map[string]models.Pipeline)149148150149 if len(shas) == 0 {151150 return m, nil