Merge pull request 'fix: fix: dev-poll spawns duplicate agents — no tmux session guard (#371)' (#372) from fix/issue-371 into main

This commit is contained in:
johba 2026-03-20 13:19:11 +01:00
commit f039507fca
2 changed files with 55 additions and 21 deletions

View file

@ -21,9 +21,9 @@ FAILED=0
# Uses awk instead of grep -Eo for busybox/Alpine compatibility (#296). # Uses awk instead of grep -Eo for busybox/Alpine compatibility (#296).
get_fns() { get_fns() {
local f="$1" local f="$1"
awk '/^[[:space:]]*[a-zA-Z_][a-zA-Z0-9_]+[[:space:]]*\(\)/ { awk '/^[ \t]*[a-zA-Z_][a-zA-Z0-9_]+[ \t]*\(\)/ {
sub(/^[[:space:]]+/, "") sub(/^[ \t]+/, "")
sub(/[[:space:]]*\(\).*/, "") sub(/[ \t]*\(\).*/, "")
print print
}' "$f" 2>/dev/null | sort -u || true }' "$f" 2>/dev/null | sort -u || true
} }
@ -157,7 +157,7 @@ check_script dev/dev-agent.sh dev/phase-handler.sh
check_script dev/phase-handler.sh dev/dev-agent.sh check_script dev/phase-handler.sh dev/dev-agent.sh
check_script dev/dev-poll.sh check_script dev/dev-poll.sh
check_script dev/phase-test.sh check_script dev/phase-test.sh
check_script gardener/gardener-agent.sh check_script gardener/gardener-agent.sh lib/agent-session.sh
check_script gardener/gardener-poll.sh check_script gardener/gardener-poll.sh
check_script review/review-pr.sh check_script review/review-pr.sh
check_script review/review-poll.sh check_script review/review-poll.sh

View file

@ -339,20 +339,35 @@ if [ "$ORPHAN_COUNT" -gt 0 ]; then
exit 0 exit 0
fi fi
# Direct merge failed (conflicts?) — fall back to dev-agent # Direct merge failed (conflicts?) — fall back to dev-agent
SESSION_NAME="dev-${PROJECT_NAME}-${ISSUE_NUM}"
if tmux has-session -t "$SESSION_NAME" 2>/dev/null; then
log "issue #${ISSUE_NUM} already has active session ${SESSION_NAME} — skipping"
else
log "falling back to dev-agent for PR #${HAS_PR} merge" log "falling back to dev-agent for PR #${HAS_PR} merge"
nohup "${SCRIPT_DIR}/dev-agent.sh" "$ISSUE_NUM" >> "$LOGFILE" 2>&1 & nohup "${SCRIPT_DIR}/dev-agent.sh" "$ISSUE_NUM" >> "$LOGFILE" 2>&1 &
log "started dev-agent PID $! for issue #${ISSUE_NUM} (agent-merge)" log "started dev-agent PID $! for issue #${ISSUE_NUM} (agent-merge)"
fi
exit 0 exit 0
# Do NOT gate REQUEST_CHANGES on ci_passed: act immediately even if CI is # Do NOT gate REQUEST_CHANGES on ci_passed: act immediately even if CI is
# pending/unknown. Definitive CI failure is handled by the elif below. # pending/unknown. Definitive CI failure is handled by the elif below.
elif [ "${HAS_CHANGES:-0}" -gt 0 ] && { ci_passed "$CI_STATE" || [ "$CI_STATE" = "pending" ] || [ "$CI_STATE" = "unknown" ] || [ -z "$CI_STATE" ]; }; then elif [ "${HAS_CHANGES:-0}" -gt 0 ] && { ci_passed "$CI_STATE" || [ "$CI_STATE" = "pending" ] || [ "$CI_STATE" = "unknown" ] || [ -z "$CI_STATE" ]; }; then
SESSION_NAME="dev-${PROJECT_NAME}-${ISSUE_NUM}"
if tmux has-session -t "$SESSION_NAME" 2>/dev/null; then
log "issue #${ISSUE_NUM} already has active session ${SESSION_NAME} — skipping"
else
log "issue #${ISSUE_NUM} PR #${HAS_PR} has REQUEST_CHANGES — spawning agent" log "issue #${ISSUE_NUM} PR #${HAS_PR} has REQUEST_CHANGES — spawning agent"
nohup "${SCRIPT_DIR}/dev-agent.sh" "$ISSUE_NUM" >> "$LOGFILE" 2>&1 & nohup "${SCRIPT_DIR}/dev-agent.sh" "$ISSUE_NUM" >> "$LOGFILE" 2>&1 &
log "started dev-agent PID $! for issue #${ISSUE_NUM} (review fix)" log "started dev-agent PID $! for issue #${ISSUE_NUM} (review fix)"
fi
exit 0 exit 0
elif ! ci_passed "$CI_STATE" && [ "$CI_STATE" != "" ] && [ "$CI_STATE" != "pending" ] && [ "$CI_STATE" != "unknown" ]; then elif ! ci_passed "$CI_STATE" && [ "$CI_STATE" != "" ] && [ "$CI_STATE" != "pending" ] && [ "$CI_STATE" != "unknown" ]; then
SESSION_NAME="dev-${PROJECT_NAME}-${ISSUE_NUM}"
if tmux has-session -t "$SESSION_NAME" 2>/dev/null; then
log "issue #${ISSUE_NUM} already has active session ${SESSION_NAME} — skipping"
exit 0
fi
if handle_ci_exhaustion "$HAS_PR" "$ISSUE_NUM"; then if handle_ci_exhaustion "$HAS_PR" "$ISSUE_NUM"; then
# Fall through to backlog scan instead of exit # Fall through to backlog scan instead of exit
: :
@ -366,10 +381,15 @@ if [ "$ORPHAN_COUNT" -gt 0 ]; then
else else
log "issue #${ISSUE_NUM} has open PR #${HAS_PR} (CI: ${CI_STATE}, waiting)" log "issue #${ISSUE_NUM} has open PR #${HAS_PR} (CI: ${CI_STATE}, waiting)"
fi fi
else
SESSION_NAME="dev-${PROJECT_NAME}-${ISSUE_NUM}"
if tmux has-session -t "$SESSION_NAME" 2>/dev/null; then
log "issue #${ISSUE_NUM} already has active session ${SESSION_NAME} — skipping"
else else
log "recovering orphaned issue #${ISSUE_NUM} (no PR found)" log "recovering orphaned issue #${ISSUE_NUM} (no PR found)"
nohup "${SCRIPT_DIR}/dev-agent.sh" "$ISSUE_NUM" >> "$LOGFILE" 2>&1 & nohup "${SCRIPT_DIR}/dev-agent.sh" "$ISSUE_NUM" >> "$LOGFILE" 2>&1 &
log "started dev-agent PID $! for issue #${ISSUE_NUM} (recovery)" log "started dev-agent PID $! for issue #${ISSUE_NUM} (recovery)"
fi
exit 0 exit 0
fi fi
fi fi
@ -424,9 +444,14 @@ for i in $(seq 0 $(($(echo "$OPEN_PRS" | jq 'length') - 1))); do
exit 0 exit 0
fi fi
# Direct merge failed (conflicts?) — fall back to dev-agent # Direct merge failed (conflicts?) — fall back to dev-agent
SESSION_NAME="dev-${PROJECT_NAME}-${STUCK_ISSUE}"
if tmux has-session -t "$SESSION_NAME" 2>/dev/null; then
log "issue #${STUCK_ISSUE} already has active session ${SESSION_NAME} — skipping"
else
log "falling back to dev-agent for PR #${PR_NUM} merge" log "falling back to dev-agent for PR #${PR_NUM} merge"
nohup "${SCRIPT_DIR}/dev-agent.sh" "$STUCK_ISSUE" >> "$LOGFILE" 2>&1 & nohup "${SCRIPT_DIR}/dev-agent.sh" "$STUCK_ISSUE" >> "$LOGFILE" 2>&1 &
log "started dev-agent PID $! for stuck PR #${PR_NUM} (agent-merge)" log "started dev-agent PID $! for stuck PR #${PR_NUM} (agent-merge)"
fi
exit 0 exit 0
fi fi
@ -436,20 +461,29 @@ for i in $(seq 0 $(($(echo "$OPEN_PRS" | jq 'length') - 1))); do
# CI to settle. Definitive CI failure (non-pending, non-unknown) is handled by # CI to settle. Definitive CI failure (non-pending, non-unknown) is handled by
# the elif below, so we only spawn here when CI has not definitively failed. # the elif below, so we only spawn here when CI has not definitively failed.
if [ "${HAS_CHANGES:-0}" -gt 0 ] && { ci_passed "$CI_STATE" || [ "$CI_STATE" = "pending" ] || [ "$CI_STATE" = "unknown" ] || [ -z "$CI_STATE" ]; }; then if [ "${HAS_CHANGES:-0}" -gt 0 ] && { ci_passed "$CI_STATE" || [ "$CI_STATE" = "pending" ] || [ "$CI_STATE" = "unknown" ] || [ -z "$CI_STATE" ]; }; then
SESSION_NAME="dev-${PROJECT_NAME}-${STUCK_ISSUE}"
if tmux has-session -t "$SESSION_NAME" 2>/dev/null; then
log "issue #${STUCK_ISSUE} already has active session ${SESSION_NAME} — skipping"
continue
fi
log "PR #${PR_NUM} (issue #${STUCK_ISSUE}) has REQUEST_CHANGES — fixing first" log "PR #${PR_NUM} (issue #${STUCK_ISSUE}) has REQUEST_CHANGES — fixing first"
nohup "${SCRIPT_DIR}/dev-agent.sh" "$STUCK_ISSUE" >> "$LOGFILE" 2>&1 & nohup "${SCRIPT_DIR}/dev-agent.sh" "$STUCK_ISSUE" >> "$LOGFILE" 2>&1 &
log "started dev-agent PID $! for stuck PR #${PR_NUM}" log "started dev-agent PID $! for stuck PR #${PR_NUM}"
exit 0 exit 0
elif ! ci_passed "$CI_STATE" && [ "$CI_STATE" != "" ] && [ "$CI_STATE" != "pending" ] && [ "$CI_STATE" != "unknown" ]; then elif ! ci_passed "$CI_STATE" && [ "$CI_STATE" != "" ] && [ "$CI_STATE" != "pending" ] && [ "$CI_STATE" != "unknown" ]; then
SESSION_NAME="dev-${PROJECT_NAME}-${STUCK_ISSUE}"
if tmux has-session -t "$SESSION_NAME" 2>/dev/null; then
log "issue #${STUCK_ISSUE} already has active session ${SESSION_NAME} — skipping"
continue
fi
if handle_ci_exhaustion "$PR_NUM" "$STUCK_ISSUE"; then if handle_ci_exhaustion "$PR_NUM" "$STUCK_ISSUE"; then
continue # skip this PR, check next stuck PR or fall through to backlog continue # skip this PR, check next stuck PR or fall through to backlog
else fi
log "PR #${PR_NUM} (issue #${STUCK_ISSUE}) CI failed — fixing (attempt ${CI_FIX_ATTEMPTS}/3)" log "PR #${PR_NUM} (issue #${STUCK_ISSUE}) CI failed — fixing (attempt ${CI_FIX_ATTEMPTS}/3)"
nohup "${SCRIPT_DIR}/dev-agent.sh" "$STUCK_ISSUE" >> "$LOGFILE" 2>&1 & nohup "${SCRIPT_DIR}/dev-agent.sh" "$STUCK_ISSUE" >> "$LOGFILE" 2>&1 &
log "started dev-agent PID $! for stuck PR #${PR_NUM}" log "started dev-agent PID $! for stuck PR #${PR_NUM}"
exit 0 exit 0
fi fi
fi
done done
# ============================================================================= # =============================================================================