#!/usr/bin/env bash # ci-test-review :: deterministic PR verification on the CI server (NO AI) # ------------------------------------------------------------------------- # Verifies a RECIPE PR the same way `!testme` does: deploy + run the FULL suite # COLD against the PR head on cc-ci. The harness decides pass/fail — this script # only runs it and reports the exit code + RUN SUMMARY. AI never judges here. # # RECIPE=ghost REF=my-fix-branch verify-pr.sh # 1 cold green = working # RECIPE=lasuite-drive REF=sha REPEAT=3 verify-pr.sh # repeated-green: ONLY # # for a known-flaky recipe # # REF is the recipe PR head (branch name or sha) on the recipe mirror that abra # fetches from. Green iff EVERY repeat exits 0. # # (CI-SERVER PRs are verified differently — check the branch out in a clone on # cc-ci, rebuild, re-run the failing recipe(s) + a regression sample — see # SKILL.md step 5; that path is bespoke and not scripted here.) set -o errexit -o nounset -o pipefail SSH="${SSH:-cc-ci}" REPEAT="${REPEAT:-1}" : "${RECIPE:?set RECIPE (e.g. ghost)}" : "${REF:?set REF (the PR head branch or sha)}" # SRC = the mirror repo under git.autonomic.zone holding the PR branch. The harness # clones SRC at REF (then pulls upstream tags so the upgrade tier can deploy a prior # published version). Defaults to the recipe's recipe-maintainers mirror. SRC="${SRC:-recipe-maintainers/${RECIPE}}" TESTENV="${TESTENV:-/srv/cc-ci/.testenv}" set -a; . "$TESTENV"; set +a : "${GITEA_USERNAME:?}" : "${GITEA_PASSWORD:?}" : "${GITEA_URL:?}" resolve_ref_sha() { if printf '%s' "$REF" | grep -Eq '^[0-9a-f]{40}$'; then printf '%s\n' "$REF" return 0 fi branch_enc="$(jq -nr --arg x "$REF" '$x|@uri')" curl -fsS -u "${GITEA_USERNAME}:${GITEA_PASSWORD}" \ "https://${GITEA_URL}/api/v1/repos/${SRC}/branches/${branch_enc}" \ | jq -r '.commit.id // .commit.sha // empty' } REF_SHA="$(resolve_ref_sha)" [ -n "$REF_SHA" ] || { echo "ERROR: could not resolve ${SRC} ref ${REF} to a commit sha" >&2 exit 1 } resolve_remote_root() { ssh "$SSH" "for d in '${REMOTE_ROOT:-/root/builder-clone}' /root/cc-ci; do [ -f \"\$d/runner/run_recipe_ci.py\" ] && { printf '%s' \"\$d\"; exit 0; }; done; exit 1" } RUNID="$(date -u +%Y%m%dT%H%M%SZ)" REMOTE_LOG="/root/cc-ci-review-logs/verify-${RECIPE}-${RUNID}" ssh "$SSH" "mkdir -p /root/cc-ci-review-logs" REMOTE_WORKTREE="$(resolve_remote_root)" || { echo "ERROR: could not locate remote cc-ci checkout (tried ${REMOTE_ROOT:-/root/builder-clone} and /root/cc-ci)" >&2 exit 1 } echo "verify-pr: RECIPE=$RECIPE SRC=$SRC REF=$REF REF_SHA=$REF_SHA cold full-suite x${REPEAT} on ${SSH} (root=${REMOTE_WORKTREE})" >&2 green=1 for i in $(seq 1 "$REPEAT"); do log="${REMOTE_LOG}.${i}.log" rc=0 # Real harness, cold (no --quick), against the mirror PR head — same path as !testme. ssh "$SSH" "cd '${REMOTE_WORKTREE}' && RECIPE='${RECIPE}' SRC='${SRC}' REF='${REF_SHA}' cc-ci-run runner/run_recipe_ci.py >'${log}' 2>&1" || rc=$? echo "--- pass ${i}/${REPEAT}: exit ${rc} (log ${SSH}:${log}) ---" >&2 ssh "$SSH" "awk '/===== RUN SUMMARY =====/{f=1} f{print}' '${log}'" >&2 || true [ "$rc" = "0" ] || green=0 done if [ "$green" = "1" ]; then echo "VERDICT: GREEN — ${RECIPE} PR (REF=${REF}) passed cold full-suite x${REPEAT}. Ready for operator merge (NOT merged)." >&2 exit 0 else echo "VERDICT: RED — ${RECIPE} PR (REF=${REF}) did not pass. Iterate the fix (<=3 attempts) or report needs-work. Do NOT weaken tests; do NOT merge." >&2 exit 2 fi