fc15a34a77
client-v1.1.10 run #362 的 Deploy → Ali 失败:安装包(android 83M 等)经 frp/ pangolin 隧道 scp 传到一半连接 reset,scp 无续传→整个 job 挂 14min。改为: - 新增 push_file():rsync -av --partial --timeout=120 + 重试 5 次,断点续传; - version.yaml 用 push_file(必达,失败即 set -e 中止); - web 目录 rsync 加 --partial+重试 3 次,失败即中止(不切不完整目录); - 三个安装包用 push_file,5 次仍失败仅告警不阻断 web/version 切换。 本机手动补发 1.1.10 时正是用 rsync --partial 续传成功补上 android apk。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bupi8Kdqkfx2N5acFsHTx5
100 lines
4.4 KiB
Bash
100 lines
4.4 KiB
Bash
#!/usr/bin/env bash
|
|
# deploy-client.sh <tag> — deploy the Flutter web app, desktop/mobile installers,
|
|
# and version.yaml. Does NOT restart the backend (version.yaml is read
|
|
# per-request) nor touch nginx / the marketing site. Target is EC2 by default;
|
|
# set DEPLOY_HOST/DEPLOY_USER/DEPLOY_SSH_KEY to retarget the Ali box (migration).
|
|
set -euo pipefail
|
|
|
|
# shellcheck source=scripts/ci/lib-forgejo.sh
|
|
. "$(dirname "$0")/lib-forgejo.sh"
|
|
|
|
TAG="$1"
|
|
TARGET_HOST="${DEPLOY_HOST:-$EC2_HOST}"
|
|
TARGET_USER="${DEPLOY_USER:-$EC2_USER}"
|
|
echo "==> deploy-client: tag=${TAG} host=${TARGET_HOST}"
|
|
|
|
if [ ! -f dist/web.tar.gz ] || [ ! -f dist/version.yaml ]; then
|
|
download_release_assets "$TAG"
|
|
fi
|
|
|
|
echo "==> deploy-client: dist/ contents:"
|
|
ls -lh dist/
|
|
|
|
# Prefer the version.yaml released for this tag (carries bumped build_number +
|
|
# changelog); fall back to the checkout copy only if the asset is absent.
|
|
VERSION_YAML="dist/version.yaml"
|
|
[ -f "$VERSION_YAML" ] || VERSION_YAML="backend/config/version.yaml"
|
|
|
|
rm -rf /tmp/jiu-web-new
|
|
mkdir -p /tmp/jiu-web-new
|
|
tar -xzf dist/web.tar.gz -C /tmp/jiu-web-new --strip-components=1
|
|
|
|
setup_ssh
|
|
RSYNC_SSH="ssh -i ~/.ssh/ec2_deploy.pem -o StrictHostKeyChecking=no"
|
|
|
|
# 经隧道推文件到 ali 偶发中断,大安装包尤甚(见 client-v1.1.10 run #362 的
|
|
# Deploy → Ali 失败:android 83M scp 传到一半连接 reset,整个 job 挂 14min)。
|
|
# 用 rsync --partial(断点续传)+ 重试替代 scp:断了从断点续传、不整段重来。
|
|
# 单文件推送,重试 5 次;安装包已压缩(apk/zip/exe)故不加 -z。
|
|
push_file() { # push_file <local-file> <remote-abs-path>
|
|
local src="$1" dst="$2" i
|
|
for i in 1 2 3 4 5; do
|
|
if rsync -av --partial --timeout=120 -e "$RSYNC_SSH" \
|
|
"$src" "${TARGET_USER}@${TARGET_HOST}:${dst}"; then
|
|
return 0
|
|
fi
|
|
echo "!! push_file: ${src} 传输中断(第 ${i}/5 次),5s 后 --partial 续传重试…" >&2
|
|
sleep 5
|
|
done
|
|
return 1
|
|
}
|
|
|
|
echo "==> deploy-client: uploading files to ${TARGET_HOST}"
|
|
# version.yaml 承载版本号/更新日志,必达;5 次仍失败则 set -e 中止发版。
|
|
push_file "$VERSION_YAML" /tmp/version.yaml
|
|
|
|
# Flutter web 目录同步(--delete 保持一致;--partial 续传;重试 3 次)。web 是
|
|
# 发版核心产物,3 次仍失败即中止(避免把不完整目录切上线)。
|
|
web_ok=0
|
|
for i in 1 2 3; do
|
|
if rsync -avz --delete --partial --timeout=120 -e "$RSYNC_SSH" \
|
|
/tmp/jiu-web-new/ "${TARGET_USER}@${TARGET_HOST}:/tmp/jiu-web-new/"; then
|
|
web_ok=1; break
|
|
fi
|
|
echo "!! web 同步中断(第 ${i}/3 次),5s 后 --partial 续传重试…" >&2; sleep 5
|
|
done
|
|
[ "$web_ok" = 1 ] || { echo "ERROR: web 同步 3 次均失败,中止发版。" >&2; exit 1; }
|
|
|
|
# Desktop / mobile installers(nginx 从 /downloads/ 提供)。文件缺失可跳过
|
|
# (部分手动发版);传输 5 次仍失败仅告警不阻断 web/version 切换(下次发版补)。
|
|
[ -f dist/jiu-windows-x64-setup.exe ] && { push_file dist/jiu-windows-x64-setup.exe /tmp/jiu-windows-x64-setup.exe || echo "!! windows 安装包 5 次仍失败,跳过。" >&2; } || true
|
|
[ -f dist/jiu-macos-x64.zip ] && { push_file dist/jiu-macos-x64.zip /tmp/jiu-macos-x64.zip || echo "!! macos 安装包 5 次仍失败,跳过。" >&2; } || true
|
|
[ -f dist/jiu-android.apk ] && { push_file dist/jiu-android.apk /tmp/jiu-android.apk || echo "!! android 安装包 5 次仍失败,跳过。" >&2; } || true
|
|
|
|
${SSH} "${TARGET_USER}@${TARGET_HOST}" << 'ENDSSH'
|
|
set -e
|
|
|
|
# Update version config (WorkingDirectory=/opt/jiu reads config/version.yaml).
|
|
# Backend re-reads it per request — no restart needed.
|
|
mkdir -p /opt/jiu/config
|
|
cp /tmp/version.yaml /opt/jiu/config/version.yaml
|
|
|
|
# Swap Flutter web app (atomic)
|
|
rm -rf /opt/jiu/web-old
|
|
mv /opt/jiu/web /opt/jiu/web-old 2>/dev/null || true
|
|
mv /tmp/jiu-web-new /opt/jiu/web
|
|
|
|
# Publish installers to the nginx-served downloads dir; keep only the latest.
|
|
mkdir -p /opt/jiu/downloads
|
|
rm -f /opt/jiu/downloads/jiu-windows-* /opt/jiu/downloads/jiu-macos-* /opt/jiu/downloads/jiu-android-* /opt/jiu/downloads/jiu-android.apk 2>/dev/null || true
|
|
[ -f /tmp/jiu-windows-x64-setup.exe ] && mv -f /tmp/jiu-windows-x64-setup.exe /opt/jiu/downloads/ || true
|
|
[ -f /tmp/jiu-macos-x64.zip ] && mv -f /tmp/jiu-macos-x64.zip /opt/jiu/downloads/ || true
|
|
[ -f /tmp/jiu-android.apk ] && mv -f /tmp/jiu-android.apk /opt/jiu/downloads/ || true
|
|
|
|
echo "Client deploy complete!"
|
|
ENDSSH
|
|
|
|
teardown_ssh
|
|
rm -rf /tmp/jiu-web-new
|
|
echo "==> deploy-client: done"
|