diff --git a/.github/workflows/deploy-dev.yaml b/.github/workflows/deploy-dev.yaml index fa140756..32ce85b8 100644 --- a/.github/workflows/deploy-dev.yaml +++ b/.github/workflows/deploy-dev.yaml @@ -102,28 +102,45 @@ jobs: ${{ secrets.DEPLOY_DEV_USER }}@${{ secrets.DEPLOY_DEV_HOST }} \ "$DEPLOY_CMD" - # Post-deploy smoke test: hit the public endpoint until /api/info - # answers 200 or we give up. A green "Build and deploy to DEV" - # without this step was historically misleading — a runtime-bootstrap - # panic left the container Up-but-unresponsive while the workflow - # reported success. Failing this step blocks the auto-release PR - # from collecting a green check and surfaces the regression in CI. + # Post-deploy smoke test: hit the public endpoint until + # /health/ready reports `ready: true` (or we give up). A green + # "Build and deploy to DEV" without this step was historically + # misleading — a runtime-bootstrap panic left the container + # Up-but-unresponsive while the workflow reported success. + # Failing this step blocks the auto-release PR from collecting + # a green check and surfaces the regression in CI. + # + # `/health/ready` (not `/api/info`) is the load-bearing gate. + # Post-#154 the node binds the HTTP listener immediately and + # warms the Plonky2 prover in a background task; `/api/info` + # returns 200 within seconds, but `/health/ready` stays at + # `{"ready":false,"prover":"warming"}` for the 10-30 s warmup. + # Downstream jobs (E2E preflight, smoke tests against the + # publisher wallet) gated on `/health/ready` and were racing + # the warmup — observed empirically in + # https://github.com/zk-coins/node/actions/runs/26793933906/job/78986599030 + # (Release PR #166, prover still warming at +4 s after the + # E2E job picked the runner up). Polling `/health/ready` here + # means the deploy job only reports success once the node is + # actually ready for traffic. - name: Smoke test public endpoint run: | set -euo pipefail - URL="https://dev-api.zkcoins.app/api/info" + URL="https://dev-api.zkcoins.app/health/ready" for i in $(seq 1 30); do - code=$(curl -sS -o /tmp/info.json -w '%{http_code}' --max-time 10 "$URL" || echo "000") - if [ "$code" = "200" ]; then - echo "DEV /api/info responded 200 after ${i} attempt(s):" - cat /tmp/info.json + body=$(curl -sS -o /tmp/ready.json -w '%{http_code}' --max-time 10 "$URL" || echo "000") + code="$body" + if [ "$code" = "200" ] && jq -e '.ready == true' /tmp/ready.json > /dev/null 2>&1; then + echo "DEV /health/ready reports ready=true after ${i} attempt(s):" + cat /tmp/ready.json echo exit 0 fi - echo "[$i/30] $URL -> ${code} (waiting 10 s)" + ready_snap=$(jq -c '. // "(no body)"' /tmp/ready.json 2>/dev/null || echo "(non-json)") + echo "[$i/30] $URL -> ${code} ${ready_snap} (waiting 10 s)" sleep 10 done - echo "::error::DEV /api/info never returned 200 within ~5 min after deploy" + echo "::error::DEV /health/ready never reported ready=true within ~5 min after deploy" exit 1 # Functional verification of the deployed DEV node.