zhizhi/.github/workflows/skyeye-pr-risk-check.yml

121 lines
4.4 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
# ═══════════════════════════════════════════════
#
# 天眼 · PR 合并风险检查
# SkyEye PR Merge Risk Check
#
# 弥补天眼系统在 PR 合并环节的安全缺口:
# gate-guard v1/v2 保护 push 事件
# 本工作流保护 pull_request 事件(合并前风险评估)
#
# 风险检测维度:
# R1 · 关键文件覆盖检测docs/index.html 等)
# R2 · 受保护路径入侵检测
# R3 · 构建产物误入检测
# R4 · 开发者路径权限检测
# R5 · 大规模删除检测
#
name: 天眼 · PR风险检查
on:
pull_request:
branches: [main]
types: [opened, synchronize, reopened]
permissions:
contents: read
pull-requests: write
jobs:
risk-check:
name: 🛡️ PR合并风险评估
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Collect PR changed files
env:
GH_TOKEN: ${{ github.token }}
run: |
# Get the list of files changed in this PR
gh pr diff ${{ github.event.pull_request.number }} --name-only > /tmp/pr_files.txt || true
# Get diff stats
gh pr diff ${{ github.event.pull_request.number }} --stat > /tmp/pr_stats_raw.txt || true
# Parse stats into numstat-like format for the script
# Extract additions/deletions from the stat output
git diff --numstat origin/${{ github.base_ref }}...origin/${{ github.head_ref }} > /tmp/pr_stats.txt 2>/dev/null || true
echo "📂 Changed files:"
cat /tmp/pr_files.txt
echo ""
echo "📊 Stats:"
cat /tmp/pr_stats.txt
- name: 🔍 天眼 PR 风险检查
id: risk_check
env:
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
PR_FILES: /tmp/pr_files.txt
PR_STATS: /tmp/pr_stats.txt
run: node scripts/skyeye/pr-risk-check.js
- name: 📝 Write risk report comment
if: always()
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const decision = '${{ steps.risk_check.outcome }}';
const riskLevel = '${{ steps.risk_check.outputs.risk_level }}' || 'unknown';
const riskSummary = '${{ steps.risk_check.outputs.risk_summary }}' || '';
const author = '${{ github.event.pull_request.user.login }}';
let body = '## 🛡️ 天眼 · PR合并风险检查报告\n\n';
body += `**PR作者:** ${author}\n`;
body += `**检查时间:** ${new Date().toISOString()}\n\n`;
if (decision === 'success') {
body += '### ✅ 风险检查通过\n\n';
body += `风险等级: **${riskLevel}**\n\n`;
if (riskSummary && riskSummary !== '仓库主人 PR直接放行' && riskSummary !== '白名单用户 PR直接放行') {
body += '> ⚠️ 注意事项:\n';
body += `> ${riskSummary}\n\n`;
}
body += '此 PR 可以安全合并。\n';
} else {
body += '### ❌ 风险检查未通过\n\n';
body += `风险等级: **${riskLevel}**\n\n`;
body += '**检测到的风险:**\n';
if (riskSummary) {
const items = riskSummary.split(' | ');
for (const item of items) {
body += `- 🔴 ${item}\n`;
}
}
body += '\n⛔ **此 PR 已被天眼系统阻止合并。**\n';
body += '请联系仓库管理员 (TCS-0002∞) 审核。\n';
}
body += '\n---\n';
body += '> 天眼 · PR合并风险检查引擎 · SkyEye PR Risk Check';
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: body
});