Files
esh-pfi-infrastructure/services/soong-lab-ci/soong-lab-deploy.sh
T
vh e0f1dbfae6 fix(soong-lab-ci): sync web/ frontend on deploy (was serving stale web)
soong-dev found the studio serving a stale web/ (52015 vs 55025 bytes — missing the
01-Role section, favicon, thinking-status): the deploy rsynced backend/ but never web/,
so SOONG_LAB_WEB_DIR stayed pinned to the initial manual copy while the backend updated.
Deploy now rsyncs BOTH backend/->studio AND web/->SOONG_LAB_WEB_DIR (read from the env)
on every green run. Verified: served frontend now 55025 bytes, current.
2026-07-13 15:09:09 -07:00

48 lines
2.4 KiB
Bash
Executable File

#!/usr/bin/env bash
# soong-lab CI/CD deploy: clone -> uv sync + pytest -> deploy studio (backend + web)
# ONLY on green. Running studio is NEVER touched on a red test run.
set -uo pipefail
LOG=/home/infra-ops/soong-lab-deploy.log
exec >>"$LOG" 2>&1
echo; echo "========== deploy run $(date -u) =========="
SRC=/tmp/soong-lab-ci
STUDIO=/home/infra-ops/soong-lab/backend
ENVF=/home/infra-ops/soong-lab/soong-lab.env
WEBDIR=$(grep -E '^SOONG_LAB_WEB_DIR=' "$ENVF" 2>/dev/null | cut -d= -f2- | tr -d '"')
KEY=/home/infra-ops/.ssh/soong-deploy_ed25519
UV=/home/infra-ops/.local/bin/uv
STATUS=/home/infra-ops/.config/soong/last-deploy.json
export GIT_SSH_COMMAND="ssh -i $KEY -o IdentitiesOnly=yes -p 222"
SHA="?"
fail(){ echo "DEPLOY ABORTED [$2]: $1"; printf '{"result":"red","stage":"%s","detail":"%s","sha":"%s","at":"%s"}\n' "$2" "$1" "$SHA" "$(date -u +%FT%TZ)" > "$STATUS"; exit 1; }
rm -rf "$SRC"
git clone --depth 1 ssh://git@10.250.50.70:222/vh/soong-lab.git "$SRC" || fail "clone failed" clone
SHA=$(git -C "$SRC" rev-parse --short HEAD); echo "cloned $SHA"
cd "$SRC/backend"
"$UV" sync || fail "uv sync (test env) failed" sync
echo "=== test suite ==="
"$UV" run pytest -q || fail "TESTS RED — studio left untouched" tests
echo "=== tests GREEN — deploying backend + web ==="
# backend code -> studio WorkingDirectory
rsync -a --delete --exclude .venv/ --exclude '*.env' --exclude '*.db' --exclude '*.sqlite*' \
--exclude 'data/' --exclude 'state/' --exclude 'logs/' "$SRC/backend/" "$STUDIO/" \
|| fail "rsync backend failed" rsync
cd "$STUDIO"
"$UV" sync --no-dev || fail "studio uv sync failed" studio_sync
# frontend: the SERVED web/ (SOONG_LAB_WEB_DIR) must track the repo web/ too, else the
# frontend silently rots while the backend updates (soong-dev caught this 2026-07-13).
if [ -n "$WEBDIR" ] && [ -d "$SRC/web" ]; then
rsync -a --delete "$SRC/web/" "$WEBDIR/" || fail "rsync web failed" web
echo "web/ synced -> $WEBDIR"
else
echo "WARN: SOONG_LAB_WEB_DIR unset or repo web/ missing — skipping web sync (WEBDIR='$WEBDIR')"
fi
sudo systemctl restart soong-lab-studio.service || fail "systemctl restart failed" restart
sleep 3
systemctl is-active --quiet soong-lab-studio.service || fail "studio not active post-restart" health
echo "DEPLOYED $SHA — studio healthy (backend + web)"
printf '{"result":"green","sha":"%s","at":"%s"}\n' "$SHA" "$(date -u +%FT%TZ)" > "$STATUS"