{% extends "base.html" %} {% import "repo_tabs.html" as m %} {% block title %}Run #{{ run.number }} · Flow · {{ repo.owner }}/{{ repo.name }}{% endblock %} {% block bodyattrs %} data-repo="{{ repo.url }}"{% if run.live() %} data-flow-live="{{ repo.url }}/flow/{{ run.number }}/live"{% endif %}{% endblock %} {% block tabs %}{% call m::tabs(repo, "flow") %}{% endblock %} {% block mainclass %} class="wide"{% endblock %} {% block content %}
{% if run.bookmark.is_empty() %}change{% else %}{{ run.bookmark }}{% endif %} at {{ run.state|short }} · {{ run.started_by() }} · {{ duration }}{% if !run.pipeline_hash.is_empty() %} · pipeline {{ run.pipeline_hash|short }}{% endif %} · .flow/pipeline.kdl · all runs
{{ run.priority }} {{ run.priority_note }}
{% endif %} {% if can_expedite %}{% endif %} {% if can_cancel %}{% endif %}{{ run.error }}Run flow check locally to see the same problems.
It takes an approval signed with your own key. In a checkout of {{ repo.owner }}/{{ repo.name }}:
{% endif %} {% if a.may_decide() %} {% else %}{{ a.why_not() }}{% endif %} {% else if a.state == "approved" %}approved by {{ a.who }} {% if !a.seal.is_empty() %}, ◈ sealed with their key (approval{{ a.seal|short }}){% else if a.sealed %}{% endif %}.
{% else if a.state == "rejected" %}rejected by {{ a.who }} .
{% else %}not approved in time.{% endif %}{{ l.j.receipt_hash|short }}{% endif %}{% if !l.artifacts.is_empty() %} · {{ l.artifacts.len()|plural("artifact", "artifacts") }}{% endif %}{% if let Some(t) = l.tests %} · {{ t.summary() }}{% endif %}{% if let Some((cid, pct)) = l.coverage %} · coverage {{ pct }}{% endif %}{{ a.blob|short }}{% if l.j.status != "passed" %} · from a job that did not pass, not in its receipt{% endif %}{% if !releases.is_empty() && l.j.status == "passed" %} {% endif %}{{ t.passed }} passed{% if t.failed > 0 %} · {{ t.failed }} failed{% endif %}{% if t.errors > 0 %} · {{ t.errors }} errored{% endif %}{% if t.skipped > 0 %} · {{ t.skipped }} skipped{% endif %} · {{ crate::flow::human_ms(*t.time_ms) }} of test time
{% for f in l.failures %}{{ f.title() }}{% if !f.message.is_empty() %} {{ f.message }}{% endif %}{{ f.output }}{% endif %}
and {{ t.broken() - l.failures.len() as i64 }} more failures; the junit artifact has them all.
{% endif %}{% for seg in l.segments %}{% match seg %}{% when crate::web::flow::Segment::Line(line) %}{{ crate::web::flow::secs(line.t) }}{{ line.text }}
{% when crate::web::flow::Segment::Group(g) %}{{ crate::web::flow::secs(g.from_t) }}{{ g.title }}{% if let Some(e) = g.to_t %} {{ crate::web::flow::secs(e - g.from_t) }}{% endif %}
{% for line in g.lines %}{{ crate::web::flow::secs(line.t) }}{{ line.text }}
{% endfor %}{% endmatch %}{% endfor %}
{% if !l.j.placed.is_empty() %}Ran on {{ l.j.runner }}: {{ l.j.placed }}.
{% endif %} {% if l.j.status == "passed" %}{% if let Some(n) = l.j.reused_from() %}Not run again: this job, with the same spec and sandbox, passed on this very state in run #{{ n }}, whose log it would repeat; that pass's receipt stands for it here.
{% endif %}{% endif %} {% if l.j.status == "queued" && !l.j.waiting.is_empty() %}Waiting: {{ l.j.waiting }}.
{% else if l.lines.is_empty() && l.j.status == "queued" %}Waiting for a runner{% if !l.j.depends_on().is_empty() %} and for {{ l.j.depends_on().join(", ") }}{% endif %}.
{% endif %} {% if l.lines.is_empty() && l.j.status == "skipped" %}Skipped: a job it depends on did not pass.
{% endif %}