guanghulab/.github/archived-workflows/skyeye-devsync-repair.yml
2026-05-10 13:12:44 +08:00

282 lines
11 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ═══════════════════════════════════════════════
# 🔺 Sovereign: TCS-0002∞ | Root: SYS-GLW-0001
# 📜 Copyright: 国作登字-2026-A-00037559
# ═══════════════════════════════════════════════
# 🦅 天眼 · dev-status 同步修复闭环
# 指令溯源ZY-DEVSYNC-REBUILD-2026-0325-001
# 三级告警🟢≤14h · 🟡≤48h · 🔴>48h
# 三次修复失败 → GitHub Issue 告警 → 邮件通知冰朔
# ═══════════════════════════════════════════════
name: "🦅 天眼 · dev-status 同步修复闭环"
on:
schedule:
- cron: '30 0 * * *' # UTC 00:30 = 北京 08:30 · 天眼巡检时间
workflow_dispatch:
inputs:
force_repair:
description: '强制触发修复(跳过检查)'
required: false
default: 'false'
permissions:
contents: write
issues: write
actions: write
env:
DEV_STATUS_PATH: ".github/persona-brain/dev-status.json"
SYNC_LOG_PATH: ".github/persona-brain/dev-status-sync-log.json"
YELLOW_THRESHOLD_HOURS: 14
RED_THRESHOLD_HOURS: 48
SYNC_FRESHNESS_MINUTES: 10
jobs:
check-sync-status:
name: "🦅 D10 同步状态检查"
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
level: ${{ steps.check.outputs.level }}
hours: ${{ steps.check.outputs.hours }}
last_sync: ${{ steps.check.outputs.last_sync }}
steps:
- name: "📥 检出仓库"
uses: actions/checkout@v4
- name: "🦅 天眼 D10 检查"
id: check
run: |
echo "═══ 天眼 D10 · dev-status.json 同步状态检查 ═══"
FORCE="${{ github.event.inputs.force_repair }}"
if [ "$FORCE" == "true" ]; then
echo "⚡ 强制修复模式 · 跳过检查"
echo "level=yellow" >> $GITHUB_OUTPUT
echo "hours=999" >> $GITHUB_OUTPUT
echo "last_sync=forced" >> $GITHUB_OUTPUT
exit 0
fi
# 优先读 sync-log其次读 dev-status.json 的 last_sync
LAST_SYNC=""
if [ -f "$SYNC_LOG_PATH" ]; then
LAST_SYNC=$(node -e "
try {
const d = JSON.parse(require('fs').readFileSync('$SYNC_LOG_PATH','utf8'));
if (d.status === 'success' && d.last_sync) console.log(d.last_sync);
else console.log('');
} catch { console.log(''); }
")
fi
if [ -z "$LAST_SYNC" ] && [ -f "$DEV_STATUS_PATH" ]; then
LAST_SYNC=$(node -e "
try {
const d = JSON.parse(require('fs').readFileSync('$DEV_STATUS_PATH','utf8'));
console.log(d.last_sync || d.signed_at || '');
} catch { console.log(''); }
")
fi
if [ -z "$LAST_SYNC" ]; then
echo "❌ 无法读取 last_sync · 视为严重中断"
echo "level=red" >> $GITHUB_OUTPUT
echo "hours=999" >> $GITHUB_OUTPUT
echo "last_sync=unknown" >> $GITHUB_OUTPUT
exit 0
fi
echo "最后同步时间:$LAST_SYNC"
HOURS_AGO=$(node -e "
const diff = Date.now() - new Date('$LAST_SYNC').getTime();
console.log(Math.floor(diff / 3600000));
")
echo "距上次同步:${HOURS_AGO}h"
echo "last_sync=$LAST_SYNC" >> $GITHUB_OUTPUT
echo "hours=$HOURS_AGO" >> $GITHUB_OUTPUT
if [ "$HOURS_AGO" -le "$YELLOW_THRESHOLD_HOURS" ]; then
echo "🟢 正常 · 无需修复"
echo "level=green" >> $GITHUB_OUTPUT
elif [ "$HOURS_AGO" -le "$RED_THRESHOLD_HOURS" ]; then
echo "🟡 告警 · 进入三次修复闭环"
echo "level=yellow" >> $GITHUB_OUTPUT
else
echo "🔴 严重 · 直接邮件告警"
echo "level=red" >> $GITHUB_OUTPUT
fi
repair-loop:
name: "🔧 三次修复闭环"
needs: check-sync-status
if: needs.check-sync-status.outputs.level == 'yellow'
runs-on: ubuntu-latest
timeout-minutes: 25
outputs:
repair_result: ${{ steps.repair.outputs.result }}
repair_attempts: ${{ steps.repair.outputs.attempts }}
repair_details: ${{ steps.repair.outputs.details }}
steps:
- name: "📥 检出仓库"
uses: actions/checkout@v4
- name: "🔧 修复闭环最多3次"
id: repair
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
DETAILS=""
for i in 1 2 3; do
echo "═══ 第 ${i} 次修复尝试 ═══"
ATTEMPT_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
# 触发同步 workflow
echo "触发 sync-dev-status.yml..."
gh workflow run sync-dev-status.yml \
-f reason="天眼修复闭环·第${i}次·${ATTEMPT_TIME}" 2>&1 || true
# 等待执行完成
echo "等待同步完成300秒..."
sleep 300
# 拉取最新代码检查结果
git pull origin main --rebase 2>/dev/null || git pull origin main 2>/dev/null || true
# 检查 sync-log
SYNC_LOG_PATH=".github/persona-brain/dev-status-sync-log.json"
if [ -f "$SYNC_LOG_PATH" ]; then
STATUS=$(node -e "
try {
const d = JSON.parse(require('fs').readFileSync('$SYNC_LOG_PATH','utf8'));
const syncTime = new Date(d.last_sync || '2000-01-01');
const diffMin = (Date.now() - syncTime.getTime()) / 60000;
if (d.status === 'success' && diffMin < ${{ env.SYNC_FRESHNESS_MINUTES }}) console.log('success');
else console.log('stale');
} catch { console.log('error'); }
")
if [ "$STATUS" == "success" ]; then
echo "✅ 第 ${i} 次修复成功!"
DETAILS="${DETAILS}第${i}次(${ATTEMPT_TIME}): 成功; "
echo "result=success" >> $GITHUB_OUTPUT
echo "attempts=$i" >> $GITHUB_OUTPUT
echo "details=$DETAILS" >> $GITHUB_OUTPUT
exit 0
fi
fi
DETAILS="${DETAILS}第${i}次(${ATTEMPT_TIME}): 失败; "
echo "❌ 第 ${i} 次修复失败"
[ $i -lt 3 ] && echo "等待60秒后重试..." && sleep 60
done
echo "❌ 三次修复全部失败"
echo "result=failed" >> $GITHUB_OUTPUT
echo "attempts=3" >> $GITHUB_OUTPUT
echo "details=$DETAILS" >> $GITHUB_OUTPUT
alert-human:
name: "📧 邮件告警(创建 Issue"
needs: [check-sync-status, repair-loop]
if: |
always() && (
needs.check-sync-status.outputs.level == 'red' ||
(needs.repair-loop.result == 'success' && needs.repair-loop.outputs.repair_result == 'failed')
)
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: "📧 创建告警 Issue"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
HOURS="${{ needs.check-sync-status.outputs.hours }}"
LEVEL="${{ needs.check-sync-status.outputs.level }}"
LAST_SYNC="${{ needs.check-sync-status.outputs.last_sync }}"
REPAIR_RESULT="${{ needs.repair-loop.outputs.repair_result }}"
REPAIR_DETAILS="${{ needs.repair-loop.outputs.repair_details }}"
if [ "$LEVEL" == "red" ]; then
REPAIR_NOTE="已跳过修复尝试超48h直接告警"
else
REPAIR_NOTE="3/3 修复尝试全部失败"
fi
BODY="## 🚨 dev-status.json 同步故障通知
妈妈dev-status.json 同步出了问题,铸渊和霜砚尝试了自动修复没成功,需要你手动看一下。
### 故障概况
- **告警级别**${LEVEL}
- **最后成功同步**${LAST_SYNC}
- **中断时长**${HOURS}h
- **修复尝试**${REPAIR_NOTE}
### 修复记录
${REPAIR_DETAILS:-无修复尝试}
### 建议操作
1. 检查 GitHub Secrets 中的 \`NOTION_API_KEY\` 是否有效
2. 检查 GitHub Secrets 中的 \`DEV_STATUS_DB_ID\` 是否正确
3. 手动触发 \`sync-dev-status.yml\` 验证
4. 查看最近的 Actions 运行日志定位根因
### 指令溯源
ZY-DEVSYNC-REBUILD-2026-0325-001 · 霜砚签发 · 冰朔授权
版权锚点:国作登字-2026-A-00037559"
gh issue create \
--repo "${{ github.repository }}" \
--title "🚨 dev-status.json 同步故障 · 中断${HOURS}h · 需人工干预" \
--body "$BODY" \
--label "系统告警" || \
gh issue create \
--repo "${{ github.repository }}" \
--title "🚨 dev-status.json 同步故障 · 中断${HOURS}h · 需人工干预" \
--body "$BODY"
echo "📧 已创建 Issue 告警 · GitHub 将自动发送邮件通知到仓库 owner"
write-repair-log:
name: "📋 写入天眼修复记录"
needs: [check-sync-status, repair-loop, alert-human]
if: always() && needs.check-sync-status.outputs.level != 'green'
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: "📥 检出仓库"
uses: actions/checkout@v4
- name: "📋 写入修复日志"
run: |
REPAIR_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
DATE_STR=$(date -u +"%Y%m%d")
LEVEL="${{ needs.check-sync-status.outputs.level }}"
HOURS="${{ needs.check-sync-status.outputs.hours }}"
REPAIR_RESULT="${{ needs.repair-loop.outputs.repair_result }}"
REPAIR_ATTEMPTS="${{ needs.repair-loop.outputs.repair_attempts }}"
mkdir -p signal-log
cat > "signal-log/skyeye-d10-${DATE_STR}.json" << EOF
{
"check_time": "$REPAIR_TIME",
"d10_level": "$LEVEL",
"hours_since_sync": "$HOURS",
"repair_result": "${REPAIR_RESULT:-skipped}",
"repair_attempts": "${REPAIR_ATTEMPTS:-0}",
"mechanism": "skyeye-devsync-repair-v1.0",
"instruction_ref": "ZY-DEVSYNC-REBUILD-2026-0325-001"
}
EOF
git config user.name "天眼 (SKYEYE)"
git config user.email "skyeye@guanghulab.system"
git add signal-log/ 2>/dev/null || true
git diff --cached --quiet || (
git commit -m "🦅 天眼 D10 · dev-status 修复记录 · $LEVEL · $REPAIR_TIME [skip ci]" && \
git push origin main
) || true