| 1 | #!/usr/bin/env bash |
| 2 | # Waits for every Diffinery Actions run on a commit (including runs that other runs |
| 3 | # start, like workflow_run followers) and prints each run and job. Prints the logs of |
| 4 | # failed jobs and exits non-zero if any run did not succeed. |
| 5 | # |
| 6 | # Usage: DIFFINERY=https://diffinery.com TOKEN=... diffinery-wait-runs.sh owner/repo sha [minutes] |
| 7 | set -euo pipefail |
| 8 | repo=$1 sha=$2 minutes=${3:-60} |
| 9 | api() { curl -fsS --retry 3 "$DIFFINERY/api/v3/repos/$repo$1" -H "Authorization: Bearer $TOKEN"; } |
| 10 | |
| 11 | deadline=$(( $(date +%s) + minutes * 60 )) |
| 12 | settled=0 |
| 13 | while :; do |
| 14 | runs=$(api "/actions/runs?head_sha=$sha&per_page=100") |
| 15 | total=$(jq '.workflow_runs | length' <<<"$runs") |
| 16 | pending=$(jq '[.workflow_runs[] | select(.status != "completed")] | length' <<<"$runs") |
| 17 | if [ "$total" -gt 0 ] && [ "$pending" = 0 ]; then |
| 18 | # Finished runs can start followers (workflow_run), so make sure nothing new appears. |
| 19 | settled=$((settled + 1)) |
| 20 | [ "$settled" -ge 3 ] && break |
| 21 | else |
| 22 | settled=0 |
| 23 | fi |
| 24 | if [ "$(date +%s)" -ge "$deadline" ]; then |
| 25 | echo "::error::Diffinery runs for $sha were not finished after $minutes minutes" |
| 26 | jq -r '.workflow_runs[] | " \(.name) [\(.event)]: \(.status)"' <<<"$runs" |
| 27 | exit 1 |
| 28 | fi |
| 29 | sleep 15 |
| 30 | done |
| 31 | |
| 32 | failed=0 |
| 33 | for id in $(jq -r '.workflow_runs[].id' <<<"$runs"); do |
| 34 | run=$(api "/actions/runs/$id") |
| 35 | jq -r '"\(.name) [\(.event)]: \(.conclusion) \(.html_url)"' <<<"$run" |
| 36 | jobs=$(api "/actions/runs/$id/jobs") |
| 37 | jq -r '.jobs[] | " \(.name): \(.conclusion)\(if .failure then " - " + (.failure.message // "") else "" end)"' <<<"$jobs" |
| 38 | if [ "$(jq -r .conclusion <<<"$run")" != success ]; then |
| 39 | failed=1 |
| 40 | for job in $(jq -r '.jobs[] | select(.conclusion == "failure" or .conclusion == "timed_out") | .id' <<<"$jobs"); do |
| 41 | echo "::group::Last log lines of job $job" |
| 42 | api "/actions/jobs/$job/logs" | tail -n 120 |
| 43 | echo "::endgroup::" |
| 44 | done |
| 45 | fi |
| 46 | done |
| 47 | [ "$failed" = 0 ] && echo "every Diffinery run on $sha succeeded" |
| 48 | exit "$failed" |