Skip to content

Commit c79ad10

Browse files
committed
Dispatch repair after CI activation failures
1 parent bd5edcf commit c79ad10

3 files changed

Lines changed: 207 additions & 16 deletions

File tree

.github/workflows/evergreen.lock.yml

Lines changed: 99 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.github/workflows/evergreen.md

Lines changed: 98 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ jobs:
6666
EXHAUSTED_LABEL: evergreen-exhausted
6767
REQUIRED_CHECKS_JSON: '["Test & Lint","Playground E2E (Playwright)","Build","Validate Python Examples"]'
6868
CHECK_GATE_MODE: configured
69+
CI_ACTIVATION_WAIT_SECONDS: "300"
6970
MANUAL_PR: ${{ github.event.inputs.pr || '' }}
7071
MANUAL_HEAD_SHA: ${{ github.event.inputs.head_sha || '' }}
7172
MANUAL_REASON: ${{ github.event.inputs.reason || '' }}
@@ -187,6 +188,30 @@ jobs:
187188
return 1
188189
}
189190
191+
any_configured_check_failing() {
192+
local payload="$1"
193+
local required="$2"
194+
local count
195+
local state
196+
197+
count="$(jq 'length' <<<"$required")"
198+
if [ "$count" -eq 0 ]; then
199+
has_failing_check "$payload"
200+
return
201+
fi
202+
203+
while IFS= read -r name; do
204+
state="$(check_state_for "$payload" "$name")"
205+
case "$state" in
206+
FAILURE|failure|FAILED|failed|ERROR|error|TIMED_OUT|timed_out|CANCELLED|cancelled)
207+
return 0
208+
;;
209+
esac
210+
done < <(jq -r '.[]' <<<"$required")
211+
212+
return 1
213+
}
214+
190215
evaluate_readiness() {
191216
local payload="$1"
192217
local required
@@ -210,6 +235,11 @@ jobs:
210235
return 0
211236
fi
212237
238+
if any_configured_check_failing "$payload" "$required"; then
239+
echo "needs_repair"
240+
return 0
241+
fi
242+
213243
if any_configured_check_missing "$payload" "$required"; then
214244
echo "needs_ci"
215245
return 0
@@ -304,7 +334,7 @@ jobs:
304334
305335
if [ -z "$run_id" ]; then
306336
echo "No CI run found for PR #$pr ($head_sha); leaving for scheduled/PR CI to start."
307-
return 0
337+
return 1
308338
fi
309339
310340
case "$status" in
@@ -317,14 +347,58 @@ jobs:
317347
case "$conclusion" in
318348
success)
319349
echo "CI run $run_id for PR #$pr ($head_sha) already succeeded; not rerunning green checks."
320-
return 0
350+
return 1
321351
;;
322352
esac
323353
324354
echo "Reactivating CI run $run_id for PR #$pr ($head_sha) (status=$status conclusion=$conclusion)."
325-
ci_gh gh run rerun "$run_id" --repo "$REPO" --failed || \
326-
ci_gh gh run rerun "$run_id" --repo "$REPO" || \
327-
echo "Could not reactivate CI run $run_id; scheduled monitor will retry."
355+
if ci_gh gh run rerun "$run_id" --repo "$REPO" --failed; then
356+
return 0
357+
fi
358+
359+
echo "Failed-jobs rerun was unavailable for CI run $run_id; trying full rerun."
360+
if ci_gh gh run rerun "$run_id" --repo "$REPO"; then
361+
return 0
362+
fi
363+
364+
echo "Could not reactivate CI run $run_id; scheduled monitor will retry."
365+
return 1
366+
}
367+
368+
wait_for_ci_activation() {
369+
local pr="$1"
370+
local head_sha="$2"
371+
local timeout="${CI_ACTIVATION_WAIT_SECONDS:-0}"
372+
local deadline payload current_head state
373+
374+
if ! grep -Eq '^[0-9]+$' <<<"$timeout" || [ "$timeout" -le 0 ]; then
375+
return 1
376+
fi
377+
378+
deadline=$((SECONDS + timeout))
379+
while [ "$SECONDS" -lt "$deadline" ]; do
380+
sleep 10
381+
payload="$(pr_json "$pr")"
382+
current_head="$(jq -r '.headRefOid' <<<"$payload")"
383+
if [ "$current_head" != "$head_sha" ]; then
384+
echo "PR #$pr head changed from $head_sha to $current_head while waiting for CI."
385+
return 0
386+
fi
387+
388+
state="$(evaluate_readiness "$payload")"
389+
case "$state" in
390+
waiting|needs_ci)
391+
echo "CI for PR #$pr is still $state; continuing to wait."
392+
;;
393+
*)
394+
echo "CI for PR #$pr settled to $state."
395+
return 0
396+
;;
397+
esac
398+
done
399+
400+
echo "CI for PR #$pr did not settle within ${timeout}s; a later Evergreen run will continue."
401+
return 1
328402
}
329403
330404
update_branch_if_needed() {
@@ -402,7 +476,25 @@ jobs:
402476
return 1
403477
;;
404478
needs_ci)
405-
trigger_ci_if_needed "$pr" "$head_sha"
479+
if trigger_ci_if_needed "$pr" "$head_sha" &&
480+
wait_for_ci_activation "$pr" "$head_sha"; then
481+
payload="$(pr_json "$pr")"
482+
head_sha="$(jq -r '.headRefOid' <<<"$payload")"
483+
state="$(evaluate_readiness "$payload")"
484+
if ! reconcile_ready_label "$pr" "$state" "$payload"; then
485+
echo "Could not reconcile $READY_LABEL for PR #$pr after CI activation; refusing to dispatch the agent."
486+
set_result "false" "$pr" "$head_sha" "blocked" "$reason:ready_label_failed"
487+
return 1
488+
fi
489+
490+
if [ "$state" = "needs_repair" ]; then
491+
if ! claim_active_label "$pr" "$head_sha" "$reason:ci_failed_after_activation"; then
492+
return 1
493+
fi
494+
set_result "true" "$pr" "$head_sha" "$state" "$reason:ci_failed_after_activation"
495+
return 0
496+
fi
497+
fi
406498
return 1
407499
;;
408500
needs_branch_update)

