{% extends "base.html.jinja" %} {% from "components/timestamp.html.jinja" import timeago as ts %} {% block content %} {# ── Breadcrumb + heading ──────────────────────────────────── #} {{ project_name }} / Releases {# Status dot #} {% if summary_status == "RUNNING" %} {% elif summary_status == "QUEUED" %} {% elif summary_status == "FAILED" %} {% elif summary_status == "SUCCEEDED" %} {% elif summary_status == "TIMED_OUT" %} {% elif summary_status == "CANCELLED" %} {% else %} {% endif %} {% if artifact.commit_message %}{{ artifact.commit_message }}{% else %}{{ artifact.title }}{% endif %} {% if artifact.version %} {{ artifact.version }} {% endif %} {{ artifact.slug }} {# ── Metadata pills ────────────────────────────────────── #} {% if artifact.branch %} {{ artifact.branch }} {% endif %} {% if artifact.commit_sha %} {{ artifact.commit_sha[:8] }} {% endif %} {% if artifact.source_type %} {% if 'github' in artifact.source_type %} {% elif 'gitlab' in artifact.source_type %} {% else %} {% endif %} {{ artifact.source_type | replace("_", " ") | replace("-", " ") }} {% endif %} {% if artifact.source_user %} {{ artifact.source_user }} {% endif %} {{ ts(artifact.created_at) }} {% if artifact.description and not artifact.description is startingwith("Branch:") %} {{ artifact.description }} {% endif %} {# ── Deploy action ─────────────────────────────────────────── #} {% if is_admin %} Deploy this release {% if has_active_pipeline %} Use pipeline (follows the configured multi-stage deployment pipeline) {% endif %} Target environment All environments (pipeline decides) {% for env in environments %} {{ env.name }} {% endfor %} Leave empty when using a pipeline — it will deploy to all configured stages. Deploy {% endif %} {# ── Pipeline stages ───────────────────────────────────────── #} {% if has_pipeline and pipeline_stages | length > 0 %} Pipeline {% for stage in pipeline_stages %} {# Status icon #} {% if stage.status == "SUCCEEDED" %} {% elif stage.status == "RUNNING" %} {% elif stage.status == "QUEUED" %} {% elif stage.status == "FAILED" %} {% elif stage.status == "AWAITING_APPROVAL" or (stage.stage_type == "plan" and (stage.approval_status == "AWAITINGAPPROVAL" or stage.approval_status == "AWAITING_APPROVAL")) %} {% else %} {% endif %} {# Stage label #} {% if stage.stage_type == "deploy" %} {% if stage.status == "SUCCEEDED" %}Deployed to{% elif stage.status == "RUNNING" %}Deploying to{% elif stage.status == "QUEUED" %}Queued for{% elif stage.status == "FAILED" %}Failed on{% elif stage.status == "TIMED_OUT" %}Timed out on{% elif stage.status == "CANCELLED" %}Cancelled{% else %}Deploy to{% endif %} {{ stage.environment }} {% elif stage.stage_type == "wait" %} {% if stage.status == "SUCCEEDED" %}Waited{% elif stage.status == "RUNNING" %}Waiting{% elif stage.status == "FAILED" %}Wait failed{% elif stage.status == "CANCELLED" %}Wait cancelled{% else %}Wait{% endif %} {% if stage.duration_seconds %}{{ stage.duration_seconds }}s{% endif %} {% elif stage.stage_type == "plan" %} {% set plan_awaiting = stage.approval_status == "AWAITINGAPPROVAL" or stage.approval_status == "AWAITING_APPROVAL" or stage.status == "AWAITING_APPROVAL" %} {% if stage.status == "SUCCEEDED" %}Plan approved{% elif plan_awaiting %}Awaiting plan approval{% elif stage.status == "RUNNING" %}Planning{% elif stage.status == "FAILED" %}Plan failed{% elif stage.status == "CANCELLED" %}Plan cancelled{% else %}Plan{% endif %} {{ stage.environment }} {% if plan_awaiting and release_intent_id %} Approve plan Reject {% endif %} {% endif %} {# Elapsed time #} {% if stage.started_at %} {{ ts(stage.started_at) }} {% endif %} {# Error message #} {% if stage.error_message %} {{ stage.error_message }} {% endif %} {% endfor %} {# Pipeline progress #} {% set ns = namespace(done=0, total=0) %} {% for stage in pipeline_stages %} {% set ns.total = ns.total + 1 %} {% if stage.status == "SUCCEEDED" %}{% set ns.done = ns.done + 1 %}{% endif %} {% endfor %} {{ ns.done }}/{{ ns.total }} stages complete {% elif has_pipeline %} Pipeline Pipeline configured — waiting for release to be triggered. {% endif %} {# ── Policy evaluations (approval, soak, branch) ──────────── #} {% if policy_evaluations | length > 0 %} {% set pns = namespace(passed=0, total=0, pending=0) %} {% for eval in policy_evaluations %} {% set pns.total = pns.total + 1 %} {% if eval.passed %} {% set pns.passed = pns.passed + 1 %} {% else %} {% set pns.pending = pns.pending + 1 %} {% endif %} {% endfor %} Policy Requirements {% if pns.passed == pns.total %} {{ pns.passed }}/{{ pns.total }} passed {% else %} {{ pns.passed }}/{{ pns.total }} passed {% endif %} {# ── Pending / failed policies (expanded) ──────────────── #} {% if pns.pending > 0 %} {% for eval in policy_evaluations %} {% if not eval.passed %} {% if eval.policy_type == "approval" %} Approval {% elif eval.policy_type == "soak_time" %} Soak Time {% elif eval.policy_type == "branch_restriction" %} Branch {% endif %} {{ eval.policy_name }} {{ eval.reason }} {# ── Approval UI ──────────────────────────────── #} {% if eval.policy_type == "approval" and eval.approval_state %} {{ eval.approval_state.current_approvals }}/{{ eval.approval_state.required_approvals }} approvals {% if eval.approval_state.decisions | length > 0 %} {% for d in eval.approval_state.decisions %} {% if d.decision == "approved" %} {{ d.username }} approved {% else %} {{ d.username }} rejected {% endif %} {% if d.comment %}— {{ d.comment }}{% endif %} {% endfor %} {% endif %} {% if is_release_author and not is_admin %} You cannot approve your own release. {% else %} {% if not is_release_author %} Approve {% endif %} {% if is_admin %} Bypass (Admin) {% endif %} Reject {% endif %} {% endif %} {% endif %} {% endfor %} {% endif %} {# ── Passed policies (collapsed) ───────────────────────── #} {% if pns.passed > 0 %} {{ pns.passed }} passed polic{{ "y" if pns.passed == 1 else "ies" }} {% for eval in policy_evaluations %} {% if eval.passed %} {% if eval.policy_type == "approval" %} Approval {% elif eval.policy_type == "soak_time" %} Soak Time {% elif eval.policy_type == "branch_restriction" %} Branch {% endif %} {{ eval.policy_name }} {{ eval.reason }} {% endif %} {% endfor %} {% endif %} {% endif %} {# ── Destinations with status ──────────────────────────────── #} {% if destinations | length > 0 or configured_destinations | length > 0 %} Destinations {% for dest in destinations %} {# Status icon #} {% if dest.status == "SUCCEEDED" %} {% elif dest.status == "RUNNING" or dest.status == "ASSIGNED" %} {% elif dest.status == "QUEUED" %} {% elif dest.status == "FAILED" %} {% else %} {% endif %} {# Environment badge #} {{ dest.environment }} {{ dest.name }} {# Status label #} {% if dest.status == "SUCCEEDED" %} Deployed {% elif dest.status == "RUNNING" %} Deploying {% elif dest.status == "QUEUED" %} Queued{% if dest.queue_position %} #{{ dest.queue_position }}{% endif %} {% elif dest.status == "FAILED" %} Failed {% elif dest.status == "TIMED_OUT" %} Timed out {% elif dest.status == "CANCELLED" %} Cancelled {% endif %} {# Error message #} {% if dest.error_message %} {{ dest.error_message }} {% endif %} {# Timestamp #} {% if dest.completed_at %} {{ ts(dest.completed_at) }} {% elif dest.started_at %} {{ ts(dest.started_at) }} {% endif %} {% endfor %} {# Show configured destinations that don't have live state yet #} {% if configured_destinations | length > 0 and destinations | length == 0 %} {% for cd in configured_destinations %} {{ cd.environment }} {{ cd.name }} Not deployed {% endfor %} {% endif %} {% endif %} {# ── Logs ──────────────────────────────────────────────────── #} {% if has_release_intents %} Logs {% endif %} {# ── Spec (forest.cue) ──────────────────────────────────────── #} {% if artifact_spec %} Spec {% endif %} {# ── Details ───────────────────────────────────────────────── #} {% if artifact.commit_message or artifact.repo_url or artifact.source_email or artifact.run_url %} Details {% if artifact.commit_message %} {{ artifact.commit_message }} {% endif %} {% if artifact.repo_url %} {{ artifact.repo_url }} {% endif %} {% if artifact.source_email %} {{ artifact.source_email }} {% endif %} {% if artifact.run_url %} View CI run {% endif %} {% endif %} {# ── Links ─────────────────────────────────────────────────── #} {% if artifact.web or artifact.pr %} Links {% if artifact.web %} Web {% endif %} {% if artifact.pr %} Pull request {% endif %} {% endif %} Created {{ ts(artifact.created_at) }} {% endblock %}
{{ artifact.slug }}
{{ artifact.description }}
Leave empty when using a pipeline — it will deploy to all configured stages.
{{ ns.done }}/{{ ns.total }} stages complete
You cannot approve your own release.
Created {{ ts(artifact.created_at) }}