feat(api): Phase D-G P0 修正 - Learning Repository 積木化
新增: - ILearningRepository Protocol (interfaces.py) - LearningRepository (Redis 持久化層) - Learning API 端點 (/api/v1/learning/*) - LearningService.get_recommended_fix() 方法 - LearningService.get_learning_summary() 方法 修正: - Service 不直接依賴 Redis Client (透過 Repository) - 符合 leWOOOgo 積木化原則 - 首席架構師審查: 74/100 → 92/100 更新: - ADR-030: 新增 Phase D-G P0 修正章節 - Skill 02: v1.9 → v2.0 - Runner 修復: 序列建構解決 _runner_file_commands 衝突 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
70
.github/workflows/cd.yaml
vendored
70
.github/workflows/cd.yaml
vendored
@@ -317,16 +317,18 @@ jobs:
|
||||
--from-literal=CLAUDE_API_KEY="${{ secrets.CLAUDE_API_KEY }}" \
|
||||
--from-literal=NVIDIA_API_KEY="${{ secrets.NVIDIA_API_KEY }}" \
|
||||
--from-literal=WEBHOOK_HMAC_SECRET="${{ secrets.WEBHOOK_HMAC_SECRET }}" \
|
||||
--from-literal=SENTRY_DSN="${{ secrets.SENTRY_DSN }}"
|
||||
--from-literal=SENTRY_DSN="${{ secrets.SENTRY_DSN }}" \
|
||||
--from-literal=SENTRY_AUTH_TOKEN="${{ secrets.SENTRY_AUTH_TOKEN }}"
|
||||
else
|
||||
echo "🔄 更新 awoooi-secrets..."
|
||||
# 使用 patch 更新,確保關鍵配置永遠是最新的
|
||||
# 2026-03-29 ogt: ADR-036 新增 NVIDIA_API_KEY
|
||||
# 2026-03-29 ogt: ADR-036 新增 NVIDIA_API_KEY, ADR-037 新增 SENTRY_AUTH_TOKEN
|
||||
kubectl patch secret awoooi-secrets -n awoooi-prod --type='merge' -p="{
|
||||
\"stringData\": {
|
||||
\"OPENCLAW_TG_BOT_TOKEN\": \"${{ secrets.OPENCLAW_TG_BOT_TOKEN }}\",
|
||||
\"OPENCLAW_TG_CHAT_ID\": \"${{ secrets.OPENCLAW_TG_CHAT_ID }}\",
|
||||
\"NVIDIA_API_KEY\": \"${{ secrets.NVIDIA_API_KEY }}\"
|
||||
\"NVIDIA_API_KEY\": \"${{ secrets.NVIDIA_API_KEY }}\",
|
||||
\"SENTRY_AUTH_TOKEN\": \"${{ secrets.SENTRY_AUTH_TOKEN }}\"
|
||||
}
|
||||
}"
|
||||
fi
|
||||
@@ -384,6 +386,68 @@ jobs:
|
||||
# 使用 Python httpx (容器沒有 curl,但有 httpx)
|
||||
kubectl exec -n awoooi-prod $API_POD -c api -- python -c "import httpx; r=httpx.get('http://localhost:8000/api/v1/health', timeout=5); print(r.status_code)" || echo "Health check failed but deployment succeeded"
|
||||
|
||||
# =======================================================================
|
||||
# ADR-037 Wave B.2: Alert Chain Smoke Test
|
||||
# 2026-03-29: 告警鏈路端到端驗證 (Wave A.6 腳本整合)
|
||||
# =======================================================================
|
||||
- name: "Alert Chain Smoke Test (ADR-037)"
|
||||
run: |
|
||||
echo "🔍 執行告警鏈路 Smoke Test..."
|
||||
API_POD=$(kubectl get pods -n awoooi-prod -l app=awoooi-api -o jsonpath='{.items[0].metadata.name}')
|
||||
|
||||
# 測試各 Webhook Endpoint
|
||||
kubectl exec -n awoooi-prod $API_POD -c api -- python -c "
|
||||
import httpx
|
||||
import sys
|
||||
|
||||
BASE = 'http://localhost:8000'
|
||||
TIMEOUT = 30
|
||||
results = []
|
||||
|
||||
# 1. Health
|
||||
try:
|
||||
r = httpx.get(f'{BASE}/api/v1/health', timeout=TIMEOUT)
|
||||
results.append(('health', r.status_code == 200))
|
||||
except Exception as e:
|
||||
results.append(('health', False))
|
||||
print(f'Health: {e}')
|
||||
|
||||
# 2. Alertmanager Webhook
|
||||
try:
|
||||
r = httpx.post(f'{BASE}/api/v1/webhooks/alertmanager', json={
|
||||
'version': '4', 'status': 'firing',
|
||||
'alerts': [{'status': 'firing', 'labels': {'alertname': 'E2E_CD_TEST', 'severity': 'info'}}]
|
||||
}, timeout=TIMEOUT)
|
||||
results.append(('alertmanager', r.status_code == 200))
|
||||
except Exception as e:
|
||||
results.append(('alertmanager', False))
|
||||
print(f'Alertmanager: {e}')
|
||||
|
||||
# 3. SignOz Webhook Health
|
||||
try:
|
||||
r = httpx.get(f'{BASE}/api/v1/webhooks/signoz/health', timeout=TIMEOUT)
|
||||
results.append(('signoz', r.status_code == 200))
|
||||
except Exception as e:
|
||||
results.append(('signoz', False))
|
||||
print(f'SignOz: {e}')
|
||||
|
||||
# Summary
|
||||
passed = sum(1 for _, ok in results if ok)
|
||||
total = len(results)
|
||||
print(f'Smoke Test: {passed}/{total} passed')
|
||||
for name, ok in results:
|
||||
print(f' {\"✅\" if ok else \"❌\"} {name}')
|
||||
|
||||
sys.exit(0 if passed == total else 1)
|
||||
" || {
|
||||
echo "⚠️ Smoke Test 部分失敗,但不阻擋部署"
|
||||
# 發送告警
|
||||
curl -sf -X POST "https://api.telegram.org/bot${{ secrets.OPENCLAW_TG_BOT_TOKEN }}/sendMessage" \
|
||||
-d chat_id="${{ secrets.OPENCLAW_TG_CHAT_ID }}" \
|
||||
-d text="⚠️ *AWOOOI Alert Chain Smoke Test 部分失敗*%0A%0A部署已完成,但部分 Webhook 可能有問題。%0A%0A🔗 ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
|
||||
-d parse_mode="Markdown" || true
|
||||
}
|
||||
|
||||
# =======================================================================
|
||||
# ADR-035: Telegram 告警鏈路 E2E 驗證
|
||||
# 2026-03-29 Claude Code: 部署後必須驗證 Telegram 發送成功
|
||||
|
||||
Reference in New Issue
Block a user