.github/workflows/shared/evergreen/repo-policy.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,14 @@ readiness controller and the agentic orchestrator must both respect this file.
4242
(new head SHA, pending, failing, missing check, conflict, out of scope).
4343
- Current-head SHA policy: readiness is evaluated only against the current PR
4444
head SHA. A new push invalidates prior readiness.
45-
- Pending check policy: `waiting` — do not repair pending or in-progress checks.
45+
- Failing check policy: `needs_repair` — if a configured gate is visibly
46+
failing for the current head SHA, dispatch the repair agent even when other
47+
configured checks are still missing or skipped.
48+
- Pending check policy: `waiting` — do not repair pending or in-progress checks
49+
unless another configured gate has already failed.
4650
- Missing/stale check policy: `needs_ci` — reactivate the latest `CI` run for the
47-
head SHA once (see CI/CD Activation). Never rerun green checks.
51+
head SHA once, wait briefly for a result, then dispatch repair in the same run
52+
if the gate fails (see CI/CD Activation). Never rerun green checks.
4853
- Branch freshness ready criterion: not required to be up to date with `main`;
4954
freshness is only enforced when the branch is conflicted (`DIRTY`/`UNKNOWN`).
5055
- Additional deterministic ready criteria: PR open, has `evergreen`, not
@@ -100,7 +105,9 @@ readiness controller and the agentic orchestrator must both respect this file.
100105
- Workflows/checks Evergreen may dispatch: none by name in v1; activation is
101106
rerun-based only.
102107
- Stale check policy: reactivate the latest `CI` run for the head SHA once per
103-
head; never rerun green checks; never re-trigger an already in-progress run.
108+
head; briefly wait for it to settle; dispatch repair immediately if a
109+
configured gate fails; never rerun green checks; never re-trigger an already
110+
in-progress run.
104111
- Missing check policy: if no `CI` run exists for the head SHA, wait for the
105112
normal `pull_request`/schedule CI to start rather than forcing activation.
106113
- Empty commit policy: empty trigger commits are a last resort only, requested

0 commit comments

Comments
 (0)