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}}