when: - branch: main event: push variables: - &ssh_setup | apk add --no-cache openssh-client rsync mkdir -p ~/.ssh printf '%s\n' "$SSH_DEPLOY_KEY" > ~/.ssh/id_ed25519 chmod 600 ~/.ssh/id_ed25519 ssh-keyscan -H git.sxbh.ltd >> ~/.ssh/known_hosts chmod 644 ~/.ssh/known_hosts steps: frontend-install: image: node:20-alpine commands: - apk add --no-cache git - cd frontend - npm install -g pnpm - pnpm install when: - path: frontend/** frontend-typecheck: image: node:20-alpine commands: - cd frontend - npm install -g pnpm - pnpm install - pnpm vue-tsc --noEmit || true when: - path: frontend/** frontend-build: image: node:20-alpine commands: - cd frontend - npm install -g pnpm - pnpm install - pnpm build when: - path: frontend/** backend-test: image: python:3.12 commands: - cd backend - pip install -r requirements.txt --quiet - python -m pytest tests/ -x -q --disable-warnings --timeout=60 || true when: - path: backend/** frontend-deploy: image: alpine:latest secrets: - SSH_DEPLOY_KEY commands: - *ssh_setup - rsync -avz --delete frontend/dist/ root@git.sxbh.ltd:/var/www/cma/ - ssh root@git.sxbh.ltd 'nginx -s reload || systemctl reload nginx' when: - path: frontend/** backend-deploy: image: alpine:latest secrets: - SSH_DEPLOY_KEY commands: - *ssh_setup - | ssh root@git.sxbh.ltd 'set -e; cd /root/cma-management; DIRTY=$(git status --porcelain 2>/dev/null | grep -v "__pycache__" | head -10); if [ -n "$DIRTY" ]; then echo "❌ 宿主机有未提交修改,中止部署:"; echo "$DIRTY"; exit 1; fi; git pull origin main; cd backend; pip install -r requirements.txt --quiet --no-cache-dir; systemctl restart cma-backend; SMOKE_READY_MAX="${SMOKE_READY_MAX:-30}"; READY_TRY=0; READY_OK=0; READY_T0=$(date +%s); READY_BODY=/tmp/cma-ci-ready-body.json; while [ $(( $(date +%s) - READY_T0 )) -lt "$SMOKE_READY_MAX" ]; do CODE=$(curl -s -o "$READY_BODY" -w "%{http_code}" --max-time 2 http://127.0.0.1:8010/health || echo 000); if [ "$CODE" = "200" ] && grep -q "\"status\":\"ok\"" "$READY_BODY" 2>/dev/null; then READY_OK=1; break; fi; sleep 0.5; READY_TRY=$(( READY_TRY + 1 )); done; if [ "$READY_OK" != "1" ]; then echo "🚨 后端就绪超时 ${SMOKE_READY_MAX}s(未达 HTTP200 + status=ok)"; cat "$READY_BODY" 2>/dev/null; exit 1; fi; echo "✅ 后端就绪(轮询 ${READY_TRY} 次,上限 ${SMOKE_READY_MAX}s)"; cat "$READY_BODY"' when: - path: backend/**