fix: the job poll cannot mistake an old run for the dispatched one, and --help covers its own header

The runner leg reads the newest run ID before dispatching and only
judges a run with a different ID — workflow_dispatch takes seconds to
materialize a run, and the previous run's 'completed' was one poll away
from being read as ours. --help's sed range stops where the header does.

(ceremony flow: issue #105)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
claude-bot-andresmgsl 2026-07-24 00:36:00 +00:00
parent 5bcd8853d4
commit 7b2de4a9e6

View file

@ -74,7 +74,7 @@ while [ $# -gt 0 ]; do
--coolify-version) COOLIFY_VERSION="$2"; shift 2 ;; --coolify-version) COOLIFY_VERSION="$2"; shift 2 ;;
--runner-repo) RUNNER_REPO="$2"; shift 2 ;; --runner-repo) RUNNER_REPO="$2"; shift 2 ;;
--runner-workflow) RUNNER_WORKFLOW="$2"; shift 2 ;; --runner-workflow) RUNNER_WORKFLOW="$2"; shift 2 ;;
-h|--help) sed -n '2,36p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;; -h|--help) sed -n '2,33p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
*) echo "drill: unknown option: $1 (see --help)" >&2; exit 2 ;; *) echo "drill: unknown option: $1 (see --help)" >&2; exit 2 ;;
esac esac
done done
@ -593,22 +593,30 @@ else
took_job=none took_job=none
if [ "$GH_OK" -eq 1 ]; then if [ "$GH_OK" -eq 1 ]; then
# Dispatch, then poll the newest run of that workflow to completion. # Dispatch, then poll the newest run of that workflow to completion.
# ~5 min bound: a queued-forever run means the runner never picked it # The newest run's ID is read BEFORE dispatching, so an old completed
# up, which is exactly what this check exists to catch. # run can never be mistaken for the one just dispatched (the poll's
# verdict must be about OUR run, and workflow_dispatch takes a few
# seconds to materialize a run at all). ~5 min bound: a queued-forever
# run means the runner never picked the job up, which is exactly what
# this check exists to catch.
pre_id="$(gh run list -R "$RUNNER_REPO" --workflow "$RUNNER_WORKFLOW" --limit 1 --json databaseId --jq '.[0].databaseId' 2>/dev/null)"
if gh workflow run "$RUNNER_WORKFLOW" -R "$RUNNER_REPO" >/dev/null 2>&1; then if gh workflow run "$RUNNER_WORKFLOW" -R "$RUNNER_REPO" >/dev/null 2>&1; then
inf "dispatched $RUNNER_WORKFLOW on $RUNNER_REPO — waiting for the runner to take it (≤5 min)…" inf "dispatched $RUNNER_WORKFLOW on $RUNNER_REPO — waiting for the runner to take it (≤5 min)…"
took_job=timeout took_job=timeout
for _i in $(seq 1 30); do for _i in $(seq 1 30); do
sleep 10 sleep 10
run_json="$(gh run list -R "$RUNNER_REPO" --workflow "$RUNNER_WORKFLOW" --limit 1 --json status,conclusion 2>/dev/null)" run_line="$(gh run list -R "$RUNNER_REPO" --workflow "$RUNNER_WORKFLOW" --limit 1 \
case "$run_json" in --json databaseId,status,conclusion --jq '.[0] | "\(.databaseId) \(.status) \(.conclusion)"' 2>/dev/null)"
*'"status":"completed"'*) read -r rid rstatus rconc <<< "$run_line"
case "$run_json" in [ -n "${rid:-}" ] || continue
*'"conclusion":"success"'*) took_job=success ;; [ "$rid" != "${pre_id:-}" ] || continue
*) took_job=failed ;; if [ "${rstatus:-}" = completed ]; then
esac case "${rconc:-}" in
break ;; success) took_job=success ;;
esac *) took_job=failed ;;
esac
break
fi
done done
else else
took_job=nodispatch took_job=nodispatch