zhizhi/.github/workflows/deploy-to-zhuyuan-server.yml
Workflow config file is invalid. Please check your config file: yaml: unmarshal errors: line 124: mapping key "run" already defined at line 119

310 lines
11 KiB
YAML

name: 🏛️ 铸渊主权服务器 · 部署
# ═══════════════════════════════════════════════════════════
# 铸渊主权服务器部署工作流
# 编号: ZY-WF-铸体 (新器官 · 服务器部署引擎)
# 守护: 铸渊 · ICE-GL-ZY001
# 版权: 国作登字-2026-A-00037559
# ═══════════════════════════════════════════════════════════
on:
push:
branches: [main]
paths:
- 'server/**'
workflow_dispatch:
inputs:
action:
description: '部署动作'
required: true
default: 'deploy'
type: choice
options:
- deploy
- init
- health-check
- promote
deploy_target:
description: '部署目标站点'
required: false
default: 'preview'
type: choice
options:
- preview
- production
concurrency:
group: zhuyuan-server-deploy
cancel-in-progress: false
permissions:
contents: read
jobs:
# ═══ §1 初始化 (仅首次) ═══
init:
name: 🔧 服务器初始化
if: github.event.inputs.action == 'init'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 🔐 配置SSH
run: |
mkdir -p ~/.ssh
# 写入私钥(支持多种格式)
printf '%s\n' "${{ secrets.ZY_SERVER_KEY }}" > ~/.ssh/zy_key
chmod 600 ~/.ssh/zy_key
# 验证私钥格式
if head -1 ~/.ssh/zy_key | grep -q "BEGIN"; then
echo "✅ SSH私钥格式正确"
else
echo "❌ SSH私钥格式异常 — 请检查 GitHub Secrets 中 ZY_SERVER_KEY 的内容"
echo " 应以 '-----BEGIN' 开头,以 '-----END' 结尾"
exit 1
fi
ssh-keyscan -H ${{ secrets.ZY_SERVER_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
- name: 🔍 SSH连接测试
run: |
echo "🔍 测试SSH连接到 ${{ secrets.ZY_SERVER_HOST }}..."
ssh -i ~/.ssh/zy_key -o BatchMode=yes -o ConnectTimeout=10 \
${{ secrets.ZY_SERVER_USER }}@${{ secrets.ZY_SERVER_HOST }} \
'echo "✅ SSH连接成功 · $(hostname) · $(date)"' || {
echo ""
echo "═══════════════════════════════════════════════"
echo "❌ SSH连接失败 · 排查指南"
echo "═══════════════════════════════════════════════"
echo ""
echo "可能原因:"
echo " 1. 服务器未配置对应的SSH公钥"
echo " 2. GitHub Secrets中的私钥不完整或格式错误"
echo " 3. SSH用户名不正确"
echo ""
echo "修复步骤(冰朔操作):"
echo " ① 登录腾讯云控制台 → 轻量应用服务器 → 选择新加坡服务器"
echo " ② 点击「远程登录」→ 使用网页终端登录"
echo " ③ 在终端中执行以下命令生成新密钥:"
echo " ssh-keygen -t ed25519 -f ~/.ssh/github_deploy -N ''"
echo " cat ~/.ssh/github_deploy.pub >> ~/.ssh/authorized_keys"
echo " chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys"
echo " cat ~/.ssh/github_deploy"
echo " ④ 复制输出的私钥内容(从 -----BEGIN 到 -----END 完整复制)"
echo " ⑤ 打开 GitHub → Settings → Secrets → 更新 ZY_SERVER_KEY"
echo "═══════════════════════════════════════════════"
exit 1
}
- name: 📦 上传初始化脚本
run: |
scp -i ~/.ssh/zy_key \
server/setup/zhuyuan-server-init.sh \
${{ secrets.ZY_SERVER_USER }}@${{ secrets.ZY_SERVER_HOST }}:/tmp/
- name: 🚀 执行初始化
run: |
ssh -i ~/.ssh/zy_key \
${{ secrets.ZY_SERVER_USER }}@${{ secrets.ZY_SERVER_HOST }} \
'chmod +x /tmp/zhuyuan-server-init.sh && sudo /tmp/zhuyuan-server-init.sh'
# ═══ §2 部署应用 (默认部署到预览站) ═══
deploy:
name: 🚀 部署应用代码
if: github.event.inputs.action == 'deploy' || github.event.inputs.action == '' || github.event_name == 'push'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 🔐 配置SSH
run: |
mkdir -p ~/.ssh
printf '%s\n' "${{ secrets.ZY_SERVER_KEY }}" > ~/.ssh/zy_key
chmod 600 ~/.ssh/zy_key
ssh-keyscan -H ${{ secrets.ZY_SERVER_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
run: |
# 确定部署目标: preview (默认) 或 production
TARGET="${{ github.event.inputs.deploy_target || 'preview' }}"
TARGET_DIR="/opt/zhuyuan/sites/${TARGET}"
echo "📦 部署目标: ${TARGET} → ${TARGET_DIR}"
# 确保目标目录存在
ssh -i ~/.ssh/zy_key \
${{ secrets.ZY_SERVER_USER }}@${{ secrets.ZY_SERVER_HOST }} \
"mkdir -p ${TARGET_DIR}"
rsync -avz --delete \
-e "ssh -i ~/.ssh/zy_key" \
server/app/ \
${{ secrets.ZY_SERVER_USER }}@${{ secrets.ZY_SERVER_HOST }}:/opt/zhuyuan/app/
- name: 📦 同步配置文件
run: |
# PM2 配置
scp -i ~/.ssh/zy_key \
server/ecosystem.config.js \
${{ secrets.ZY_SERVER_USER }}@${{ secrets.ZY_SERVER_HOST }}:/opt/zhuyuan/config/pm2/
# Nginx 配置
scp -i ~/.ssh/zy_key \
server/nginx/zhuyuan-sovereign.conf \
${{ secrets.ZY_SERVER_USER }}@${{ secrets.ZY_SERVER_HOST }}:/opt/zhuyuan/config/nginx/
- name: 📥 安装依赖 & 重启
run: |
COMMIT_SHA="${{ github.sha }}"
REF_NAME="${{ github.ref_name }}"
ssh -i ~/.ssh/zy_key \
${{ secrets.ZY_SERVER_USER }}@${{ secrets.ZY_SERVER_HOST }} << DEPLOY_CMD
set -e
cd /opt/zhuyuan/app
# 安装依赖
npm install --production 2>&1
# 复制Nginx配置
sudo cp /opt/zhuyuan/config/nginx/zhuyuan-sovereign.conf /etc/nginx/sites-available/zhuyuan.conf
sudo ln -sf /etc/nginx/sites-available/zhuyuan.conf /etc/nginx/sites-enabled/zhuyuan.conf
sudo nginx -t && sudo systemctl reload nginx
# PM2 重启
pm2 delete zhuyuan-server 2>/dev/null || true
pm2 start /opt/zhuyuan/config/pm2/ecosystem.config.js
pm2 save
# 健康检查
sleep 3
curl -sf http://localhost:3800/api/health || echo "⚠️ 健康检查失败,等待更长时间..."
sleep 5
curl -sf http://localhost:3800/api/health && echo "✅ 服务器已上线" || echo "❌ 服务器启动失败"
# 记录部署操作
curl -sf -X POST http://localhost:3800/api/operations \
-H "Content-Type: application/json" \
-d "{
\"operator\": \"铸渊 · GitHub Actions\",
\"action\": \"自动部署\",
\"details\": \"commit: ${COMMIT_SHA}, branch: ${REF_NAME}\"
}" || true
DEPLOY_CMD
# ═══ §3 健康检查 ═══
health-check:
name: 💚 健康检查
if: github.event.inputs.action == 'health-check'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 🔐 配置SSH
run: |
mkdir -p ~/.ssh
printf '%s\n' "${{ secrets.ZY_SERVER_KEY }}" > ~/.ssh/zy_key
chmod 600 ~/.ssh/zy_key
ssh-keyscan -H ${{ secrets.ZY_SERVER_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
- name: 💚 执行健康检查
run: |
ssh -i ~/.ssh/zy_key \
${{ secrets.ZY_SERVER_USER }}@${{ secrets.ZY_SERVER_HOST }} << 'HEALTH_CMD'
echo "═══ 铸渊主权服务器健康报告 ═══"
echo ""
echo "§1 系统状态:"
uptime
echo ""
echo "§2 磁盘使用:"
df -h /
echo ""
echo "§3 内存使用:"
free -m
echo ""
echo "§4 PM2 进程:"
pm2 list 2>/dev/null || echo "PM2 未运行"
echo ""
echo "§5 Nginx 状态:"
systemctl is-active nginx && echo "Nginx: 运行中" || echo "Nginx: 已停止"
echo ""
echo "§6 应用健康:"
curl -sf http://localhost:3800/api/health | jq . 2>/dev/null || echo "应用未响应"
echo ""
echo "§7 大脑状态:"
curl -sf http://localhost:3800/api/brain | jq '.files_present, .files_total' 2>/dev/null || echo "大脑API未响应"
echo ""
echo "§8 双站点状态:"
curl -sf http://localhost:3800/api/sites | jq . 2>/dev/null || echo "站点API未响应"
HEALTH_CMD
# ═══ §4 一键推送: 预览站 → 主站 ═══
promote:
name: 🚀 预览站→主站 一键推送
if: github.event.inputs.action == 'promote'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 🔐 配置SSH
run: |
mkdir -p ~/.ssh
printf '%s\n' "${{ secrets.ZY_SERVER_KEY }}" > ~/.ssh/zy_key
chmod 600 ~/.ssh/zy_key
ssh-keyscan -H ${{ secrets.ZY_SERVER_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
- name: 🚀 执行推送
run: |
echo "🚀 一键推送: 预览站 → 主站"
RUN_ID="${{ github.run_id }}"
ssh -i ~/.ssh/zy_key \
${{ secrets.ZY_SERVER_USER }}@${{ secrets.ZY_SERVER_HOST }} << PROMOTE_CMD
# 调用铸渊 API 执行推送
RESULT=\$(curl -sf -X POST http://localhost:3800/api/sites/promote \
-H "Content-Type: application/json" \
-d "{
\"operator\": \"冰朔 · 通过 GitHub Actions 授权推送\",
\"note\": \"workflow_dispatch promote · run_id: ${RUN_ID}\"
}" 2>/dev/null)
if [ \$? -eq 0 ]; then
echo "\$RESULT" | jq . 2>/dev/null || echo "\$RESULT"
echo ""
echo "✅ 预览站已推送到主站"
else
echo "❌ 推送失败"
echo "尝试手动执行..."
if [ -d /opt/zhuyuan/sites/preview ] && [ -f /opt/zhuyuan/sites/preview/index.html ]; then
rsync -a --delete /opt/zhuyuan/sites/preview/ /opt/zhuyuan/sites/production/
echo "✅ 手动推送完成"
else
echo "❌ 预览站无内容,无法推送"
exit 1
fi
fi
PROMOTE_CMD
- name: 💚 推送后验证
run: |
ssh -i ~/.ssh/zy_key \
${{ secrets.ZY_SERVER_USER }}@${{ secrets.ZY_SERVER_HOST }} << 'VERIFY_CMD'
echo "═══ 推送后验证 ═══"
echo ""
echo "主站内容:"
ls -la /opt/zhuyuan/sites/production/ | head -10
echo ""
echo "站点状态:"
curl -sf http://localhost:3800/api/sites | jq . 2>/dev/null || echo "API未响应"
VERIFY_CMD