feat(soong-lab-ci): green-gated push-to-deploy CI/CD for the soong-lab studio
Vuong-directed. gitea webhook (push→main) → HMAC listener on corviduo-dev:9010 → clone (read-only deploy key) → uv sync + pytest → redeploy soong-lab-studio.service ONLY on green (running studio untouched on red). Validated end-to-end 2026-07-13. Canonical copies of the deploy script + listener + unit; runbook in docs/runbooks.
This commit is contained in:
Executable
+31
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env bash
|
||||
# soong-lab CI/CD deploy: clone -> uv sync + pytest -> deploy studio ONLY on green.
|
||||
# Running studio is NEVER touched on a red test run (safe-by-construction).
|
||||
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
|
||||
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 to studio ==="
|
||||
rsync -a --delete --exclude .venv/ --exclude "*.env" --exclude "*.db" --exclude "*.sqlite*" --exclude "data/" --exclude "state/" --exclude "logs/" "$SRC/backend/" "$STUDIO/" || fail "rsync to studio failed" rsync
|
||||
cd "$STUDIO"
|
||||
"$UV" sync --no-dev || fail "studio uv sync failed" studio_sync
|
||||
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"
|
||||
printf "{\"result\":\"green\",\"sha\":\"%s\",\"at\":\"%s\"}\n" "$SHA" "$(date -u +%FT%TZ)" > "$STATUS"
|
||||
Reference in New Issue
Block a user