Monorepo for Tangled tangled.org

appview: add CI status component to pulls view

Signed-off-by: oppiliappan <me@oppi.li>

authored by oppi.li and committed by Tangled d55ad618 d52bd97a

Changed files
+89 -20
appview
db
pages
templates
repo
pulls
+4 -3
appview/db/pipeline.go
··· 9 9 "github.com/bluesky-social/indigo/atproto/syntax" 10 10 "github.com/go-git/go-git/v5/plumbing" 11 11 spindle "tangled.sh/tangled.sh/core/spindle/models" 12 + "tangled.sh/tangled.sh/core/workflow" 12 13 ) 13 14 14 15 type Pipeline struct { ··· 85 86 86 87 type Trigger struct { 87 88 Id int 88 - Kind string 89 + Kind workflow.TriggerKind 89 90 90 91 // push trigger fields 91 92 PushRef *string ··· 100 101 } 101 102 102 103 func (t *Trigger) IsPush() bool { 103 - return t != nil && t.Kind == "push" 104 + return t != nil && t.Kind == workflow.TriggerKindPush 104 105 } 105 106 106 107 func (t *Trigger) IsPullRequest() bool { 107 - return t != nil && t.Kind == "pull_request" 108 + return t != nil && t.Kind == workflow.TriggerKindPullRequest 108 109 } 109 110 110 111 func (t *Trigger) TargetRef() string {
+1
appview/pages/pages.go
··· 797 797 AbandonedPulls []*db.Pull 798 798 MergeCheck types.MergeCheckResponse 799 799 ResubmitCheck ResubmitResult 800 + Pipelines map[string]db.Pipeline 800 801 } 801 802 802 803 func (p *Pages) RepoSinglePull(w io.Writer, params RepoSinglePullParams) error {
+3 -4
appview/pages/templates/repo/pipelines/fragments/logBlock.html
··· 1 1 {{ define "repo/pipelines/fragments/logBlock" }} 2 2 <div id="lines" hx-swap-oob="beforeend"> 3 - <details id="step-{{ .Id }}" {{if not .Collapsed}}open{{end}} class="group bg-gray-100 px-2 dark:bg-gray-900"> 4 - <summary class="sticky top-0 py-1 list-none cursor-pointer py-2 bg-gray-100 dark:bg-gray-900 hover:text-gray-500 hover:dark:text-gray-400"> 3 + <details id="step-{{ .Id }}" {{if not .Collapsed}}open{{end}} class="group bg-gray-100 pb-2 px-2 dark:bg-gray-900"> 4 + <summary class="sticky top-0 pt-2 group-open:pb-2 list-none cursor-pointer bg-gray-100 dark:bg-gray-900 hover:text-gray-500 hover:dark:text-gray-400"> 5 5 <div class="group-open:hidden flex items-center gap-1"> 6 6 {{ i "chevron-right" "w-4 h-4" }} {{ .Name }} 7 7 </div> ··· 9 9 {{ i "chevron-down" "w-4 h-4" }} {{ .Name }} 10 10 </div> 11 11 </summary> 12 - <div class="text-blue-600 dark:text-blue-300 font-mono">{{ .Command }}</div> 13 - <div id="step-body-{{ .Id }}" class="font-mono"></div> 12 + <div class="font-mono whitespace-pre overflow-x-auto"><div class="text-blue-600 dark:text-blue-300">{{ .Command }}</div><div id="step-body-{{ .Id }}"></div></div> 14 13 </details> 15 14 </div> 16 15 {{ end }}
+1 -3
appview/pages/templates/repo/pipelines/fragments/logLine.html
··· 1 1 {{ define "repo/pipelines/fragments/logLine" }} 2 - <div id="step-body-{{ .Id }}" hx-swap-oob="beforeend"> 3 - <p>{{ .Content }}</p> 4 - </div> 2 + <div id="step-body-{{ .Id }}" hx-swap-oob="beforeend" class="whitespace-pre"><p>{{ .Content }}</p></div> 5 3 {{ end }} 6 4
+13 -8
appview/pages/templates/repo/pipelines/pipelines.html
··· 34 34 {{ $p := index . 1 }} 35 35 {{ with $p }} 36 36 <div class="grid grid-cols-6 md:grid-cols-12 gap-2 items-center w-full"> 37 - <div class="col-span-2 md:col-span-8 flex items-center gap-4"> 37 + <div class="text-sm md:text-base col-span-1"> 38 + {{ .Trigger.Kind.String }} 39 + </div> 40 + 41 + <div class="col-span-2 md:col-span-7 flex items-center gap-4"> 38 42 {{ $target := .Trigger.TargetRef }} 39 43 {{ $workflows := .Workflows }} 40 44 {{ $link := "" }} ··· 43 47 {{ end }} 44 48 {{ if .Trigger.IsPush }} 45 49 <span class="font-bold">{{ $target }}</span> 46 - <span>push</span> 47 50 <span class="hidden md:inline-flex gap-2 items-center font-mono text-sm"> 48 51 {{ $old := deref .Trigger.PushOldSha }} 49 52 {{ $new := deref .Trigger.PushNewSha }} ··· 53 56 <a href="/{{ $root.RepoInfo.FullName }}/commit/{{ $old }}">{{ slice $old 0 8 }}</a> 54 57 </span> 55 58 {{ else if .Trigger.IsPullRequest }} 56 - <span> 57 - pull request 58 - <span class="inline-flex gap-2 items-center"> 59 - {{ $target }} 60 - {{ i "arrow-left" "size-4" }} 61 - {{ .Trigger.PRSourceBranch }} 59 + {{ $sha := deref .Trigger.PRSourceSha }} 60 + <span class="inline-flex gap-2 items-center"> 61 + <span class="font-bold">{{ $target }}</span> 62 + {{ i "arrow-left" "size-4" }} 63 + {{ .Trigger.PRSourceBranch }} 64 + <span class="text-sm font-mono"> 65 + @ 66 + <a href="/{{ $root.RepoInfo.FullName }}/commit/{{ $sha }}">{{ slice $sha 0 8 }}</a> 62 67 </span> 63 68 </span> 64 69 {{ end }}
+40 -1
appview/pages/templates/repo/pulls/pull.html
··· 162 162 </div> 163 163 {{ end }} 164 164 165 + {{ block "pipelineStatus" (list $ .) }} {{ end }} 166 + 165 167 {{ if eq $lastIdx .RoundNumber }} 166 168 {{ block "mergeStatus" $ }} {{ end }} 167 169 {{ block "resubmitStatus" $ }} {{ end }} ··· 260 262 {{ end }} 261 263 {{ end }} 262 264 263 - {{ define "commits" }} 265 + {{ define "pipelineStatus" }} 266 + {{ $root := index . 0 }} 267 + {{ $submission := index . 1 }} 268 + {{ $pipeline := index $root.Pipelines $submission.SourceRev }} 269 + {{ with $pipeline }} 270 + {{ $id := .Id }} 271 + {{ if .Statuses }} 272 + <div class="max-w-80 grid grid-cols-1 bg-white dark:bg-gray-800 rounded border border-gray-200 dark:border-gray-700 divide-y divide-gray-200 dark:divide-gray-700"> 273 + {{ range $name, $all := .Statuses }} 274 + <a href="/{{ $root.RepoInfo.FullName }}/pipelines/{{ $id }}/workflow/{{ $name }}" class="no-underline hover:no-underline hover:bg-gray-100/25 hover:dark:bg-gray-700/25"> 275 + <div 276 + class="flex gap-2 items-center justify-between p-2"> 277 + {{ $lastStatus := $all.Latest }} 278 + {{ $kind := $lastStatus.Status.String }} 279 + 280 + {{ $t := .TimeTaken }} 281 + {{ $time := "" }} 282 + 283 + {{ if $t }} 284 + {{ $time = durationFmt $t }} 285 + {{ else }} 286 + {{ $time = printf "%s ago" (shortTimeFmt $lastStatus.Created) }} 287 + {{ end }} 288 + 289 + <div id="left" class="flex items-center gap-2 flex-shrink-0"> 290 + {{ template "repo/pipelines/fragments/workflowSymbol" $all }} 291 + {{ $name }} 292 + </div> 293 + <div id="right" class="flex items-center gap-2 flex-shrink-0"> 294 + <span class="font-bold">{{ $kind }}</span> 295 + <time>{{ $time }}</time> 296 + </div> 297 + </div> 298 + </a> 299 + {{ end }} 300 + </div> 301 + {{ end }} 302 + {{ end }} 264 303 {{ end }}
+27 -1
appview/pulls/pulls.go
··· 167 167 resubmitResult = s.resubmitCheck(f, pull, stack) 168 168 } 169 169 170 + repoInfo := f.RepoInfo(user) 171 + 172 + m := make(map[string]db.Pipeline) 173 + 174 + var shas []string 175 + for _, s := range pull.Submissions { 176 + shas = append(shas, s.SourceRev) 177 + } 178 + 179 + ps, err := db.GetPipelineStatuses( 180 + s.db, 181 + db.FilterEq("repo_owner", repoInfo.OwnerDid), 182 + db.FilterEq("repo_name", repoInfo.Name), 183 + db.FilterEq("knot", repoInfo.Knot), 184 + db.FilterIn("sha", shas), 185 + ) 186 + if err != nil { 187 + log.Printf("failed to fetch pipeline statuses: %s", err) 188 + // non-fatal 189 + } 190 + 191 + for _, p := range ps { 192 + m[p.Sha] = p 193 + } 194 + 170 195 s.pages.RepoSinglePull(w, pages.RepoSinglePullParams{ 171 196 LoggedInUser: user, 172 - RepoInfo: f.RepoInfo(user), 197 + RepoInfo: repoInfo, 173 198 DidHandleMap: didHandleMap, 174 199 Pull: pull, 175 200 Stack: stack, 176 201 AbandonedPulls: abandonedPulls, 177 202 MergeCheck: mergeCheckResponse, 178 203 ResubmitCheck: resubmitResult, 204 + Pipelines: m, 179 205 }) 180 206 } 181 207