Files
font2pic/deploy.sh
2026-07-26 10:44:05 +08:00

145 lines
6.4 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
# Font2SVG 生产部署脚本M4 本机构建 → myweb 资源同步 → 服务与 Nginx 验收。
set -euo pipefail
DEPLOY_BRANCH="${DEPLOY_BRANCH:-main}"
GITRUN_SCRIPT="${GITRUN_SCRIPT:-./gitrun.sh}"
SERVER_WEB="${SERVER_WEB:-myweb}"
REMOTE_WORKDIR="${REMOTE_WORKDIR:-/home/gavin/font2svg}"
SKIP_PUSH="${SKIP_PUSH:-0}"
SKIP_SUDO="${SKIP_SUDO:-0}"
COLOR_RESET=$'\033[0m'
COLOR_INFO=$'\033[1;36m'
COLOR_OK=$'\033[1;32m'
COLOR_WARN=$'\033[1;33m'
COLOR_ERROR=$'\033[1;31m'
COLOR_STEP=$'\033[1;35m'
log_step() { printf '\n%s==> %s%s\n' "$COLOR_STEP" "$1" "$COLOR_RESET"; }
log_info() { printf '%s[信息]%s %s\n' "$COLOR_INFO" "$COLOR_RESET" "$1"; }
log_ok() { printf '%s[完成]%s %s\n' "$COLOR_OK" "$COLOR_RESET" "$1"; }
log_warn() { printf '%s[注意]%s %s\n' "$COLOR_WARN" "$COLOR_RESET" "$1"; }
log_error() { printf '%s[失败]%s %s\n' "$COLOR_ERROR" "$COLOR_RESET" "$1" >&2; }
require_command() {
command -v "$1" >/dev/null 2>&1 || {
log_error "缺少本机命令:$1"
exit 1
}
}
ssh_web() {
ssh -o BatchMode=yes -o ConnectTimeout=12 "$SERVER_WEB" "$@"
}
check_local_environment() {
log_step '1/8 检查 M4 本机环境'
for tool in git pnpm node python3 rsync ssh curl; do
require_command "$tool"
done
[[ -f frontend/package.json ]] || { log_error '未找到 frontend/package.json请在仓库根目录执行。'; exit 1; }
[[ -f frontend/vite.config.ts ]] || {
log_error '缺少 frontend/vite.config.ts该本机配置用于加载 UnoCSS无法构建前端。'
exit 1
}
[[ -f miniprogram/assets/fonts.json ]] || { log_error '缺少小程序字体清单。'; exit 1; }
[[ -f frontend/public/fonts.json ]] || { log_error '缺少 Web 字体清单。'; exit 1; }
[[ -d fonts ]] || { log_error '缺少 fonts/ 字体目录。'; exit 1; }
node scripts/check-font-assets.js --manifest miniprogram/assets/fonts.json --root .
node scripts/check-font-assets.js --manifest frontend/public/fonts.json --root .
log_info "本机字体文件:$(find fonts -type f | wc -l | tr -d ' ')"
log_ok '本机构建与同步依赖齐全'
}
build_and_check() {
log_step '2/8 构建并校验 Web 前端'
# 单独执行应用类型检查,避免将 Vite 配置文件误作应用源码检查。
pnpm -C frontend exec vue-tsc --noEmit -p tsconfig.app.json
pnpm -C frontend run build
[[ -f frontend/dist/index.html ]] || { log_error '前端构建未生成 index.html。'; exit 1; }
pnpm run mp:syntax
pnpm run mp:lint
pnpm run mp:test
log_ok '前端构建、类型检查和小程序校验通过'
}
push_source() {
log_step '3/8 推送源代码到 Git'
if [[ "$SKIP_PUSH" == '1' ]]; then
log_warn 'SKIP_PUSH=1跳过 Git 推送'
return
fi
[[ -x "$GITRUN_SCRIPT" ]] || { log_error "推送脚本不可执行:$GITRUN_SCRIPT"; exit 1; }
"$GITRUN_SCRIPT"
log_ok '源代码已推送'
}
prepare_remote_code() {
log_step '4/8 检查 myweb 并同步代码'
ssh_web "bash -lc 'set -e; command -v git python3 node npm curl >/dev/null; test -d \"$REMOTE_WORKDIR/.git\"; cd \"$REMOTE_WORKDIR\"; git fetch origin \"$DEPLOY_BRANCH\"; git checkout \"$DEPLOY_BRANCH\"; git pull --ff-only origin \"$DEPLOY_BRANCH\"; git log -1 --oneline'"
log_ok 'myweb 代码已同步'
}
sync_assets() {
log_step '5/8 增量同步字体、前端构建产物与图标'
ssh_web "mkdir -p '$REMOTE_WORKDIR/fonts' '$REMOTE_WORKDIR/miniprogram/assets' '$REMOTE_WORKDIR/assets/icons' '$REMOTE_WORKDIR/frontend/dist'"
rsync -az --partial fonts/ "$SERVER_WEB:$REMOTE_WORKDIR/fonts/"
rsync -az miniprogram/assets/fonts.json miniprogram/assets/default.json miniprogram/assets/route-config.json "$SERVER_WEB:$REMOTE_WORKDIR/miniprogram/assets/"
rsync -az frontend/public/fonts.json "$SERVER_WEB:$REMOTE_WORKDIR/fonts.json"
rsync -az --delete frontend/dist/ "$SERVER_WEB:$REMOTE_WORKDIR/frontend/dist/"
rsync -az miniprogram/assets/icons/ "$SERVER_WEB:$REMOTE_WORKDIR/assets/icons/"
rsync -az miniprogram/assets/icons/webicon.png "$SERVER_WEB:$REMOTE_WORKDIR/assets/webicon.png"
rsync -az fonts.conf "$SERVER_WEB:$REMOTE_WORKDIR/fonts.conf"
log_ok '静态资源和 Nginx 配置已同步'
}
prepare_remote_runtime() {
log_step '6/8 修复 myweb Python 运行环境'
ssh_web "bash -lc 'set -e; cd \"$REMOTE_WORKDIR\"; python3 -m venv .venv; .venv/bin/python -m pip install -q -r requirements.txt; .venv/bin/python -c \"import cv2, fontTools, uharfbuzz, numpy; print(\\\"Python 依赖正常\\\")\"'"
log_ok 'Python 虚拟环境与依赖正常'
}
apply_nginx_and_restart() {
log_step '7/8 应用 Nginx 配置并重启 API'
if [[ "$SKIP_SUDO" == '1' ]]; then
log_warn 'SKIP_SUDO=1跳过需要 sudo 的 Nginx/API 重启'
return
fi
log_info '将要求输入 myweb 的 sudo 密码,用于安装配置、校验并重载 Nginx。'
ssh -tt -o ConnectTimeout=12 "$SERVER_WEB" "sudo install -m 644 '$REMOTE_WORKDIR/fonts.conf' /etc/nginx/conf.d/fonts.conf && sudo nginx -t && sudo systemctl reload nginx && sudo systemctl restart font2svg-api"
log_ok 'Nginx 已重载Font2SVG API 已重启'
}
verify_deployment() {
log_step '8/8 验收 myweb 与公网服务'
local local_font_count remote_font_count
local_font_count=$(find fonts -type f | wc -l | tr -d ' ')
remote_font_count=$(ssh_web "find '$REMOTE_WORKDIR/fonts' -type f | wc -l | tr -d ' '")
[[ "$remote_font_count" -ge "$local_font_count" ]] || {
log_error "远端字体数量不足:$remote_font_count/$local_font_count"
exit 1
}
ssh_web "bash -lc 'cd \"$REMOTE_WORKDIR\"; node scripts/check-font-assets.js --manifest miniprogram/assets/fonts.json --root .; node scripts/check-font-assets.js --manifest fonts.json --root .; test -s frontend/dist/index.html; test -s assets/webicon.png'"
ssh_web "bash -lc 'systemctl is-active --quiet font2svg-api; curl -fsS http://127.0.0.1:9300/healthz'"
curl --noproxy '*' --connect-timeout 10 --max-time 30 -fsS https://fonts.biboer.cn/ >/dev/null
curl --noproxy '*' --connect-timeout 10 --max-time 30 -fsS https://fonts.biboer.cn/healthz >/dev/null
curl --noproxy '*' --connect-timeout 10 --max-time 30 -fsS https://fonts.biboer.cn/fonts.json >/dev/null
log_ok "部署验收通过:字体 $remote_font_count/$local_font_count首页、API 与清单均可访问"
}
main() {
check_local_environment
build_and_check
push_source
prepare_remote_code
sync_assets
prepare_remote_runtime
apply_nginx_and_restart
verify_deployment
printf '\n%s部署完成M4 → %s%s\n' "$COLOR_OK" "$SERVER_WEB" "$COLOR_RESET"
}
main "$@"