guanghulab/.github/archived-workflows/syslog-pipeline.yml
2026-05-10 13:12:44 +08:00

364 lines
14 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
# ═══════════════════════════════════════════════
name: 铸渊 · SYSLOG Pipeline (A/D/E)
on:
push:
branches: [main]
paths:
- 'syslog-inbox/**'
workflow_run:
workflows: ["铸渊 · 飞书SYSLOG桥接"]
types: [completed]
workflow_dispatch:
jobs:
# ── Pipeline ASYSLOG 读取与处理 ──────────────────────
pipeline-a-syslog:
name: 📥 Pipeline A · SYSLOG 读取处理
if: >-
github.event_name != 'workflow_run' ||
github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-latest
permissions:
contents: write
issues: read
outputs:
processed_count: ${{ steps.process.outputs.processed_count }}
has_syslog: ${{ steps.parse.outputs.has_syslog }}
sender_open_id: ${{ steps.parse.outputs.sender_open_id }}
chat_id: ${{ steps.parse.outputs.chat_id }}
sender_name: ${{ steps.parse.outputs.sender_name }}
syslog_file: ${{ steps.parse.outputs.syslog_file }}
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
ref: main
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
# Step 0: 解析 sender 信息(在 process-syslog.js 归档之前)
- name: 📋 解析 SYSLOG sender 信息
id: parse
run: |
LATEST=$(ls -t syslog-inbox/*.json 2>/dev/null | grep -v '.gitkeep' | head -1 || true)
if [ -z "$LATEST" ]; then
echo "📭 syslog-inbox/ 无待处理文件"
echo "has_syslog=false" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "has_syslog=true" >> "$GITHUB_OUTPUT"
echo "syslog_file=$LATEST" >> "$GITHUB_OUTPUT"
SENDER_OPEN_ID=$(jq -r '.sender_open_id // .sender_id // empty' "$LATEST" 2>/dev/null || true)
CHAT_ID=$(jq -r '.chat_id // empty' "$LATEST" 2>/dev/null || true)
SENDER_NAME=$(jq -r '.sender_name // empty' "$LATEST" 2>/dev/null || true)
echo "sender_open_id=$SENDER_OPEN_ID" >> "$GITHUB_OUTPUT"
echo "chat_id=$CHAT_ID" >> "$GITHUB_OUTPUT"
echo "sender_name=$SENDER_NAME" >> "$GITHUB_OUTPUT"
echo "📋 SYSLOG 文件: $LATEST"
echo " sender_open_id: ${SENDER_OPEN_ID:-无}"
echo " chat_id: ${CHAT_ID:-无}"
echo " sender_name: ${SENDER_NAME:-无}"
# Step 1: 写入 Notion SYSLOG 收件箱
- name: 📝 写入 Notion SYSLOG 收件箱
if: steps.parse.outputs.has_syslog == 'true'
env:
NOTION_TOKEN: ${{ secrets.ZY_NOTION_TOKEN }}
NOTION_DB_SYSLOG: ${{ secrets.ZY_NOTION_SYSLOG_DB }}
run: node scripts/write-notion-syslog.js "${{ steps.parse.outputs.syslog_file }}"
# Step 2: 处理 syslog-inbox 条目(归档到 syslog-processed/
- name: 📥 处理 syslog-inbox 条目
id: process
run: |
node scripts/process-syslog.js
COUNT=$(ls syslog-processed/ -R 2>/dev/null | grep -c '\.json' || echo 0)
echo "processed_count=$COUNT" >> "$GITHUB_OUTPUT"
- name: 提交处理结果
run: |
git config user.name "铸渊[bot]"
git config user.email "zhu-yuan-bot@guanghulab.com"
git add syslog-inbox/ syslog-processed/ .github/brain/memory.json
git diff --staged --quiet || git commit -m "📥 syslog: 处理 inbox 条目,更新大脑记忆 [skip ci]"
git push
# ── Pipeline BClaude API 唤醒人格体 ────────────────────
pipeline-b-persona:
name: 🧠 Pipeline B · 人格体唤醒
runs-on: ubuntu-latest
needs: pipeline-a-syslog
if: needs.pipeline-a-syslog.outputs.has_syslog == 'true'
permissions:
contents: read
outputs:
broadcast_title: ${{ steps.persona.outputs.broadcast_title }}
broadcast_url: ${{ steps.persona.outputs.broadcast_url }}
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
ref: main
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: 🧠 唤醒人格体处理 SYSLOG
id: persona
env:
LLM_API_KEY: ${{ secrets.ZY_LLM_API_KEY }}
LLM_BASE_URL: ${{ secrets.ZY_LLM_BASE_URL }}
NOTION_TOKEN: ${{ secrets.ZY_NOTION_TOKEN }}
CORE_BRAIN_PAGE_ID: ${{ secrets.ZY_NOTION_BRAIN_PAGE }}
PORTRAIT_DB_ID: ${{ secrets.ZY_NOTION_PORTRAIT_DB }}
FINGERPRINT_DB_ID: ${{ secrets.ZY_NOTION_FINGERPRINT_DB }}
SUBMIT_TYPE: syslog
SYSLOG_FILE: ${{ needs.pipeline-a-syslog.outputs.syslog_file }}
AUTHOR: ${{ needs.pipeline-a-syslog.outputs.sender_name }}
run: |
if [ -z "$LLM_API_KEY" ] || [ -z "$LLM_BASE_URL" ]; then
echo "⚠️ LLM_API_KEY 或 LLM_BASE_URL 未配置,跳过人格体唤醒"
echo "broadcast_title=" >> "$GITHUB_OUTPUT"
echo "broadcast_url=" >> "$GITHUB_OUTPUT"
exit 0
fi
# 读取 SYSLOG 文件内容传递给 wake-persona.js
# 注意Pipeline A 可能已将文件从 syslog-inbox/ 归档到 syslog-processed/
if [ -f "$SYSLOG_FILE" ]; then
export SUBMIT_CONTENT=$(cat "$SYSLOG_FILE")
else
BASENAME=$(basename "$SYSLOG_FILE")
PROCESSED_FILE=$(find syslog-processed/ -name "$BASENAME" -type f 2>/dev/null | head -1)
if [ -n "$PROCESSED_FILE" ]; then
echo "📂 文件已归档,从 $PROCESSED_FILE 读取"
export SUBMIT_CONTENT=$(cat "$PROCESSED_FILE")
else
echo "⚠️ SYSLOG 文件未找到: $SYSLOG_FILEinbox 和 processed 均不存在)"
fi
fi
if [ -z "$SUBMIT_CONTENT" ]; then
echo "⚠️ SUBMIT_CONTENT 为空,跳过人格体唤醒"
echo "broadcast_title=" >> "$GITHUB_OUTPUT"
echo "broadcast_url=" >> "$GITHUB_OUTPUT"
exit 0
fi
if node scripts/wake-persona.js; then
echo "✅ 人格体唤醒成功"
else
echo "⚠️ 人格体唤醒失败exit code: $?),继续后续步骤"
fi
# 读取人格体输出的广播信息(如果有)
if [ -f /tmp/broadcast-result.json ]; then
BROADCAST_TITLE=$(jq -r '.title // empty' /tmp/broadcast-result.json)
BROADCAST_URL=$(jq -r '.notion_url // empty' /tmp/broadcast-result.json)
echo "broadcast_title=$BROADCAST_TITLE" >> "$GITHUB_OUTPUT"
echo "broadcast_url=$BROADCAST_URL" >> "$GITHUB_OUTPUT"
echo "✅ 人格体处理完成,广播标题: $BROADCAST_TITLE"
else
echo "⚠️ /tmp/broadcast-result.json 未生成(人格体可能未产出广播)"
echo "broadcast_title=" >> "$GITHUB_OUTPUT"
echo "broadcast_url=" >> "$GITHUB_OUTPUT"
fi
# ── Pipeline C推送广播到飞书 ───────────────────────────
pipeline-c-push:
name: 📢 Pipeline C · 飞书广播推送
runs-on: ubuntu-latest
needs: [pipeline-a-syslog, pipeline-b-persona]
permissions: {}
if: >-
needs.pipeline-b-persona.outputs.broadcast_title != '' &&
(needs.pipeline-a-syslog.outputs.chat_id != '' || needs.pipeline-a-syslog.outputs.sender_open_id != '')
steps:
- name: 📢 推送广播到飞书
env:
PUSH_URL: https://guanghulab.com/webhook/push-broadcast
PUSH_TOKEN: ${{ secrets.ZY_PUSH_TOKEN }}
CHAT_ID: ${{ needs.pipeline-a-syslog.outputs.chat_id }}
SENDER_OPEN_ID: ${{ needs.pipeline-a-syslog.outputs.sender_open_id }}
BROADCAST_TITLE: ${{ needs.pipeline-b-persona.outputs.broadcast_title }}
BROADCAST_URL: ${{ needs.pipeline-b-persona.outputs.broadcast_url }}
run: |
if [ -z "$PUSH_TOKEN" ]; then
echo "⚠️ PUSH_BROADCAST_TOKEN 未配置,跳过飞书推送"
exit 0
fi
echo "📢 推送广播到飞书..."
echo " 标题: $BROADCAST_TITLE"
echo " 目标: ${CHAT_ID:-$SENDER_OPEN_ID}"
HTTP_CODE=$(curl -s -o /tmp/push-response.txt -w "%{http_code}" \
-X POST "$PUSH_URL" \
-H "Content-Type: application/json" \
-H "x-push-token: $PUSH_TOKEN" \
-d "$(jq -n \
--arg chat_id "$CHAT_ID" \
--arg sender_open_id "$SENDER_OPEN_ID" \
--arg broadcast_title "$BROADCAST_TITLE" \
--arg broadcast_content "人格体已验收,请查看完整广播。" \
--arg broadcast_url "$BROADCAST_URL" \
'{chat_id: $chat_id, sender_open_id: $sender_open_id, broadcast_title: $broadcast_title, broadcast_content: $broadcast_content, broadcast_url: $broadcast_url}')")
echo " HTTP 响应: $HTTP_CODE"
cat /tmp/push-response.txt 2>/dev/null || true
echo ""
if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ]; then
echo "✅ 广播已推送到飞书"
else
echo "❌ 推送失败 (HTTP $HTTP_CODE),可通过 push-broadcast-feishu workflow 手动补推"
fi
# ── Pipeline DIssues 巡检 ─────────────────────────────
pipeline-d-issues:
name: 🔍 Pipeline D · Issues 巡检
runs-on: ubuntu-latest
needs: pipeline-a-syslog
permissions:
contents: write
issues: read
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
ref: main
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: 🔍 巡检 Issues
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
run: |
echo "🔍 Pipeline D · Issues 巡检开始"
node -e "
const https = require('https');
const token = process.env.GITHUB_TOKEN;
const repo = process.env.REPO;
const opts = {
hostname: 'api.github.com',
path: '/repos/' + repo + '/issues?state=open&per_page=20',
headers: { 'Authorization': 'Bearer ' + token, 'User-Agent': 'zhuyuan-bot' }
};
https.get(opts, res => {
let body = '';
res.on('data', c => body += c);
res.on('end', () => {
const issues = JSON.parse(body);
console.log('📋 开放 Issues 数量:' + (Array.isArray(issues) ? issues.length : '读取失败'));
if (Array.isArray(issues) && issues.length > 0) {
issues.slice(0, 5).forEach(i => console.log(' #' + i.number + ' ' + i.title));
}
console.log('✅ Pipeline D 巡检完成');
});
}).on('error', e => { console.error('❌ 巡检失败:', e.message); process.exit(1); });
"
# ── Pipeline E变更感知 ────────────────────────────────
pipeline-e-changes:
name: 📡 Pipeline E · 变更感知
runs-on: ubuntu-latest
needs: pipeline-a-syslog
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
ref: main
fetch-depth: 10
- name: 📡 感知近期变更
run: |
echo "📡 Pipeline E · 变更感知开始"
echo "=== 近期 10 次提交 ==="
git --no-pager log --oneline -10
echo ""
echo "=== syslog-inbox 文件状态 ==="
ls -la syslog-inbox/ || echo "(空)"
echo ""
echo "=== syslog-processed 文件状态 ==="
ls -laR syslog-processed/ || echo "(空)"
echo "✅ Pipeline E 变更感知完成"
# ━━━ 🧬 双端神经系统·自报告 ━━━
- name: "🧬 写入神经自报告"
if: always()
run: |
WORKFLOW_ID="syslog"
BRAIN="SY-03"
REPORT_DIR="data/neural-reports/syslog"
TIMESTAMP=$(TZ=Asia/Shanghai date +%Y-%m-%d-%H%M)
STATUS="${{ job.status }}"
mkdir -p "$REPORT_DIR"
cat > "${REPORT_DIR}/${WORKFLOW_ID}-${TIMESTAMP}.json" << EOF
{
"workflow_id": "${WORKFLOW_ID}",
"run_id": "${{ github.run_id }}",
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
"status": "${STATUS}",
"brain": "${BRAIN}",
"event": "${{ github.event_name }}",
"branch": "${{ github.ref_name }}",
"commit": "${{ github.sha }}"
}
EOF
git config user.name "zhuyuan-bot"
git config user.email "zhuyuan@guanghulab.com"
git add "$REPORT_DIR/"
git diff --cached --quiet || \
git commit -m "🧬 ${WORKFLOW_ID} 自报告 · ${TIMESTAMP} [skip ci]"
git push || echo "⚠️ 自报告push失败不阻断主流程"
# ━━━ 📡 指令回执·自动同步 ━━━
- name: "📡 同步回执到 Notion"
if: always()
env:
NOTION_API_KEY: ${{ secrets.ZY_NOTION_TOKEN }}
RECEIPT_DB_ID: ${{ secrets.ZY_NOTION_RECEIPT_DB }}
run: |
node scripts/neural/write-receipt-to-notion.js \
--instruction-id "${{ github.event.inputs.instruction_id || 'AUTO' }}" \
--status "${{ job.status }}" \
--workflow "syslog" \
--summary "syslog 自动执行" \
--related-agent "SY-03"