Files
cozsweet-frontend-nextjs/scripts/deploy/_deploy_lib.sh
T

240 lines
7.5 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.
#!/bin/bash
# ==========================================
# Web 部署公共函数库(Next.js 16 + pnpm 版本,**默认**部署模型)
# 原始 Dart: scripts/deploy/_deploy_lib.sh
# 上一轮(rsync standalone)→ 本轮:标准 .next/ + public/ + next start
#
# 主要差异:
# - 构建命令:flutter build web → pnpm install + pnpm build
# - 构建输出:./build/web/ → ./.next/ + ./public/
# - 版本号源:pubspec.yaml → package.json
# - 删除 compress_main_jsNext.js 无单 JS 入口)
# - 删除 standalone 三段 rsyncstandalone + static + public
# ==========================================
# 标准 Next.js 构建产物
LOCAL_WEB_DIR="./.next"
LOCAL_PUBLIC_DIR="./public"
# 设置环境(Next.js 按 NODE_ENV 自动加载 .env.{development,test,production}
# 但保留 cp 到 .env 的行为以兼容历史流程)
setup_env() {
local env_file="$1"
if [ -z "$env_file" ]; then
echo "未设置环境配置文件,跳过"
return 0
fi
if [ -f "$env_file" ]; then
echo "复制 $env_file 到项目根 .env"
cp "$env_file" .env
else
echo "警告: $env_file 不存在"
fi
}
# 检查本地构建目录是否存在
check_local_build_dir() {
if [ ! -d "$LOCAL_WEB_DIR" ]; then
echo "错误: 本地构建目录 $LOCAL_WEB_DIR 不存在"
echo "请先运行: pnpm build"
return 1
fi
return 0
}
# 构建函数:执行 pnpm install + pnpm build
build() {
echo "=========================================="
echo "开始构建 Next.js 制品..."
echo "=========================================="
# 安装依赖(frozen-lockfile 保证 lockfile 一致)
pnpm install --frozen-lockfile
if [ $? -ne 0 ]; then
echo "=========================================="
echo "pnpm install 失败!"
echo "=========================================="
return 1
fi
# 构建(默认 Turbopack,输出到 .next/
pnpm build
if [ $? -ne 0 ]; then
echo "=========================================="
echo "构建失败!"
echo "=========================================="
return 1
fi
# 检查本地构建目录
check_local_build_dir || return 1
echo "=========================================="
echo "构建完成!"
echo "构建目录: $LOCAL_WEB_DIR"
echo "=========================================="
return 0
}
# 执行部署:rsync .next/ + public/
deploy() {
echo "=========================================="
echo "开始部署 Web 制品到服务器..."
echo "服务器: $SERVER_USER@$SERVER_HOST"
echo "目标路径: $SERVER_PATH"
echo "=========================================="
# 1. 同步 .next/(含 build manifest / chunks / 路由表 / 静态预渲染)
sshpass -p "$SERVER_PASSWORD" rsync -avz --delete \
-e "ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" \
"$LOCAL_WEB_DIR/" \
"$SERVER_USER@$SERVER_HOST:$SERVER_PATH/"
if [ $? -ne 0 ]; then
echo "=========================================="
echo "部署 .next/ 失败!"
echo "=========================================="
return 1
fi
# 2. 同步 public/favicon / manifest / 静态图片)
sshpass -p "$SERVER_PASSWORD" rsync -avz \
-e "ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" \
"$LOCAL_PUBLIC_DIR/" \
"$SERVER_USER@$SERVER_HOST:$SERVER_PATH/public/"
if [ $? -eq 0 ]; then
echo "=========================================="
echo "部署成功!"
echo "服务器启动:cd $SERVER_PATH && next start -H 0.0.0.0 -p 3000"
echo "=========================================="
else
echo "=========================================="
echo "部署失败!请检查错误信息"
echo "=========================================="
return 1
fi
return 0
}
# 归档函数:复制构建产物到 archives/{版本号}/
archive() {
local version="$1"
if [ -z "$version" ]; then
echo "错误: 未指定版本号"
return 1
fi
local archive_dir="./archives/$version"
echo "=========================================="
echo "开始归档 Web 制品..."
echo "版本号: $version"
echo "归档目录: $archive_dir"
echo "=========================================="
# 创建归档目录
mkdir -p "$archive_dir"
# 复制 .next/
if [ -d "$LOCAL_WEB_DIR" ]; then
cp -r "$LOCAL_WEB_DIR/"* "$archive_dir/"
fi
# 复制 public/
if [ -d "$LOCAL_PUBLIC_DIR" ]; then
mkdir -p "$archive_dir/public"
cp -r "$LOCAL_PUBLIC_DIR/"* "$archive_dir/public/"
fi
if [ $? -eq 0 ]; then
echo "=========================================="
echo "归档成功!"
echo "归档路径: $archive_dir"
echo "=========================================="
else
echo "=========================================="
echo "归档失败!请检查错误信息"
echo "=========================================="
return 1
fi
return 0
}
# 读取当前版本号(package.json
get_version() {
grep '"version":' package.json | head -1 | sed -E 's/.*"version":\s*"([^"]+)".*/\1/'
}
# 递增 build number 并更新 package.json
# 返回新的版本号(仅 stdout 输出版本号,日志输出到 stderr)
bump_version() {
local current=$(get_version)
if [ -z "$current" ]; then
echo "错误: 无法读取当前版本号" >&2
return 1
fi
# 解析版本号(格式: x.y.z+build
local build_num=$(echo "$current" | cut -d'+' -f2)
local new_build_num=$((build_num + 1))
local new_version="${current%%+*}+${new_build_num}"
# 日志输出到 stderr
echo "==========================================" >&2
echo "更新版本号..." >&2
echo "当前版本: $current" >&2
echo "新版本: $new_version" >&2
echo "==========================================" >&2
# 更新 package.jsonJSON 格式)
sed -i.bak "s/\"version\":\s*\"$current\"/\"version\": \"$new_version\"/" package.json
rm -f package.json.bak
if [ $? -eq 0 ]; then
echo "版本号更新成功: $new_version" >&2
else
echo "版本号更新失败!" >&2
return 1
fi
# 只输出版本号到 stdout
echo "$new_version"
}
# 清除 Cloudflare CDN 缓存
purge_cdn_cache() {
if [ -z "$ZONE_ID" ] || [ -z "$CF_API_TOKEN" ]; then
echo "错误: Cloudflare 配置不完整,跳过缓存清除"
return 1
fi
echo "=========================================="
echo "开始清除 Cloudflare CDN 缓存..."
echo "Zone ID: $ZONE_ID"
echo "=========================================="
local response=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/purge_cache" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"purge_everything":true}')
if echo "$response" | grep -q '"success":true'; then
echo "=========================================="
echo "CDN 缓存清除成功!"
echo "=========================================="
return 0
else
echo "=========================================="
echo "CDN 缓存清除失败!"
echo "响应: $response"
echo "=========================================="
return 1
fi
}