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

{{ crate::web::flow::glyph(run.status) }} Run #{{ run.number }} {{ run.status }}

{% 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

{% if can_rerun %}
{% endif %} {% if can_cancel %}
{% endif %}
{% if let Some(q) = queue %}
Waiting for a runner: {{ q.place().unwrap_or_default() }}.{% if !q.running.is_empty() %} Running now: {{ q.running.join(", ") }}.{% endif %}{% if !q.ahead.is_empty() %} Queued ahead: {{ q.ahead.join(", ") }}.{% endif %}{% if q.hidden > 0 %} Also ahead or running: {{ q.hidden }} job{% if q.hidden != 1 %}s{% endif %} in private repositories.{% endif %}
{% endif %} {% if run.status == "error" %}
The pipeline is not valid, so nothing ran.
{{ run.error }}

Run flow check locally to see the same problems.

{% else %}
{% for e in graph.edges %}{% endfor %} {% for n in graph.nodes %} {{ crate::web::flow::glyph(n.j.status) }} {{ n.j.name }} {{ n.j.status }} · {{ n.duration }} {% endfor %}
{% for l in logs %}
{{ crate::web::flow::glyph(l.j.status) }} {{ l.j.name }} {{ l.j.status }}{% if let Some(c) = l.j.exit_code %} · exit {{ c }}{% endif %} · {{ l.duration }}{% if !l.j.runner.is_empty() %} · on {{ l.j.runner }}{% endif %}{% if !l.j.receipt_attest.is_empty() %} · signed receipt by {{ l.j.receipt_signer }}{% else if !l.j.receipt_note.is_empty() %} · receipt not kept: {{ l.j.receipt_note }}{% else if !l.j.receipt_hash.is_empty() %} · unsigned receipt {{ 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 %} {% if !l.j.error.is_empty() %}
{{ l.j.error }}
{% endif %} {% if !l.artifacts.is_empty() %}{% endif %} {% if let Some(t) = l.tests %}

{{ 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 %}
{% if f.status == "error" %}!{% else %}✕{% endif %} {{ f.title() }}{% if !f.message.is_empty() %} {{ f.message }}{% endif %} {% if !f.output.is_empty() %}
{{ f.output }}
{% endif %}
{% endfor %} {% if t.broken() > l.failures.len() as i64 %}

and {{ t.broken() - l.failures.len() as i64 }} more failures; the junit artifact has them all.

{% endif %}
{% endif %}
{% for line in l.lines %}{{ line.t / 1000 }}.{{ "{:01}"|format(line.t % 1000 / 100) }}s{{ line.text }}
{% endfor %}
{% if !l.j.placed.is_empty() %}

Ran on {{ l.j.runner }}: {{ l.j.placed }}.

{% 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 %}
{% endfor %} {% endif %} {% endblock %}