name: Deploy on: push: branches: [main] jobs: deploy: runs-on: prod-deploy env: DEPLOY_BASE: /opt/ziwei-power REPO_URL: https://qiukai:${{ secrets.DEPLOY_TOKEN }}@git.qiukai.me/qiukai/ziwei-power.git SERVICE_NAME: ziwei-power steps: - name: Clone and deploy run: | set -e RELEASE_ID="${{ github.sha }}" RELEASE_DIR="${DEPLOY_BASE}/releases/${RELEASE_ID}" CLONE_DIR="/tmp/zw-deploy-${RELEASE_ID}" echo "=== 1. Clone repository ===" rm -rf "${CLONE_DIR}" git clone --depth 1 --branch main "${REPO_URL}" "${CLONE_DIR}" echo "=== 2. Prepare release directory ===" rm -rf "${RELEASE_DIR}" mkdir -p "${RELEASE_DIR}" # Copy repo content to release dir (exclude .git, .env, venv, data) rsync -a --exclude='.git' \ --exclude='.env' \ --exclude='.env.local' \ --exclude='.venv' \ --exclude='data/' \ --exclude='__pycache__' \ --exclude='.gitea' \ "${CLONE_DIR}/" "${RELEASE_DIR}/" echo "=== 2.5 Ensure .env secrets ===" mkdir -p "${DEPLOY_BASE}/shared" SHARED_ENV="${DEPLOY_BASE}/shared/.env" touch "${SHARED_ENV}" ensure_env_var() { key="$1"; val="$2" if [ -z "$val" ]; then echo " ! ${key} 未提供(CI secret 为空),跳过写入" return fi if ! grep -q "^${key}=" "${SHARED_ENV}"; then echo "${key}=${val}" >> "${SHARED_ENV}" echo " + 已写入 ${key}" else echo " = ${key} 已存在,保留原值" fi } ensure_env_var "SECRET_KEY" "${{ secrets.ZW_SECRET_KEY }}" echo "=== 3. Link shared resources ===" mkdir -p "${RELEASE_DIR}/data" # .env from shared dir (not in git) ln -sfn "${DEPLOY_BASE}/shared/.env" "${RELEASE_DIR}/.env" # Database dir symlink to persist across releases DB_DIR="$HOME/.workbuddy/data/ziwei-power" mkdir -p "${DB_DIR}" ln -sfn "${DB_DIR}" "${RELEASE_DIR}/data" echo "=== 4. Setup Python venv ===" cd "${RELEASE_DIR}" python3 -m venv .venv . .venv/bin/activate pip install --no-cache-dir -r requirements.txt echo "=== 5. Setup systemd service ===" if ! systemctl is-enabled "${SERVICE_NAME}" >/dev/null 2>&1; then cat > "/etc/systemd/system/${SERVICE_NAME}.service" </dev/null 2>&1; then echo "Health check passed" break fi echo "Attempt $i: waiting for service..." sleep 2 done # Final verify if ! curl -fsS http://127.0.0.1:5058/api/health >/dev/null 2>&1; then echo "ERROR: Health check failed after 5 attempts" echo "Rolling back to previous release..." PREV=$(ls -t "${DEPLOY_BASE}/releases" | sed -n '2p') if [ -n "${PREV}" ]; then ln -sfn "${DEPLOY_BASE}/releases/${PREV}" "${DEPLOY_BASE}/current" systemctl restart "${SERVICE_NAME}" echo "Rolled back to ${PREV}" fi exit 1 fi echo "=== 8. Cleanup old releases ===" ls -dt "${DEPLOY_BASE}"/releases/*/ | tail -n +6 | xargs -r rm -rf echo "=== 9. Cleanup temp ===" rm -rf "${CLONE_DIR}" echo "=== Deploy complete: ${RELEASE_ID} ==="