deploy.sh
5.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#!/usr/bin/env bash
#
# 部署脚本:构建项目 -> 上传七牛 -> 打包并上传到服务器
# 说明:在 macOS 环境下执行,依赖 npm、qshell、ssh/scp
set -euo pipefail
# 全局变量(按需修改)
repo_root="$(cd "$(dirname "$0")/.." && pwd)"
server_host="zhsy@oa.jcedu.org"
server_port="12101"
remote_dir="/home/www/f"
local_tar="dist.tar.gz"
local_package_dir="stdj"
qshell_dir="$HOME/.qshell"
qshell_conf="stdj_upload.conf"
build_out_dir="dist"
# 打印信息日志
# 说明:输出带前缀的日志,便于观察执行过程
log_info() {
echo "[deploy] $1"
}
# 执行命令并显示日志
# 参数:cmd 命令字符串
# 说明:包装命令执行,便于统一错误处理与日志输出
run_cmd() {
local cmd="$1"
log_info "执行:$cmd"
eval "$cmd"
}
# 检测构建输出目录
# 说明:按优先级读取 .env.production -> .env -> .env.development 中的 VITE_OUTDIR,缺省为 dist
detect_out_dir() {
# POSIX 兼容实现:按顺序检查 .env.production -> .env -> .env.development
# 若未设置,回退为 dist
local outdir="dist"
for env_file in "$repo_root/.env.production" "$repo_root/.env" "$repo_root/.env.development"; do
if [ -f "$env_file" ]; then
# 提取键值:去注释、去空格、去引号
local value
value=$(grep -E '^\s*VITE_OUTDIR\s*=' "$env_file" | head -n1 | cut -d '=' -f2- | sed 's/#.*$//' | tr -d '[:space:]' | sed -e 's/^"//;s/"$//' -e "s/^'//;s/'$//" || true)
if [ -n "${value:-}" ]; then
outdir="$value"
break
fi
fi
done
echo "$outdir"
}
# 构建项目
# 说明:使用 npm 脚本进行构建,产物位于 dist/
build_project() {
log_info "开始构建项目"
cd "$repo_root"
if command -v pnpm >/dev/null 2>&1; then
run_cmd "pnpm run build"
elif command -v npm >/dev/null 2>&1; then
run_cmd "npm run build"
elif command -v yarn >/dev/null 2>&1; then
run_cmd "yarn build"
else
echo "错误:未检测到 pnpm/npm/yarn,请先安装其中之一"
exit 1
fi
build_out_dir="$(detect_out_dir)"
if [ ! -d "$repo_root/${build_out_dir:-}" ]; then
echo "错误:未找到构建输出目录 '${build_out_dir:-}/',请检查 .env/.env.production 的 VITE_OUTDIR 或构建是否成功"
exit 1
fi
log_info "构建完成:${build_out_dir:-}/"
}
# 准备打包目录
# 说明:将 dist 内容复制到 stdj 目录,用于后续打包
prepare_package_dir() {
log_info "准备打包目录:$local_package_dir"
cd "$repo_root"
# 保留 stdj 目录,仅增量同步构建产物
run_cmd "mkdir -p '$local_package_dir'"
if [ "${build_out_dir:-}" = "$local_package_dir" ]; then
# 输出目录与包目录一致,直接使用,无需复制
log_info "输出目录与包目录一致:${build_out_dir:-},跳过复制"
return 0
fi
if command -v rsync >/dev/null 2>&1; then
# 使用 rsync 增量复制,保留 stdj 目录和其他文件(不删除已有文件)
run_cmd "rsync -a '${build_out_dir:-}/' '$local_package_dir/'"
else
# 回退到 cp -R,同样保留 stdj 目录
run_cmd "cp -R '${build_out_dir:-}'/. '$local_package_dir'/"
fi
}
# 上传静态资源到七牛云
# 说明:进入 ~/.qshell 并执行 qupload,同步 upload.conf 中配置的资源
upload_qiniu() {
log_info "检查 qshell 安装与配置"
if ! command -v qshell >/dev/null 2>&1; then
echo "错误:未检测到 qshell,请先安装 https://developer.qiniu.com/kodo/tools/1302/qshell"
exit 1
fi
if [ ! -d "$qshell_dir" ]; then
echo "错误:未找到目录 $qshell_dir"
exit 1
fi
if [ ! -f "$qshell_dir/$qshell_conf" ]; then
echo "错误:未找到七牛配置文件 $qshell_dir/$qshell_conf"
exit 1
fi
log_info "开始上传七牛云资源(qupload)"
cd "$qshell_dir"
# 说明:部分文件已存在会导致 qshell 返回非零退出码,此处不终止流程
log_info "执行:qshell qupload '$qshell_conf'"
if ! qshell qupload "$qshell_conf"; then
log_info "qshell qupload 退出码非零(可能因文件已存在),继续后续部署"
fi
log_info "七牛云资源上传完成"
}
# 打包本地目录并上传到服务器
# 说明:打包 stdj -> 通过 scp 上传到指定目录 -> 远端解压并删除压缩包
upload_server() {
log_info "开始打包:${local_tar:-}"
cd "$repo_root"
run_cmd "tar -czvpf '${local_tar:-}' '${local_package_dir:-}'"
log_info "上传到服务器:${server_host:-}:${remote_dir:-}(端口 ${server_port:-})"
run_cmd "scp -P '${server_port:-}' '${local_tar:-}' '${server_host:-}':'${remote_dir:-}'"
log_info "服务器解压:${remote_dir:-}/${local_tar:-}"
# 说明:构造远端命令,避免变量名意外字符导致的未绑定错误
local remote_cmd
remote_cmd="cd \"${remote_dir:-}\" && tar -xzvf \"${local_tar:-}\" && rm -rf \"${local_tar:-}\""
run_cmd "ssh -p '${server_port:-}' '${server_host:-}' \"$remote_cmd\""
log_info "删除本地压缩包"
run_cmd "rm -f '${local_tar:-}'"
}
# 主流程
# 说明:串行执行:构建 -> 七牛上传 -> 服务器打包上传
main() {
build_project
prepare_package_dir
upload_qiniu
upload_server
log_info "部署完成"
}
main "$@"