#!/usr/bin/env bash # 服务器部署脚本:拉取代码、准备 .venv、安装依赖、执行迁移并重启服务。 set -euo pipefail PROJECT_DIR="${PROJECT_DIR:-$(cd "$(dirname "$0")" && pwd)}" REMOTE="${REMOTE:-origin}" BRANCH="${DEPLOY_BRANCH:-${GITHUB_REF_NAME:-}}" SERVICE_NAME="${SERVICE_NAME:-weread.service}" VENV_DIR="${VENV_DIR:-$PROJECT_DIR/.venv}" ENV_FILE="${ENV_FILE:-$PROJECT_DIR/.env}" cd "$PROJECT_DIR" if [ -z "$BRANCH" ]; then BRANCH="$(git branch --show-current)" fi if [ -z "$BRANCH" ]; then echo "未检测到部署分支,请设置 DEPLOY_BRANCH" exit 1 fi if [ "${SKIP_GIT_PULL:-0}" = "1" ]; then echo "[1/5] 代码已拉取,跳过 git pull" else echo "[1/5] 拉取 $REMOTE/$BRANCH" git fetch "$REMOTE" git checkout "$BRANCH" git pull --ff-only "$REMOTE" "$BRANCH" fi if [ -f "$ENV_FILE" ]; then set -a # shellcheck disable=SC1090 . "$ENV_FILE" set +a elif command -v systemctl >/dev/null 2>&1; then SERVICE_ENV="$(systemctl show "$SERVICE_NAME" --property=Environment --value 2>/dev/null || true)" for item in $SERVICE_ENV; do case "$item" in *=*) export "$item" ;; esac done fi find_python() { if command -v python3 >/dev/null 2>&1; then command -v python3 return fi if command -v python >/dev/null 2>&1; then command -v python return fi echo "未找到 python3 或 python,请先在服务器安装 Python" exit 1 } echo "[2/5] 检测 Python 虚拟环境" if [ ! -x "$VENV_DIR/bin/python" ]; then "$(find_python)" -m venv "$VENV_DIR" fi PYTHON="$VENV_DIR/bin/python" echo "[3/5] 安装依赖" if ! "$PYTHON" -m pip --version >/dev/null 2>&1; then "$PYTHON" -m ensurepip --upgrade fi "$PYTHON" -m pip install -r requirements.txt echo "[4/5] 执行数据库迁移" "$PYTHON" - <<'PY' from pathlib import Path import pymysql from reading_api import MYSQL_CONFIG migration = Path("migrations/001_reading_goals.sql") if migration.exists(): with pymysql.connect(**MYSQL_CONFIG) as conn: with conn.cursor() as cur: for sql in migration.read_text(encoding="utf-8").split(";"): if sql.strip(): cur.execute(sql) conn.commit() PY echo "[5/5] 重启服务 $SERVICE_NAME" if command -v systemctl >/dev/null 2>&1; then if [ "$(id -u)" -eq 0 ]; then systemctl restart "$SERVICE_NAME" systemctl status "$SERVICE_NAME" --no-pager else sudo systemctl restart "$SERVICE_NAME" sudo systemctl status "$SERVICE_NAME" --no-pager fi else echo "当前系统没有 systemctl,请手动用 $PYTHON app.py 启动" fi