From 816357b4773de4b80cccaa6201f7cdb7ef522d6e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 2 Apr 2026 16:34:04 +0000 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=B7=A5=E5=8D=95observer-23?= =?UTF-8?q?906843495=E4=B8=89=E4=B8=AABug=EF=BC=9A=E5=91=8A=E8=AD=A6?= =?UTF-8?q?=E9=98=88=E5=80=BC/IP=E5=AD=90=E5=9F=9F=E5=90=8D=E8=AF=AF?= =?UTF-8?q?=E5=88=A4/=E9=82=AE=E4=BB=B6=E6=AC=A1=E6=95=B0=E5=86=99?= =?UTF-8?q?=E6=AD=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Agent-Logs-Url: https://github.com/qinfendebingshuo/guanghulab/sessions/fd18e928-cba0-469e-b2c5-ce77d8efc2b1 Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com> --- .github/workflows/zhuyuan-deploy-observer.yml | 6 +++-- data/work-orders/active.json | 10 ++++++-- scripts/deputy-auto-repair.js | 7 ++++-- scripts/staging-ops-agent.js | 23 +++++++++++++------ 4 files changed, 33 insertions(+), 13 deletions(-) diff --git a/.github/workflows/zhuyuan-deploy-observer.yml b/.github/workflows/zhuyuan-deploy-observer.yml index 48722256..46706e52 100644 --- a/.github/workflows/zhuyuan-deploy-observer.yml +++ b/.github/workflows/zhuyuan-deploy-observer.yml @@ -114,6 +114,7 @@ jobs: outputs: repair_success: ${{ steps.repair.outputs.repair_success }} repair_attempt: ${{ steps.repair.outputs.repair_attempt }} + needs_human: ${{ steps.repair.outputs.needs_human }} steps: - name: '📥 检出代码' @@ -212,7 +213,7 @@ jobs: if: >- always() && needs.analyze-and-repair.result != 'skipped' && - needs.analyze-and-repair.outputs.repair_success != 'true' + needs.analyze-and-repair.outputs.needs_human == 'true' runs-on: ubuntu-latest steps: @@ -269,7 +270,8 @@ jobs: run: | if [ -n "$ZY_SMTP_USER" ] && [ -n "$ZY_SMTP_PASS" ]; then node scripts/staging-ops-agent.js alert \ - --order-id "observer-${{ needs.collect-logs.outputs.run_id }}" || true + --order-id "observer-${{ needs.collect-logs.outputs.run_id }}" \ + --attempt "${{ needs.analyze-and-repair.outputs.repair_attempt }}" || true else echo "ℹ️ SMTP未配置 · 跳过邮件告警 · 已创建GitHub Issue" fi diff --git a/data/work-orders/active.json b/data/work-orders/active.json index 3a181e98..b0b37ef1 100644 --- a/data/work-orders/active.json +++ b/data/work-orders/active.json @@ -116,7 +116,7 @@ { "id": "WO-20260402-1457", "title": "Merge pull request #258 from qinfendebingshuo/copilot/update-homepage-three-column-layout", - "status": "failed", + "status": "human-intervened", "commit_sha": "b3f38e263f6f6aa6e03a516445cbea8b63bd9c09", "branch": "main", "created_by": "qinfendebingshuo", @@ -141,6 +141,12 @@ "status": "failed", "actor": "Agent", "message": "部署失败" + }, + { + "timestamp": "2026-04-02T16:33:46.728Z", + "status": "human-intervened", + "actor": "铸渊", + "message": "铸渊人工干预 · 已定位根因:健康检查IP子域名误判Bug + 告警阈值Bug · 正在修复" } ], "deploy_logs": [ @@ -150,7 +156,7 @@ } ], "created_at": "2026-04-02T14:57:46.729Z", - "updated_at": "2026-04-02T14:58:27.523Z" + "updated_at": "2026-04-02T16:33:46.728Z" } ] } diff --git a/scripts/deputy-auto-repair.js b/scripts/deputy-auto-repair.js index 8571d0c9..96377c37 100644 --- a/scripts/deputy-auto-repair.js +++ b/scripts/deputy-auto-repair.js @@ -284,6 +284,7 @@ async function repair() { console.log(`❌ 已达最大修复次数(${MAX_REPAIR_ATTEMPTS}) · 放弃修复 · 通知人类`); setOutput('repair_success', 'false'); setOutput('repair_attempt', String(attemptNumber - 1)); + setOutput('needs_human', 'true'); return; } @@ -460,16 +461,18 @@ async function repair() { } // §7 设置输出 + const needsHuman = !repairSuccess && attemptNumber >= MAX_REPAIR_ATTEMPTS; setOutput('repair_success', repairSuccess ? 'true' : 'false'); setOutput('repair_attempt', String(attemptNumber)); + setOutput('needs_human', needsHuman ? 'true' : 'false'); console.log('═'.repeat(60)); if (repairSuccess) { console.log(`✅ 修复成功 · 第${attemptNumber}次尝试`); - } else if (attemptNumber >= MAX_REPAIR_ATTEMPTS) { + } else if (needsHuman) { console.log(`❌ ${MAX_REPAIR_ATTEMPTS}次修复均失败 · 需要人工干预`); } else { - console.log(`❌ 第${attemptNumber}次修复失败 · 还有${MAX_REPAIR_ATTEMPTS - attemptNumber}次尝试机会`); + console.log(`❌ 第${attemptNumber}次修复失败 · 还有${MAX_REPAIR_ATTEMPTS - attemptNumber}次尝试机会 · 等待下次重试`); } } diff --git a/scripts/staging-ops-agent.js b/scripts/staging-ops-agent.js index cdfede61..a9d04cb7 100644 --- a/scripts/staging-ops-agent.js +++ b/scripts/staging-ops-agent.js @@ -100,14 +100,22 @@ async function runHealthCheck(host) { console.log(`🔍 健康检查 · 目标: ${host}`); console.log('─'.repeat(50)); + // 如果host是IP地址,带host_prefix的检查无效(IP不支持子域名)→ 降级为non-critical + const isIpAddress = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(host); + if (isIpAddress) { + console.log(' ℹ️ 目标为IP地址 · 子域名检查降级为非关键'); + } + const results = []; let criticalFail = false; for (const endpoint of HEALTH_ENDPOINTS) { const checkHost = endpoint.host_prefix ? `${endpoint.host_prefix}.${host}` : host; + // IP地址不支持子域名前缀,降级为non-critical避免误报 + const isCritical = endpoint.critical && !(isIpAddress && endpoint.host_prefix); const result = await httpCheck(checkHost, endpoint.path, endpoint.port); - const icon = result.ok ? '✅' : (endpoint.critical ? '❌' : '⚠️'); + const icon = result.ok ? '✅' : (isCritical ? '❌' : '⚠️'); console.log(` ${icon} ${endpoint.name}: ${result.ok ? 'OK' : result.error || `HTTP ${result.status}`}`); results.push({ @@ -116,7 +124,7 @@ async function runHealthCheck(host) { checked_at: new Date().toISOString() }); - if (!result.ok && endpoint.critical) { + if (!result.ok && isCritical) { criticalFail = true; } } @@ -302,16 +310,17 @@ async function analyzeLog(logContent, orderId) { return deepResult; } -// ── 邮件告警 (3次重试失败) ────────────────── -async function sendAlert(orderId, email) { +// ── 邮件告警 (最大重试失败) ────────────────── +async function sendAlert(orderId, email, options = {}) { const smtpUser = process.env.ZY_SMTP_USER; const smtpPass = process.env.ZY_SMTP_PASS; + const attemptCount = options.attempt || process.env.REPAIR_ATTEMPT || '?'; if (!smtpUser || !smtpPass) { console.error('❌ SMTP未配置 (需要ZY_SMTP_USER和ZY_SMTP_PASS)'); console.log('📧 告警内容 (控制台输出):'); console.log(` 工单: ${orderId}`); - console.log(` 状态: 3次自动修复未能解决,需要人工干预`); + console.log(` 状态: ${attemptCount}次自动修复未能解决,需要人工干预`); return false; } @@ -345,7 +354,7 @@ async function sendAlert(orderId, email) {
ZY-Staging-Ops-Agent · 自动告警