以下问题经过 3轮自动修复 仍未解决,需要你手动处理:
| 问题 Workflow | {workflow_name} |
| 错误类型 | {error_type} |
| 首次发现 | {first_seen_date} |
| 修复尝试 | 3次(全部失败) |
— 光湖系统 · Merge Watchdog · {timestamp}
``` --- ## 六、成功静默机制 ### 6.1 触发条件 目标 Workflow 运行结果为 `conclusion: "success"`。 ### 6.2 静默更新仪表盘 ```jsx // 修复成功 → 只更新仪表盘,不发任何通知 const onSuccess = async (watchRecord) => { // 1. 更新仪表盘 JSON await updateDashboard({ workflow: watchRecord.target_workflows[0], status: "fixed", fixed_at: new Date().toISOString(), fixed_by: "auto-repair", retry_count: watchRecord.retry_count, resolution: "auto_fixed" }); // 2. 在修复 PR 上添加评论 await addPRComment(watchRecord.pr_number, `✅ **Merge Watchdog 确认:修复已生效**\n` + `目标 Workflow \`${watchRecord.target_workflows[0]}\` ` + `运行成功。仪表盘已更新。`); // 3. 关闭看守记录 watchRecord.status = "fixed"; watchRecord.resolution = "auto_fixed"; // ❌ 不发邮件 // ❌ 不发 Notion 通知 // ❌ 不在公告板留言 // ✅ 只有仪表盘静默更新 } ``` --- ## 七、仪表盘看守者面板 在天眼仪表盘(`docs/dashboard/status.json`)中新增 `merge_watchdog` 区块: ```json { "merge_watchdog": { "last_updated": "2026-03-25T09:00:00+08:00", "active_watches": 1, "resolved_watches": 5, "escalated_watches": 0, "records": [ { "pr_number": 42, "workflow": "sync-to-drive.yml", "status": "fixed", "retry_count": 0, "merged_at": "2026-03-25T08:30:00+08:00", "resolved_at": "2026-03-25T09:00:00+08:00", "resolution": "auto_fixed" }, { "pr_number": 38, "workflow": "token-renew.yml", "status": "escalated", "retry_count": 3, "merged_at": "2026-03-24T08:00:00+08:00", "escalated_at": "2026-03-25T02:00:00+08:00", "resolution": "human_intervention", "human_action": "pending" } ] } } ``` --- ## 八、Workflow 完整模板 **文件名:** `.github/workflows/merge-watchdog.yml` ```yaml name: "👁️ Merge Watchdog · 合并指令看守者" on: pull_request: types: [closed] branches: [main] workflow_dispatch: inputs: pr_number: description: '手动指定要观察的 PR 编号' type: number required: false permissions: actions: read contents: write pull-requests: write issues: read env: MAX_RETRIES: 3 OBSERVATION_WINDOW_HOURS: 48 ROUND_2_DELAY_HOURS: 1 ROUND_3_DELAY_HOURS: 2 WATCHDOG_DATA: "docs/dashboard/watchdog-records.json" jobs: # ======================================== # Gate: 只看行动类(已合并的 auto-repair PR) # ======================================== gate: runs-on: ubuntu-latest if: > github.event.pull_request.merged == true && startsWith(github.event.pull_request.head.ref, 'fix/auto-repair-') outputs: should_watch: $ steps.check.outputs.should_watch target_workflows: $ steps.check.outputs.target_workflows steps: - name: "🔍 识别修复目标" id: check env: GH_TOKEN: $ secrets.DEPLOY_GITHUB_TOKEN PR_BODY: $ github.event.pull_request.body PR_TITLE: $ github.event.pull_request.title run: | echo "[Merge Watchdog] 检测到 auto-repair PR 合并" echo "PR #$ github.event.pull_request.number : $PR_TITLE" # 从 PR 标题/body 中提取修复的目标 Workflow # 格式约定:PR title 包含 [AUTO-FIX] {workflow_name}: ... WORKFLOW=$(echo "$PR_TITLE" | grep -oP '\[AUTO-FIX\] \K[^:]+' || echo "unknown") echo "target_workflows=$WORKFLOW" >> $GITHUB_OUTPUT echo "should_watch=true" >> $GITHUB_OUTPUT echo "👁️ 开始看守: $WORKFLOW" # ======================================== # 观察: 等待目标 Workflow 下一次运行 # ======================================== observe: needs: gate if: needs.gate.outputs.should_watch == 'true' runs-on: ubuntu-latest outputs: workflow_result: $ steps.wait.outputs.result run_url: $ steps.wait.outputs.run_url steps: - name: "⏳ 等待目标 Workflow 运行" id: wait env: GH_TOKEN: $ secrets.DEPLOY_GITHUB_TOKEN TARGET: $ needs.gate.outputs.target_workflows run: | echo "[Merge Watchdog] 等待 $TARGET 的下一次运行..." MERGE_TIME=$(date -u +%Y-%m-%dT%H:%M:%SZ) MAX_WAIT=172800 # 48 hours in seconds POLL_INTERVAL=300 # 每5分钟检查一次 ELAPSED=0 while [ $ELAPSED -lt $MAX_WAIT ]; do sleep $POLL_INTERVAL ELAPSED=$((ELAPSED + POLL_INTERVAL)) # 查找合并后的新运行 LATEST_RUN=$(gh api \ "repos/$ github.repository /actions/runs?created=>$MERGE_TIME" \ --jq ".workflow_runs[] | select(.name | contains(\"$TARGET\"))" \ | head -1) if [ -n "$LATEST_RUN" ]; then CONCLUSION=$(echo "$LATEST_RUN" | jq -r '.conclusion // "pending"') RUN_URL=$(echo "$LATEST_RUN" | jq -r '.html_url') if [ "$CONCLUSION" = "success" ]; then echo "result=success" >> $GITHUB_OUTPUT echo "run_url=$RUN_URL" >> $GITHUB_OUTPUT echo "✅ 修复已生效!" exit 0 elif [ "$CONCLUSION" = "failure" ]; then echo "result=failure" >> $GITHUB_OUTPUT echo "run_url=$RUN_URL" >> $GITHUB_OUTPUT echo "❌ 修复未生效" exit 0 fi # conclusion=pending → 继续等 fi done # 超时 → 手动触发一次 echo "result=timeout" >> $GITHUB_OUTPUT echo "⏰ 观察窗口超时" # ======================================== # 判定: 成功 → 静默 / 失败 → 计数+重试/告警 # ======================================== verdict: needs: [gate, observe] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: "📊 读取看守记录" id: load run: | if [ -f "$WATCHDOG_DATA" ]; then RECORD=$(jq ".records[] | select(.pr_number == $ github.event.pull_request.number )" "$WATCHDOG_DATA") RETRY_COUNT=$(echo "$RECORD" | jq -r '.retry_count // 0') else RETRY_COUNT=0 mkdir -p docs/dashboard echo '{"records":[]}' > "$WATCHDOG_DATA" fi echo "retry_count=$RETRY_COUNT" >> $GITHUB_OUTPUT # -------- 成功路径:静默更新 -------- - name: "✅ 修复确认 — 静默更新仪表盘" if: needs.observe.outputs.workflow_result == 'success' run: | echo "[Merge Watchdog] ✅ 修复已生效 — 静默更新仪表盘" # 更新看守记录 jq --arg pr "$ github.event.pull_request.number " \ --arg now "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \ '.records += [{ "pr_number": ($pr | tonumber), "status": "fixed", "resolved_at": $now, "resolution": "auto_fixed" }]' "$WATCHDOG_DATA" > tmp.json && mv tmp.json "$WATCHDOG_DATA" git config user.name "Merge Watchdog" git config user.email "watchdog@guanghulab.com" git add "$WATCHDOG_DATA" git commit -m "[WATCHDOG] ✅ PR #$ github.event.pull_request.number 修复已确认生效" git push # 在 PR 上留评论 gh pr comment $ github.event.pull_request.number \ --body "✅ **Merge Watchdog 确认:修复已生效** — 仪表盘已静默更新。" echo "🤫 不发邮件,不通知,安静收工。" # -------- 失败路径:计数 + 重试或告警 -------- - name: "❌ 修复未生效 — 判断重试/告警" if: needs.observe.outputs.workflow_result == 'failure' env: RETRY_COUNT: $ steps.load.outputs.retry_count GH_TOKEN: $ secrets.DEPLOY_GITHUB_TOKEN GEMINI_API_KEY: $ secrets.GEMINI_API_KEY run: | NEW_COUNT=$((RETRY_COUNT + 1)) echo "[Merge Watchdog] ❌ 第 $NEW_COUNT 次失败" if [ $NEW_COUNT -lt $ env.MAX_RETRIES ]; then echo "🔄 触发重新修复(策略 $NEW_COUNT)" # 根据轮次使用不同策略: # 轮次1 → 标准修复(已用过) # 轮次2 → 深度根因分析(附加前一轮失败信息) # 轮次3 → 保守降级方案 # 更新看守记录 jq --arg pr "$ github.event.pull_request.number " \ --argjson count $NEW_COUNT \ '(.records[] | select(.pr_number == ($pr | tonumber))).retry_count = $count' \ "$WATCHDOG_DATA" > tmp.json && mv tmp.json "$WATCHDOG_DATA" git config user.name "Merge Watchdog" git config user.email "watchdog@guanghulab.com" git add "$WATCHDOG_DATA" git commit -m "[WATCHDOG] 🔄 PR #$ github.event.pull_request.number 第${NEW_COUNT}次修复失败,触发重试" git push # 触发天眼重新修复(使用 repository_dispatch) gh api repos/$ github.repository /dispatches \ --method POST \ -f event_type="watchdog-retry" \ -f client_payload[pr_number]="$ github.event.pull_request.number " \ -f client_payload[retry_round]="$NEW_COUNT" \ -f client_payload[run_url]="$ needs.observe.outputs.run_url " else echo "⛔ 三振出局!发送邮件通知冰朔" # 更新看守记录为 escalated jq --arg pr "$ github.event.pull_request.number " \ --arg now "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \ '(.records[] | select(.pr_number == ($pr | tonumber))) |= . + { "status": "escalated", "escalated_at": $now, "resolution": "human_intervention" }' "$WATCHDOG_DATA" > tmp.json && mv tmp.json "$WATCHDOG_DATA" git config user.name "Merge Watchdog" git config user.email "watchdog@guanghulab.com" git add "$WATCHDOG_DATA" git commit -m "[WATCHDOG] ⛔ PR #$ github.event.pull_request.number 三次修复失败,已通知人类" git push fi # -------- 三振出局:发邮件 -------- - name: "📧 发送人类介入邮件" if: > needs.observe.outputs.workflow_result == 'failure' && steps.load.outputs.retry_count >= 2 uses: dawidd6/action-send-mail@v3 with: server_address: smtp.gmail.com server_port: 465 secure: true username: $ secrets.MAIL_USERNAME password: $ secrets.MAIL_PASSWORD subject: "⛔ [光湖系统] 自动修复三次失败 — 需要手动介入" to: $ secrets.HUMAN_EMAIL from: "光湖 Merge Watchdog以下修复经过 3轮自动修复 仍未解决:
| PR | #$ github.event.pull_request.number |
| 目标 Workflow | $ needs.gate.outputs.target_workflows |
| 最新失败日志 | 点击查看 |
看守者已暂停对该 Workflow 的自动修复。
手动修复成功后,仪表盘会自动更新。
— 光湖系统 · Merge Watchdog
``` --- ## 九、安全护栏 --- ## 十、与现有系统的协作关系 ```mermaid flowchart LR A["🌙 天眼夜间修复引擎