#!/usr/bin/env bash # 测试服一键:build:test → standalone → Linux sharp → web_hjsq_h5.tar.gz → scp → run.sh set -euo pipefail SCRIPT_DIR=$(cd "$(dirname "$0")/.." && pwd) cd "$SCRIPT_DIR" TARGET_ARCH="${DEPLOY_TARGET_ARCH:-x64}" TARGET_LIBC="${DEPLOY_TARGET_LIBC:-glibc}" PACKAGE_NAME=web_hjsq_h5.tar.gz MD5_NAME=web_hjsq_h5.md5 RELEASE="$SCRIPT_DIR/dist/test-linux-$TARGET_ARCH-$TARGET_LIBC" JUMP_HOST="${DEPLOY_TEST_HOST:-root@172.104.181.99}" JUMP_DIR="${DEPLOY_TEST_DIR:-/server/web_hjsq/h5}" SCP_PORT="${DEPLOY_SCP_PORT:-22889}" SSH_PORT="${DEPLOY_SSH_PORT:-22889}" REMOTE_SCRIPT="${DEPLOY_TEST_REMOTE_SCRIPT:-run.sh}" SSH_IDENTITY="${DEPLOY_SSH_IDENTITY:-$HOME/.ssh/id_ed25519}" PACKAGE_ONLY=0 fail() { printf '错误:%s\n' "$*" >&2; exit 1; } step() { printf '\n▸ %s\n' "$*"; } for argument in "$@"; do case "$argument" in --package-only) PACKAGE_ONLY=1 ;; -h|--help) printf '用法:%s [--package-only]\n' "$0" printf '默认:测试打包并 scp + cd 远程目录执行 %s\n' "$REMOTE_SCRIPT" printf '可选:DEPLOY_TEST_HOST / DEPLOY_TEST_DIR / DEPLOY_SCP_PORT / DEPLOY_SSH_PORT\n' printf ' DEPLOY_TEST_REMOTE_SCRIPT / DEPLOY_SSH_IDENTITY / DEPLOY_TARGET_ARCH / DEPLOY_TARGET_LIBC\n' exit 0 ;; *) fail "不支持的参数 $argument;使用 --help 查看用法" ;; esac done JUMP_DIR="${JUMP_DIR%/}" command -v pnpm >/dev/null || fail '缺少 pnpm' node -e 'const [a,b]=process.versions.node.split(".").map(Number); if(a<20 || a===20 && b<9) process.exit(1)' \ || fail '需要 Node.js >=20.9' [ -s config/test.env ] || fail '缺少 config/test.env' if [ "$PACKAGE_ONLY" = 0 ]; then for tool in ssh scp; do command -v "$tool" >/dev/null || fail "缺少命令 $tool"; done [ -n "$JUMP_HOST" ] || fail '请设置 DEPLOY_TEST_HOST' [ -f "$SSH_IDENTITY" ] || fail "缺少 SSH 私钥:$SSH_IDENTITY(可用 DEPLOY_SSH_IDENTITY 指定)" fi step '测试环境构建' pnpm run build:test step '整理 standalone' pnpm run bundle:test step "补 Linux $TARGET_ARCH/$TARGET_LIBC sharp(test)" pnpm run bundle:linux -- "$TARGET_ARCH" "$TARGET_LIBC" test for file in start.mjs server.js .next/BUILD_ID config/test.env ecosystem.config.cjs; do [ -s "$RELEASE/$file" ] || fail "运行包缺少 $file" done [ -d "$RELEASE/.next/static" ] && [ -d "$RELEASE/public" ] || fail '运行包缺少静态资源' step "打包 $PACKAGE_NAME" rm -f "$SCRIPT_DIR/$PACKAGE_NAME" "$SCRIPT_DIR/$MD5_NAME" COPYFILE_DISABLE=1 COPY_EXTENDED_ATTRIBUTES_DISABLE=1 tar \ --no-xattrs \ --exclude='._*' --exclude='.DS_Store' --exclude='.env*' \ --exclude='*.local.env' --exclude='*.log' \ -czf "$SCRIPT_DIR/$PACKAGE_NAME" -C "$RELEASE" . chmod 600 "$SCRIPT_DIR/$PACKAGE_NAME" if command -v md5sum >/dev/null; then md5sum "$SCRIPT_DIR/$PACKAGE_NAME" | awk '{print $1}' > "$SCRIPT_DIR/$MD5_NAME" else md5 -q "$SCRIPT_DIR/$PACKAGE_NAME" > "$SCRIPT_DIR/$MD5_NAME" fi printf '\n完成:%s(%s)\n' "$PACKAGE_NAME" "$(du -h "$SCRIPT_DIR/$PACKAGE_NAME" | awk '{print $1}')" printf 'MD5:%s\n' "$(cat "$SCRIPT_DIR/$MD5_NAME")" if [ "$PACKAGE_ONLY" = 1 ]; then printf '已跳过上传(--package-only)。\n' exit 0 fi SSH_OPTS=(-i "$SSH_IDENTITY" -o IdentitiesOnly=yes -o BatchMode=yes) step "上传 $JUMP_HOST:$JUMP_DIR/" scp -P "$SCP_PORT" "${SSH_OPTS[@]}" \ "$SCRIPT_DIR/$PACKAGE_NAME" \ "$JUMP_HOST:$JUMP_DIR/" step "执行远程 cd $JUMP_DIR && bash $REMOTE_SCRIPT" ssh -p "$SSH_PORT" "${SSH_OPTS[@]}" \ "$JUMP_HOST" "cd $JUMP_DIR && bash $REMOTE_SCRIPT" printf '\n测试服打包并推送完成。\n' printf '若远程解压报 File exists:先在服务器清理旧 node_modules 后再跑 %s。\n' "$REMOTE_SCRIPT"