Merge pull request #21 from pezkuwichain/ci/backend-deploy-guard

ci: backend indexer deploy — self-contained config + host gate
This commit is contained in:
SatoshiQaziMuhammed
2026-07-25 21:26:56 -07:00
committed by GitHub
+39 -5
View File
@@ -753,12 +753,34 @@ jobs:
# Host param via secret BACKEND_VPS_HOST (no hardcoded IP). If the backend
# shares the web DEV VPS, set BACKEND_VPS_HOST = VPS_HOST (see backend/DEPLOY.md).
# ========================================
# Config gate: the backend indexer only deploys once its host is provisioned.
# Until BACKEND_VPS_HOST is set, deploy-backend skips cleanly (neutral, no false
# failure/alert) instead of erroring on "missing server host" every push.
backend-cfg:
name: Backend deploy config check
runs-on: pwap-runner
if: (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')) && (github.event_name == 'push' || github.event_name == 'workflow_dispatch')
outputs:
configured: ${{ steps.c.outputs.configured }}
steps:
- id: c
env:
BH: ${{ secrets.BACKEND_VPS_HOST }}
run: |
if [ -n "$BH" ]; then
echo "configured=true" >> "$GITHUB_OUTPUT"
else
echo "::notice::BACKEND_VPS_HOST unset — backend indexer deploy skipped (provision the host to enable)"
echo "configured=false" >> "$GITHUB_OUTPUT"
fi
deploy-backend:
name: Deploy Backend (indexer)
runs-on: pwap-runner
needs: [telegram-gate, build-image-backend]
needs: [telegram-gate, build-image-backend, backend-cfg]
if: |
always() &&
needs.backend-cfg.outputs.configured == 'true' &&
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')) &&
needs.telegram-gate.result == 'success' &&
((github.event_name == 'push' && needs.build-image-backend.result == 'success') ||
@@ -811,7 +833,7 @@ jobs:
username: ${{ secrets.BACKEND_VPS_USER }}
key: ${{ secrets.BACKEND_VPS_SSH_KEY }}
port: ${{ secrets.BACKEND_VPS_SSH_PORT || 22 }}
envs: IMAGE_REF,NEW_SHA,GHCR_USER,GHCR_TOKEN
envs: IMAGE_REF,NEW_SHA,GHCR_USER,GHCR_TOKEN,WS_ENDPOINT,HOST_PORT
command_timeout: 10m
script_stop: true
script: |
@@ -820,6 +842,7 @@ jobs:
IMAGE="$REGISTRY_IMAGE:$NEW_SHA"
STATE_DIR="/opt/pwap-indexer"
NAME="pwap-indexer"
HOST_PORT="${HOST_PORT:-3001}"
mkdir -p "$STATE_DIR"
PREV="$(cat "$STATE_DIR/.deploy-sha" 2>/dev/null || echo "")"
echo "Deploying $IMAGE (previous: ${PREV:-none})"
@@ -832,18 +855,25 @@ jobs:
docker rm -f "$NAME" >/dev/null 2>&1 || true
# Named volume pwap-indexer-db = stateful sqlite DB. NEVER removed
# by this script — it is created on first run and reused forever.
# Config comes from the workflow (GitHub secrets/vars), NOT a
# hand-placed file on the host. The indexer (src/index.js) only
# needs WS_ENDPOINT beyond the fixed PORT/DB_PATH; it runs no
# KYC/council service, so no seed/Supabase secret is required.
# Host port is configurable (HOST_PORT, default 3001) so the indexer
# can co-exist with whatever else runs on the box; the container
# always listens on 3001 internally.
docker run -d --name "$NAME" --restart unless-stopped \
-p 3001:3001 \
-p "${HOST_PORT}:3001" \
-v pwap-indexer-db:/data \
-e DB_PATH=/data/transactions.db \
-e PORT=3001 \
--env-file "$STATE_DIR/.env" \
-e WS_ENDPOINT="$WS_ENDPOINT" \
"$img"
}
healthy () {
for i in $(seq 1 12); do
if curl -fsS --max-time 5 "http://localhost:3001/health" >/dev/null 2>&1; then
if curl -fsS --max-time 5 "http://localhost:${HOST_PORT}/health" >/dev/null 2>&1; then
return 0
fi
echo "health attempt $i/12 failed, retry in 5s..."
@@ -880,6 +910,10 @@ jobs:
NEW_SHA: ${{ steps.sha.outputs.sha }}
GHCR_USER: ${{ github.actor }}
GHCR_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Non-secret chain endpoint; override via the INDEXER_WS_ENDPOINT secret if needed.
WS_ENDPOINT: ${{ secrets.INDEXER_WS_ENDPOINT || 'wss://rpc.pezkuwichain.io' }}
# Host port for the indexer (container is always 3001 internally).
HOST_PORT: ${{ secrets.INDEXER_HOST_PORT || '3001' }}
- name: Post-deploy notification
if: success()