hookehuyr

feat(deploy): 添加多环境部署系统

- 新增 deploy/ 目录,包含部署脚本和配置
- 支持 dev、oa、behalo 三个环境
- 支持单环境和批量部署
- 添加交互确认和进度提示
- 更新 package.json 部署脚本命令

影响文件:
- deploy/config.sh
- deploy/deploy.sh
- deploy/README.md
- package.json
1 +# H5 项目多环境部署方案
2 +
3 +## 概述
4 +
5 +本部署方案支持将 H5 项目一键部署到一个或多个环境,适用于前端开发团队的日常发布流程。
6 +
7 +### 特性
8 +
9 +-**多环境支持**:dev、oa、behalo 三个环境
10 +-**批量部署**:一次部署到多个环境
11 +-**交互确认**:部署前需确认,防止误操作
12 +-**自动归档**:自动打包构建产物
13 +-**进度提示**:清晰的部署进度和结果反馈
14 +
15 +## 快速开始
16 +
17 +### 环境要求
18 +
19 +- Node.js 18.19.1(项目使用 `.nvm` 管理)
20 +- pnpm
21 +- SSH 访问权限(配置 `ipadbiz-inner` 别名)
22 +
23 +### 部署命令
24 +
25 +```bash
26 +# 单环境部署
27 +pnpm deploy:dev # 部署到开发环境
28 +pnpm deploy:oa # 部署到 OA 环境
29 +pnpm deploy:behalo # 部署到 Behalo 环境
30 +
31 +# 或者使用脚本直接调用
32 +./deploy/deploy.sh dev
33 +./deploy/deploy.sh oa
34 +./deploy/deploy.sh behalo
35 +
36 +# 多环境部署
37 +./deploy/deploy.sh dev oa # 部署到开发和 OA 环境
38 +./deploy/deploy.sh dev oa behalo # 部署到所有环境
39 +```
40 +
41 +## 环境说明
42 +
43 +| 环境名称 | 服务器路径 | 访问地址 | 说明 |
44 +| ---------- | ------------------ | ----------------------- | ----------- |
45 +| **dev** | `/opt/space-dev/f` | http://oa-dev.onwall.cn | 开发环境 |
46 +| **oa** | `/opt/oa/f` | http://oa.onwall.cn | OA 环境 |
47 +| **behalo** | `/opt/behalo/f` | http://behalo.onwall.cn | Behalo 环境 |
48 +
49 +## 部署流程
50 +
51 +```
52 +1. 检查环境
53 +
54 +2. 确认部署环境(交互式)
55 +
56 +3. 执行构建 (pnpm build)
57 +
58 +4. 创建归档 (mlaj.tar.gz)
59 +
60 +5. 上传归档到服务器
61 +
62 +6. 远程解压部署
63 +
64 +7. 清理归档文件
65 +
66 +8. 显示访问地址
67 +```
68 +
69 +## 文件结构
70 +
71 +```
72 +deploy/
73 +├── README.md # 本文档
74 +├── config.sh # 环境配置文件
75 +└── deploy.sh # 主部署脚本
76 +```
77 +
78 +### config.sh
79 +
80 +环境配置文件,定义了每个环境的:
81 +
82 +- 服务器信息(SSH 别名)
83 +- 远程部署路径
84 +- 构建命令和产物目录
85 +- 备份配置
86 +- 健康检查配置(预留)
87 +- 通知配置(预留)
88 +
89 +**配置结构**
90 +
91 +```bash
92 +# 每个环境对应一个配置函数
93 +deploy_config_dev() {
94 + export PROJECT_NAME="mlaj"
95 + export SERVER_HOST="ipadbiz-inner"
96 + export REMOTE_DEPLOY_DIR="/opt/space-dev/f"
97 + export BUILD_DIR="dist"
98 + export BUILD_COMMAND="pnpm build"
99 + # ...
100 +}
101 +```
102 +
103 +### deploy.sh
104 +
105 +主部署脚本,负责:
106 +
107 +1. 检查必需命令(pnpm、ssh、scp、tar)
108 +2. 解析环境参数
109 +3. 加载对应环境配置
110 +4. 执行构建
111 +5. 创建并上传归档
112 +6. 远程解压部署
113 +7. 输出部署结果
114 +
115 +## 添加新环境
116 +
117 +1.`config.sh` 中添加配置函数:
118 +
119 +```bash
120 +deploy_config_newenv() {
121 + export PROJECT_NAME="mlaj"
122 + export SERVER_HOST="your-ssh-alias"
123 + export REMOTE_DEPLOY_DIR="/path/to/deploy"
124 + export BUILD_DIR="dist"
125 + export BUILD_COMMAND="pnpm build"
126 + # ...其他配置
127 +}
128 +```
129 +
130 +2.`config.sh``load_env_config()` 函数中添加:
131 +
132 +```bash
133 +load_env_config() {
134 + case "$1" in
135 + # ...现有环境
136 + newenv)
137 + deploy_config_newenv
138 + ;;
139 + # ...
140 + esac
141 +}
142 +```
143 +
144 +3.`deploy.sh` 的提示信息中添加新环境名称
145 +
146 +## 常见问题
147 +
148 +### Q: SSH 连接失败?
149 +
150 +确保已配置 SSH 别名 `ipadbiz-inner`,在 `~/.ssh/config` 中:
151 +
152 +```
153 +Host ipadbiz-inner
154 + HostName your-server-ip
155 + User your-username
156 + Port 22
157 + IdentityFile ~/.ssh/your-key
158 +```
159 +
160 +### Q: 构建失败?
161 +
162 +检查 Node.js 版本是否为 18.19.1:
163 +
164 +```bash
165 +nvm use 18.19.1
166 +```
167 +
168 +### Q: 权限不足?
169 +
170 +确保脚本有执行权限:
171 +
172 +```bash
173 +chmod +x deploy/deploy.sh
174 +chmod +x deploy/config.sh
175 +```
176 +
177 +## 注意事项
178 +
179 +1. **部署前确认**:脚本会在部署前要求确认,请仔细核对环境
180 +2. **构建时间**:首次构建可能需要较长时间,请耐心等待
181 +3. **网络稳定**:部署过程中请保持网络稳定
182 +4. **环境隔离**:不同环境的配置相互独立,互不影响
183 +
184 +---
185 +
186 +**维护者**: 前端开发团队
187 +**最后更新**: 2026-02-23
1 +#!/bin/bash
2 +# ============================================================================
3 +# H5 项目多环境部署配置
4 +# ============================================================================
5 +#
6 +# 说明:
7 +# - 每个环境对应一个配置段
8 +# - 部署时通过环境名称加载对应配置
9 +# - 支持命令行参数覆盖配置
10 +#
11 +# 使用方法:
12 +# source deploy/config.sh
13 +# ./deploy/deploy.sh <env1> [env2] ...
14 +#
15 +# 环境命名建议:
16 +# - dev: 开发环境
17 +# - test: 测试环境
18 +# - staging: 预发布环境
19 +# - prod: 生产环境
20 +# ============================================================================
21 +
22 +# ============================================================================
23 +# 环境配置段
24 +# ============================================================================
25 +
26 +# ----- 开发环境配置 -----
27 +deploy_config_dev() {
28 + # 项目名称(用于标识)
29 + export PROJECT_NAME="mlaj"
30 +
31 + # 服务器配置 - 使用 SSH alias
32 + export SERVER_HOST="ipadbiz-inner"
33 + export SERVER_USER="" # SSH alias 已配置用户
34 + export SERVER_PORT="" # SSH alias 已配置端口
35 +
36 + # 远程路径配置
37 + export REMOTE_BASE_DIR="/opt/space-dev/f" # 远程基础目录
38 + export REMOTE_DEPLOY_DIR="${REMOTE_BASE_DIR}" # 部署目录
39 +
40 + # 本地路径配置
41 + export BUILD_DIR="dist" # 构建产物目录
42 + export BUILD_ARCHIVE="${PROJECT_NAME}.tar.gz" # 归档文件名(固定名称)
43 +
44 + # 构建命令
45 + export BUILD_COMMAND="pnpm build"
46 +
47 + # 备份配置(保留备份数量,0=不备份)
48 + export BACKUP_ENABLED="false"
49 + export BACKUP_MAX_COUNT="0"
50 +
51 + # 部署后操作
52 + export DEPLOY_CLEANUP="true" # 是否清理部署归档
53 + export RESTART_SERVER="false" # 是否重启服务器
54 +
55 + # 健康检查配置
56 + export HEALTH_CHECK_ENABLED="false" # 是否启用健康检查
57 + export HEALTH_CHECK_URL="" # 健康检查 URL
58 + export HEALTH_CHECK_TIMEOUT="10" # 健康检查超时(秒)
59 +
60 + # 通知配置
61 + export NOTIFY_ENABLED="false" # 是否发送通知
62 + export NOTIFY_WEBHOOK="" # 通知 Webhook URL
63 +}
64 +
65 +# ----- OA 服务器配置(已有 oa_upload )-----
66 +deploy_config_oa() {
67 + export PROJECT_NAME="mlaj"
68 +
69 + # 服务器配置 - 使用 SSH alias
70 + export SERVER_HOST="ipadbiz-inner"
71 + export SERVER_USER="" # SSH alias 已配置用户
72 + export SERVER_PORT="" # SSH alias 已配置端口
73 +
74 + # 远程路径配置
75 + export REMOTE_BASE_DIR="/opt/oa/f" # 远程基础目录
76 + export REMOTE_DEPLOY_DIR="${REMOTE_BASE_DIR}" # 部署目录
77 +
78 + # 本地路径配置
79 + export BUILD_DIR="dist" # 构建产物目录
80 + export BUILD_ARCHIVE="${PROJECT_NAME}.tar.gz" # 归档文件名(固定名称)
81 +
82 + # 构建命令
83 + export BUILD_COMMAND="pnpm build"
84 +
85 + # 备份配置(保留备份数量,0=不备份)
86 + export BACKUP_ENABLED="false"
87 + export BACKUP_MAX_COUNT="0"
88 +
89 + # 部署后操作
90 + export DEPLOY_CLEANUP="true" # 是否清理部署归档
91 + export RESTART_SERVER="false" # 是否重启服务器
92 +
93 + # 健康检查配置
94 + export HEALTH_CHECK_ENABLED="false" # 是否启用健康检查
95 + export HEALTH_CHECK_URL="" # 健康检查 URL
96 + export HEALTH_CHECK_TIMEOUT="10" # 健康检查超时(秒)
97 +
98 + # 通知配置
99 + export NOTIFY_ENABLED="false" # 是否发送通知
100 + export NOTIFY_WEBHOOK="" # 通知 Webhook URL
101 +}
102 +
103 +# ----- Behalo 服务器配置(已有 behalo_upload)-----
104 +deploy_config_behalo() {
105 + export PROJECT_NAME="mlaj"
106 +
107 + # 服务器配置 - 使用 SSH alias
108 + export SERVER_HOST="ipadbiz-inner"
109 + export SERVER_USER="" # SSH alias 已配置用户
110 + export SERVER_PORT="" # SSH alias 已配置端口
111 +
112 + # 远程路径配置
113 + export REMOTE_BASE_DIR="/opt/behalo/f" # 远程基础目录
114 + export REMOTE_DEPLOY_DIR="${REMOTE_BASE_DIR}" # 部署目录
115 +
116 + # 本地路径配置
117 + export BUILD_DIR="dist" # 构建产物目录
118 + export BUILD_ARCHIVE="${PROJECT_NAME}.tar.gz" # 归档文件名(固定名称)
119 +
120 + # 构建命令
121 + export BUILD_COMMAND="pnpm build"
122 +
123 + # 备份配置(保留备份数量,0=不备份)
124 + export BACKUP_ENABLED="false"
125 + export BACKUP_MAX_COUNT="0"
126 +
127 + # 部署后操作
128 + export DEPLOY_CLEANUP="true" # 是否清理部署归档
129 + export RESTART_SERVER="false" # 是否重启服务器
130 +
131 + # 健康检查配置
132 + export HEALTH_CHECK_ENABLED="false" # 是否启用健康检查
133 + export HEALTH_CHECK_URL="" # 健康检查 URL
134 + export HEALTH_CHECK_TIMEOUT="10" # 健康检查超时(秒)
135 +
136 + # 通知配置
137 + export NOTIFY_ENABLED="false" # 是否发送通知
138 + export NOTIFY_WEBHOOK="" # 通知 Webhook URL
139 +}
140 +
141 +# ============================================================================
142 +# 辅助函数
143 +# ============================================================================
144 +
145 +# 打印带颜色的消息
146 +log_info() {
147 + echo -e "\033[0;32m[INFO]\033[0m $@"
148 +}
149 +
150 +log_success() {
151 + echo -e "\033[0;32m[SUCCESS]\033[0m $@"
152 +}
153 +
154 +log_warning() {
155 + echo -e "\033[0;33m[WARNING]\033[0m $@"
156 +}
157 +
158 +log_error() {
159 + echo -e "\033[0;31m[ERROR]\033[0m $@"
160 +}
161 +
162 +# 打印分隔线
163 +print_separator() {
164 + echo "================================================================================"
165 +}
166 +
167 +# 加载环境配置
168 +# 参数: $1 - 环境名称
169 +load_env_config() {
170 + local env_name="$1"
171 +
172 + case "$env_name" in
173 + dev)
174 + deploy_config_dev
175 + ;;
176 + oa)
177 + deploy_config_oa
178 + ;;
179 + behalo)
180 + deploy_config_behalo
181 + ;;
182 + *)
183 + log_error "未知环境: $env_name"
184 + log_info "可用环境: dev, oa, behalo"
185 + exit 1
186 + ;;
187 + esac
188 +}
189 +
190 +# ============================================================================
191 +# 验证配置
192 +# ============================================================================
193 +
194 +validate_config() {
195 + log_info "验证配置..."
196 +
197 + # 检查必需变量
198 + required_vars=(
199 + "PROJECT_NAME"
200 + "SERVER_HOST"
201 + "SERVER_USER"
202 + "REMOTE_DEPLOY_DIR"
203 + "BUILD_DIR"
204 + "BUILD_ARCHIVE"
205 + )
206 +
207 + for var in "${required_vars[@]}"; do
208 + if [ -z "${!var}" ]; then
209 + log_error "缺少必需配置: $var"
210 + exit 1
211 + fi
212 + done
213 +
214 + # 检查本地构建目录
215 + if [ ! -d "$BUILD_DIR" ]; then
216 + log_error "构建目录不存在: $BUILD_DIR"
217 + log_info "请先运行: $BUILD_COMMAND"
218 + exit 1
219 + fi
220 +
221 + log_success "配置验证通过"
222 +}
223 +
224 +# 导出主函数供 deploy.sh 使用
225 +export load_env_config
226 +export validate_config
1 +#!/bin/bash
2 +# ============================================================================
3 +# H5 项目多环境部署脚本
4 +# ============================================================================
5 +#
6 +# 说明:支持一次部署到一个或多个环境
7 +# 使用方法:./deploy.sh <env1> [env2] [env3] ...
8 +#
9 +# 示例:
10 +# ./deploy.sh dev # 部署到开发环境
11 +# ./deploy.sh test prod # 部署到测试和生产环境
12 +# ./deploy.sh dev test prod # 部署到开发、测试和生产环境
13 +#
14 +# ============================================================================
15 +
16 +set -e # 遇到错误立即退出
17 +
18 +# 获取脚本所在目录
19 +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
20 +PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
21 +
22 +# 加载配置文件
23 +source "${SCRIPT_DIR}/config.sh"
24 +
25 +# ============================================================================
26 +# 辅助函数
27 +# ============================================================================
28 +
29 +# 显示分隔线
30 +print_separator() {
31 + echo "================================================================================"
32 +}
33 +
34 +# 检查必需的命令
35 +check_commands() {
36 + local required_cmds=("pnpm" "ssh" "scp" "tar" "rm")
37 + for cmd in "${required_cmds[@]}"; do
38 + if ! command -v "$cmd" &> /dev/null; then
39 + log_error "缺少必需命令: $cmd"
40 + log_info "请先安装缺失的工具"
41 + exit 1
42 + fi
43 + done
44 +}
45 +
46 +# 检查本地构建产物
47 +check_build() {
48 + if [ ! -d "$BUILD_DIR" ]; then
49 + log_error "构建目录不存在: $BUILD_DIR"
50 + log_info "请先运行: $BUILD_COMMAND"
51 + exit 1
52 + fi
53 +}
54 +
55 +# 执行构建
56 +do_build() {
57 + log_info "开始构建项目..."
58 + cd "$PROJECT_DIR"
59 + $BUILD_COMMAND
60 +
61 + if [ $? -ne 0 ]; then
62 + log_error "构建失败"
63 + exit 1
64 + fi
65 +
66 + log_success "构建完成"
67 + cd "$SCRIPT_DIR"
68 +}
69 +
70 +# 创建归档
71 +create_archive() {
72 + local archive_name="$BUILD_ARCHIVE"
73 +
74 + log_info "创建部署归档: $archive_name"
75 + cd "$PROJECT_DIR"
76 +
77 + tar -czf "$archive_name" "$BUILD_DIR"
78 +
79 + if [ $? -ne 0 ]; then
80 + log_error "创建归档失败"
81 + exit 1
82 + fi
83 +
84 + log_success "归档创建完成: $archive_name"
85 + cd "$SCRIPT_DIR"
86 +}
87 +
88 +# 上传归档
89 +upload_archive() {
90 + local archive_name="$1"
91 +
92 + log_info "上传归档到服务器..."
93 +
94 + scp -P "$SERVER_PORT" "$archive_name" \
95 + "${SERVER_USER}@${SERVER_HOST}:/tmp/"
96 +
97 + if [ $? -ne 0 ]; then
98 + log_error "上传失败"
99 + exit 1
100 + fi
101 +
102 + log_success "归档上传完成"
103 +}
104 +
105 +# 执行远程部署
106 +do_deploy() {
107 + local archive_name="$1"
108 + local remote_archive_path="/tmp/${archive_name}"
109 + local remote_deploy_dir="$REMOTE_DEPLOY_DIR"
110 +
111 + log_info "开始远程部署..."
112 +
113 + ssh -p "$SERVER_PORT" "${SERVER_USER}@${SERVER_HOST}" << EOF
114 +set -e
115 +
116 +# 进入部署目录
117 +cd "\$remote_deploy_dir" || mkdir -p "\$remote_deploy_dir"
118 +
119 +# 备份当前版本(如果启用)
120 +if [ "\$BACKUP_ENABLED" = "true" ]; then
121 + echo "[INFO] 备份当前版本..."
122 + if [ -d "\$remote_deploy_dir" ]; then
123 + # 查找现有的备份目录
124 + BACKUP_DIR="\${remote_deploy_dir}_backup_\$(date +%Y%m%d_%H%M%S)"
125 + mkdir -p "\$BACKUP_DIR"
126 + # 备份当前版本
127 + cp -r "\$remote_deploy_dir/"* "\$BACKUP_DIR/" 2>/dev/null || true
128 + echo "[SUCCESS] 备份完成: \$BACKUP_DIR"
129 +
130 + # 清理旧备份(保留指定数量)
131 + if [ "\$BACKUP_MAX_COUNT" -gt 0 ]; then
132 + echo "[INFO] 清理旧备份(保留 \$BACKUP_MAX_COUNT 个)..."
133 + ls -td "\${remote_deploy_dir}_backup_" | sort -r | tail -n +\`"\$BACKUP_MAX_COUNT\" | xargs rm -rf
134 + fi
135 + fi
136 +fi
137 +
138 +# 解压新版本
139 +echo "[INFO] 解压新版本..."
140 +tar -xzf "\$remote_archive_path" -C "\$remote_deploy_dir"
141 +
142 +# 清理归档文件
143 +rm -f "\$remote_archive_path"
144 +
145 +echo "[SUCCESS] 部署完成"
146 +EOF
147 +
148 + if [ $? -ne 0 ]; then
149 + log_error "远程部署失败"
150 + exit 1
151 + fi
152 +
153 + log_success "远程部署完成"
154 +}
155 +
156 +# 部署到单个环境
157 +deploy_to_env() {
158 + local env_name="$1"
159 +
160 + log_info "=========================================="
161 + log_info "开始部署到环境: $env_name"
162 + log_info "=========================================="
163 +
164 + # 加载环境配置
165 + load_env_config "$env_name"
166 +
167 + # 执行构建
168 + do_build
169 +
170 + # 创建归档
171 + create_archive "$BUILD_ARCHIVE"
172 +
173 + # 上传归档
174 + upload_archive "$BUILD_ARCHIVE"
175 +
176 + # 执行远程部署
177 + do_deploy "$BUILD_ARCHIVE"
178 +
179 + log_success "环境 [$env_name] 部署完成"
180 +}
181 +
182 +# ============================================================================
183 +# 主流程
184 +# ============================================================================
185 +
186 +# 检查命令
187 +check_commands
188 +
189 +# 检查是否提供了环境参数
190 +if [ $# -eq 0 ]; then
191 + log_error "使用方法: $0 <env1> [env2] [env3] ..."
192 + log_info "可用环境: dev, oa, behalo"
193 + exit 1
194 +fi
195 +
196 +# 显示将要部署的环境
197 +log_info "将要部署到以下环境:"
198 +for env in "$@"; do
199 + echo " - $env"
200 +done
201 +print_separator
202 +
203 +# 确认部署
204 +read -p "确认部署以上环境?(y/N): " confirm
205 +if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then
206 + log_warning "已取消部署"
207 + exit 0
208 +fi
209 +
210 +print_separator
211 +
212 +# 逐个部署环境
213 +for env in "$@"; do
214 + deploy_to_env "$env"
215 + print_separator
216 +done
217 +
218 +# 最终总结
219 +log_success "所有环境部署完成!"
220 +print_separator
221 +log_info "部署摘要:"
222 +for env in "$@"; do
223 + echo " ✓ $env"
224 +done
225 +print_separator
226 +
227 +log_info "访问地址:"
228 +for env in "$@"; do
229 + case "$env" in
230 + dev)
231 + echo " - 开发环境: http://oa-dev.onwall.cn"
232 + ;;
233 + oa)
234 + echo " - OA环境: http://oa.onwall.cn"
235 + ;;
236 + behalo)
237 + echo " - Behalo环境: http://behalo.onwall.cn"
238 + ;;
239 + esac
240 +done
241 +print_separator
242 +
243 +log_success "部署流程全部结束!"
...@@ -32,6 +32,10 @@ ...@@ -32,6 +32,10 @@
32 "dev_upload": "npm run build_tar && npm run scp-dev && npm run dec-dev && npm run remove_tar", 32 "dev_upload": "npm run build_tar && npm run scp-dev && npm run dec-dev && npm run remove_tar",
33 "behalo_upload": "npm run build_tar && npm run scp-behalo && npm run dec-behalo && npm run remove_tar", 33 "behalo_upload": "npm run build_tar && npm run scp-behalo && npm run dec-behalo && npm run remove_tar",
34 "oa_upload": "npm run build_tar && npm run scp-oa && npm run dec-oa && npm run remove_tar", 34 "oa_upload": "npm run build_tar && npm run scp-oa && npm run dec-oa && npm run remove_tar",
35 + "deploy": "./deploy/deploy.sh",
36 + "deploy:dev": "./deploy/deploy.sh dev",
37 + "deploy:oa": "./deploy/deploy.sh oa",
38 + "deploy:behalo": "./deploy/deploy.sh behalo",
35 "api:generate": "node .claude/custom_skills/api-generator/scripts/generateApiFromOpenAPI.cjs", 39 "api:generate": "node .claude/custom_skills/api-generator/scripts/generateApiFromOpenAPI.cjs",
36 "api:diff": "node .claude/custom_skills/api-generator/scripts/apiDiff.cjs", 40 "api:diff": "node .claude/custom_skills/api-generator/scripts/apiDiff.cjs",
37 "prepare": "husky" 41 "prepare": "husky"
......