diff --git a/.github/workflows/evergreen.lock.yml b/.github/workflows/evergreen.lock.yml index 8e2acbb8..88d74f31 100644 --- a/.github/workflows/evergreen.lock.yml +++ b/.github/workflows/evergreen.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"0f396f50935c8f16ec533e43058978b14bf053bc2c6f489fc5e8612b2e68ec55","body_hash":"145147ca182cc8ee81f803eb3eab5c35bd5bb1da0ed427b93dfc341f5bc4025b","compiler_version":"v0.79.4","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.60"}} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"d45f839a4ad149d101caba80163b04d9a444aac746fb65fe7469d58d44a7ee40","body_hash":"a4d7db91f7e9ca4e7cba1676052255426f43cca5d5bf193047ff845a5ba81892","compiler_version":"v0.79.4","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.60"}} # gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"df4cb1c069e1874edd31b4311f1884172cec0e10","version":"v6.0.3"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"d059700c6a8ec3b5fd798b9ea60f5d048447b918","version":"v0.79.4"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.0"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.0"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.0"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.25","digest":"sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa"},{"image":"ghcr.io/github/github-mcp-server:v1.1.2","digest":"sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c","pinned_image":"ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c"},{"image":"node:lts-alpine","digest":"sha256:2bdb65ed1dab192432bc31c95f94155ca5ad7fc1392fb7eb7526ab682fa5bf14","pinned_image":"node:lts-alpine@sha256:2bdb65ed1dab192432bc31c95f94155ca5ad7fc1392fb7eb7526ab682fa5bf14"}]} # ___ _ _ # / _ \ | | (_) @@ -1827,6 +1827,30 @@ jobs: return 1 } + any_configured_check_failing() { + local payload="$1" + local required="$2" + local count + local state + + count="$(jq 'length' <<<"$required")" + if [ "$count" -eq 0 ]; then + has_failing_check "$payload" + return + fi + + while IFS= read -r name; do + state="$(check_state_for "$payload" "$name")" + case "$state" in + FAILURE|failure|FAILED|failed|ERROR|error|TIMED_OUT|timed_out|CANCELLED|cancelled) + return 0 + ;; + esac + done < <(jq -r '.[]' <<<"$required") + + return 1 + } + evaluate_readiness() { local payload="$1" local required @@ -1850,6 +1874,11 @@ jobs: return 0 fi + if any_configured_check_failing "$payload" "$required"; then + echo "needs_repair" + return 0 + fi + if any_configured_check_missing "$payload" "$required"; then echo "needs_ci" return 0 @@ -1944,7 +1973,7 @@ jobs: if [ -z "$run_id" ]; then echo "No CI run found for PR #$pr ($head_sha); leaving for scheduled/PR CI to start." - return 0 + return 1 fi case "$status" in @@ -1957,14 +1986,22 @@ jobs: case "$conclusion" in success) echo "CI run $run_id for PR #$pr ($head_sha) already succeeded; not rerunning green checks." - return 0 + return 1 ;; esac echo "Reactivating CI run $run_id for PR #$pr ($head_sha) (status=$status conclusion=$conclusion)." - ci_gh gh run rerun "$run_id" --repo "$REPO" --failed || \ - ci_gh gh run rerun "$run_id" --repo "$REPO" || \ - echo "Could not reactivate CI run $run_id; scheduled monitor will retry." + if ci_gh gh run rerun "$run_id" --repo "$REPO" --failed; then + return 0 + fi + + echo "Failed-jobs rerun was unavailable for CI run $run_id; trying full rerun." + if ci_gh gh run rerun "$run_id" --repo "$REPO"; then + return 0 + fi + + echo "Could not reactivate CI run $run_id; scheduled monitor will retry." + return 1 } update_branch_if_needed() { @@ -2042,7 +2079,7 @@ jobs: return 1 ;; needs_ci) - trigger_ci_if_needed "$pr" "$head_sha" + trigger_ci_if_needed "$pr" "$head_sha" || true return 1 ;; needs_branch_update) diff --git a/.github/workflows/evergreen.md b/.github/workflows/evergreen.md index 8e66399c..d6713e89 100644 --- a/.github/workflows/evergreen.md +++ b/.github/workflows/evergreen.md @@ -187,6 +187,30 @@ jobs: return 1 } + any_configured_check_failing() { + local payload="$1" + local required="$2" + local count + local state + + count="$(jq 'length' <<<"$required")" + if [ "$count" -eq 0 ]; then + has_failing_check "$payload" + return + fi + + while IFS= read -r name; do + state="$(check_state_for "$payload" "$name")" + case "$state" in + FAILURE|failure|FAILED|failed|ERROR|error|TIMED_OUT|timed_out|CANCELLED|cancelled) + return 0 + ;; + esac + done < <(jq -r '.[]' <<<"$required") + + return 1 + } + evaluate_readiness() { local payload="$1" local required @@ -210,6 +234,11 @@ jobs: return 0 fi + if any_configured_check_failing "$payload" "$required"; then + echo "needs_repair" + return 0 + fi + if any_configured_check_missing "$payload" "$required"; then echo "needs_ci" return 0 @@ -304,7 +333,7 @@ jobs: if [ -z "$run_id" ]; then echo "No CI run found for PR #$pr ($head_sha); leaving for scheduled/PR CI to start." - return 0 + return 1 fi case "$status" in @@ -317,14 +346,22 @@ jobs: case "$conclusion" in success) echo "CI run $run_id for PR #$pr ($head_sha) already succeeded; not rerunning green checks." - return 0 + return 1 ;; esac echo "Reactivating CI run $run_id for PR #$pr ($head_sha) (status=$status conclusion=$conclusion)." - ci_gh gh run rerun "$run_id" --repo "$REPO" --failed || \ - ci_gh gh run rerun "$run_id" --repo "$REPO" || \ - echo "Could not reactivate CI run $run_id; scheduled monitor will retry." + if ci_gh gh run rerun "$run_id" --repo "$REPO" --failed; then + return 0 + fi + + echo "Failed-jobs rerun was unavailable for CI run $run_id; trying full rerun." + if ci_gh gh run rerun "$run_id" --repo "$REPO"; then + return 0 + fi + + echo "Could not reactivate CI run $run_id; scheduled monitor will retry." + return 1 } update_branch_if_needed() { @@ -402,7 +439,7 @@ jobs: return 1 ;; needs_ci) - trigger_ci_if_needed "$pr" "$head_sha" + trigger_ci_if_needed "$pr" "$head_sha" || true return 1 ;; needs_branch_update) diff --git a/.github/workflows/shared/evergreen/repo-policy.md b/.github/workflows/shared/evergreen/repo-policy.md index 95dd48d5..4e69f5a1 100644 --- a/.github/workflows/shared/evergreen/repo-policy.md +++ b/.github/workflows/shared/evergreen/repo-policy.md @@ -42,9 +42,14 @@ readiness controller and the agentic orchestrator must both respect this file. (new head SHA, pending, failing, missing check, conflict, out of scope). - Current-head SHA policy: readiness is evaluated only against the current PR head SHA. A new push invalidates prior readiness. -- Pending check policy: `waiting` — do not repair pending or in-progress checks. +- Failing check policy: `needs_repair` — if a configured gate is visibly + failing for the current head SHA, dispatch the repair agent even when other + configured checks are still missing or skipped. +- Pending check policy: `waiting` — do not repair pending or in-progress checks + unless another configured gate has already failed. - Missing/stale check policy: `needs_ci` — reactivate the latest `CI` run for the - head SHA once (see CI/CD Activation). Never rerun green checks. + head SHA once, then stop so a later reconciliation can classify the resulting + checks (see CI/CD Activation). Never rerun green checks. - Branch freshness ready criterion: not required to be up to date with `main`; freshness is only enforced when the branch is conflicted (`DIRTY`/`UNKNOWN`). - Additional deterministic ready criteria: PR open, has `evergreen`, not