#!/usr/bin/env bash set -Eeuo pipefail PROJECT_DIR="${AMEIBA_PROJECT_DIR:-/var/www/ameiba-cn-new}" BRANCH="${AMEIBA_BRANCH:-main}" BACKUP_DIR="${AMEIBA_BACKUP_DIR:-/var/backups/ameiba-cms}" CMS_ENV_FILE="$PROJECT_DIR/cms/server/.env" LOCK_FILE="/var/lock/ameiba-update.lock" log() { printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" } fail() { log "失败:$*" exit 1 } wait_for_url() { local url="$1" local attempts="${2:-20}" local i for ((i = 1; i <= attempts; i += 1)); do if curl --fail --silent --show-error --max-time 10 "$url" >/dev/null 2>&1; then return 0 fi sleep 1 done fail "健康检查超时:$url" } command -v git >/dev/null 2>&1 || fail '未安装 git' command -v npm >/dev/null 2>&1 || fail '未安装 npm' command -v pm2 >/dev/null 2>&1 || fail '未安装 pm2' command -v mysqldump >/dev/null 2>&1 || fail '未安装 mysqldump' command -v curl >/dev/null 2>&1 || fail '未安装 curl' exec 9>"$LOCK_FILE" flock -n 9 || fail '已有更新任务正在运行' [[ -d "$PROJECT_DIR/.git" ]] || fail "项目目录不是 Git 仓库:$PROJECT_DIR" [[ -f "$CMS_ENV_FILE" ]] || fail "CMS 环境变量文件不存在:$CMS_ENV_FILE" cd "$PROJECT_DIR" if ! git diff --quiet || ! git diff --cached --quiet; then fail '服务器存在未提交的受版本控制文件修改,请先处理后再更新' fi log '备份 MySQL 数据库' install -d -m 700 "$BACKUP_DIR" umask 077 BACKUP_FILE="$BACKUP_DIR/ameiba_cms_$(date '+%Y%m%d_%H%M%S').sql.gz" ( set -a # shellcheck disable=SC1090 source "$CMS_ENV_FILE" set +a : "${DB_HOST:?DB_HOST 未配置}" : "${DB_PORT:?DB_PORT 未配置}" : "${DB_USER:?DB_USER 未配置}" : "${DB_PASSWORD:?DB_PASSWORD 未配置}" : "${DB_NAME:?DB_NAME 未配置}" MYSQL_PWD="$DB_PASSWORD" mysqldump \ --single-transaction \ --quick \ --host="$DB_HOST" \ --port="$DB_PORT" \ --user="$DB_USER" \ "$DB_NAME" | gzip -c > "$BACKUP_FILE" ) [[ -s "$BACKUP_FILE" ]] || fail '数据库备份文件为空' log "数据库已备份:$BACKUP_FILE" OLD_COMMIT="$(git rev-parse --short HEAD)" log "从 origin/$BRANCH 拉取代码(当前 $OLD_COMMIT)" git fetch origin "$BRANCH" git pull --ff-only origin "$BRANCH" log '安装前台依赖并构建' npm ci --include=dev npm run build log '安装 CMS 后端生产依赖' ( cd "$PROJECT_DIR/cms/server" npm ci --omit=dev ) log '构建 CMS 管理后台' ( cd "$PROJECT_DIR/cms/admin" npm ci --include=dev npm run build ) log '重启 CMS 服务并保存 PM2 进程清单' pm2 restart ameba-cms --update-env pm2 save log '执行服务健康检查' wait_for_url http://127.0.0.1:13001/health wait_for_url https://www.ameiba.cn/ NEW_COMMIT="$(git rev-parse --short HEAD)" log "更新完成:$OLD_COMMIT -> $NEW_COMMIT"