go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/milo/frontend/templates/pages/build.html (about) 1 {{define "title"}} 2 {{ .BuildPage.HumanStatus}} 3 - 4 {{ with .BuildPage.Build -}} 5 {{ with .Builder }}{{ .Builder }}{{ end }} 6 {{ if .Number }}{{ .Number }}{{ else }}{{ .Id }}{{ end }} 7 {{- end }} 8 {{end}} 9 10 {{define "head"}} 11 <link rel="stylesheet" href="/static/common/css/timeline.css" type="text/css"> 12 <link rel="stylesheet" href="/static/common/css/tabs.css" type="text/css"> 13 <link rel="stylesheet" href="/static/common/css/build.css" type="text/css"> 14 <script> 15 const timelineData = JSON.parse({{ .BuildPage.Timeline }}); 16 const useTabs = true; 17 // If true, the blamelist tab contains the blamelist. 18 // If false, the blamelist tab should reload the page to force the blamelist to load. 19 const blamelistLoaded = {{ if .BuildPage.BlamelistError }}false{{ else }}true{{ end }}; 20 const buildbucketId = '{{ .BuildPage.Id }}'; 21 </script> 22 <script type="text/javascript" src="https://www.gstatic.com/feedback/js/help/prod/service/lazy.min.js"></script> 23 <script src="/static/common/js/build.js"></script> 24 {{end}} 25 26 {{define "interval"}} 27 {{ if .Started }} 28 <span class="duration" 29 data-starttime="{{ .Start | formatTime }}" 30 {{ if .Ended -}} 31 data-endtime="{{ .End | formatTime }}" 32 {{- end }}> 33 ( {{ .Duration | humanDuration }} )</span> 34 {{ end }} 35 {{end}} 36 37 {{define "favicon"}} 38 <link id="favicon" rel="shortcut icon" type="image/png" href="/static/common/favicon/ 39 {{- with .BuildPage.Status.String -}} 40 {{- if eq . "STARTED" -}} yellow 41 {{- else if eq . "SUCCESS" -}} green 42 {{- else if eq . "INFRA_FAILURE" -}} purple 43 {{- else if eq . "FAILURE" -}} red 44 {{- else if eq . "CANCELED" -}} brown 45 {{- else if eq . "SCHEDULED" -}} gray 46 {{- else -}} milo 47 {{- end -}} 48 {{- end -}}-32.png"> 49 50 {{end}} 51 52 {{define "step"}} 53 <li class="{{ if eq .Step.Status.String "SUCCESS" }}green{{ end }} 54 {{- if .Children }} substeps 55 {{- if .Collapsed }} collapsed{{ end }} 56 {{- end }}"> 57 <div class="status {{.Step.Status}} result"> 58 {{ template "interval" .Interval }} 59 <b>{{.ShortName}}</b> 60 <span class="summary-markdown"> 61 {{ .Step.SummaryMarkdown | renderMarkdown }} 62 </span> 63 </div> 64 <ul> 65 {{ range .Logs }} 66 <li class="sublink{{ if startswith .Name "$" }} debug-log{{ end }}"> 67 <a href="{{ .ViewUrl }}">{{ .Name }}</a> 68 {{- if eq .Name "stdout" "stderr" }} 69 [{{ logdogLink . true }}] 70 {{- end }} 71 </li> 72 {{ else }} 73 {{ if not .Children }} 74 <li class="sublink"> - no logs - </li> 75 {{ end }} 76 {{ end }} 77 </ul> 78 {{ if .Children }} 79 <ol> 80 {{ range .Children }} 81 {{ template "step" . }} 82 {{ end }} 83 </ol> 84 {{ end }} 85 </li> 86 {{ end }} 87 88 {{define "body"}} 89 {{ template "overlay" .}} 90 <div class="content"> 91 <h1> 92 {{ with .BuildPage.BuilderLink }} 93 Builder {{ .HTML }} 94 {{ end }} 95 Build {{ .BuildPage.Link.HTML }} 96 {{ range .BuildPage.Banners }} 97 <img src="/static/common/logos/{{.Img}}" alt="{{.Alt}}" width="25px"> 98 {{ end }} 99 100 </h1> 101 102 {{ if .BuildPage.Build.ShouldShowCanaryWarning }} 103 <div class="canary-warning"> 104 WARNING: This build ran on a canary version of LUCI. If you suspect it 105 failed due to infra, retry the build. Next time it may use the 106 non-canary version. 107 </div> 108 {{ end }} 109 110 <div id="tabs" style="display: none"> 111 <ul> 112 <li><a href="#overview-tab">Overview</a></li> 113 <li><a href="#related-tab">Related Builds</a></li> 114 <li><a href="#timeline-tab">Timeline</a></li> 115 <li><a href="#blamelist-tab">Blamelist</a></li> 116 </ul> 117 <div id="overview-tab"> 118 {{ template "overview" . }} 119 {{ template "attributes" . }} 120 </div> 121 <div id="timeline-tab" style="display: none;">{{ template "timeline_tab" . }}</div> 122 <div id="related-tab" style="display: none;">{{ template "related_tab" .BuildPage }}</div> 123 <div id="blamelist-tab" style="display: none;">{{ template "blamelist_tab" . }}</div> 124 </div> 125 </div> 126 {{end}} 127 128 {{define "overlay"}} 129 <div id="modal-overlay"> 130 <div id="retry-build-modal" class="modal-content"> 131 <h1>Retry Build</h1> 132 <p>Note: this doesn't trigger anything else (e.g. CQ).</p> 133 <form id="retry-build-form" action="/actions/retry_build" method="POST" style="overflow: auto;"> 134 {{ .XsrfTokenField }} 135 <input name="buildbucket-id" type="hidden" value="{{.BuildPage.Id}}"> 136 <input name="retry-request-id" type="hidden" value="{{.RetryRequestID}}"> 137 <div style="float: right; margin: 0;"> 138 <input id="dismiss-retry-build-button" type="button" value="Dismiss"> 139 <input type="submit" value="Confirm"> 140 </div> 141 </form> 142 </div> 143 <div id="cancel-build-modal" class="modal-content"> 144 <h1>Cancel Build</h1> 145 <form id="cancel-build-form" action="/actions/cancel_build" method="POST" style="overflow: auto;"> 146 {{ .XsrfTokenField }} 147 <input name="buildbucket-id" type="hidden" value="{{.BuildPage.Id}}"> 148 Reason:<br/> 149 <textarea name="reason" form="cancel-build-form" required style="width: 100%; box-sizing: border-box; resize: none;"></textarea><br> 150 <div style="float: right; margin: 0;"> 151 <input id="dismiss-cancel-build-button" type="button" value="Dismiss"> 152 <input type="submit" value="Confirm"> 153 </div> 154 </form> 155 </div> 156 </div> 157 {{end}} 158 159 {{define "overview"}} 160 <div id="overview" class="column"> 161 {{ range .BuildPage.Errors }} 162 <p class="errors status FAILURE">Error while rendering page: {{.}}</p> 163 {{ end }} 164 <h2>Overview</h2> 165 <div class="result status {{.BuildPage.Status}}"> 166 <div class="main-status">{{ .BuildPage.HumanStatus }}{{ if eq .BuildPage.Status.String "CANCELED" }} (by {{ or .BuildPage.CanceledBy "UNKNOWN"}}){{ end }}</div> 167 {{ with .BuildPage.SummaryMarkdown }} 168 {{ . | renderMarkdown }} 169 {{ end }} 170 </div> 171 172 <h2>Actions</h2> 173 <input id="retry-build-button" type="button" value="Retry Build" 174 {{if not .BuildPage.EndTime}} disabled title="this build is still running" 175 {{else if not .BuildPage.CanRetry}} disabled title="unauthorized to retry the build" 176 {{end}} 177 > 178 <input id="cancel-build-button" type="button" value="Cancel Build" 179 {{if .BuildPage.EndTime}} disabled title="this build has already ended" 180 {{else if not .BuildPage.CanCancel}} disabled title="unauthorized to cancel the build" 181 {{end}} 182 > 183 <br> 184 185 {{ with .BuildPage.Input }} 186 <h2>Input</h2> 187 <table> 188 {{ with .GitilesCommit }} 189 <tr> 190 <td class="left">Revision</td> 191 <td><a href="https://{{ .Host }}/{{ .Project }}/+/{{ .Id }}">{{ .Id }}</a> 192 {{ with .Position }}(CP #{{ . }}){{ end }} 193 </td> 194 </tr> 195 {{ end }} 196 197 {{ range .GerritChanges }} 198 <tr> 199 <td class="left">Patch</td> 200 <td> 201 <a href="https://{{ .Host }}/c/{{ .Change }}/{{ .Patchset }}"> 202 {{ .Change }} (ps #{{ .Patchset }}) 203 </a> 204 </td> 205 </tr> 206 {{ end }} 207 </table> 208 {{ end }} 209 210 <h2>Infra</h2> 211 <ul> 212 <li>Buildbucket ID: {{ .BuildPage.BuildbucketLink.HTML }}</li> 213 214 {{ with .BuildPage.Infra }} 215 {{ with .Swarming }} 216 <li> 217 Swarming Task: 218 {{ if .TaskId }} 219 <a href="https://{{ .Hostname }}/task?id={{ .TaskId }}&o=true&w=true"> 220 {{ .TaskId }} 221 </a> 222 {{ else }} 223 N/A 224 {{ end }} 225 </li> 226 <li>Bot: {{ . | botLink }}</li> 227 {{ end }} 228 {{ end }} 229 <li> 230 Recipe: {{ .BuildPage.RecipeLink.HTML }} 231 </li> 232 </ul> 233 234 <h2>Timing</h2> 235 <table class="info" width="100%"> 236 <tr class="alt"> 237 <td class="left">Create</td> 238 <td>{{ .BuildPage.CreateTime | toTime | localTime "N/A" }}</td> 239 </tr> 240 <tr> 241 <td class="left">Start</td> 242 <td>{{ .BuildPage.StartTime | toTime | localTime "N/A" }}</td> 243 </tr> 244 <tr class="alt"> 245 <td class="left">End</td> 246 <td>{{ .BuildPage.EndTime | toTime | localTime "N/A" }}</td> 247 </tr> 248 <tr> 249 <td class="left">Pending</td> 250 <td id="duration">{{ duration .BuildPage.CreateTime .BuildPage.StartTime .BuildPage.EndTime .BuildPage.Now }}</td> 251 </tr> 252 <tr class="alt"> 253 <td class="left">Execution</td> 254 <td id="duration">{{ duration .BuildPage.StartTime .BuildPage.EndTime .BuildPage.Now }}</td> 255 </tr> 256 </table> 257 258 {{ with .BuildPage.GetOutput.GetLogs }} 259 <h2>Build Logs</h2> 260 <ul> 261 {{ range . }} 262 <li> 263 <a href="{{ .ViewUrl }}">{{ .Name }}</a> 264 {{- if eq .Name "stdout" "stderr" }} 265 [{{ logdogLink . true }}] 266 {{- end }} 267 </li> 268 {{ end }} 269 </ul> 270 {{ end }} 271 272 <h2>Build Steps</h2> 273 Show: 274 <input type="radio" name="hider" id="showExpanded" value="expanded" 275 {{- if eq .BuildPage.StepDisplayPref "expanded" }} checked{{ end }}> 276 <label for="showExpanded">Expanded</label> 277 <input type="radio" name="hider" id="showDefault" value="default" 278 {{- if eq .BuildPage.StepDisplayPref "default" }} checked{{ end }}> 279 <label for="showDefault">Default</label> 280 <input type="radio" name="hider" id="showNonGreen" value="non-green" 281 {{- if eq .BuildPage.StepDisplayPref "non-green" }} checked{{ end }}> 282 <label for="showNonGreen">Non-Green</label> 283 284 <br/> 285 Debug Logs: 286 <input type="checkbox" name="debug_hider" id="showDebugLogs" 287 {{- if .BuildPage.ShowDebugLogsPref }} checked{{ end }}> 288 289 <ol id="steps" class=" 290 {{- if eq .BuildPage.StepDisplayPref "non-green" }} non-green{{ end -}} 291 {{- if not .BuildPage.ShowDebugLogsPref }} hide-debug-logs{{ end -}} 292 "> 293 {{ range .BuildPage.Steps }} 294 {{ template "step" . }} 295 {{ end }} 296 </ol> 297 </div> 298 {{end}} 299 300 {{define "related_tab"}} 301 {{ $now := .Now }} 302 <h2>Related Builds</h2> 303 {{ if .BuildSets }} 304 <h3>Other builds with the same buildsets:</h3> 305 {{ range .BuildSetLinks }} 306 <li>{{ . }}</li> 307 {{ end }} 308 <div id="related-builds-table-container">Rendering...</div> 309 {{ else }} 310 <h3>No buildsets found</h3> 311 {{ end }} 312 {{end}} 313 314 {{define "attributes"}} 315 <div id="attributes" class="column"> 316 <h2>Tags</h2>{{ template "tags_table" .BuildPage.GetTags }} 317 <h2>Input Properties</h2>{{ template "properties_table" .BuildPage.InputProperties }} 318 <h2>Output Properties</h2>{{ template "properties_table" .BuildPage.OutputProperties }} 319 </div> 320 {{end}} 321 322 <!--- Note: Properties have "Names" and Tags have "Keys". 323 This is the standard nomenclature stemming from 324 Buildbot Properties and Swarming Tags. 325 We will preserve this nomenclature in the UI.--> 326 {{define "properties_table"}} 327 {{ with . }} 328 <table class="info BuildProperties" width="100%"> 329 <tr><th>Name</th><th>Value</th></tr> 330 {{ range . }} 331 <tr> 332 <td class="left">{{.Name}}</td> 333 <td class="middle"><abbr title="{{.Value}}">{{.Value | trimLong 1024}}</abbr></td> 334 </tr> 335 {{ end }} 336 </table> 337 {{ else }} 338 <div>N/A</div> 339 {{ end }} 340 {{end}} 341 342 {{define "tags_table"}} 343 {{ with . }} 344 <table class="info BuildTags" width="100%"> 345 <tr><th>Key</th><th>Value</th></tr> 346 {{ range . }} 347 <tr> 348 <td class="left">{{.Key}}</td> 349 <td class="middle">{{.Value}}</td> 350 </tr> 351 {{ end }} 352 </table> 353 {{ else }} 354 <div>N/A</div> 355 {{ end }} 356 {{end}} 357 358 {{define "blamelist_tab"}} 359 <div id="changes" class="column"> 360 {{ if .BuildPage.Blame }} 361 {{ with .BuildPage.BlamelistError }} 362 <div class="errors failure"> 363 Got an error while loading blamelist, showing partial results.<br> 364 Error: {{ . }} 365 </div> 366 {{ end }} 367 <ol> 368 {{ range .BuildPage.Blame }} 369 <li> 370 <h3>{{.Title}}</h3> 371 <table class="info"> 372 <tbody> 373 <tr> 374 <td class="left">Changed by</td> 375 <td class="value"> 376 {{ if .AuthorName }}{{ .AuthorName }} - {{ end }} 377 {{ .AuthorEmail | obfuscateEmail }} 378 </td> 379 </tr> 380 <tr> 381 <td class="left">Changed at</td> 382 <td class="value">{{ .CommitTime | localTime "N/A" }}</td> 383 </tr> 384 <tr> 385 <td class="left">Repository</td> 386 <td class="value">{{ .Repo }}</td> 387 </tr> 388 <tr> 389 <td class="left">Branch</td> 390 <td class="value">{{ .Branch }}</td> 391 </tr> 392 {{ with .Revision }} 393 <tr> 394 <td class="left">Revision</td> 395 <td class="value">{{ .HTML }}</td> 396 </tr> 397 {{ end }} 398 </tbody> 399 </table> 400 401 {{ if .Description }} 402 <h3>Comments</h3> 403 <pre class="comments">{{ .Description | formatCommitDesc }}</pre> 404 {{ end }} 405 406 {{ if .File }} 407 <h3 class="files">Changed files</h3> 408 <ul class="alternating"> 409 {{ range .File }} 410 <li class="file">{{ . }}</li> 411 {{ end }} 412 </ul> 413 {{ end }} 414 415 </li> 416 {{ end }} <!-- range .Build.Blame --> 417 </ol> 418 {{ else if .BuildPage.BlamelistError }} 419 {{ if .BuildPage.ForcedBlamelist }} 420 <div class="errors failure"> 421 Error while loading blamelist:<br>{{ .BuildPage.BlamelistError }} 422 </div> 423 {{ else }} 424 Loading blamelist... (<a title="{{ .BuildPage.BlamelistError }}">why?</a>) 425 {{ end }} 426 {{ else }} 427 No Blamelist 428 {{ end }} <!-- if .Build.Blame --> 429 </div> 430 {{end}} 431 432 {{define "timeline_tab"}} 433 <div id="timeline"> 434 <div id="timeline-rendering">Rendering...</div> 435 </div> 436 {{end}}