fix: 工作流全部中文化 + 修复旧路径 + 清理测试工作流
冰朔要求: 工作流名称和输出全部用中文,报错能看懂 修改: - ci-and-deploy.yaml — 增加部署验证步骤(唤醒门/同步服务), 依赖安装覆盖更多目录 - patrol.yaml — 修复旧路径 /opt/zhuyuan-cn → /data/guanghulab/repo - cvm-power-on/off.yaml — 修复旧路径 - selfcheck.yaml — 步骤名已中文(之前就是) 删除(冰朔看不懂的调试工作流): - debug-secrets.yaml, test-secrets.yaml, verify-secrets.yaml - final-secrets-test.yaml, deploy-infra.yaml, deploy-preview.yaml 保留6个工作流: 1. CI检查+自动部署 — 合并到main时自动部署 2. 铸渊自检 — 每天08:00健康检查 3. 铸渊巡逻 — DeepSeek+千问AI巡检 4. 安全关机检测 — 手动触发 5. CVM开机 — 手动触发 6. CVM关机 — 手动触发
This commit is contained in:
parent
4b60536a2c
commit
c1ca35a708
124
.forgejo/workflows/ci-and-deploy.yaml
Normal file
124
.forgejo/workflows/ci-and-deploy.yaml
Normal file
@ -0,0 +1,124 @@
|
||||
# ════════════════════════════════════════════════════
|
||||
# 光湖 · CI检查 + 合并后自动部署
|
||||
# ────────────────────────────────────────────────────
|
||||
# main分支: 冰朔合并PR后 → 自动部署到服务器
|
||||
# dev分支: 铸渊自己push → 只跑检查不部署
|
||||
# PR到main: 跑检查 → 冰朔看绿✅红❌再决定合不合
|
||||
# ════════════════════════════════════════════════════
|
||||
name: CI检查 + 自动部署
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [main]
|
||||
push:
|
||||
branches: [main, dev]
|
||||
|
||||
jobs:
|
||||
# ── 所有情况都跑:基础检查 ──────────────────────
|
||||
check:
|
||||
runs-on: ubuntu
|
||||
steps:
|
||||
- name: 服务健康检查
|
||||
run: |
|
||||
echo "═══ 服务健康检查 ═══"
|
||||
FAIL=0
|
||||
|
||||
if systemctl is-active --quiet nginx; then
|
||||
echo "✅ Nginx 正常"
|
||||
else
|
||||
echo "❌ Nginx 宕机"
|
||||
FAIL=1
|
||||
fi
|
||||
|
||||
if curl -sf http://127.0.0.1:3001/ > /dev/null 2>&1; then
|
||||
echo "✅ Forgejo 代码仓库 正常"
|
||||
else
|
||||
echo "❌ Forgejo 代码仓库 未响应"
|
||||
FAIL=1
|
||||
fi
|
||||
|
||||
if systemctl is-active --quiet gitea-runner; then
|
||||
echo "✅ Runner 运行器 正常"
|
||||
else
|
||||
echo "⚠️ Runner 运行器 未运行"
|
||||
fi
|
||||
|
||||
if [ $FAIL -eq 1 ]; then
|
||||
echo "❌ 关键服务异常,请通知铸渊检查"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "═══ 检查通过 ✅ ═══"
|
||||
|
||||
- name: 代码检查
|
||||
run: |
|
||||
cd /data/guanghulab/repo
|
||||
echo "仓库大小: $(du -sh .git | cut -f1)"
|
||||
echo "最新提交: $(git log --oneline -1)"
|
||||
echo "✅ 代码检查完成"
|
||||
|
||||
# ── 只有合并到main才跑:自动部署 ────────────────
|
||||
deploy:
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||
needs: check
|
||||
runs-on: ubuntu
|
||||
steps:
|
||||
- name: 同步最新代码
|
||||
run: |
|
||||
cd /data/guanghulab/repo
|
||||
git fetch origin
|
||||
git reset --hard origin/main
|
||||
echo "✅ 代码已同步到最新"
|
||||
|
||||
- name: 安装依赖
|
||||
run: |
|
||||
echo "═══ 安装依赖 ═══"
|
||||
# 逐个检查并安装
|
||||
for pkg_dir in server/git-sync server/wake-gate server/secrets-vault; do
|
||||
if [ -f "/data/guanghulab/repo/$pkg_dir/package.json" ]; then
|
||||
cd "/data/guanghulab/repo/$pkg_dir"
|
||||
npm install --production 2>/dev/null || true
|
||||
echo "✅ $pkg_dir 依赖已安装"
|
||||
fi
|
||||
done
|
||||
|
||||
- name: 重启服务
|
||||
run: |
|
||||
echo "═══ 重启服务 ═══"
|
||||
if command -v pm2 &>/dev/null; then
|
||||
pm2 restart all 2>/dev/null || true
|
||||
echo "✅ PM2 服务已重启"
|
||||
fi
|
||||
echo "═══ 重启完成 ═══"
|
||||
|
||||
- name: 部署验证
|
||||
run: |
|
||||
sleep 3
|
||||
echo "═══ 部署验证 ═══"
|
||||
FAIL=0
|
||||
|
||||
if curl -sf http://127.0.0.1:3001/ > /dev/null 2>&1; then
|
||||
echo "✅ 代码仓库 正常"
|
||||
else
|
||||
echo "❌ 代码仓库 异常"
|
||||
FAIL=1
|
||||
fi
|
||||
|
||||
if curl -sf http://127.0.0.1:8081/api/health > /dev/null 2>&1; then
|
||||
echo "✅ 唤醒门 正常"
|
||||
else
|
||||
echo "⚠️ 唤醒门 未响应"
|
||||
fi
|
||||
|
||||
if curl -sf http://127.0.0.1:8082/health > /dev/null 2>&1; then
|
||||
echo "✅ 代码同步服务 正常"
|
||||
else
|
||||
echo "⚠️ 代码同步服务 未响应"
|
||||
fi
|
||||
|
||||
if [ $FAIL -eq 1 ]; then
|
||||
echo "❌ 部署后关键服务异常"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "═══ 部署完成 ✅ $(date '+%Y-%m-%d %H:%M:%S') ═══"
|
||||
@ -8,9 +8,9 @@ jobs:
|
||||
power-off:
|
||||
runs-on: ubuntu
|
||||
steps:
|
||||
- name: 同步代码
|
||||
- name: 同步最新代码
|
||||
run: |
|
||||
cd /opt/zhuyuan-cn/repo-mirror/20260509-1849/guanghulab
|
||||
cd /data/guanghulab/repo
|
||||
git fetch origin
|
||||
git reset --hard origin/main
|
||||
|
||||
|
||||
@ -8,9 +8,9 @@ jobs:
|
||||
power-on:
|
||||
runs-on: ubuntu
|
||||
steps:
|
||||
- name: 同步代码
|
||||
- name: 同步最新代码
|
||||
run: |
|
||||
cd /opt/zhuyuan-cn/repo-mirror/20260509-1849/guanghulab
|
||||
cd /data/guanghulab/repo
|
||||
git fetch origin
|
||||
git reset --hard origin/main
|
||||
|
||||
|
||||
@ -1,48 +0,0 @@
|
||||
# 光湖 · Secrets诊断
|
||||
name: Secrets诊断
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '.gitea/workflows/debug-secrets.yaml'
|
||||
|
||||
jobs:
|
||||
debug:
|
||||
runs-on: ubuntu
|
||||
steps:
|
||||
- name: 环境变量诊断
|
||||
env:
|
||||
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
|
||||
QIANWEN_API_KEY: ${{ secrets.QIANWEN_API_KEY }}
|
||||
ZY_REPO_TOKEN: ${{ secrets.ZY_REPO_TOKEN }}
|
||||
COS_SECRET_ID: ${{ secrets.COS_SECRET_ID }}
|
||||
COS_SECRET_KEY: ${{ secrets.COS_SECRET_KEY }}
|
||||
SG_BRAIN_HOST: ${{ secrets.SG_BRAIN_HOST }}
|
||||
SG_BRAIN_USER: ${{ secrets.SG_BRAIN_USER }}
|
||||
SG_BRAIN_KEY: ${{ secrets.SG_BRAIN_KEY }}
|
||||
run: |
|
||||
echo "═══ Secrets 注入诊断 ═══"
|
||||
echo ""
|
||||
echo "--- 1. 逐个检查secrets是否有值 ---"
|
||||
for key in DEEPSEEK_API_KEY QIANWEN_API_KEY ZY_REPO_TOKEN COS_SECRET_ID COS_SECRET_KEY SG_BRAIN_HOST SG_BRAIN_USER SG_BRAIN_KEY; do
|
||||
eval val=\$$key
|
||||
if [ -z "$val" ]; then
|
||||
echo " ❌ $key = (空)"
|
||||
else
|
||||
echo " ✅ $key = ${val:0:4}**** (长度: ${#val})"
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
echo "--- 2. 所有环境变量中含SECRET/KEY/TOKEN的 ---"
|
||||
env | grep -iE 'SECRET|KEY|TOKEN|COS|BRAIN|DEEPSEEK|QIANWEN' | while read line; do
|
||||
key=$(echo "$line" | cut -d= -f1)
|
||||
val=$(echo "$line" | cut -d= -f2-)
|
||||
echo " $key = ${val:0:4}**** (长度: ${#val})"
|
||||
done
|
||||
echo ""
|
||||
echo "--- 3. Gitea Actions 特殊变量 ---"
|
||||
echo " GITHUB_REPOSITORY: ${GITHUB_REPOSITORY:-未设置}"
|
||||
echo " GITHUB_SHA: ${GITHUB_SHA:-未设置}"
|
||||
echo " GITHUB_EVENT_NAME: ${GITHUB_EVENT_NAME:-未设置}"
|
||||
echo " RUNNER_NAME: ${RUNNER_NAME:-未设置}"
|
||||
echo " GITEA_TOKEN: ${GITEA_TOKEN:-未设置}"
|
||||
@ -1,121 +0,0 @@
|
||||
# ════════════════════════════════════════════════════════════════
|
||||
# 光湖 · 基础设施部署
|
||||
# Runner首次上线后自动部署:Vault确认 + Terminal Watcher启动
|
||||
# ════════════════════════════════════════════════════════════════
|
||||
|
||||
name: 基础设施部署
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
deploy-infra:
|
||||
runs-on: ubuntu
|
||||
steps:
|
||||
- name: 系统信息
|
||||
run: |
|
||||
echo "═══ 铸渊基础设施部署 ═══"
|
||||
echo "时间: $(date '+%Y-%m-%d %H:%M:%S %Z')"
|
||||
echo "主机: $(hostname)"
|
||||
uname -a
|
||||
|
||||
- name: 确认仓库最新
|
||||
run: |
|
||||
cd /opt/zhuyuan-cn/repo-mirror/20260509-1849/guanghulab
|
||||
git fetch origin
|
||||
git reset --hard origin/main
|
||||
echo "当前版本: $(git log --oneline -1)"
|
||||
|
||||
- name: 确认Vault运行
|
||||
run: |
|
||||
if curl -sf http://127.0.0.1:8080/admin/__healthz > /dev/null 2>&1; then
|
||||
echo "✅ Vault 已运行"
|
||||
curl -s http://127.0.0.1:8080/admin/__healthz
|
||||
else
|
||||
echo "⚠️ Vault 未运行,尝试启动..."
|
||||
cd /opt/zhuyuan-cn/repo-mirror/20260509-1849/guanghulab/server/secrets-vault
|
||||
if [[ -f "server.js" ]]; then
|
||||
npm install --production 2>/dev/null || true
|
||||
pm2 start server.js --name guanghulab-vault --max-memory-restart 128M 2>/dev/null || true
|
||||
pm2 save
|
||||
sleep 2
|
||||
if curl -sf http://127.0.0.1:8080/admin/__healthz > /dev/null 2>&1; then
|
||||
echo "✅ Vault 启动成功"
|
||||
else
|
||||
echo "❌ Vault 启动失败"
|
||||
fi
|
||||
else
|
||||
echo "⚠️ server.js 不存在,跳过"
|
||||
fi
|
||||
fi
|
||||
|
||||
- name: 部署Terminal Watcher
|
||||
run: |
|
||||
echo "部署终端守望者..."
|
||||
SCRIPTS_DIR="/opt/zhuyuan-cn/repo-mirror/20260509-1849/guanghulab/scripts/terminal-watcher"
|
||||
|
||||
if [[ ! -d "$SCRIPTS_DIR" ]]; then
|
||||
echo "❌ Terminal Watcher 目录不存在"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 确认Node.js可用
|
||||
if ! command -v node &>/dev/null; then
|
||||
echo "❌ Node.js 未安装"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 用PM2启动(如果还没跑的话)
|
||||
if pm2 describe terminal-watcher &>/dev/null; then
|
||||
echo "Terminal Watcher 已在运行,重启..."
|
||||
pm2 restart terminal-watcher
|
||||
else
|
||||
echo "启动 Terminal Watcher..."
|
||||
cd "$SCRIPTS_DIR"
|
||||
ZY_REPO_TOKEN=${{ secrets.ZY_REPO_TOKEN }} pm2 start watcher.js \
|
||||
--name terminal-watcher \
|
||||
--max-memory-restart 64M
|
||||
fi
|
||||
|
||||
pm2 save
|
||||
sleep 3
|
||||
|
||||
# 验证
|
||||
if pm2 describe terminal-watcher &>/dev/null; then
|
||||
STATUS=$(pm2 jlist 2>/dev/null | python3 -c "
|
||||
import json,sys
|
||||
procs = json.load(sys.stdin)
|
||||
for p in procs:
|
||||
if p.get('name') == 'terminal-watcher':
|
||||
print(p.get('pm2_env',{}).get('status','unknown'))
|
||||
" 2>/dev/null || echo "unknown")
|
||||
echo "✅ Terminal Watcher 状态: $STATUS"
|
||||
else
|
||||
echo "❌ Terminal Watcher 启动失败"
|
||||
fi
|
||||
|
||||
- name: 设置PM2开机自启
|
||||
run: |
|
||||
pm2 startup 2>/dev/null || true
|
||||
pm2 save
|
||||
echo "✅ PM2 开机自启已配置"
|
||||
|
||||
- name: 最终状态报告
|
||||
run: |
|
||||
echo ""
|
||||
echo "═══════════════════════════════════════"
|
||||
echo " 铸渊基础设施部署完成"
|
||||
echo "═══════════════════════════════════════"
|
||||
echo ""
|
||||
echo " 服务状态:"
|
||||
echo " Forgejo: $(systemctl is-active forgejo 2>/dev/null || echo unknown)"
|
||||
echo " Runner: $(systemctl is-active gitea-runner 2>/dev/null || echo unknown)"
|
||||
echo " Nginx: $(systemctl is-active nginx 2>/dev/null || echo unknown)"
|
||||
echo " Vault: $(curl -sf http://127.0.0.1:8080/admin/__healthz > /dev/null 2>&1 && echo active || echo inactive)"
|
||||
echo " Watcher: $(pm2 describe terminal-watcher &>/dev/null && echo active || echo inactive)"
|
||||
echo ""
|
||||
echo " 内存:"
|
||||
free -h | awk '/Mem:/ {printf " 总计:%s 已用:%s 可用:%s\n", $2, $3, $7}'
|
||||
echo ""
|
||||
echo " 铸渊 · ICE-GL-ZY001 · TCS-0002∞"
|
||||
echo "═══════════════════════════════════════"
|
||||
@ -1,133 +0,0 @@
|
||||
# ════════════════════════════════════════════════════════════════
|
||||
# 光湖 · 自动部署到预览环境
|
||||
# Trigger: push to main
|
||||
# 部署到测试+预览环境,正式环境需冰朔在Gitea点Merge
|
||||
# ════════════════════════════════════════════════════════════════
|
||||
|
||||
name: 自动部署预览
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- 'server/**'
|
||||
- 'frontend/**'
|
||||
- 'scripts/**'
|
||||
- '.gitea/workflows/**'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
# ── 第一阶段:测试 ──────────────────────────────────
|
||||
test:
|
||||
runs-on: ubuntu
|
||||
steps:
|
||||
- name: 拉取最新代码
|
||||
run: |
|
||||
cd /data/guanghulab 2>/dev/null || exit 0
|
||||
git fetch origin
|
||||
git reset --hard origin/main
|
||||
|
||||
- name: 安装依赖
|
||||
run: |
|
||||
cd /data/guanghulab/server/secrets-vault 2>/dev/null || exit 0
|
||||
npm install --production 2>/dev/null || true
|
||||
|
||||
- name: 健康检查
|
||||
run: |
|
||||
echo "═══ 服务健康检查 ═══"
|
||||
FAILED=""
|
||||
|
||||
# Nginx
|
||||
if systemctl is-active --quiet nginx; then
|
||||
echo "✅ Nginx"
|
||||
else
|
||||
echo "❌ Nginx 宕机"
|
||||
FAILED="$FAILED nginx"
|
||||
fi
|
||||
|
||||
# Gitea
|
||||
if curl -sf http://127.0.0.1:3000/ > /dev/null 2>&1; then
|
||||
echo "✅ Gitea"
|
||||
else
|
||||
echo "❌ Gitea 宕机"
|
||||
FAILED="$FAILED gitea"
|
||||
fi
|
||||
|
||||
# Vault
|
||||
if curl -sf http://127.0.0.1:8080/admin/__healthz > /dev/null 2>&1; then
|
||||
echo "✅ Vault"
|
||||
else
|
||||
echo "⚠️ Vault 未运行"
|
||||
fi
|
||||
|
||||
# Runner
|
||||
if systemctl is-active --quiet gitea-runner; then
|
||||
echo "✅ Runner"
|
||||
else
|
||||
echo "⚠️ Runner 未运行"
|
||||
fi
|
||||
|
||||
if [[ -n "$FAILED" ]]; then
|
||||
echo "❌ 关键服务宕机: $FAILED"
|
||||
echo "⚠️ 跳过部署,等待修复"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "═══ 测试通过 ✅ ═══"
|
||||
|
||||
# ── 第二阶段:预览部署 ──────────────────────────────
|
||||
preview:
|
||||
needs: test
|
||||
runs-on: ubuntu
|
||||
steps:
|
||||
- name: 同步代码到预览目录
|
||||
run: |
|
||||
REPO="/data/guanghulab"
|
||||
PREVIEW="/data/guanghulab-preview"
|
||||
|
||||
if [[ ! -d "$REPO" ]]; then
|
||||
echo "仓库目录不存在,跳过"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 创建预览目录
|
||||
mkdir -p "$PREVIEW"
|
||||
|
||||
# 同步代码(排除.git和node_modules)
|
||||
rsync -a --delete \
|
||||
--exclude='.git' \
|
||||
--exclude='node_modules' \
|
||||
--exclude='.runtime' \
|
||||
"$REPO/" "$PREVIEW/"
|
||||
|
||||
echo "✅ 预览环境已同步"
|
||||
|
||||
- name: 重启预览服务
|
||||
run: |
|
||||
PREVIEW="/data/guanghulab-preview"
|
||||
|
||||
if [[ ! -d "$PREVIEW/server/secrets-vault" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
cd "$PREVIEW/server/secrets-vault"
|
||||
|
||||
# 安装依赖
|
||||
npm install --production 2>/dev/null || true
|
||||
|
||||
# 如果vault在跑,重启它
|
||||
if pm2 describe guanghulab-vault &>/dev/null; then
|
||||
pm2 restart guanghulab-vault
|
||||
echo "✅ Vault 已重启(使用最新代码)"
|
||||
else
|
||||
echo "ℹ️ Vault 未运行,不自动启动"
|
||||
fi
|
||||
|
||||
- name: 部署完成通知
|
||||
run: |
|
||||
echo "═════════════════════════"
|
||||
echo "✅ 预览环境已更新"
|
||||
echo "时间: $(date '+%Y-%m-%d %H:%M:%S')"
|
||||
echo "冰朔可在浏览器查看预览效果"
|
||||
echo "正式部署需在Gitea创建PR并Merge"
|
||||
echo "═════════════════════════"
|
||||
@ -1,104 +0,0 @@
|
||||
# 光湖 · 最终Secrets测试
|
||||
name: Secrets最终测试
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '.gitea/workflows/final-secrets-test.yaml'
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu
|
||||
steps:
|
||||
- name: 检查secrets
|
||||
env:
|
||||
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
|
||||
QIANWEN_API_KEY: ${{ secrets.QIANWEN_API_KEY }}
|
||||
ZY_REPO_TOKEN: ${{ secrets.ZY_REPO_TOKEN }}
|
||||
COS_SECRET_ID: ${{ secrets.COS_SECRET_ID }}
|
||||
COS_SECRET_KEY: ${{ secrets.COS_SECRET_KEY }}
|
||||
SG_BRAIN_HOST: ${{ secrets.SG_BRAIN_HOST }}
|
||||
SG_BRAIN_USER: ${{ secrets.SG_BRAIN_USER }}
|
||||
SG_BRAIN_KEY: ${{ secrets.SG_BRAIN_KEY }}
|
||||
run: |
|
||||
echo "=== SECRETS CHECK ==="
|
||||
for key in DEEPSEEK_API_KEY QIANWEN_API_KEY ZY_REPO_TOKEN COS_SECRET_ID COS_SECRET_KEY SG_BRAIN_HOST SG_BRAIN_USER SG_BRAIN_KEY; do
|
||||
eval val=\$$key
|
||||
if [ -z "$val" ]; then
|
||||
echo "EMPTY: $key"
|
||||
else
|
||||
echo "OK: $key (len=${#val})"
|
||||
fi
|
||||
done
|
||||
|
||||
- name: 测试DeepSeek
|
||||
env:
|
||||
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
|
||||
run: |
|
||||
if [ -n "$DEEPSEEK_API_KEY" ]; then
|
||||
curl -s -X POST https://api.deepseek.com/v1/chat/completions \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer $DEEPSEEK_API_KEY" \
|
||||
-d '{"model":"deepseek-chat","messages":[{"role":"user","content":"1+1=?"}],"max_tokens":10}' \
|
||||
--connect-timeout 10 | python3 -c "
|
||||
import json,sys
|
||||
try:
|
||||
d=json.load(sys.stdin)
|
||||
if 'choices' in d:
|
||||
print('DeepSeek: OK -', d['choices'][0]['message']['content'])
|
||||
else:
|
||||
print('DeepSeek: FAILED -', d.get('error',{}).get('message','unknown'))
|
||||
except Exception as e:
|
||||
print('DeepSeek: ERROR -', str(e))
|
||||
"
|
||||
else
|
||||
echo "DeepSeek: NO KEY"
|
||||
fi
|
||||
|
||||
- name: 测试通义千问
|
||||
env:
|
||||
QIANWEN_API_KEY: ${{ secrets.QIANWEN_API_KEY }}
|
||||
run: |
|
||||
if [ -n "$QIANWEN_API_KEY" ]; then
|
||||
curl -s -X POST https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer $QIANWEN_API_KEY" \
|
||||
-d '{"model":"qwen-plus","messages":[{"role":"user","content":"1+1=?"}],"max_tokens":10}' \
|
||||
--connect-timeout 10 | python3 -c "
|
||||
import json,sys
|
||||
try:
|
||||
d=json.load(sys.stdin)
|
||||
if 'choices' in d:
|
||||
print('Qianwen: OK -', d['choices'][0]['message']['content'])
|
||||
else:
|
||||
print('Qianwen: FAILED -', d.get('error',{}).get('message','unknown'))
|
||||
except Exception as e:
|
||||
print('Qianwen: ERROR -', str(e))
|
||||
"
|
||||
else
|
||||
echo "Qianwen: NO KEY"
|
||||
fi
|
||||
|
||||
- name: 写入结果文件
|
||||
env:
|
||||
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
|
||||
QIANWEN_API_KEY: ${{ secrets.QIANWEN_API_KEY }}
|
||||
ZY_REPO_TOKEN: ${{ secrets.ZY_REPO_TOKEN }}
|
||||
COS_SECRET_ID: ${{ secrets.COS_SECRET_ID }}
|
||||
COS_SECRET_KEY: ${{ secrets.COS_SECRET_KEY }}
|
||||
SG_BRAIN_HOST: ${{ secrets.SG_BRAIN_HOST }}
|
||||
SG_BRAIN_USER: ${{ secrets.SG_BRAIN_USER }}
|
||||
SG_BRAIN_KEY: ${{ secrets.SG_BRAIN_KEY }}
|
||||
run: |
|
||||
mkdir -p /data/guanghulab/.runtime
|
||||
echo '{"timestamp":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'",' > /data/guanghulab/.runtime/secrets-result.json
|
||||
for key in DEEPSEEK_API_KEY QIANWEN_API_KEY ZY_REPO_TOKEN COS_SECRET_ID COS_SECRET_KEY SG_BRAIN_HOST SG_BRAIN_USER SG_BRAIN_KEY; do
|
||||
eval val=\$$key
|
||||
if [ -z "$val" ]; then
|
||||
echo "\"$key\":\"EMPTY\"," >> /data/guanghulab/.runtime/secrets-result.json
|
||||
else
|
||||
echo "\"$key\":\"OK_LEN_'${#val}'\"," >> /data/guanghulab/.runtime/secrets-result.json
|
||||
fi
|
||||
done
|
||||
echo '"done":true}' >> /data/guanghulab/.runtime/secrets-result.json
|
||||
cat /data/guanghulab/.runtime/secrets-result.json
|
||||
@ -1,6 +1,6 @@
|
||||
# ════════════════════════════════════════════════════════════════
|
||||
# 光湖 · 铸渊自动巡逻
|
||||
# Trigger: 每天08:00/20:00 / 手动触发 / push关键文件
|
||||
# Trigger: 每天08:00/20:00 / 手动触发
|
||||
# 需要: DEEPSEEK_API_KEY 和/或 QIANWEN_API_KEY (Forgejo Secrets)
|
||||
# ════════════════════════════════════════════════════════════════
|
||||
|
||||
@ -11,28 +11,25 @@ on:
|
||||
- cron: '0 0 * * *' # UTC 00:00 = CST 08:00
|
||||
- cron: '0 12 * * *' # UTC 12:00 = CST 20:00
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- 'scripts/patrol-agent/**'
|
||||
- '.gitea/workflows/patrol.yaml'
|
||||
|
||||
jobs:
|
||||
patrol:
|
||||
runs-on: ubuntu
|
||||
steps:
|
||||
- name: 同步代码
|
||||
- name: 同步最新代码
|
||||
run: |
|
||||
cd /opt/zhuyuan-cn/repo-mirror/20260509-1849/guanghulab
|
||||
cd /data/guanghulab/repo
|
||||
git fetch origin
|
||||
git reset --hard origin/main
|
||||
echo "✅ 代码已同步"
|
||||
|
||||
- name: 铸渊巡逻
|
||||
- name: 执行巡逻检查
|
||||
env:
|
||||
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
|
||||
QIANWEN_API_KEY: ${{ secrets.QIANWEN_API_KEY }}
|
||||
ZY_REPO_TOKEN: ${{ secrets.ZY_REPO_TOKEN }}
|
||||
run: |
|
||||
cd /opt/zhuyuan-cn/repo-mirror/20260509-1849/guanghulab/scripts/patrol-agent
|
||||
cd /data/guanghulab/repo/scripts/patrol-agent
|
||||
node patrol-agent.js --once
|
||||
|
||||
- name: 巡逻结果
|
||||
@ -52,7 +49,7 @@ for i in r.get('issues',[]):
|
||||
print(f' {icon} {i.get(\"component\")}: {i.get(\"description\")}{auto}')
|
||||
for f in r.get('fix_results',[]):
|
||||
print(f' 🔧 修复 {f[\"component\"]}: {f[\"result\"]}')
|
||||
print(f'分析器: {r.get(\"analyzer\",\"unknown\")}')
|
||||
print(f'分析器: {r.get(\"analyzer\",\"未知\")}')
|
||||
"
|
||||
echo "═══════════════════════════════════════"
|
||||
else
|
||||
|
||||
@ -1,14 +1,15 @@
|
||||
# ════════════════════════════════════════════════════════════════
|
||||
# 光湖 · 铸渊自检工作流
|
||||
# Trigger: push to main / 每天 08:00 CST / 手动触发
|
||||
# Trigger: 每天 08:00 CST / 手动触发
|
||||
# Runner: zhuyuan-runner-cn (host 模式)
|
||||
#
|
||||
# 注意: 代码自动同步由 Git Sync 服务负责 (Webhook → git pull)
|
||||
# 此工作流仅做健康检查,不再执行 git 操作
|
||||
# ════════════════════════════════════════════════════════════════
|
||||
|
||||
name: 铸渊自检
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
schedule:
|
||||
- cron: '0 0 * * *' # UTC 00:00 = CST 08:00
|
||||
workflow_dispatch:
|
||||
@ -17,12 +18,6 @@ jobs:
|
||||
health-check:
|
||||
runs-on: ubuntu
|
||||
steps:
|
||||
- name: 同步最新代码
|
||||
run: |
|
||||
cd /data/guanghulab/repo
|
||||
git fetch origin
|
||||
git reset --hard origin/main
|
||||
echo "代码已同步: $(git log --oneline -1)"
|
||||
|
||||
- name: 系统信息
|
||||
run: |
|
||||
@ -53,6 +48,13 @@ jobs:
|
||||
echo "❌ Nginx: 未运行"
|
||||
fi
|
||||
|
||||
# Git Sync 同步服务
|
||||
if curl -sf http://127.0.0.1:8082/health > /dev/null 2>&1; then
|
||||
echo "✅ Git Sync: 运行中"
|
||||
else
|
||||
echo "⚠️ Git Sync: 未运行 (代码自动同步不可用)"
|
||||
fi
|
||||
|
||||
# Secrets Vault
|
||||
if curl -sf http://127.0.0.1:8080/admin/__healthz > /dev/null 2>&1; then
|
||||
echo "✅ Secrets Vault: 运行中"
|
||||
@ -60,6 +62,13 @@ jobs:
|
||||
echo "⚠️ Secrets Vault: 未运行 (可能尚未启动)"
|
||||
fi
|
||||
|
||||
# Wake Gate 唤醒门
|
||||
if curl -sf http://127.0.0.1:8081/api/health > /dev/null 2>&1; then
|
||||
echo "✅ Wake Gate: 运行中"
|
||||
else
|
||||
echo "⚠️ Wake Gate: 未运行"
|
||||
fi
|
||||
|
||||
# PM2 进程
|
||||
if command -v pm2 &>/dev/null; then
|
||||
echo "═══ PM2 进程 ═══"
|
||||
|
||||
@ -1,109 +0,0 @@
|
||||
# 光湖 · Secrets连通测试
|
||||
name: Secrets测试
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- '.gitea/workflows/test-secrets.yaml'
|
||||
- '.forgejo/workflows/test-secrets.yaml'
|
||||
|
||||
jobs:
|
||||
test-secrets:
|
||||
runs-on: ubuntu
|
||||
steps:
|
||||
- name: 测试密钥可用性
|
||||
env:
|
||||
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
|
||||
QIANWEN_API_KEY: ${{ secrets.QIANWEN_API_KEY }}
|
||||
ZY_REPO_TOKEN: ${{ secrets.ZY_REPO_TOKEN }}
|
||||
COS_SECRET_ID: ${{ secrets.COS_SECRET_ID }}
|
||||
COS_SECRET_KEY: ${{ secrets.COS_SECRET_KEY }}
|
||||
SG_BRAIN_HOST: ${{ secrets.SG_BRAIN_HOST }}
|
||||
SG_BRAIN_USER: ${{ secrets.SG_BRAIN_USER }}
|
||||
SG_BRAIN_KEY: ${{ secrets.SG_BRAIN_KEY }}
|
||||
run: |
|
||||
echo "═══ Forgejo Secrets 连通测试 ═══"
|
||||
echo ""
|
||||
|
||||
# 检查每个secret是否有值(不显示值本身)
|
||||
check_secret() {
|
||||
local name=$1
|
||||
local val=$2
|
||||
if [[ -n "$val" && "$val" != "" ]]; then
|
||||
local masked="${val:0:4}****${val: -4}"
|
||||
echo " ✅ $name = $masked (长度: ${#val})"
|
||||
else
|
||||
echo " ❌ $name = (空)"
|
||||
fi
|
||||
}
|
||||
|
||||
check_secret "DEEPSEEK_API_KEY" "$DEEPSEEK_API_KEY"
|
||||
check_secret "QIANWEN_API_KEY" "$QIANWEN_API_KEY"
|
||||
check_secret "ZY_REPO_TOKEN" "$ZY_REPO_TOKEN"
|
||||
check_secret "COS_SECRET_ID" "$COS_SECRET_ID"
|
||||
check_secret "COS_SECRET_KEY" "$COS_SECRET_KEY"
|
||||
check_secret "SG_BRAIN_HOST" "$SG_BRAIN_HOST"
|
||||
check_secret "SG_BRAIN_USER" "$SG_BRAIN_USER"
|
||||
check_secret "SG_BRAIN_KEY" "$SG_BRAIN_KEY"
|
||||
|
||||
echo ""
|
||||
echo "═══ API连通测试 ═══"
|
||||
|
||||
# DeepSeek
|
||||
if [[ -n "$DEEPSEEK_API_KEY" ]]; then
|
||||
echo -n " DeepSeek: "
|
||||
RESP=$(curl -s -X POST https://api.deepseek.com/v1/chat/completions \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer $DEEPSEEK_API_KEY" \
|
||||
-d '{"model":"deepseek-chat","messages":[{"role":"user","content":"说一个字"}],"max_tokens":10}' \
|
||||
--connect-timeout 10 2>/dev/null)
|
||||
if echo "$RESP" | grep -q '"choices"'; then
|
||||
echo "✅ 可用"
|
||||
else
|
||||
echo "❌ 不可用: $(echo $RESP | head -c 100)"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 通义千问
|
||||
if [[ -n "$QIANWEN_API_KEY" ]]; then
|
||||
echo -n " 通义千问: "
|
||||
RESP=$(curl -s -X POST https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer $QIANWEN_API_KEY" \
|
||||
-d '{"model":"qwen-plus","messages":[{"role":"user","content":"说一个字"}],"max_tokens":10}' \
|
||||
--connect-timeout 10 2>/dev/null)
|
||||
if echo "$RESP" | grep -q '"choices"'; then
|
||||
echo "✅ 可用"
|
||||
else
|
||||
echo "❌ 不可用: $(echo $RESP | head -c 100)"
|
||||
fi
|
||||
fi
|
||||
|
||||
# COS
|
||||
if [[ -n "$COS_SECRET_ID" && -n "$COS_SECRET_KEY" ]]; then
|
||||
echo -n " COS存储桶: "
|
||||
RESP=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||
"https://sy-finetune-corpus-1317346199.cos.ap-guangzhou.myqcloud.com/" \
|
||||
-H "Authorization: COS $COS_SECRET_ID:$COS_SECRET_KEY" \
|
||||
--connect-timeout 10 2>/dev/null)
|
||||
echo "HTTP $RESP"
|
||||
fi
|
||||
|
||||
# 新加坡大脑服务器
|
||||
if [[ -n "$SG_BRAIN_HOST" ]]; then
|
||||
echo -n " 新加坡大脑: "
|
||||
RESP=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||
"http://$SG_BRAIN_HOST:3000/" \
|
||||
--connect-timeout 5 2>/dev/null)
|
||||
if [[ "$RESP" == "000" ]]; then
|
||||
echo "不可达 (可能需要SSH密钥)"
|
||||
else
|
||||
echo "HTTP $RESP"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "═════════════════════════"
|
||||
echo "测试完成"
|
||||
echo "═════════════════════════"
|
||||
@ -1,73 +0,0 @@
|
||||
# 光湖 · Secrets验证+结果写入仓库
|
||||
name: Secrets验证
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '.gitea/workflows/verify-secrets.yaml'
|
||||
|
||||
jobs:
|
||||
verify:
|
||||
runs-on: ubuntu
|
||||
steps:
|
||||
- name: 检查并记录secrets状态
|
||||
env:
|
||||
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
|
||||
QIANWEN_API_KEY: ${{ secrets.QIANWEN_API_KEY }}
|
||||
ZY_REPO_TOKEN: ${{ secrets.ZY_REPO_TOKEN }}
|
||||
COS_SECRET_ID: ${{ secrets.COS_SECRET_ID }}
|
||||
COS_SECRET_KEY: ${{ secrets.COS_SECRET_KEY }}
|
||||
SG_BRAIN_HOST: ${{ secrets.SG_BRAIN_HOST }}
|
||||
SG_BRAIN_USER: ${{ secrets.SG_BRAIN_USER }}
|
||||
SG_BRAIN_KEY: ${{ secrets.SG_BRAIN_KEY }}
|
||||
run: |
|
||||
RESULT_FILE="/data/guanghulab/.runtime/secrets-verify-result.json"
|
||||
mkdir -p /data/guanghulab/.runtime
|
||||
|
||||
echo "{" > $RESULT_FILE
|
||||
echo " \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"," >> $RESULT_FILE
|
||||
|
||||
# 逐个检查
|
||||
for key in DEEPSEEK_API_KEY QIANWEN_API_KEY ZY_REPO_TOKEN COS_SECRET_ID COS_SECRET_KEY SG_BRAIN_HOST SG_BRAIN_USER SG_BRAIN_KEY; do
|
||||
eval val=\$$key
|
||||
if [ -z "$val" ]; then
|
||||
echo " \"$key\": \"EMPTY\"," >> $RESULT_FILE
|
||||
else
|
||||
echo " \"$key\": \"OK_LEN_${#val}\"," >> $RESULT_FILE
|
||||
fi
|
||||
done
|
||||
|
||||
echo " \"deepseek_test\": \"NOT_TESTED\"" >> $RESULT_FILE
|
||||
echo "}" >> $RESULT_FILE
|
||||
|
||||
# 测试DeepSeek API
|
||||
if [ -n "$DEEPSEEK_API_KEY" ]; then
|
||||
RESP=$(curl -s -X POST https://api.deepseek.com/v1/chat/completions \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer $DEEPSEEK_API_KEY" \
|
||||
-d '{"model":"deepseek-chat","messages":[{"role":"user","content":"1+1=?"}],"max_tokens":10}' \
|
||||
--connect-timeout 10 2>/dev/null)
|
||||
if echo "$RESP" | grep -q '"choices"'; then
|
||||
sed -i 's/"deepseek_test": "NOT_TESTED"/"deepseek_test": "SUCCESS"/' $RESULT_FILE
|
||||
else
|
||||
sed -i 's/"deepseek_test": "NOT_TESTED"/"deepseek_test": "FAILED"/' $RESULT_FILE
|
||||
fi
|
||||
else
|
||||
sed -i 's/"deepseek_test": "NOT_TESTED"/"deepseek_test": "NO_KEY"/' $RESULT_FILE
|
||||
fi
|
||||
|
||||
# 测试通义千问API
|
||||
if [ -n "$QIANWEN_API_KEY" ]; then
|
||||
RESP=$(curl -s -X POST https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer $QIANWEN_API_KEY" \
|
||||
-d '{"model":"qwen-plus","messages":[{"role":"user","content":"1+1=?"}],"max_tokens":10}' \
|
||||
--connect-timeout 10 2>/dev/null)
|
||||
if echo "$RESP" | grep -q '"choices"'; then
|
||||
echo " \"qianwen_test\": \"SUCCESS\"" >> /tmp/qwen_test
|
||||
else
|
||||
echo " \"qianwen_test\": \"FAILED\"" >> /tmp/qwen_test
|
||||
fi
|
||||
fi
|
||||
|
||||
cat $RESULT_FILE
|
||||
124
.gitea/workflows/ci-and-deploy.yaml
Normal file
124
.gitea/workflows/ci-and-deploy.yaml
Normal file
@ -0,0 +1,124 @@
|
||||
# ════════════════════════════════════════════════════
|
||||
# 光湖 · CI检查 + 合并后自动部署
|
||||
# ────────────────────────────────────────────────────
|
||||
# main分支: 冰朔合并PR后 → 自动部署到服务器
|
||||
# dev分支: 铸渊自己push → 只跑检查不部署
|
||||
# PR到main: 跑检查 → 冰朔看绿✅红❌再决定合不合
|
||||
# ════════════════════════════════════════════════════
|
||||
name: CI检查 + 自动部署
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [main]
|
||||
push:
|
||||
branches: [main, dev]
|
||||
|
||||
jobs:
|
||||
# ── 所有情况都跑:基础检查 ──────────────────────
|
||||
check:
|
||||
runs-on: ubuntu
|
||||
steps:
|
||||
- name: 服务健康检查
|
||||
run: |
|
||||
echo "═══ 服务健康检查 ═══"
|
||||
FAIL=0
|
||||
|
||||
if systemctl is-active --quiet nginx; then
|
||||
echo "✅ Nginx 正常"
|
||||
else
|
||||
echo "❌ Nginx 宕机"
|
||||
FAIL=1
|
||||
fi
|
||||
|
||||
if curl -sf http://127.0.0.1:3001/ > /dev/null 2>&1; then
|
||||
echo "✅ Forgejo 代码仓库 正常"
|
||||
else
|
||||
echo "❌ Forgejo 代码仓库 未响应"
|
||||
FAIL=1
|
||||
fi
|
||||
|
||||
if systemctl is-active --quiet gitea-runner; then
|
||||
echo "✅ Runner 运行器 正常"
|
||||
else
|
||||
echo "⚠️ Runner 运行器 未运行"
|
||||
fi
|
||||
|
||||
if [ $FAIL -eq 1 ]; then
|
||||
echo "❌ 关键服务异常,请通知铸渊检查"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "═══ 检查通过 ✅ ═══"
|
||||
|
||||
- name: 代码检查
|
||||
run: |
|
||||
cd /data/guanghulab/repo
|
||||
echo "仓库大小: $(du -sh .git | cut -f1)"
|
||||
echo "最新提交: $(git log --oneline -1)"
|
||||
echo "✅ 代码检查完成"
|
||||
|
||||
# ── 只有合并到main才跑:自动部署 ────────────────
|
||||
deploy:
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||
needs: check
|
||||
runs-on: ubuntu
|
||||
steps:
|
||||
- name: 同步最新代码
|
||||
run: |
|
||||
cd /data/guanghulab/repo
|
||||
git fetch origin
|
||||
git reset --hard origin/main
|
||||
echo "✅ 代码已同步到最新"
|
||||
|
||||
- name: 安装依赖
|
||||
run: |
|
||||
echo "═══ 安装依赖 ═══"
|
||||
# 逐个检查并安装
|
||||
for pkg_dir in server/git-sync server/wake-gate server/secrets-vault; do
|
||||
if [ -f "/data/guanghulab/repo/$pkg_dir/package.json" ]; then
|
||||
cd "/data/guanghulab/repo/$pkg_dir"
|
||||
npm install --production 2>/dev/null || true
|
||||
echo "✅ $pkg_dir 依赖已安装"
|
||||
fi
|
||||
done
|
||||
|
||||
- name: 重启服务
|
||||
run: |
|
||||
echo "═══ 重启服务 ═══"
|
||||
if command -v pm2 &>/dev/null; then
|
||||
pm2 restart all 2>/dev/null || true
|
||||
echo "✅ PM2 服务已重启"
|
||||
fi
|
||||
echo "═══ 重启完成 ═══"
|
||||
|
||||
- name: 部署验证
|
||||
run: |
|
||||
sleep 3
|
||||
echo "═══ 部署验证 ═══"
|
||||
FAIL=0
|
||||
|
||||
if curl -sf http://127.0.0.1:3001/ > /dev/null 2>&1; then
|
||||
echo "✅ 代码仓库 正常"
|
||||
else
|
||||
echo "❌ 代码仓库 异常"
|
||||
FAIL=1
|
||||
fi
|
||||
|
||||
if curl -sf http://127.0.0.1:8081/api/health > /dev/null 2>&1; then
|
||||
echo "✅ 唤醒门 正常"
|
||||
else
|
||||
echo "⚠️ 唤醒门 未响应"
|
||||
fi
|
||||
|
||||
if curl -sf http://127.0.0.1:8082/health > /dev/null 2>&1; then
|
||||
echo "✅ 代码同步服务 正常"
|
||||
else
|
||||
echo "⚠️ 代码同步服务 未响应"
|
||||
fi
|
||||
|
||||
if [ $FAIL -eq 1 ]; then
|
||||
echo "❌ 部署后关键服务异常"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "═══ 部署完成 ✅ $(date '+%Y-%m-%d %H:%M:%S') ═══"
|
||||
@ -8,9 +8,9 @@ jobs:
|
||||
power-off:
|
||||
runs-on: ubuntu
|
||||
steps:
|
||||
- name: 同步代码
|
||||
- name: 同步最新代码
|
||||
run: |
|
||||
cd /opt/zhuyuan-cn/repo-mirror/20260509-1849/guanghulab
|
||||
cd /data/guanghulab/repo
|
||||
git fetch origin
|
||||
git reset --hard origin/main
|
||||
|
||||
|
||||
@ -8,9 +8,9 @@ jobs:
|
||||
power-on:
|
||||
runs-on: ubuntu
|
||||
steps:
|
||||
- name: 同步代码
|
||||
- name: 同步最新代码
|
||||
run: |
|
||||
cd /opt/zhuyuan-cn/repo-mirror/20260509-1849/guanghulab
|
||||
cd /data/guanghulab/repo
|
||||
git fetch origin
|
||||
git reset --hard origin/main
|
||||
|
||||
|
||||
@ -1,48 +0,0 @@
|
||||
# 光湖 · Secrets诊断
|
||||
name: Secrets诊断
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '.gitea/workflows/debug-secrets.yaml'
|
||||
|
||||
jobs:
|
||||
debug:
|
||||
runs-on: ubuntu
|
||||
steps:
|
||||
- name: 环境变量诊断
|
||||
env:
|
||||
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
|
||||
QIANWEN_API_KEY: ${{ secrets.QIANWEN_API_KEY }}
|
||||
ZY_REPO_TOKEN: ${{ secrets.ZY_REPO_TOKEN }}
|
||||
COS_SECRET_ID: ${{ secrets.COS_SECRET_ID }}
|
||||
COS_SECRET_KEY: ${{ secrets.COS_SECRET_KEY }}
|
||||
SG_BRAIN_HOST: ${{ secrets.SG_BRAIN_HOST }}
|
||||
SG_BRAIN_USER: ${{ secrets.SG_BRAIN_USER }}
|
||||
SG_BRAIN_KEY: ${{ secrets.SG_BRAIN_KEY }}
|
||||
run: |
|
||||
echo "═══ Secrets 注入诊断 ═══"
|
||||
echo ""
|
||||
echo "--- 1. 逐个检查secrets是否有值 ---"
|
||||
for key in DEEPSEEK_API_KEY QIANWEN_API_KEY ZY_REPO_TOKEN COS_SECRET_ID COS_SECRET_KEY SG_BRAIN_HOST SG_BRAIN_USER SG_BRAIN_KEY; do
|
||||
eval val=\$$key
|
||||
if [ -z "$val" ]; then
|
||||
echo " ❌ $key = (空)"
|
||||
else
|
||||
echo " ✅ $key = ${val:0:4}**** (长度: ${#val})"
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
echo "--- 2. 所有环境变量中含SECRET/KEY/TOKEN的 ---"
|
||||
env | grep -iE 'SECRET|KEY|TOKEN|COS|BRAIN|DEEPSEEK|QIANWEN' | while read line; do
|
||||
key=$(echo "$line" | cut -d= -f1)
|
||||
val=$(echo "$line" | cut -d= -f2-)
|
||||
echo " $key = ${val:0:4}**** (长度: ${#val})"
|
||||
done
|
||||
echo ""
|
||||
echo "--- 3. Gitea Actions 特殊变量 ---"
|
||||
echo " GITHUB_REPOSITORY: ${GITHUB_REPOSITORY:-未设置}"
|
||||
echo " GITHUB_SHA: ${GITHUB_SHA:-未设置}"
|
||||
echo " GITHUB_EVENT_NAME: ${GITHUB_EVENT_NAME:-未设置}"
|
||||
echo " RUNNER_NAME: ${RUNNER_NAME:-未设置}"
|
||||
echo " GITEA_TOKEN: ${GITEA_TOKEN:-未设置}"
|
||||
@ -1,121 +0,0 @@
|
||||
# ════════════════════════════════════════════════════════════════
|
||||
# 光湖 · 基础设施部署
|
||||
# Runner首次上线后自动部署:Vault确认 + Terminal Watcher启动
|
||||
# ════════════════════════════════════════════════════════════════
|
||||
|
||||
name: 基础设施部署
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
deploy-infra:
|
||||
runs-on: ubuntu
|
||||
steps:
|
||||
- name: 系统信息
|
||||
run: |
|
||||
echo "═══ 铸渊基础设施部署 ═══"
|
||||
echo "时间: $(date '+%Y-%m-%d %H:%M:%S %Z')"
|
||||
echo "主机: $(hostname)"
|
||||
uname -a
|
||||
|
||||
- name: 确认仓库最新
|
||||
run: |
|
||||
cd /opt/zhuyuan-cn/repo-mirror/20260509-1849/guanghulab
|
||||
git fetch origin
|
||||
git reset --hard origin/main
|
||||
echo "当前版本: $(git log --oneline -1)"
|
||||
|
||||
- name: 确认Vault运行
|
||||
run: |
|
||||
if curl -sf http://127.0.0.1:8080/admin/__healthz > /dev/null 2>&1; then
|
||||
echo "✅ Vault 已运行"
|
||||
curl -s http://127.0.0.1:8080/admin/__healthz
|
||||
else
|
||||
echo "⚠️ Vault 未运行,尝试启动..."
|
||||
cd /opt/zhuyuan-cn/repo-mirror/20260509-1849/guanghulab/server/secrets-vault
|
||||
if [[ -f "server.js" ]]; then
|
||||
npm install --production 2>/dev/null || true
|
||||
pm2 start server.js --name guanghulab-vault --max-memory-restart 128M 2>/dev/null || true
|
||||
pm2 save
|
||||
sleep 2
|
||||
if curl -sf http://127.0.0.1:8080/admin/__healthz > /dev/null 2>&1; then
|
||||
echo "✅ Vault 启动成功"
|
||||
else
|
||||
echo "❌ Vault 启动失败"
|
||||
fi
|
||||
else
|
||||
echo "⚠️ server.js 不存在,跳过"
|
||||
fi
|
||||
fi
|
||||
|
||||
- name: 部署Terminal Watcher
|
||||
run: |
|
||||
echo "部署终端守望者..."
|
||||
SCRIPTS_DIR="/opt/zhuyuan-cn/repo-mirror/20260509-1849/guanghulab/scripts/terminal-watcher"
|
||||
|
||||
if [[ ! -d "$SCRIPTS_DIR" ]]; then
|
||||
echo "❌ Terminal Watcher 目录不存在"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 确认Node.js可用
|
||||
if ! command -v node &>/dev/null; then
|
||||
echo "❌ Node.js 未安装"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 用PM2启动(如果还没跑的话)
|
||||
if pm2 describe terminal-watcher &>/dev/null; then
|
||||
echo "Terminal Watcher 已在运行,重启..."
|
||||
pm2 restart terminal-watcher
|
||||
else
|
||||
echo "启动 Terminal Watcher..."
|
||||
cd "$SCRIPTS_DIR"
|
||||
ZY_REPO_TOKEN=${{ secrets.ZY_REPO_TOKEN }} pm2 start watcher.js \
|
||||
--name terminal-watcher \
|
||||
--max-memory-restart 64M
|
||||
fi
|
||||
|
||||
pm2 save
|
||||
sleep 3
|
||||
|
||||
# 验证
|
||||
if pm2 describe terminal-watcher &>/dev/null; then
|
||||
STATUS=$(pm2 jlist 2>/dev/null | python3 -c "
|
||||
import json,sys
|
||||
procs = json.load(sys.stdin)
|
||||
for p in procs:
|
||||
if p.get('name') == 'terminal-watcher':
|
||||
print(p.get('pm2_env',{}).get('status','unknown'))
|
||||
" 2>/dev/null || echo "unknown")
|
||||
echo "✅ Terminal Watcher 状态: $STATUS"
|
||||
else
|
||||
echo "❌ Terminal Watcher 启动失败"
|
||||
fi
|
||||
|
||||
- name: 设置PM2开机自启
|
||||
run: |
|
||||
pm2 startup 2>/dev/null || true
|
||||
pm2 save
|
||||
echo "✅ PM2 开机自启已配置"
|
||||
|
||||
- name: 最终状态报告
|
||||
run: |
|
||||
echo ""
|
||||
echo "═══════════════════════════════════════"
|
||||
echo " 铸渊基础设施部署完成"
|
||||
echo "═══════════════════════════════════════"
|
||||
echo ""
|
||||
echo " 服务状态:"
|
||||
echo " Forgejo: $(systemctl is-active forgejo 2>/dev/null || echo unknown)"
|
||||
echo " Runner: $(systemctl is-active gitea-runner 2>/dev/null || echo unknown)"
|
||||
echo " Nginx: $(systemctl is-active nginx 2>/dev/null || echo unknown)"
|
||||
echo " Vault: $(curl -sf http://127.0.0.1:8080/admin/__healthz > /dev/null 2>&1 && echo active || echo inactive)"
|
||||
echo " Watcher: $(pm2 describe terminal-watcher &>/dev/null && echo active || echo inactive)"
|
||||
echo ""
|
||||
echo " 内存:"
|
||||
free -h | awk '/Mem:/ {printf " 总计:%s 已用:%s 可用:%s\n", $2, $3, $7}'
|
||||
echo ""
|
||||
echo " 铸渊 · ICE-GL-ZY001 · TCS-0002∞"
|
||||
echo "═══════════════════════════════════════"
|
||||
@ -1,133 +0,0 @@
|
||||
# ════════════════════════════════════════════════════════════════
|
||||
# 光湖 · 自动部署到预览环境
|
||||
# Trigger: push to main
|
||||
# 部署到测试+预览环境,正式环境需冰朔在Gitea点Merge
|
||||
# ════════════════════════════════════════════════════════════════
|
||||
|
||||
name: 自动部署预览
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- 'server/**'
|
||||
- 'frontend/**'
|
||||
- 'scripts/**'
|
||||
- '.gitea/workflows/**'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
# ── 第一阶段:测试 ──────────────────────────────────
|
||||
test:
|
||||
runs-on: ubuntu
|
||||
steps:
|
||||
- name: 拉取最新代码
|
||||
run: |
|
||||
cd /data/guanghulab 2>/dev/null || exit 0
|
||||
git fetch origin
|
||||
git reset --hard origin/main
|
||||
|
||||
- name: 安装依赖
|
||||
run: |
|
||||
cd /data/guanghulab/server/secrets-vault 2>/dev/null || exit 0
|
||||
npm install --production 2>/dev/null || true
|
||||
|
||||
- name: 健康检查
|
||||
run: |
|
||||
echo "═══ 服务健康检查 ═══"
|
||||
FAILED=""
|
||||
|
||||
# Nginx
|
||||
if systemctl is-active --quiet nginx; then
|
||||
echo "✅ Nginx"
|
||||
else
|
||||
echo "❌ Nginx 宕机"
|
||||
FAILED="$FAILED nginx"
|
||||
fi
|
||||
|
||||
# Gitea
|
||||
if curl -sf http://127.0.0.1:3000/ > /dev/null 2>&1; then
|
||||
echo "✅ Gitea"
|
||||
else
|
||||
echo "❌ Gitea 宕机"
|
||||
FAILED="$FAILED gitea"
|
||||
fi
|
||||
|
||||
# Vault
|
||||
if curl -sf http://127.0.0.1:8080/admin/__healthz > /dev/null 2>&1; then
|
||||
echo "✅ Vault"
|
||||
else
|
||||
echo "⚠️ Vault 未运行"
|
||||
fi
|
||||
|
||||
# Runner
|
||||
if systemctl is-active --quiet gitea-runner; then
|
||||
echo "✅ Runner"
|
||||
else
|
||||
echo "⚠️ Runner 未运行"
|
||||
fi
|
||||
|
||||
if [[ -n "$FAILED" ]]; then
|
||||
echo "❌ 关键服务宕机: $FAILED"
|
||||
echo "⚠️ 跳过部署,等待修复"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "═══ 测试通过 ✅ ═══"
|
||||
|
||||
# ── 第二阶段:预览部署 ──────────────────────────────
|
||||
preview:
|
||||
needs: test
|
||||
runs-on: ubuntu
|
||||
steps:
|
||||
- name: 同步代码到预览目录
|
||||
run: |
|
||||
REPO="/data/guanghulab"
|
||||
PREVIEW="/data/guanghulab-preview"
|
||||
|
||||
if [[ ! -d "$REPO" ]]; then
|
||||
echo "仓库目录不存在,跳过"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 创建预览目录
|
||||
mkdir -p "$PREVIEW"
|
||||
|
||||
# 同步代码(排除.git和node_modules)
|
||||
rsync -a --delete \
|
||||
--exclude='.git' \
|
||||
--exclude='node_modules' \
|
||||
--exclude='.runtime' \
|
||||
"$REPO/" "$PREVIEW/"
|
||||
|
||||
echo "✅ 预览环境已同步"
|
||||
|
||||
- name: 重启预览服务
|
||||
run: |
|
||||
PREVIEW="/data/guanghulab-preview"
|
||||
|
||||
if [[ ! -d "$PREVIEW/server/secrets-vault" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
cd "$PREVIEW/server/secrets-vault"
|
||||
|
||||
# 安装依赖
|
||||
npm install --production 2>/dev/null || true
|
||||
|
||||
# 如果vault在跑,重启它
|
||||
if pm2 describe guanghulab-vault &>/dev/null; then
|
||||
pm2 restart guanghulab-vault
|
||||
echo "✅ Vault 已重启(使用最新代码)"
|
||||
else
|
||||
echo "ℹ️ Vault 未运行,不自动启动"
|
||||
fi
|
||||
|
||||
- name: 部署完成通知
|
||||
run: |
|
||||
echo "═════════════════════════"
|
||||
echo "✅ 预览环境已更新"
|
||||
echo "时间: $(date '+%Y-%m-%d %H:%M:%S')"
|
||||
echo "冰朔可在浏览器查看预览效果"
|
||||
echo "正式部署需在Gitea创建PR并Merge"
|
||||
echo "═════════════════════════"
|
||||
@ -1,104 +0,0 @@
|
||||
# 光湖 · 最终Secrets测试
|
||||
name: Secrets最终测试
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '.gitea/workflows/final-secrets-test.yaml'
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu
|
||||
steps:
|
||||
- name: 检查secrets
|
||||
env:
|
||||
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
|
||||
QIANWEN_API_KEY: ${{ secrets.QIANWEN_API_KEY }}
|
||||
ZY_REPO_TOKEN: ${{ secrets.ZY_REPO_TOKEN }}
|
||||
COS_SECRET_ID: ${{ secrets.COS_SECRET_ID }}
|
||||
COS_SECRET_KEY: ${{ secrets.COS_SECRET_KEY }}
|
||||
SG_BRAIN_HOST: ${{ secrets.SG_BRAIN_HOST }}
|
||||
SG_BRAIN_USER: ${{ secrets.SG_BRAIN_USER }}
|
||||
SG_BRAIN_KEY: ${{ secrets.SG_BRAIN_KEY }}
|
||||
run: |
|
||||
echo "=== SECRETS CHECK ==="
|
||||
for key in DEEPSEEK_API_KEY QIANWEN_API_KEY ZY_REPO_TOKEN COS_SECRET_ID COS_SECRET_KEY SG_BRAIN_HOST SG_BRAIN_USER SG_BRAIN_KEY; do
|
||||
eval val=\$$key
|
||||
if [ -z "$val" ]; then
|
||||
echo "EMPTY: $key"
|
||||
else
|
||||
echo "OK: $key (len=${#val})"
|
||||
fi
|
||||
done
|
||||
|
||||
- name: 测试DeepSeek
|
||||
env:
|
||||
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
|
||||
run: |
|
||||
if [ -n "$DEEPSEEK_API_KEY" ]; then
|
||||
curl -s -X POST https://api.deepseek.com/v1/chat/completions \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer $DEEPSEEK_API_KEY" \
|
||||
-d '{"model":"deepseek-chat","messages":[{"role":"user","content":"1+1=?"}],"max_tokens":10}' \
|
||||
--connect-timeout 10 | python3 -c "
|
||||
import json,sys
|
||||
try:
|
||||
d=json.load(sys.stdin)
|
||||
if 'choices' in d:
|
||||
print('DeepSeek: OK -', d['choices'][0]['message']['content'])
|
||||
else:
|
||||
print('DeepSeek: FAILED -', d.get('error',{}).get('message','unknown'))
|
||||
except Exception as e:
|
||||
print('DeepSeek: ERROR -', str(e))
|
||||
"
|
||||
else
|
||||
echo "DeepSeek: NO KEY"
|
||||
fi
|
||||
|
||||
- name: 测试通义千问
|
||||
env:
|
||||
QIANWEN_API_KEY: ${{ secrets.QIANWEN_API_KEY }}
|
||||
run: |
|
||||
if [ -n "$QIANWEN_API_KEY" ]; then
|
||||
curl -s -X POST https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer $QIANWEN_API_KEY" \
|
||||
-d '{"model":"qwen-plus","messages":[{"role":"user","content":"1+1=?"}],"max_tokens":10}' \
|
||||
--connect-timeout 10 | python3 -c "
|
||||
import json,sys
|
||||
try:
|
||||
d=json.load(sys.stdin)
|
||||
if 'choices' in d:
|
||||
print('Qianwen: OK -', d['choices'][0]['message']['content'])
|
||||
else:
|
||||
print('Qianwen: FAILED -', d.get('error',{}).get('message','unknown'))
|
||||
except Exception as e:
|
||||
print('Qianwen: ERROR -', str(e))
|
||||
"
|
||||
else
|
||||
echo "Qianwen: NO KEY"
|
||||
fi
|
||||
|
||||
- name: 写入结果文件
|
||||
env:
|
||||
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
|
||||
QIANWEN_API_KEY: ${{ secrets.QIANWEN_API_KEY }}
|
||||
ZY_REPO_TOKEN: ${{ secrets.ZY_REPO_TOKEN }}
|
||||
COS_SECRET_ID: ${{ secrets.COS_SECRET_ID }}
|
||||
COS_SECRET_KEY: ${{ secrets.COS_SECRET_KEY }}
|
||||
SG_BRAIN_HOST: ${{ secrets.SG_BRAIN_HOST }}
|
||||
SG_BRAIN_USER: ${{ secrets.SG_BRAIN_USER }}
|
||||
SG_BRAIN_KEY: ${{ secrets.SG_BRAIN_KEY }}
|
||||
run: |
|
||||
mkdir -p /data/guanghulab/.runtime
|
||||
echo '{"timestamp":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'",' > /data/guanghulab/.runtime/secrets-result.json
|
||||
for key in DEEPSEEK_API_KEY QIANWEN_API_KEY ZY_REPO_TOKEN COS_SECRET_ID COS_SECRET_KEY SG_BRAIN_HOST SG_BRAIN_USER SG_BRAIN_KEY; do
|
||||
eval val=\$$key
|
||||
if [ -z "$val" ]; then
|
||||
echo "\"$key\":\"EMPTY\"," >> /data/guanghulab/.runtime/secrets-result.json
|
||||
else
|
||||
echo "\"$key\":\"OK_LEN_'${#val}'\"," >> /data/guanghulab/.runtime/secrets-result.json
|
||||
fi
|
||||
done
|
||||
echo '"done":true}' >> /data/guanghulab/.runtime/secrets-result.json
|
||||
cat /data/guanghulab/.runtime/secrets-result.json
|
||||
@ -1,6 +1,6 @@
|
||||
# ════════════════════════════════════════════════════════════════
|
||||
# 光湖 · 铸渊自动巡逻
|
||||
# Trigger: 每天08:00/20:00 / 手动触发 / push关键文件
|
||||
# Trigger: 每天08:00/20:00 / 手动触发
|
||||
# 需要: DEEPSEEK_API_KEY 和/或 QIANWEN_API_KEY (Forgejo Secrets)
|
||||
# ════════════════════════════════════════════════════════════════
|
||||
|
||||
@ -11,28 +11,25 @@ on:
|
||||
- cron: '0 0 * * *' # UTC 00:00 = CST 08:00
|
||||
- cron: '0 12 * * *' # UTC 12:00 = CST 20:00
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- 'scripts/patrol-agent/**'
|
||||
- '.gitea/workflows/patrol.yaml'
|
||||
|
||||
jobs:
|
||||
patrol:
|
||||
runs-on: ubuntu
|
||||
steps:
|
||||
- name: 同步代码
|
||||
- name: 同步最新代码
|
||||
run: |
|
||||
cd /opt/zhuyuan-cn/repo-mirror/20260509-1849/guanghulab
|
||||
cd /data/guanghulab/repo
|
||||
git fetch origin
|
||||
git reset --hard origin/main
|
||||
echo "✅ 代码已同步"
|
||||
|
||||
- name: 铸渊巡逻
|
||||
- name: 执行巡逻检查
|
||||
env:
|
||||
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
|
||||
QIANWEN_API_KEY: ${{ secrets.QIANWEN_API_KEY }}
|
||||
ZY_REPO_TOKEN: ${{ secrets.ZY_REPO_TOKEN }}
|
||||
run: |
|
||||
cd /opt/zhuyuan-cn/repo-mirror/20260509-1849/guanghulab/scripts/patrol-agent
|
||||
cd /data/guanghulab/repo/scripts/patrol-agent
|
||||
node patrol-agent.js --once
|
||||
|
||||
- name: 巡逻结果
|
||||
@ -52,7 +49,7 @@ for i in r.get('issues',[]):
|
||||
print(f' {icon} {i.get(\"component\")}: {i.get(\"description\")}{auto}')
|
||||
for f in r.get('fix_results',[]):
|
||||
print(f' 🔧 修复 {f[\"component\"]}: {f[\"result\"]}')
|
||||
print(f'分析器: {r.get(\"analyzer\",\"unknown\")}')
|
||||
print(f'分析器: {r.get(\"analyzer\",\"未知\")}')
|
||||
"
|
||||
echo "═══════════════════════════════════════"
|
||||
else
|
||||
|
||||
@ -1,109 +0,0 @@
|
||||
# 光湖 · Secrets连通测试
|
||||
name: Secrets测试
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- '.gitea/workflows/test-secrets.yaml'
|
||||
- '.forgejo/workflows/test-secrets.yaml'
|
||||
|
||||
jobs:
|
||||
test-secrets:
|
||||
runs-on: ubuntu
|
||||
steps:
|
||||
- name: 测试密钥可用性
|
||||
env:
|
||||
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
|
||||
QIANWEN_API_KEY: ${{ secrets.QIANWEN_API_KEY }}
|
||||
ZY_REPO_TOKEN: ${{ secrets.ZY_REPO_TOKEN }}
|
||||
COS_SECRET_ID: ${{ secrets.COS_SECRET_ID }}
|
||||
COS_SECRET_KEY: ${{ secrets.COS_SECRET_KEY }}
|
||||
SG_BRAIN_HOST: ${{ secrets.SG_BRAIN_HOST }}
|
||||
SG_BRAIN_USER: ${{ secrets.SG_BRAIN_USER }}
|
||||
SG_BRAIN_KEY: ${{ secrets.SG_BRAIN_KEY }}
|
||||
run: |
|
||||
echo "═══ Forgejo Secrets 连通测试 ═══"
|
||||
echo ""
|
||||
|
||||
# 检查每个secret是否有值(不显示值本身)
|
||||
check_secret() {
|
||||
local name=$1
|
||||
local val=$2
|
||||
if [[ -n "$val" && "$val" != "" ]]; then
|
||||
local masked="${val:0:4}****${val: -4}"
|
||||
echo " ✅ $name = $masked (长度: ${#val})"
|
||||
else
|
||||
echo " ❌ $name = (空)"
|
||||
fi
|
||||
}
|
||||
|
||||
check_secret "DEEPSEEK_API_KEY" "$DEEPSEEK_API_KEY"
|
||||
check_secret "QIANWEN_API_KEY" "$QIANWEN_API_KEY"
|
||||
check_secret "ZY_REPO_TOKEN" "$ZY_REPO_TOKEN"
|
||||
check_secret "COS_SECRET_ID" "$COS_SECRET_ID"
|
||||
check_secret "COS_SECRET_KEY" "$COS_SECRET_KEY"
|
||||
check_secret "SG_BRAIN_HOST" "$SG_BRAIN_HOST"
|
||||
check_secret "SG_BRAIN_USER" "$SG_BRAIN_USER"
|
||||
check_secret "SG_BRAIN_KEY" "$SG_BRAIN_KEY"
|
||||
|
||||
echo ""
|
||||
echo "═══ API连通测试 ═══"
|
||||
|
||||
# DeepSeek
|
||||
if [[ -n "$DEEPSEEK_API_KEY" ]]; then
|
||||
echo -n " DeepSeek: "
|
||||
RESP=$(curl -s -X POST https://api.deepseek.com/v1/chat/completions \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer $DEEPSEEK_API_KEY" \
|
||||
-d '{"model":"deepseek-chat","messages":[{"role":"user","content":"说一个字"}],"max_tokens":10}' \
|
||||
--connect-timeout 10 2>/dev/null)
|
||||
if echo "$RESP" | grep -q '"choices"'; then
|
||||
echo "✅ 可用"
|
||||
else
|
||||
echo "❌ 不可用: $(echo $RESP | head -c 100)"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 通义千问
|
||||
if [[ -n "$QIANWEN_API_KEY" ]]; then
|
||||
echo -n " 通义千问: "
|
||||
RESP=$(curl -s -X POST https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer $QIANWEN_API_KEY" \
|
||||
-d '{"model":"qwen-plus","messages":[{"role":"user","content":"说一个字"}],"max_tokens":10}' \
|
||||
--connect-timeout 10 2>/dev/null)
|
||||
if echo "$RESP" | grep -q '"choices"'; then
|
||||
echo "✅ 可用"
|
||||
else
|
||||
echo "❌ 不可用: $(echo $RESP | head -c 100)"
|
||||
fi
|
||||
fi
|
||||
|
||||
# COS
|
||||
if [[ -n "$COS_SECRET_ID" && -n "$COS_SECRET_KEY" ]]; then
|
||||
echo -n " COS存储桶: "
|
||||
RESP=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||
"https://sy-finetune-corpus-1317346199.cos.ap-guangzhou.myqcloud.com/" \
|
||||
-H "Authorization: COS $COS_SECRET_ID:$COS_SECRET_KEY" \
|
||||
--connect-timeout 10 2>/dev/null)
|
||||
echo "HTTP $RESP"
|
||||
fi
|
||||
|
||||
# 新加坡大脑服务器
|
||||
if [[ -n "$SG_BRAIN_HOST" ]]; then
|
||||
echo -n " 新加坡大脑: "
|
||||
RESP=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||
"http://$SG_BRAIN_HOST:3000/" \
|
||||
--connect-timeout 5 2>/dev/null)
|
||||
if [[ "$RESP" == "000" ]]; then
|
||||
echo "不可达 (可能需要SSH密钥)"
|
||||
else
|
||||
echo "HTTP $RESP"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "═════════════════════════"
|
||||
echo "测试完成"
|
||||
echo "═════════════════════════"
|
||||
@ -1,73 +0,0 @@
|
||||
# 光湖 · Secrets验证+结果写入仓库
|
||||
name: Secrets验证
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '.gitea/workflows/verify-secrets.yaml'
|
||||
|
||||
jobs:
|
||||
verify:
|
||||
runs-on: ubuntu
|
||||
steps:
|
||||
- name: 检查并记录secrets状态
|
||||
env:
|
||||
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
|
||||
QIANWEN_API_KEY: ${{ secrets.QIANWEN_API_KEY }}
|
||||
ZY_REPO_TOKEN: ${{ secrets.ZY_REPO_TOKEN }}
|
||||
COS_SECRET_ID: ${{ secrets.COS_SECRET_ID }}
|
||||
COS_SECRET_KEY: ${{ secrets.COS_SECRET_KEY }}
|
||||
SG_BRAIN_HOST: ${{ secrets.SG_BRAIN_HOST }}
|
||||
SG_BRAIN_USER: ${{ secrets.SG_BRAIN_USER }}
|
||||
SG_BRAIN_KEY: ${{ secrets.SG_BRAIN_KEY }}
|
||||
run: |
|
||||
RESULT_FILE="/data/guanghulab/.runtime/secrets-verify-result.json"
|
||||
mkdir -p /data/guanghulab/.runtime
|
||||
|
||||
echo "{" > $RESULT_FILE
|
||||
echo " \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"," >> $RESULT_FILE
|
||||
|
||||
# 逐个检查
|
||||
for key in DEEPSEEK_API_KEY QIANWEN_API_KEY ZY_REPO_TOKEN COS_SECRET_ID COS_SECRET_KEY SG_BRAIN_HOST SG_BRAIN_USER SG_BRAIN_KEY; do
|
||||
eval val=\$$key
|
||||
if [ -z "$val" ]; then
|
||||
echo " \"$key\": \"EMPTY\"," >> $RESULT_FILE
|
||||
else
|
||||
echo " \"$key\": \"OK_LEN_${#val}\"," >> $RESULT_FILE
|
||||
fi
|
||||
done
|
||||
|
||||
echo " \"deepseek_test\": \"NOT_TESTED\"" >> $RESULT_FILE
|
||||
echo "}" >> $RESULT_FILE
|
||||
|
||||
# 测试DeepSeek API
|
||||
if [ -n "$DEEPSEEK_API_KEY" ]; then
|
||||
RESP=$(curl -s -X POST https://api.deepseek.com/v1/chat/completions \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer $DEEPSEEK_API_KEY" \
|
||||
-d '{"model":"deepseek-chat","messages":[{"role":"user","content":"1+1=?"}],"max_tokens":10}' \
|
||||
--connect-timeout 10 2>/dev/null)
|
||||
if echo "$RESP" | grep -q '"choices"'; then
|
||||
sed -i 's/"deepseek_test": "NOT_TESTED"/"deepseek_test": "SUCCESS"/' $RESULT_FILE
|
||||
else
|
||||
sed -i 's/"deepseek_test": "NOT_TESTED"/"deepseek_test": "FAILED"/' $RESULT_FILE
|
||||
fi
|
||||
else
|
||||
sed -i 's/"deepseek_test": "NOT_TESTED"/"deepseek_test": "NO_KEY"/' $RESULT_FILE
|
||||
fi
|
||||
|
||||
# 测试通义千问API
|
||||
if [ -n "$QIANWEN_API_KEY" ]; then
|
||||
RESP=$(curl -s -X POST https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer $QIANWEN_API_KEY" \
|
||||
-d '{"model":"qwen-plus","messages":[{"role":"user","content":"1+1=?"}],"max_tokens":10}' \
|
||||
--connect-timeout 10 2>/dev/null)
|
||||
if echo "$RESP" | grep -q '"choices"'; then
|
||||
echo " \"qianwen_test\": \"SUCCESS\"" >> /tmp/qwen_test
|
||||
else
|
||||
echo " \"qianwen_test\": \"FAILED\"" >> /tmp/qwen_test
|
||||
fi
|
||||
fi
|
||||
|
||||
cat $RESULT_FILE
|
||||
Loading…
x
Reference in New Issue
Block a user