ci(vps-deploy): 纳入前端dist同步+API重启(治公网前端无管线手动步骤): Mac构建+tar+scp→VPS换dist(脚本入仓scripts/nas_sync,vps_update_dist.py); 重启加端口释放等待(防end→run竞态10048静默崩,今日实踩)+起服探活(上限10min) [nas]
This commit is contained in:
@@ -40,6 +40,40 @@ jobs:
|
||||
run: bash scripts/nas_sync/promote.sh --target vps
|
||||
- name: VPS 冒烟 (LocalUnifiedProvider 真数据)
|
||||
run: ssh 49.232.102.198 'cd C:\sanguo_vnpy_v2 && C:\Python310\python.exe -X utf8 scripts/data_platform/verify_unified_e2e.py'
|
||||
- name: 前端构建 + 推 dist 到 VPS (公网前端无管线, 此处补齐)
|
||||
run: |
|
||||
set -e
|
||||
cd frontend
|
||||
npm ci
|
||||
npm run build
|
||||
cd ..
|
||||
tar czf /tmp/dist_latest.tgz -C frontend/dist .
|
||||
scp -o ConnectTimeout=20 /tmp/dist_latest.tgz 49.232.102.198:C:/sanguo_vnpy_v2/dist_latest.tgz
|
||||
- name: VPS 替换 dist + 重启 sanguo-api (等端口释放防 10048 竞态, 再等起服)
|
||||
run: |
|
||||
set -e
|
||||
ssh 49.232.102.198 'C:\Python310\python.exe -X utf8 C:\sanguo_vnpy_v2\scripts\nas_sync\vps_update_dist.py' | tee /tmp/dist_swap.log
|
||||
grep -q DIST_UPDATE_DONE /tmp/dist_swap.log
|
||||
# 停 API → 等端口彻底释放(旧实例被杀后端口有滞留, 立即重启会 10048 静默崩)
|
||||
ssh 49.232.102.198 'schtasks /end /tn sanguo-api' || true
|
||||
for i in $(seq 1 30); do
|
||||
ssh 49.232.102.198 'netstat -ano -p tcp' | tr -d '\r' | grep -q ':8000.*LISTEN' || { echo "port freed after $((i*2))s"; break; }
|
||||
sleep 2
|
||||
done
|
||||
ssh 49.232.102.198 'schtasks /run /tn sanguo-api'
|
||||
# 等新实例监听 + /docs 可用(VPS 启动需数分钟, 上限 10 分钟)
|
||||
for i in $(seq 1 60); do
|
||||
if ssh 49.232.102.198 'netstat -ano -p tcp' | tr -d '\r' | grep -q ':8000.*LISTEN'; then
|
||||
echo "API listening after ~$((i*10))s"; break
|
||||
fi
|
||||
sleep 10
|
||||
if [ "$i" = "60" ]; then echo "API 10 分钟未监听 8000"; exit 1; fi
|
||||
done
|
||||
for i in $(seq 1 12); do
|
||||
ssh 49.232.102.198 'powershell -NoProfile -Command "(Invoke-WebRequest -UseBasicParsing http://127.0.0.1:8000/docs).StatusCode"' 2>/dev/null | grep -q 200 && { echo "API /docs 200"; exit 0; }
|
||||
sleep 10
|
||||
done
|
||||
echo "API 监听但 /docs 2 分钟未返回 200"; exit 1
|
||||
- name: mark vps-deployed tag (VPS 版本真相, session 用 git log vps-deployed..HEAD 查未部署)
|
||||
env:
|
||||
TOKEN: ${{ github.token }}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""VPS: 替换 frontend/dist 为最新构建(先备份旧版)。
|
||||
|
||||
用法(VPS 上): C:\\Python310\\python.exe -X utf8 C:\\sanguo_vnpy_v2\\scripts\\nas_sync\\vps_update_dist.py
|
||||
输入: C:\\sanguo_vnpy_v2\\dist_latest.tgz (Mac 构建后 scp 上来的 tar 包, 内容为 dist 根)
|
||||
输出: 尾行 DIST_UPDATE_DONE(成功标记, CI 用)
|
||||
"""
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import tarfile
|
||||
|
||||
ROOT = r"C:\sanguo_vnpy_v2"
|
||||
TGZ = os.path.join(ROOT, "dist_latest.tgz")
|
||||
DIST = os.path.join(ROOT, "frontend", "dist")
|
||||
BAK = os.path.join(ROOT, "frontend", "dist_bak")
|
||||
|
||||
if not os.path.exists(TGZ):
|
||||
raise SystemExit(f"tgz not found: {TGZ}")
|
||||
|
||||
if os.path.exists(BAK):
|
||||
shutil.rmtree(BAK)
|
||||
if os.path.exists(DIST):
|
||||
shutil.move(DIST, BAK)
|
||||
print("old dist ->", BAK, flush=True)
|
||||
os.makedirs(DIST, exist_ok=True)
|
||||
with tarfile.open(TGZ) as t:
|
||||
t.extractall(DIST)
|
||||
idx = os.path.join(DIST, "index.html")
|
||||
with open(idx, encoding="utf-8") as f:
|
||||
head = f.read(400)
|
||||
m = re.search(r"assets/index-[^\"']*", head)
|
||||
print("new index:", m.group(0) if m else "?", flush=True)
|
||||
print("DIST_UPDATE_DONE", flush=True)
|
||||
Reference in New Issue
Block a user