4242 checks : read
4343 contents : read
4444 issues : write
45- pull-requests : read
45+ pull-requests : write
4646 statuses : read
4747 outputs :
4848 should_run : ${{ steps.evaluate.outputs.should_run }}
@@ -101,6 +101,14 @@ jobs:
101101 jq -e --arg label "$label" '[.labels[].name] | index($label) != null' <<<"$payload" >/dev/null
102102 }
103103
104+ edit_pr_label() {
105+ local pr="$1"
106+ local flag="$2"
107+ local label="$3"
108+
109+ gh issue edit "$pr" --repo "$REPO" "$flag" "$label"
110+ }
111+
104112 ensure_active_label() {
105113 gh label create "$ACTIVE_LABEL" --repo "$REPO" \
106114 --color "fbca04" \
@@ -228,13 +236,42 @@ jobs:
228236 reconcile_ready_label() {
229237 local pr="$1"
230238 local state="$2"
239+ local payload="$3"
231240
232241 if [ "$state" = "ready" ]; then
233- gh issue edit "$pr" --repo "$REPO" --add-label "$READY_LABEL" || true
242+ if pr_has_label "$payload" "$READY_LABEL"; then
243+ return 0
244+ fi
245+ edit_pr_label "$pr" --add-label "$READY_LABEL"
234246 return 0
235247 fi
236248
237- gh issue edit "$pr" --repo "$REPO" --remove-label "$READY_LABEL" || true
249+ if pr_has_label "$payload" "$READY_LABEL"; then
250+ edit_pr_label "$pr" --remove-label "$READY_LABEL"
251+ fi
252+ return 0
253+ }
254+
255+ claim_active_label() {
256+ local pr="$1"
257+ local head_sha="$2"
258+ local reason="$3"
259+ local payload
260+
261+ ensure_active_label
262+ if ! edit_pr_label "$pr" --add-label "$ACTIVE_LABEL"; then
263+ echo "Could not add $ACTIVE_LABEL to PR #$pr; refusing to dispatch the agent without a lease."
264+ set_result "false" "$pr" "$head_sha" "blocked" "$reason:active_label_failed"
265+ return 1
266+ fi
267+
268+ payload="$(pr_json "$pr")"
269+ if ! pr_has_label "$payload" "$ACTIVE_LABEL"; then
270+ echo "PR #$pr still does not have $ACTIVE_LABEL after label update; refusing to dispatch the agent."
271+ set_result "false" "$pr" "$head_sha" "blocked" "$reason:active_label_missing"
272+ return 1
273+ fi
274+ return 0
238275 }
239276
240277 trigger_ci_if_needed() {
@@ -327,7 +364,11 @@ jobs:
327364 fi
328365
329366 state="$(evaluate_readiness "$payload")"
330- reconcile_ready_label "$pr" "$state"
367+ if ! reconcile_ready_label "$pr" "$state" "$payload"; then
368+ echo "Could not reconcile $READY_LABEL for PR #$pr; refusing to dispatch the agent with stale readiness state."
369+ set_result "false" "$pr" "$head_sha" "blocked" "$reason:ready_label_failed"
370+ return 1
371+ fi
331372
332373 case "$state" in
333374 ready|waiting|blocked|out_of_scope)
@@ -339,8 +380,9 @@ jobs:
339380 return 1
340381 ;;
341382 needs_branch_update|needs_repair)
342- ensure_active_label
343- gh issue edit "$pr" --repo "$REPO" --add-label "$ACTIVE_LABEL"
383+ if ! claim_active_label "$pr" "$head_sha" "$reason"; then
384+ return 1
385+ fi
344386 set_result "true" "$pr" "$head_sha" "$state" "$reason:$state"
345387 return 0
346388 ;;
0 commit comments