| 1 |
{% extends "base.html" %} |
| 2 |
{% import "repo_tabs.html" as m %} |
| 3 |
{% block title %}Trust · {{ t.tag }} · {{ repo.owner }}/{{ repo.name }}{% endblock %} |
| 4 |
{% block bodyattrs %} data-repo="{{ repo.url }}"{% endblock %} |
| 5 |
{% block tabs %}{% call m::tabs(repo, "releases") %}{% endblock %} |
| 6 |
{% block mainclass %} class="wide"{% endblock %} |
| 7 |
{% block content %} |
| 8 |
<div class="head"><h1>Trust <small>release <a href="{{ repo.url }}/releases/tag/{{ t.tag }}">{{ t.tag }}</a>{% if !t.title.is_empty() %} · {{ t.title }}{% endif %}</small></h1> |
| 9 |
<a class="go small" href="?format=json" download>Export JSON</a></div> |
| 10 |
<p class="small mute">Who wrote what this release holds, how it is authenticated, what built each asset and from what, with every claim audited below.{% if let Some(p) = t.since %} Changes are counted since the previous release, {{ p }}.{% endif %} The export carries the signed receipts: check each with <code>oxy receipt verify</code>.</p> |
| 11 |
|
| 12 |
<ul class="plain trust-summary">{% for b in t.summary() %}<li class="tb tb-{{ b.class }}"><span class="tb-mark" aria-hidden="true">{% if b.class == "pass" %}<svg viewBox="0 0 16 16" width="14" height="14"><path d="M5 7V5a3 3 0 0 1 6 0v2" fill="none" stroke="currentColor" stroke-width="1.6"/><rect x="3.5" y="7" width="9" height="7" rx="1.5" fill="currentColor"/></svg>{% else if b.class == "warn" %}!{% else %}✘{% endif %}</span>{{ b.text }}</li>{% endfor %}</ul> |
| 13 |
|
| 14 |
<section class="panel audit audit-{{ t.verdict_class() }}"> |
| 15 |
<h2>Audit <span class="small mute">{{ t.audit.len()|plural("check", "checks") }}</span></h2> |
| 16 |
<ul class="plain checks">{% for c in t.audit %}<li class="{{ c.class() }}"><span class="glyph">{{ c.glyph() }}</span> <strong>{{ c.title }}</strong>{% if !c.detail.is_empty() %} <span class="small mute">{{ c.detail }}</span>{% endif %}</li>{% endfor %}</ul> |
| 17 |
</section> |
| 18 |
|
| 19 |
<section class="panel"> |
| 20 |
<h2>Graph</h2> |
| 21 |
<p class="small mute">Authors → the tagged state → the jobs that built the assets → the assets. A lock marks what is signed and checked, <strong>!</strong> what is not (unsigned, or uploaded by hand), <strong>✘</strong> what fails. A dashed line is a build from another state than the tag's. Hover a box for the details.</p> |
| 22 |
<div class="trust-graph-wrap">{{ graph|safe }}</div> |
| 23 |
</section> |
| 24 |
|
| 25 |
<section class="panel"> |
| 26 |
<h2>Tag <span class="lbl lbl-tag">{{ t.tag }}</span></h2> |
| 27 |
<dl class="facts"> |
| 28 |
<dt>Signature</dt><dd>{% if t.tag_signature == "valid" %}<span class="sig sig-valid">✔</span> valid{% else if t.tag_signature == "unsigned" %}<span class="sig sig-unsigned">○</span> unsigned{% else %}<span class="sig sig-invalid">✘</span> {{ t.tag_signature }}{% endif %}{% if let Some(k) = t.tag_signer %} · {% if let Some(a) = k.account %}<a href="/{{ a }}">{{ k.name }}</a>{% else %}{{ k.name }}{% endif %} <code title="{{ k.key }}">{{ k.key|short }}</code>{% endif %}</dd> |
| 29 |
<dt>State</dt><dd>{% for h in t.heads %}<a class="chip" href="{{ repo.url }}/change/{{ h }}">{{ h|short }}</a> {% endfor %}</dd> |
| 30 |
</dl> |
| 31 |
</section> |
| 32 |
|
| 33 |
<section class="panel"> |
| 34 |
<h2>Authors <span class="small mute">{{ t.changes|plural("change", "changes") }}</span></h2> |
| 35 |
<div class="table"><table> |
| 36 |
<tr><th>Author</th><th>Key</th><th>Changes</th><th>Signed</th><th>Sealed</th><th>Unsigned</th><th>Problems</th></tr> |
| 37 |
{% for a in t.authors %}<tr><td>{% if let Some(acc) = a.who.account %}<a href="/{{ acc }}">{{ a.who.name }}</a>{% else %}{{ a.who.name }}{% endif %}</td><td><code title="{{ a.who.key }}">{{ a.who.key|short }}</code></td><td>{{ a.changes }}</td><td>{{ a.signed }}</td><td>{{ a.sealed }}</td><td>{% if a.unsigned > 0 %}<span class="warn">{{ a.unsigned }}</span>{% else %}0{% endif %}</td><td>{% if a.invalid + a.revoked > 0 %}<span class="bad">{{ a.invalid }} invalid, {{ a.revoked }} revoked</span>{% else %}none{% endif %}</td></tr>{% endfor %} |
| 38 |
</table></div> |
| 39 |
</section> |
| 40 |
|
| 41 |
<section class="panel"> |
| 42 |
<h2>Assets</h2> |
| 43 |
{% if t.assets.is_empty() %}<p class="mute">This release has no assets.</p>{% endif %} |
| 44 |
{% for a in t.assets %} |
| 45 |
<h3><a href="{{ a.url }}">{{ a.name }}</a> {% if let Some(b) = a.build %}{% if b.receipt.is_some() && b.receipt_problem.is_none() %}<span class="tb tb-pass tb-sm">attested build</span>{% else %}<span class="tb tb-warn tb-sm">built, not attested</span>{% endif %}{% else %}<span class="tb tb-warn tb-sm">uploaded by hand</span>{% endif %} <span class="small mute">{{ a.size|bytes }} · blake3 <code title="{{ a.blake3 }}">{{ a.blake3|short }}</code></span></h3> |
| 46 |
{% if let Some(b) = a.build %} |
| 47 |
<dl class="facts"> |
| 48 |
<dt>Built by</dt><dd><a href="{{ b.run_url }}">run #{{ b.run }}</a> job <strong>{{ b.job }}</strong>{% if let Some(c) = b.exit_code %}, exit {{ c }}{% endif %}</dd> |
| 49 |
<dt>Runner</dt><dd>{% if let Some(r) = b.runner %}{{ r.name }} <code title="{{ r.key }}">{{ r.key|short }}</code>{% if b.runner_known %} <span class="tag">runner key of this hub</span>{% endif %}{% if b.runner_revoked %} <span class="tag bad">revoked</span>{% endif %}{% else %}<span class="mute">no signed receipt</span>{% endif %}</dd> |
| 50 |
<dt>Receipt</dt><dd>{% if let Some(u) = b.receipt_url %}<a href="{{ u }}">signed receipt</a>{% if let Some(p) = b.receipt_problem %} <span class="bad">{{ p }}</span>{% else %} <span class="sig sig-valid">✔</span> verifies{% endif %}{% else %}<span class="mute">none kept</span>{% endif %}</dd> |
| 51 |
<dt>Environment</dt><dd>{{ b.runtime }} · rootfs <code title="{{ b.rootfs }}">{{ b.rootfs|short }}</code> · environment <code title="{{ b.environment }}">{{ b.environment|short }}</code></dd> |
| 52 |
<dt>Inputs</dt><dd>state {% for h in b.heads.split('+') %}<a class="chip" href="{{ repo.url }}/change/{{ h }}">{{ h|short }}</a> {% endfor %}{% if b.same_state_as_tag %}<span class="tag">the tagged state</span>{% else %}<span class="tag warn">not the tagged state</span>{% endif %} · pipeline <code title="{{ b.pipeline_hash }}">{{ b.pipeline_hash|short }}</code> · scope <code title="{{ b.scope_tree_hash }}">{{ b.scope_tree_hash|short }}</code></dd> |
| 53 |
</dl> |
| 54 |
{% else %} |
| 55 |
<p class="small warn">No passed OxygenFlow job of this repository produced these bytes: uploaded by hand.</p> |
| 56 |
{% endif %} |
| 57 |
{% endfor %} |
| 58 |
</section> |
| 59 |
{% endblock %} |