Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/vole.git

Write over SSH with a registered key:

git clone ssh://git@rodent.software:2222/vole.git

A free and open-source forge that lives in your Git repo.

Show run durations and lazy step logs

c765ae2e18691b3f98d93b00b4eb418ce781e3f1 · Keenan Nemetz · 13d ago · parent bdf6a0de

server/web/templates/run.html +84−6

@@ -5,10 +5,11 @@
5 5 <div class="page-head-main">
6 6 <h1>Run · {{.Run.Job}}</h1>
7 7 <p class="page-sub">
8 {{.Run.Workflow}} · {{if .Run.Tag}}tag {{.Run.Tag}}{{else}}{{.Run.Branch}}{{end}} at <a class="sha" href="/r/{{.Name}}/commit/{{.Run.SHA}}">{{short .Run.SHA}}</a>
9 · {{.Run.Status}}{{if eq .Run.Status "failed"}} (exit {{.Run.ExitCode}}){{end}}
8 <span class="status {{.Run.Status}}">{{.Run.Status}}</span>
9 · {{.Run.Workflow}}
10 · {{if .Run.Tag}}tag {{.Run.Tag}}{{else}}{{.Run.Branch}}{{end}}
11 at <a class="sha" href="/r/{{.Name}}/commit/{{.Run.SHA}}">{{short .Run.SHA}}</a>
10 12 · attempt {{.Run.Attempts}}
11 · {{since .Run.Created.Unix}}
12 13 </p>
13 14 </div>
14 15 {{if or .CanCancel .CanRerun}}
@@ -24,13 +25,90 @@
24 25 </div>
25 26 {{end}}
26 27 </div>
28
29 <div class="run-summary">
30 <div class="card">
31 <span class="run-summary-label">{{icon "history"}}Duration</span>
32 {{if .Run.Started.IsZero}}
33 <strong>{{duration .Wait}}</strong>
34 <span class="status-note">{{if eq .Run.Status "queued"}}waiting for a runner{{else}}queued{{end}}</span>
35 {{else}}
36 <strong>{{duration .Duration}}</strong>
37 <span class="status-note">{{if .Run.Finished.IsZero}}running now{{else}}finished {{since .Run.Finished.Unix}}{{end}}</span>
38 {{end}}
39 </div>
40 <div class="card">
41 <span class="run-summary-label">{{icon "history"}}Queue wait</span>
42 <strong>{{duration .Wait}}</strong>
43 <span class="status-note">{{if .Run.Started.IsZero}}so far{{else}}before the first runner leased it{{end}}</span>
44 </div>
45 <div class="card">
46 <span class="run-summary-label">{{icon "server"}}Environment</span>
47 {{if .Run.OS}}<strong>{{.Run.OS}}/{{.Run.Arch}}</strong>{{else}}<strong class="muted">not reported</strong>{{end}}
48 <span class="status-note">{{if .Run.Image}}<code>{{if .Run.ImageFile}}{{.Run.ImageFile}}{{else}}{{.Run.Image}}{{end}}</code>{{if .Run.Runtime}} via {{.Run.Runtime}}{{end}}{{else}}no image recorded{{end}}</span>
49 </div>
50 <div class="card">
51 <span class="run-summary-label">{{icon "git-commit-horizontal"}}Commit</span>
52 <strong><a class="sha" href="/r/{{.Name}}/commit/{{.Run.SHA}}">{{short .Run.SHA}}</a></strong>
53 <span class="status-note">{{if .Run.Tag}}tag {{.Run.Tag}}{{else}}branch {{.Run.Branch}}{{end}}{{if eq .Run.Status "failed"}} · exit {{.Run.ExitCode}}{{end}}</span>
54 </div>
55 </div>
56
27 57 {{if .Run.OS}}<p class="muted">ran on {{.Run.OS}}/{{.Run.Arch}}{{if .Run.Image}} · in {{if .Run.ImageFile}}image-file <code>{{.Run.ImageFile}}</code> ({{short .Run.ImageSHA}}){{else}}<code>{{.Run.Image}}</code>{{end}} via {{.Run.Runtime}}{{end}}</p>{{end}}
28 58 {{if .Attestation}}<p class="muted">reported by <strong>{{.Signer}}</strong>{{if .Attestation.CommitID}} · <a href="/r/{{.Name}}/commit/{{.Attestation.CommitID}}">the commit that records it</a>{{end}} · the instance accepted this from that account's key at the push boundary, and logged it</p>{{end}}
29 59 {{if .Counts}}<p class="muted">counts as a check for this repository</p>{{else if .CountsWhy}}<p class="muted">does not count as a check: {{.CountsWhy}}</p>{{end}}
30 {{if .HasLog}}<p><a href="/r/{{.Name}}/runs/{{.Run.ID}}/log">log</a>{{if gt (len .Logs) 1}} · by attempt:
31 {{range .Logs}}<a href="/r/{{$.Name}}/runs/{{$.Run.ID}}/log?attempt={{.Attempt}}">{{.Attempt}}</a> {{end}}{{end}}</p>{{end}}
32 60
33 <h2>Artifacts</h2>
61 <h2>{{icon "list"}}Steps</h2>
62 {{if .Steps}}
63 <div class="panel run-steps">
64 <table>
65 <thead>
66 <tr><th>#</th><th>Step</th><th>Result</th><th>Duration</th><th>Log</th></tr>
67 </thead>
68 <tbody>
69 {{range .Steps}}
70 <tr>
71 <td class="fit muted">{{.Number}}</td>
72 <td>{{.Name}}</td>
73 <td class="fit"><span class="status {{.Status}}">{{.Label}}</span></td>
74 <td class="nowrap">{{if .Duration}}{{duration .Duration}}{{else}}<span class="muted">—</span>{{end}}</td>
75 <td>{{if .LogURL}}<a href="{{.LogURL}}">open</a>{{else}}<span class="muted">—</span>{{end}}</td>
76 </tr>
77 {{if .LogURL}}
78 <tr class="run-step-log">
79 <td></td>
80 <td colspan="4">
81 <details class="run-log" hx-get="{{.LogURL}}" hx-trigger="toggle once" hx-target="find pre" hx-swap="textContent">
82 <summary>{{icon "terminal"}}Show step log</summary>
83 <pre class="run-log-text"></pre>
84 </details>
85 </td>
86 </tr>
87 {{end}}
88 {{end}}
89 </tbody>
90 </table>
91 </div>
92 {{else}}
93 <p class="muted">This run has no steps recorded.</p>
94 {{end}}
95
96 <h2>{{icon "terminal"}}Logs</h2>
97 {{if .HasLog}}
98 <div class="run-logbar">
99 <span class="muted">{{bytes .LogBytes}} archived log{{if gt (len .Logs) 1}} · {{len .Logs}} attempts{{end}}</span>
100 <a href="/r/{{.Name}}/runs/{{.Run.ID}}/log">Open full log</a>
101 {{if gt (len .Logs) 1}}{{range .Logs}}<a class="chip" href="/r/{{$.Name}}/runs/{{$.Run.ID}}/log?attempt={{.Attempt}}">{{icon "file"}}attempt {{.Attempt}}</a> {{end}}{{end}}
102 </div>
103 <details class="run-log" hx-get="/r/{{.Name}}/runs/{{.Run.ID}}/log" hx-trigger="toggle once" hx-target="find pre" hx-swap="textContent">
104 <summary>{{icon "terminal"}}Show the full job log</summary>
105 <pre class="run-log-text"></pre>
106 </details>
107 {{else}}
108 <p class="muted">No log was archived for this run.</p>
109 {{end}}
110
111 <h2>{{icon "hard-drive"}}Artifacts</h2>
34 112 {{if .Artifacts}}
35 113 <table>
36 114 <tr><th>File</th><th>Size</th><th>SHA-256</th><th></th></tr>