auto-sync: 2026-05-22 18:25:30
This commit is contained in:
@@ -0,0 +1,166 @@
|
||||
#!/usr/bin/env bash
|
||||
# deploy.sh — 部署/升级 moziplus v2
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
|
||||
# 默认值
|
||||
SOURCE_DIR="$PROJECT_DIR"
|
||||
TARGET_DIR="$HOME/.sanguo_projects/sanguo_moziplus_v2"
|
||||
PM2_NAME="sanguo-moziplus-v2"
|
||||
SKIP_BUILD=false
|
||||
|
||||
usage() {
|
||||
echo "Usage: $0 [options]"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --source=DIR 源码目录 (default: 项目开发目录)"
|
||||
echo " --target=DIR 安装目标目录 (default: ~/.sanguo_projects/sanguo_moziplus_v2)"
|
||||
echo " --skip-build 跳过前端构建"
|
||||
echo " -h, --help 显示帮助"
|
||||
exit 0
|
||||
}
|
||||
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--source=*) SOURCE_DIR="${arg#*=}" ;;
|
||||
--target=*) TARGET_DIR="${arg#*=}" ;;
|
||||
--skip-build) SKIP_BUILD=true ;;
|
||||
-h|--help) usage ;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo "🚀 Deploying moziplus v2"
|
||||
echo " Source: $SOURCE_DIR"
|
||||
echo " Target: $TARGET_DIR"
|
||||
|
||||
# ── 前置检查 ──
|
||||
echo ""
|
||||
echo "📋 Pre-flight checks..."
|
||||
|
||||
if ! command -v python3 &>/dev/null; then
|
||||
echo "❌ python3 not found" && exit 1
|
||||
fi
|
||||
PYTHON_VERSION=$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')
|
||||
echo " Python: $PYTHON_VERSION ✅"
|
||||
|
||||
if ! command -v pm2 &>/dev/null; then
|
||||
echo "❌ pm2 not found" && exit 1
|
||||
fi
|
||||
echo " PM2: $(pm2 --version) ✅"
|
||||
|
||||
if [ ! -d "$SOURCE_DIR/src" ]; then
|
||||
echo "❌ Source directory invalid: $SOURCE_DIR/src not found" && exit 1
|
||||
fi
|
||||
|
||||
# ── 前端构建 ──
|
||||
if [ "$SKIP_BUILD" = false ]; then
|
||||
echo ""
|
||||
echo "🔨 Building frontend..."
|
||||
bash "$SCRIPT_DIR/build-frontend.sh"
|
||||
else
|
||||
echo ""
|
||||
echo "⏭️ Skipping frontend build (--skip-build)"
|
||||
# 确保前端 dist 存在
|
||||
if [ ! -d "$SOURCE_DIR/src/frontend/dist" ]; then
|
||||
echo "❌ Frontend dist not found. Run without --skip-build first." && exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# ── 创建目标目录 ──
|
||||
FIRST_INSTALL=false
|
||||
if [ ! -d "$TARGET_DIR" ]; then
|
||||
FIRST_INSTALL=true
|
||||
echo ""
|
||||
echo "📁 Creating target directory: $TARGET_DIR"
|
||||
mkdir -p "$TARGET_DIR"
|
||||
fi
|
||||
|
||||
# ── 同步代码 ──
|
||||
echo ""
|
||||
echo "🔄 Syncing code..."
|
||||
rsync -a --delete \
|
||||
--exclude='.git/' \
|
||||
--exclude='docs/' \
|
||||
--exclude='tests/' \
|
||||
--exclude='scripts/' \
|
||||
--exclude='data/' \
|
||||
--exclude='logs/' \
|
||||
--exclude='inbox/' \
|
||||
--exclude='node_modules/' \
|
||||
--exclude='tsconfig.tsbuildinfo' \
|
||||
--exclude='__pycache__/' \
|
||||
--exclude='.venv/' \
|
||||
--exclude='.DS_Store' \
|
||||
"$SOURCE_DIR/" "$TARGET_DIR/"
|
||||
|
||||
# 但不覆盖运行时配置和数据
|
||||
# rsync --delete 不影响 exclude 的目录
|
||||
|
||||
echo " Code synced ✅"
|
||||
|
||||
# ── 确保目录结构 ──
|
||||
mkdir -p "$TARGET_DIR/data"
|
||||
mkdir -p "$TARGET_DIR/logs"
|
||||
mkdir -p "$TARGET_DIR/inbox"
|
||||
|
||||
# 确保默认配置存在(不覆盖已有配置)
|
||||
if [ ! -f "$TARGET_DIR/config/default.yaml" ]; then
|
||||
if [ -f "$SOURCE_DIR/config/default.yaml" ]; then
|
||||
cp "$SOURCE_DIR/config/default.yaml" "$TARGET_DIR/config/default.yaml"
|
||||
echo " Created default config ✅"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -f "$TARGET_DIR/config/guardrails.yaml" ]; then
|
||||
if [ -f "$SOURCE_DIR/config/guardrails.yaml" ]; then
|
||||
cp "$SOURCE_DIR/config/guardrails.yaml" "$TARGET_DIR/config/guardrails.yaml"
|
||||
echo " Created guardrails config ✅"
|
||||
fi
|
||||
fi
|
||||
|
||||
# ── PM2 管理 ──
|
||||
echo ""
|
||||
if [ "$FIRST_INSTALL" = true ]; then
|
||||
echo "🆕 First install — starting with PM2..."
|
||||
cd "$TARGET_DIR"
|
||||
pm2 start ecosystem.config.cjs
|
||||
else
|
||||
echo "♻️ Upgrading — restarting PM2..."
|
||||
pm2 restart "$PM2_NAME" --update-env
|
||||
fi
|
||||
pm2 save
|
||||
|
||||
# ── 健康检查 ──
|
||||
echo ""
|
||||
echo "🏥 Health check..."
|
||||
HEALTH_URL="http://localhost:8083/api/health"
|
||||
OK=false
|
||||
for i in $(seq 1 10); do
|
||||
if curl -sf "$HEALTH_URL" >/dev/null 2>&1; then
|
||||
OK=true
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
if [ "$OK" = true ]; then
|
||||
echo " Health check passed ✅"
|
||||
else
|
||||
echo " ⚠️ Health check timeout (service may still be starting)"
|
||||
echo " Check: pm2 logs $PM2_NAME"
|
||||
fi
|
||||
|
||||
# ── 完成 ──
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
if [ "$FIRST_INSTALL" = true ]; then
|
||||
echo "✅ moziplus v2 installed successfully!"
|
||||
else
|
||||
echo "✅ moziplus v2 upgraded successfully!"
|
||||
fi
|
||||
echo " URL: http://localhost:8083/"
|
||||
echo " PM2: pm2 status $PM2_NAME"
|
||||
echo " Logs: pm2 logs $PM2_NAME"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
Reference in New Issue
Block a user