#!/bin/bash ############################################################################### # 部署配置向导 # 首次使用时运行,引导用户完成部署配置 ############################################################################### set -e # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' CYAN='\033[0;36m' BOLD='\033[1m' NC='\033[0m' # 获取脚本所在目录 SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" CONFIG_FILE="$PROJECT_ROOT/.env.deploy" EXAMPLE_FILE="$PROJECT_ROOT/.env.deploy.example" ############################################################################### # 函数:打印带颜色的消息 ############################################################################### log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } log_success() { echo -e "${GREEN}[✓]${NC} $1"; } log_warning() { echo -e "${YELLOW}[⚠]${NC} $1"; } log_error() { echo -e "${RED}[✗]${NC} $1"; } log_step() { echo -e "${CYAN}${BOLD}[$1]${NC} $2"; } ############################################################################### # 函数:读取用户输入(带默认值) ############################################################################### read_input() { local prompt="$1" local default="$2" local result if [ -n "$default" ]; then read -p "$prompt [$default]: " result echo "${result:-$default}" else read -p "$prompt: " result echo "$result" fi } ############################################################################### # 函数:读取密码(隐藏输入) ############################################################################### read_password() { local prompt="$1" local result read -sp "$prompt: " result echo "" echo "$result" } ############################################################################### # 函数:测试 SSH 连接 ############################################################################### test_ssh() { local host="$1" local user="$2" local port="$3" local key_path="$4" local ssh_options="-o ConnectTimeout=10 -o BatchMode=yes" if [ -n "$key_path" ]; then ssh_options="$ssh_options -i $key_path" fi if [ -n "$port" ] && [ "$port" != "22" ]; then ssh_options="$ssh_options -p $port" fi ssh $ssh_options "$user@$host" "echo 'SSH 连接测试成功'" 2>/dev/null return $? } ############################################################################### # 函数:测试企业微信 Webhook ############################################################################### test_wechat_webhook() { local webhook_url="$1" local test_message='{"msgtype":"text","text":{"content":"企业微信通知测试\n发送时间: '$(date +"%Y-%m-%d %H:%M:%S")'"}}' local response=$(curl -s -w "\n%{http_code}" \ -H "Content-Type: application/json" \ -d "$test_message" \ "$webhook_url") local http_code=$(echo "$response" | tail -n1) if [ "$http_code" -eq 200 ]; then return 0 else return 1 fi } ############################################################################### # 函数:显示欢迎信息 ############################################################################### show_welcome() { clear echo "" echo "╔════════════════════════════════════════════════════════════════╗" echo "║ VF React 部署配置向导 ║" echo "╚════════════════════════════════════════════════════════════════╝" echo "" echo "本向导将帮助您完成以下配置:" echo " 1. 服务器连接配置 (SSH)" echo " 2. 部署路径配置" echo " 3. 企业微信通知配置 (可选)" echo " 4. 初始化服务器环境" echo "" read -p "按 Enter 键继续..." echo "" } ############################################################################### # 函数:配置服务器信息 ############################################################################### configure_server() { log_step "1/4" "服务器配置" echo "" # 服务器地址 SERVER_HOST=$(read_input "请输入服务器 IP 或域名") while [ -z "$SERVER_HOST" ]; do log_error "服务器地址不能为空" SERVER_HOST=$(read_input "请输入服务器 IP 或域名") done # SSH 用户名 SERVER_USER=$(read_input "请输入 SSH 用户名" "ubuntu") # SSH 端口 SERVER_PORT=$(read_input "请输入 SSH 端口" "22") # SSH 密钥路径 local default_key="$HOME/.ssh/id_rsa" if [ -f "$default_key" ]; then log_info "检测到 SSH 密钥: $default_key" local use_default=$(read_input "是否使用该密钥? (y/n)" "y") if [ "$use_default" = "y" ] || [ "$use_default" = "Y" ]; then SSH_KEY_PATH="$default_key" else SSH_KEY_PATH=$(read_input "请输入 SSH 密钥路径") fi else SSH_KEY_PATH=$(read_input "请输入 SSH 密钥路径 (留空使用默认)") fi # 测试 SSH 连接 echo "" log_info "正在测试 SSH 连接..." if test_ssh "$SERVER_HOST" "$SERVER_USER" "$SERVER_PORT" "$SSH_KEY_PATH"; then log_success "SSH 连接测试成功" else log_error "SSH 连接测试失败" echo "" echo "请检查:" echo " 1. 服务器地址是否正确" echo " 2. SSH 用户名和端口是否正确" echo " 3. SSH 密钥是否配置正确" echo "" read -p "是否继续配置? (y/n): " continue_setup if [ "$continue_setup" != "y" ] && [ "$continue_setup" != "Y" ]; then exit 1 fi fi echo "" } ############################################################################### # 函数:配置部署路径 ############################################################################### configure_paths() { log_step "2/4" "部署路径配置" echo "" # Git 仓库路径 REMOTE_PROJECT_PATH=$(read_input "Git 仓库路径" "/home/ubuntu/vf_react") # 生产环境路径 PRODUCTION_PATH=$(read_input "生产环境路径" "/var/www/valuefrontier.cn") # 备份目录 BACKUP_DIR=$(read_input "备份目录" "/home/ubuntu/deployments") # 日志目录 LOG_DIR=$(read_input "日志目录" "/home/ubuntu/deploy-logs") # 部署分支 DEPLOY_BRANCH=$(read_input "部署分支" "feature") # 保留备份数量 KEEP_BACKUPS=$(read_input "保留备份数量" "5") echo "" } ############################################################################### # 函数:配置企业微信通知 ############################################################################### configure_wechat() { log_step "3/4" "企业微信通知配置" echo "" local enable_notify=$(read_input "是否启用企业微信通知? (y/n)" "n") if [ "$enable_notify" = "y" ] || [ "$enable_notify" = "Y" ]; then ENABLE_WECHAT_NOTIFY="true" echo "" echo "请按以下步骤获取企业微信 Webhook URL:" echo " 1. 打开企业微信群聊" echo " 2. 点击群设置 -> 群机器人 -> 添加机器人" echo " 3. 复制 Webhook URL" echo "" WECHAT_WEBHOOK_URL=$(read_input "请输入企业微信 Webhook URL") if [ -n "$WECHAT_WEBHOOK_URL" ]; then log_info "正在测试企业微信通知..." if test_wechat_webhook "$WECHAT_WEBHOOK_URL"; then log_success "企业微信通知测试成功" else log_warning "企业微信通知测试失败,请检查 Webhook URL" fi fi WECHAT_MENTIONED_LIST=$(read_input "提及用户 (手机号/userid,留空不提及)" "") else ENABLE_WECHAT_NOTIFY="false" WECHAT_WEBHOOK_URL="" WECHAT_MENTIONED_LIST="" fi echo "" } ############################################################################### # 函数:初始化服务器环境 ############################################################################### initialize_server() { log_step "4/4" "初始化服务器环境" echo "" local ssh_options="" if [ -n "$SSH_KEY_PATH" ]; then ssh_options="-i $SSH_KEY_PATH" fi if [ -n "$SERVER_PORT" ] && [ "$SERVER_PORT" != "22" ]; then ssh_options="$ssh_options -p $SERVER_PORT" fi log_info "正在创建服务器目录..." # 创建必要的目录 ssh $ssh_options "$SERVER_USER@$SERVER_HOST" " mkdir -p $BACKUP_DIR mkdir -p $LOG_DIR mkdir -p $PRODUCTION_PATH " || { log_error "创建目录失败" return 1 } log_success "服务器目录创建完成" # 设置脚本执行权限 log_info "设置脚本执行权限..." chmod +x "$SCRIPT_DIR"/*.sh log_success "服务器环境初始化完成" echo "" } ############################################################################### # 函数:保存配置文件 ############################################################################### save_config() { log_info "保存配置文件..." # 如果配置文件已存在,先备份 if [ -f "$CONFIG_FILE" ]; then local backup_file="$CONFIG_FILE.backup.$(date +%Y%m%d%H%M%S)" cp "$CONFIG_FILE" "$backup_file" log_info "已备份原配置文件: $backup_file" fi # 从示例文件复制 if [ -f "$EXAMPLE_FILE" ]; then cp "$EXAMPLE_FILE" "$CONFIG_FILE" else touch "$CONFIG_FILE" fi # 写入配置 cat > "$CONFIG_FILE" <