deploy(cinny): follow origin/lotus HEAD while gating on CI
Companion to cinny's `concurrency: cancel-in-progress`. The poll loop latched origin/lotus once at startup; with CI cancel-in-progress a superseded run's status flips to error/failure, so polling the latched (now-cancelled) SHA would abort and — with the flock skipping the newer push's deploy — strand the newest commit undeployed (a deploy freeze, the exact class this script fought before). - Re-resolve origin/lotus each poll iteration; retarget the CI gate to HEAD if it advanced (fresh MAX_WAIT window). - On a failure/error status, re-check HEAD before aborting — only a genuine failure of the CURRENT HEAD aborts; a superseded/blip SHA is followed instead. - Reset to the gated $COMMIT_SHA (not a bare origin/lotus that may have advanced past the gate after the loop) so we build exactly what passed CI. shellcheck clean; reviewed (SHIP). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+34
-2
@@ -54,6 +54,19 @@ if [ -n "${GITEA_API_TOKEN:-}" ]; then
|
|||||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Waiting for CI '$GATE_CONTEXT' on $COMMIT_SHA..."
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Waiting for CI '$GATE_CONTEXT' on $COMMIT_SHA..."
|
||||||
|
|
||||||
while [ "$elapsed" -lt "$MAX_WAIT" ]; do
|
while [ "$elapsed" -lt "$MAX_WAIT" ]; do
|
||||||
|
# Follow origin/lotus. A newer push supersedes ours — with CI
|
||||||
|
# cancel-in-progress its run is CANCELLED (reported error/failure), and a
|
||||||
|
# newer deploy is skipped by our flock — so polling the latched (now
|
||||||
|
# cancelled) SHA would abort and strand the newest commit undeployed.
|
||||||
|
# Re-resolve HEAD each iteration and retarget the gate if it advanced,
|
||||||
|
# giving the fresh commit a full MAX_WAIT window.
|
||||||
|
git fetch --quiet origin lotus 2>/dev/null || true
|
||||||
|
newest=$(git rev-parse origin/lotus 2>/dev/null || echo "$COMMIT_SHA")
|
||||||
|
if [ "$newest" != "$COMMIT_SHA" ]; then
|
||||||
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] origin/lotus advanced ${COMMIT_SHA:0:8} -> ${newest:0:8}; retargeting CI gate."
|
||||||
|
COMMIT_SHA="$newest"
|
||||||
|
elapsed=0
|
||||||
|
fi
|
||||||
state=$(curl -s -H "Authorization: token $GITEA_API_TOKEN" \
|
state=$(curl -s -H "Authorization: token $GITEA_API_TOKEN" \
|
||||||
"$GITEA_API/repos/$REPO_PATH/commits/$COMMIT_SHA/status" \
|
"$GITEA_API/repos/$REPO_PATH/commits/$COMMIT_SHA/status" \
|
||||||
| GATE="$GATE_CONTEXT" python3 -c "
|
| GATE="$GATE_CONTEXT" python3 -c "
|
||||||
@@ -72,7 +85,23 @@ else:
|
|||||||
|
|
||||||
case "$state" in
|
case "$state" in
|
||||||
success) ci_result=success; break ;;
|
success) ci_result=success; break ;;
|
||||||
failure|error) ci_result="$state"; break ;;
|
failure|error)
|
||||||
|
# Before aborting: a superseded run reports its status as
|
||||||
|
# error/failure (cancel-in-progress). If a fetch blip on the
|
||||||
|
# retarget iteration left us on a stale SHA, re-check HEAD — if it
|
||||||
|
# advanced, follow it and keep waiting rather than aborting on a
|
||||||
|
# commit that a newer push already replaced. Only a genuine
|
||||||
|
# failure of the CURRENT HEAD aborts the deploy.
|
||||||
|
git fetch --quiet origin lotus 2>/dev/null || true
|
||||||
|
head_now=$(git rev-parse origin/lotus 2>/dev/null || echo "$COMMIT_SHA")
|
||||||
|
if [ "$head_now" != "$COMMIT_SHA" ]; then
|
||||||
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] gated ${COMMIT_SHA:0:8} reported ${state}, but origin/lotus advanced to ${head_now:0:8}; retargeting."
|
||||||
|
COMMIT_SHA="$head_now"
|
||||||
|
elapsed=0
|
||||||
|
else
|
||||||
|
ci_result="$state"; break
|
||||||
|
fi
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] CI not yet passed (${elapsed}s elapsed, '$GATE_CONTEXT': ${state}), waiting..."
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] CI not yet passed (${elapsed}s elapsed, '$GATE_CONTEXT': ${state}), waiting..."
|
||||||
sleep "$POLL_INTERVAL"
|
sleep "$POLL_INTERVAL"
|
||||||
@@ -88,7 +117,10 @@ else
|
|||||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] WARNING: GITEA_API_TOKEN not set, deploying without CI gate."
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] WARNING: GITEA_API_TOKEN not set, deploying without CI gate."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
git reset --hard origin/lotus
|
# Reset to the exact commit we gated on (which the poll loop keeps in step with
|
||||||
|
# origin/lotus), not a bare origin/lotus that may have advanced past the gate
|
||||||
|
# after the loop exited — so we deploy precisely what passed CI.
|
||||||
|
git reset --hard "$COMMIT_SHA"
|
||||||
|
|
||||||
# Tag this build with the exact commit so Sentry can link errors to source
|
# Tag this build with the exact commit so Sentry can link errors to source
|
||||||
export VITE_APP_VERSION=$COMMIT_SHA
|
export VITE_APP_VERSION=$COMMIT_SHA
|
||||||
|
|||||||
Reference in New Issue
Block a user