Merge pull request 'fix: bug: dev-poll stale detection races with issue_claim — blocks freshly claimed issues (#471)' (#512) from fix/issue-471 into main
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
This commit is contained in:
commit
449d83f233
2 changed files with 45 additions and 4 deletions
|
|
@ -103,6 +103,39 @@ is_blocked() {
|
||||||
# STALENESS DETECTION FOR IN-PROGRESS ISSUES
|
# STALENESS DETECTION FOR IN-PROGRESS ISSUES
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
||||||
|
# Check if in-progress label was added recently (within grace period).
|
||||||
|
# Prevents race where a poller marks an issue as stale before the claiming
|
||||||
|
# agent's assign + label sequence has fully propagated. See issue #471.
|
||||||
|
# Args: issue_number [grace_seconds]
|
||||||
|
# Returns: 0 if recently added (within grace period), 1 if not
|
||||||
|
in_progress_recently_added() {
|
||||||
|
local issue="$1" grace="${2:-60}"
|
||||||
|
local now label_ts delta
|
||||||
|
|
||||||
|
now=$(date +%s)
|
||||||
|
|
||||||
|
# Query issue timeline for the most recent in-progress label event.
|
||||||
|
# Forgejo serializes CommentType as an integer, not a string —
|
||||||
|
# CommentTypeLabel is 7 in the Gitea/Forgejo enum.
|
||||||
|
label_ts=$(curl -sf -H "Authorization: token ${FORGE_TOKEN}" \
|
||||||
|
"${API}/issues/${issue}/timeline" | \
|
||||||
|
jq -r '[.[] | select(.type == 7) | select(.label.name == "in-progress")] | last | .created_at // empty') || true
|
||||||
|
|
||||||
|
if [ -z "$label_ts" ]; then
|
||||||
|
return 1 # no label event found — not recently added
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Convert ISO timestamp to epoch and compare
|
||||||
|
local label_epoch
|
||||||
|
label_epoch=$(date -d "$label_ts" +%s 2>/dev/null || echo 0)
|
||||||
|
delta=$(( now - label_epoch ))
|
||||||
|
|
||||||
|
if [ "$delta" -lt "$grace" ]; then
|
||||||
|
return 0 # within grace period
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
# Check if there's an open PR for a specific issue
|
# Check if there's an open PR for a specific issue
|
||||||
# Args: issue_number
|
# Args: issue_number
|
||||||
# Returns: 0 if open PR exists, 1 if not
|
# Returns: 0 if open PR exists, 1 if not
|
||||||
|
|
@ -460,9 +493,15 @@ if [ "$ORPHAN_COUNT" -gt 0 ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$OPEN_PR" = false ] && [ "$BLOCKED_BY_INPROGRESS" = false ]; then
|
if [ "$OPEN_PR" = false ] && [ "$BLOCKED_BY_INPROGRESS" = false ]; then
|
||||||
log "issue #${ISSUE_NUM} is stale (no assignee, no open PR, no agent lock) — relabeling to blocked"
|
# Grace period: skip if in-progress label was added <60s ago (issue #471)
|
||||||
relabel_stale_issue "$ISSUE_NUM" "no_assignee_no_open_pr_no_lock"
|
if in_progress_recently_added "$ISSUE_NUM" 60; then
|
||||||
BLOCKED_BY_INPROGRESS=true
|
log "issue #${ISSUE_NUM} in-progress label added <60s ago — skipping stale detection (grace period)"
|
||||||
|
BLOCKED_BY_INPROGRESS=true
|
||||||
|
else
|
||||||
|
log "issue #${ISSUE_NUM} is stale (no assignee, no open PR, no agent lock) — relabeling to blocked"
|
||||||
|
relabel_stale_issue "$ISSUE_NUM" "no_assignee_no_open_pr_no_lock"
|
||||||
|
BLOCKED_BY_INPROGRESS=true
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Formula guard: formula-labeled issues should not be worked on by dev-agent.
|
# Formula guard: formula-labeled issues should not be worked on by dev-agent.
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,9 @@ issue_claim() {
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Assign to self (Forgejo rejects if already assigned differently)
|
# Assign to self BEFORE adding in-progress label (issue #471).
|
||||||
|
# This ordering ensures the assignee is set by the time other pollers
|
||||||
|
# see the in-progress label, reducing the stale-detection race window.
|
||||||
curl -sf -X PATCH \
|
curl -sf -X PATCH \
|
||||||
-H "Authorization: token ${FORGE_TOKEN}" \
|
-H "Authorization: token ${FORGE_TOKEN}" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue