57 lines
3.0 KiB
Bash
Executable File
57 lines
3.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Failure-safe rescue: when a run FAILED after a dev agent already pushed commits, the normal
|
|
# Publish step never ran and the work would be stranded on the branch with no PR (issue #33).
|
|
# This opens a PR for the pushed branch so nothing is silently lost. It is strictly best-effort:
|
|
# every failure here is swallowed (the caller also appends `|| true`) so it can never itself break
|
|
# the run. Comment-only roles (pm/qa) push nothing, so they are skipped.
|
|
#
|
|
# Required env (provided by the workflow step):
|
|
# GT TOKEN_PM TOKEN_INTERN TOKEN_SENIOR TOKEN_JUNIOR TOKEN_LEAD TOKEN_QA
|
|
# NAME MODE NUM TITLE BRANCH GITHUB_SERVER_URL GITHUB_REPOSITORY
|
|
set +e
|
|
|
|
# Only dev agents (mode=pr) ever push a branch to rescue.
|
|
[ "${MODE:-}" = "pr" ] || { echo "rescue: comment-mode agent, nothing to rescue"; exit 0; }
|
|
[ -n "${BRANCH:-}" ] || { echo "rescue: no branch known, skipping"; exit 0; }
|
|
|
|
# Post/PR as the agent's OWN Gitea user when its token is configured; else the built-in bot.
|
|
case "$NAME" in
|
|
pm) TOK="$TOKEN_PM";; intern) TOK="$TOKEN_INTERN";; senior) TOK="$TOKEN_SENIOR";; junior) TOK="$TOKEN_JUNIOR";;
|
|
lead) TOK="$TOKEN_LEAD";; qa) TOK="$TOKEN_QA";; *) TOK="";;
|
|
esac
|
|
[ -z "$TOK" ] && TOK="$GT"
|
|
API="${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}"
|
|
hdr=(-H "Authorization: token $TOK" -H "Content-Type: application/json")
|
|
|
|
git fetch -q origin 2>/dev/null || true
|
|
|
|
# Nothing to rescue unless the branch exists on the remote with commits beyond main.
|
|
ahead=$(git rev-list --count "origin/main..origin/$BRANCH" 2>/dev/null || echo 0)
|
|
if [ "${ahead:-0}" -eq 0 ]; then
|
|
echo "rescue: no pushed commits on origin/$BRANCH beyond main — nothing to rescue"
|
|
exit 0
|
|
fi
|
|
echo "rescue: origin/$BRANCH is $ahead commit(s) ahead of main — ensuring a PR exists"
|
|
|
|
# Idempotent: Gitea ignores ?head=, so match the head branch client-side.
|
|
resp=$(curl -sS "${hdr[@]}" "$API/pulls?state=open&limit=50" \
|
|
| jq -r --arg br "$BRANCH" 'if type=="array" then (map(select(.head.ref==$br)) | .[0] // empty) else empty end' 2>/dev/null)
|
|
url=$(printf '%s' "$resp" | jq -r '.html_url // empty' 2>/dev/null)
|
|
if [ -z "$url" ]; then
|
|
body=$(printf 'The run failed before it could publish, but pushed work exists on this branch — opening a PR so it is not lost.\n\n---\nResolves #%s · 🤖 @%s (auto-rescued after a failed run)' "$NUM" "$NAME")
|
|
resp=$(curl -sS -X POST "${hdr[@]}" "$API/pulls" \
|
|
-d "$(jq -nc --arg t "@$NAME: $TITLE" --arg h "$BRANCH" --arg b "$body" \
|
|
'{title:$t, head:$h, base:"main", body:$b}')")
|
|
echo "rescue PR create ($BRANCH): $resp"
|
|
url=$(printf '%s' "$resp" | jq -r '.html_url // empty' 2>/dev/null)
|
|
fi
|
|
|
|
if [ -n "$url" ]; then
|
|
curl -sS -X POST "${hdr[@]}" "$API/issues/$NUM/comments" \
|
|
-d "$(jq -nc --arg b "$(printf '🤖 **@%s** — ⚠️ the run failed, but your pushed work was not lost — a PR was opened for branch \`%s\`:\n- %s' "$NAME" "$BRANCH" "$url")" '{body:$b}')" \
|
|
-w '\nrescue comment -> HTTP %{http_code}\n' || true
|
|
else
|
|
echo "rescue: could not open/find a PR for $BRANCH"
|
|
fi
|
|
exit 0
|