191 lines
7.1 KiB
Bash
Executable File
191 lines
7.1 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
# ============================================
|
||
# 从 GitHub 部署到生产环境(迁移后:Git 根 = wildgrowth-backend,应用根 = backend)
|
||
# ============================================
|
||
# 使用方法:
|
||
# ssh root@120.55.112.195
|
||
# cd /var/www/wildgrowth-backend/backend && bash deploy/deploy-from-github.sh [分支名]
|
||
# 默认分支:1.30dazhi合并前(不部署 main 上的错误合并)
|
||
# git pull 超时 60s,失败会提示在本机执行 backend/deploy/deploy-rsync-from-local.sh
|
||
# SKIP_GIT_PULL=1 时跳过拉取(供 rsync 回退后使用);GIT_PULL_TIMEOUT=90 可改超时秒数
|
||
# 回滚:bash deploy/deploy-from-github.sh rollback
|
||
# ============================================
|
||
|
||
set -e
|
||
|
||
GIT_ROOT="/var/www/wildgrowth-backend"
|
||
APP_ROOT="/var/www/wildgrowth-backend/backend"
|
||
|
||
# ---------- 回滚模式 ----------
|
||
if [ "$1" = "rollback" ]; then
|
||
echo "═══════════════════════════════════════════════════════════"
|
||
echo " 🔄 回滚模式:回退到上次成功部署的版本"
|
||
echo "═══════════════════════════════════════════════════════════"
|
||
echo ""
|
||
|
||
if [ ! -d "$APP_ROOT" ]; then
|
||
echo "❌ 错误: $APP_ROOT 不存在"
|
||
exit 1
|
||
fi
|
||
if [ ! -f "$APP_ROOT/.deploy-last" ]; then
|
||
echo "❌ 无上次部署记录(.deploy-last 不存在)"
|
||
echo " 请手动:git -C $GIT_ROOT log --oneline -5,checkout <commit> 后重新 build 并 pm2 restart"
|
||
exit 1
|
||
fi
|
||
PREV=$(cat "$APP_ROOT/.deploy-last" | tr -d '[:space:]')
|
||
if [ -z "$PREV" ]; then
|
||
echo "❌ .deploy-last 为空,无法回滚"
|
||
exit 1
|
||
fi
|
||
|
||
echo "📌 回滚到: $PREV"
|
||
echo ""
|
||
|
||
(cd "$GIT_ROOT" && git fetch origin && git checkout "$PREV")
|
||
|
||
echo "📦 安装依赖..."
|
||
(cd "$APP_ROOT" && npm install)
|
||
echo "🔧 Prisma generate..."
|
||
(cd "$APP_ROOT" && npx prisma generate)
|
||
echo "🗄️ 数据库迁移..."
|
||
MIGRATIONS="$APP_ROOT/prisma/migrations"
|
||
if [ -d "$MIGRATIONS" ]; then
|
||
for d in "$MIGRATIONS"/*/; do
|
||
[ -d "$d" ] || continue
|
||
if [ ! -f "${d}migration.sql" ]; then rm -rf "$d"; fi
|
||
done
|
||
fi
|
||
(cd "$APP_ROOT" && npx prisma migrate deploy)
|
||
echo "🔨 构建..."
|
||
(cd "$APP_ROOT" && npm run build)
|
||
echo "🔄 重启服务..."
|
||
pm2 restart wildgrowth-api
|
||
|
||
echo "⏳ 等待 3s 后健康检查..."
|
||
sleep 3
|
||
if curl -sf http://localhost:3000/health > /dev/null; then
|
||
echo "✅ 回滚完成,服务正常"
|
||
else
|
||
echo "⚠️ 健康检查未通过,请检查: pm2 logs wildgrowth-api"
|
||
fi
|
||
echo ""
|
||
exit 0
|
||
fi
|
||
|
||
# ---------- 正常部署 ----------
|
||
BRANCH=${1:-1.30dazhi合并前}
|
||
GIT_PULL_TIMEOUT=${GIT_PULL_TIMEOUT:-60}
|
||
|
||
echo "═══════════════════════════════════════════════════════════"
|
||
echo " 🚀 开始从 GitHub 部署到生产环境"
|
||
echo " 📦 部署分支: $BRANCH"
|
||
echo "═══════════════════════════════════════════════════════════"
|
||
echo ""
|
||
|
||
if [ ! -d "$APP_ROOT" ]; then
|
||
echo "❌ 错误: $APP_ROOT 不存在"
|
||
exit 1
|
||
fi
|
||
if [ ! -f "$APP_ROOT/.env" ]; then
|
||
echo "❌ 错误: $APP_ROOT/.env 不存在"
|
||
exit 1
|
||
fi
|
||
|
||
# 1. 拉取最新代码(在 Git 根);若 SKIP_GIT_PULL=1 则跳过(供 rsync 回退后使用)
|
||
if [ -n "$SKIP_GIT_PULL" ]; then
|
||
echo "📥 步骤 1: 跳过 git pull(SKIP_GIT_PULL=1,代码已由 rsync 同步)"
|
||
else
|
||
echo "📥 步骤 1: 拉取最新代码(超时 ${GIT_PULL_TIMEOUT}s)..."
|
||
(cd "$GIT_ROOT" && git fetch origin)
|
||
if ! (cd "$GIT_ROOT" && git show-ref --verify --quiet refs/remotes/origin/$BRANCH); then
|
||
echo "❌ 分支 $BRANCH 不存在"
|
||
(cd "$GIT_ROOT" && git branch -r | grep -v HEAD | sed 's/origin\///' | sed 's/^/ - /')
|
||
exit 1
|
||
fi
|
||
if ! (cd "$GIT_ROOT" && timeout "$GIT_PULL_TIMEOUT" git checkout $BRANCH && timeout "$GIT_PULL_TIMEOUT" git pull origin $BRANCH); then
|
||
echo ""
|
||
echo "❌ Git 拉取失败(超时或网络/凭据问题)。请在本机执行 rsync 回退部署:"
|
||
echo " cd <项目根目录> && bash backend/deploy/deploy-rsync-from-local.sh"
|
||
echo " 详见 DEPLOY_QUICK.md「三、git pull 超时:rsync 回退部署」。"
|
||
exit 1
|
||
fi
|
||
echo "✅ 代码已更新 (分支: $BRANCH)"
|
||
fi
|
||
echo ""
|
||
|
||
# 2. 安装依赖
|
||
echo "📦 步骤 2: 安装依赖..."
|
||
(cd "$APP_ROOT" && npm install)
|
||
echo "✅ 依赖已安装"
|
||
echo ""
|
||
|
||
# 3. Prisma generate
|
||
echo "🔧 步骤 3: Prisma generate..."
|
||
(cd "$APP_ROOT" && npx prisma generate)
|
||
echo ""
|
||
|
||
# 4. 数据库迁移(先删缺 migration.sql 的目录,避免 P3015)
|
||
echo "🗄️ 步骤 4: 数据库迁移..."
|
||
MIGRATIONS="$APP_ROOT/prisma/migrations"
|
||
if [ -d "$MIGRATIONS" ]; then
|
||
for d in "$MIGRATIONS"/*/; do
|
||
[ -d "$d" ] || continue
|
||
if [ ! -f "${d}migration.sql" ]; then
|
||
echo " 删除残缺 migration 目录: $(basename "$d")"
|
||
rm -rf "$d"
|
||
fi
|
||
done
|
||
fi
|
||
(cd "$APP_ROOT" && npx prisma migrate deploy)
|
||
echo "✅ 数据库迁移完成"
|
||
echo ""
|
||
|
||
# 4.5. 迁移Prompt配置(如果脚本存在)
|
||
echo "📝 步骤 4.5: 迁移Prompt配置..."
|
||
if [ -f "$APP_ROOT/scripts/migrate-prompt-configs.ts" ]; then
|
||
(cd "$APP_ROOT" && npx ts-node scripts/migrate-prompt-configs.ts) || echo "⚠️ Prompt配置迁移失败,但继续部署"
|
||
echo "✅ Prompt配置迁移完成"
|
||
else
|
||
echo "ℹ️ Prompt配置迁移脚本不存在,跳过"
|
||
fi
|
||
echo ""
|
||
|
||
# 5. 构建
|
||
echo "🔨 步骤 5: 构建项目..."
|
||
(cd "$APP_ROOT" && npm run build)
|
||
echo "✅ 项目已构建"
|
||
echo ""
|
||
|
||
# 6. 重启服务
|
||
echo "🔄 步骤 6: 重启服务..."
|
||
pm2 restart wildgrowth-api
|
||
echo ""
|
||
|
||
# 7. 健康检查
|
||
echo "🏥 步骤 7: 健康检查..."
|
||
sleep 2
|
||
if curl -sf http://localhost:3000/health > /dev/null; then
|
||
echo "✅ 健康检查通过"
|
||
(cd "$GIT_ROOT" && git rev-parse HEAD) > "$APP_ROOT/.deploy-last"
|
||
echo " (已记录到 .deploy-last,供 rollback 使用)"
|
||
else
|
||
echo "❌ 健康检查失败: curl http://localhost:3000/health 未返回成功"
|
||
echo " 请检查: pm2 logs wildgrowth-api"
|
||
exit 1
|
||
fi
|
||
echo ""
|
||
|
||
# 8. 状态与日志
|
||
echo "📊 步骤 8: 服务状态"
|
||
pm2 status wildgrowth-api
|
||
echo "📝 最近日志:"
|
||
pm2 logs wildgrowth-api --lines 20 --nostream
|
||
echo ""
|
||
|
||
echo "═══════════════════════════════════════════════════════════"
|
||
echo " ✅ 部署完成!分支: $BRANCH"
|
||
echo "═══════════════════════════════════════════════════════════"
|
||
echo "💡 回滚: bash deploy/deploy-from-github.sh rollback"
|
||
echo ""
|