Files
ci-actions/pipeline/scripts/finish-steps.sh
T
2026-09-26 05:57:32 +00:00

45 lines
1.9 KiB
Bash
Executable File

#!/usr/bin/env bash
# The pipeline's last step, run however the steps before it ended (if:
# always()). Settles the step list with how the run ended and sends it one
# last time:
# * a step still running never finished, so it failed;
# * a step that never started was skipped;
# * when nothing closed the build record (a step died without fail_build:
# Set up Node.js, a crash), close it as failed, naming the step, so the hub
# does not show the run as running until it goes stale.
# Never fails: the run's result is already decided.
set -uo pipefail
. "$(dirname "$0")/lib.sh"
settle() {
local f before stopped reason
f="$(steps_file)"
[ -s "$f" ] && command -v jq >/dev/null || return 0
before="$(cat "$f")"
# Why the run stopped, from the step that stopped it: one still running
# (never finished), else the first that failed, else the first that never
# started (it died before it could say so).
stopped="$(jq -r '
(map(select(.status == "running"))[0] | select(.) | .name + " did not finish.")
// (map(select(.status == "failed"))[0] | select(.) | .name + (if .summary then ": " + .summary else " failed." end))
// (map(select(.status == "pending"))[0] | select(.) | "The run stopped before " + .name + ".")
// empty' "$f")"
_steps_edit 'map(if .status == "running" then .status = "failed"
elif .status == "pending" then .status = "skipped" else . end)' || return 0
# A step that was running when the run stopped gets its finish time too.
_steps_edit --arg at "$(iso_now)" --argjson ms "$(now_ms)" \
'map(if .status == "failed" and .startedMs and (.finishedAt | not)
then .finishedAt = $at | .durationMs = ($ms - .startedMs) else . end)' || return 0
if [ -n "${BUILD_ID:-}" ] && [ ! -e "$f.finished" ]; then
reason="${stopped:-The run stopped before it finished.}"
report_build_finish failed "$reason"
fi
[ "$(cat "$f")" = "$before" ] || steps_post
}
( settle ) || true
exit 0