xzawed/SCAManager

GitHub: xzawed/SCAManager

SCAManager 是一个自托管的 GitHub 代码质量服务,通过并行运行静态分析器和 Claude AI 审查来量化评分并自动化 PR 门禁流程。

Stars: 1 | Forks: 0

# 🛡️ SCAManager **自动化代码质量分析 · AI Review · GitHub 的 PR Gate 服务** [![Python](https://img.shields.io/badge/Python-3.12-3776AB?style=flat-square&logo=python&logoColor=white)](https://www.python.org/) [![FastAPI](https://img.shields.io/badge/FastAPI-0.139-009688?style=flat-square&logo=fastapi&logoColor=white)](https://fastapi.tiangolo.com/) [![PostgreSQL](https://img.shields.io/badge/PostgreSQL-SQLAlchemy_2-336791?style=flat-square&logo=postgresql&logoColor=white)](https://www.postgresql.org/) [![Claude AI](https://img.shields.io/badge/Claude_AI-Sonnet_4.6_(default)-CC6600?style=flat-square&logo=anthropic&logoColor=white)](https://www.anthropic.com/) [![Railway](https://img.shields.io/badge/Deploy-Railway-0B0D0E?style=flat-square&logo=railway&logoColor=white)](https://railway.app/) [![License](https://img.shields.io/badge/License-MIT-green?style=flat-square)](LICENSE) [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/xzawed/SCAManager/actions/workflows/ci.yml) [![CodeQL](https://static.pigsec.cn/wp-content/uploads/repos/cas/53/539e9a6bf48ad24469a4363bff3aa68124154549e26592783d3d8577f2acbbfc.svg)](https://github.com/xzawed/SCAManager/actions/workflows/codeql.yml) [![codecov](https://codecov.io/gh/xzawed/SCAManager/branch/main/graph/badge.svg)](https://codecov.io/gh/xzawed/SCAManager) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=xzawed_SCAManager&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=xzawed_SCAManager) [![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=xzawed_SCAManager&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=xzawed_SCAManager) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=xzawed_SCAManager&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=xzawed_SCAManager) [![Tests](https://img.shields.io/badge/Tests-6386%2B_total_(6215_unit_%2B_171_integration)-brightgreen?style=flat-square&logo=pytest&logoColor=white)](tests/) [![E2E](https://img.shields.io/badge/E2E-122_tests_(local_only%2C_not_in_CI)-lightgrey?style=flat-square&logo=playwright&logoColor=white)](e2e/) [![pylint](https://img.shields.io/badge/pylint-10.00%2F10-brightgreen?style=flat-square&logo=python&logoColor=white)](src/) [![bandit](https://img.shields.io/badge/bandit-HIGH_0-brightgreen?style=flat-square&logo=security&logoColor=white)](src/) [![Coverage](https://img.shields.io/badge/Coverage-97%25-brightgreen?style=flat-square&logo=codecov&logoColor=white)](tests/) [🇰🇷 한국어](README.ko.md)
## 📖 概述 **SCAManager** 自动管理你 GitHub 仓库的代码质量。 在每次 Push 或 PR 事件时,它会并行运行**静态分析**(25 个已注册的分析器 — pylint · flake8 · bandit · Semgrep · ESLint · ShellCheck · cppcheck · slither · RuboCop · golangci-lint 及[另外 15 个](docs/reference/language-coverage.md))和 **Claude AI review**,并给出百分制评分及从 A 到 F 的等级。 结果会通过 **Telegram · GitHub · Discord · Slack · Email · n8n** 即时推送,并且可以根据分数自动批准、拒绝或 squash-merge PR。 对于直接推送到 `main` 分支的团队,它还支持在低分提交上执行**自动提交评论**和**创建 GitHub Issue**。 ## 🎯 为什么选择 SCAManager? 大多数代码审查工具让你在静态分析的精确度和 AI 的理解力之间做选择。SCAManager 并行运行这两者,并将结果合并为一个单一的分数 — 然后基于此自动执行操作。 **它的独特之处:** - **自托管的控制平面** — pipeline、数据库和 dashboard 运行在你自己的基础设施上;没有供应商锁定,运行它也不需要第三方 SaaS 账户。你分析的代码仍然会被发送到*你*配置的服务:用于 AI review 的 Anthropic API,以及你启用的任何通知渠道。有关确切的出口列表以及如何在零外部调用的情况下运行,请参阅 [SECURITY.md § 代码去向](SECURITY.md#where-your-code-goes)。 - **集成静态分析与 AI 的单一 pipeline** — 25 个已注册的静态分析器与 Claude AI review 并行运行;结果汇聚为单一分数 - **基于评分的 PR Gate** — 根据数值阈值自动批准、拒绝或通过 Telegram 请求人工决策 - **从手机批准** — Telegram 内联按钮允许你在任何地方审查和合并 PR,无需笔记本电脑 - **Push + PR 分析** — 不仅仅是 PR;纯粹的 push 也会触发分析,自动创建 GitHub Issue,并发布提交评论 - **49 种语言的 AI review** — 为每种支持的语言提供特定的检查清单,而非通用的 prompt **最适合:** 希望对代码质量 pipeline 拥有完全控制权的独立开发者和小型团队。 ## 🌐 多语言支持 (English / 한국어 / 日本語) SCAManager 在所有面向用户的界面 — UI、通知和 AI 代码审查 prompt — 支持 **3 种语言**。 | 界面 | 翻译范围 | 事实来源 | |---------|------------|-----------------| | **Web UI** (登录 / dashboard / 设置 / 管理) | 所有标签、按钮、提示 | 标题下拉菜单 🌐 (顶部导航) | | **通知** (Telegram / Discord / Slack / Email / GitHub PR 评论 / 提交评论 / Issue) | 所有消息模板 | 3 层回退:用户语言 → 仓库通知语言 → 默认 | | **AI 代码审查** (Claude — 49 种语言) | Tier1/Tier2/Tier3 + 通用指南 | 2 层回退:仓库所有者语言 → 用户语言 → 默认 | **如何切换**:点击顶部标题栏中的语言下拉菜单 🌐。更改将立即应用并通过 cookie 持久化。 **注意**: - 语言偏好存储在用户账户上(标题下拉菜单是唯一的事实来源 — 在 `/settings` 中没有单独的语言设置) - GitHub Issue 标题 + Email 主题保留英文前缀以便于搜索 (`[SCAManager]`, `[Code Review]`) - Anthropic prompt 缓存会根据语言自动区分(系统文本哈希不同 → 缓存键分离,无需手动配置) - 熔断开关:设置 `I18N_DISABLED=1` 以仅回退到默认语言环境(用于操作紧急情况) 详细环境变量:[docs/reference/env-vars.md](docs/reference/env-vars.md) ## ✨ 功能 ### 🔍 自动化代码分析 | 分析项 | 工具 | 目标 | |----------|-------|--------| | 代码质量 | pylint + flake8 + Semgrep + cppcheck + RuboCop + golangci-lint | `.py` + C/C++ (cppcheck) + `.rb` (RuboCop) + `.go` (golangci-lint) + **22 种语言** (Semgrep — [src/analyzer/io/tools/semgrep.py](src/analyzer/io/tools/semgrep.py) 中的 `SUPPORTED_LANGUAGES`) | | 安全性 | bandit + Semgrep + slither + RuboCop Security cops + gosec (通过 golangci-lint) | `.py` 文件(排除测试)+ Solidity (slither) + Ruby / Go 安全规则 | | JS/TS 质量 | ESLint (flat config) | `.js` `.mjs` `.ts` `.tsx` | | Shell 质量 | ShellCheck | `.sh` `.bash` 及其他 shell 脚本 | | Solidity | slither | `.sol` — reentrancy · tx.origin · weak-prng · 感知类别 | | Ruby | RuboCop | `.rb` — 单独检测 Security cops | | Go | golangci-lint | `.go` — meta-linter (gosec / errcheck / staticcheck / unused,自动 `go.mod`) | | AI Review | Claude Sonnet 4.6 | **49 种语言**,带有特定语言的检查清单 | | 提交信息 | Claude AI | Push / PR 信息 | - 自动处理 `push` 和 PR (`opened` / `synchronize` / `reopened`) 事件 - 静态分析和 AI review 通过 `asyncio.gather()` **并行**运行 — 延迟最低 - 如果没有 `ANTHROPIC_API_KEY`,AI 项目使用中性默认值 — **在没有 AI 的情况下最高可达 89 分(等级 B)** ### 🏆 评分系统 | 类别 | 分数 | 扣分规则 | |----------|--------|----------------| | 🧹 代码质量 | 25 | error −3 · warning −1 (CQ_WARNING_CAP = 合计上限 25) | | 🔒 安全性 | 20 | HIGH −7 · LOW/MED −2 | | 📝 提交信息 | 15 | Claude AI (0–20 → 缩放至 0–15) | | 🧠 实现方向 | 25 | Claude AI (0–20 → 缩放至 0–25) | | 🧪 测试覆盖率 | 15 | Claude AI (0–10 → 缩放至 0–15;豁免配置/文档文件) | | **总分** | **100** | | **等级阈值** | 等级 | 分数 | 含义 | |-------|-------|---------| | 🥇 A | 90+ | 优秀 | | 🥈 B | 75+ | 良好 | | 🥉 C | 60+ | 平均水平 | | ⚠️ D | 45+ | 需要改进 | | 🚨 F | ≤ 44 | 严重 | ### 🔔 通知渠道 | 渠道 | 内容 | 配置 | |---------|---------|---------------| | 📱 Telegram | 评分 · AI 总结 · 建议 · 静态问题 (HTML) | 默认 | | 💬 GitHub PR 评论 | 分类/文件反馈 + 评分表 | 逐仓库配置 | | 📌 GitHub 提交评论 | 在 push 提交上发布的 AI review | 逐仓库配置 | | 🐛 GitHub Issue | 在低分或 bandit HIGH 时自动创建 | 逐仓库配置 | | 🎮 Discord | Embed 格式的通知 | 逐仓库配置 | | 💼 Slack | Attachment 格式的通知 | 逐仓库配置 | | 📧 Email | SMTP HTML 邮件 | 逐仓库配置 | | 🔗 通用 Webhook | 通用 JSON POST | 逐仓库配置 | | 🔄 n8n | 外部工作流触发 (Issue → Claude CLI → 自动 PR) | 逐仓库配置 | 所有渠道都通过 `asyncio.gather(return_exceptions=True)` 独立运行 — 一个渠道的失败永远不会影响其他渠道。 ### 📡 Telegram 洞察 除了实时的 push/PR 提醒外,SCAManager 的 Telegram 集成还提供定期的报告、趋势检测和交互式的 bot 命令。 #### 每周报告 每周一 KST 09:00,SCAManager 会向每个仓库配置的 Telegram 聊天发送一份每周总结: ``` 📊 Weekly Report — owner/myrepo Period: Apr 21 – Apr 27 Analyses: 12 | Avg score: 81.4 (B) High: 94 (A) | Low: 62 (C) Top issues this week: · security: 8 occurrences · code_quality: 14 occurrences ``` #### 趋势警报 每天 KST 12:00,SCAManager 会检查 7 天移动平均值。如果它比前一时期**下降 10 分以上**(至少需要 5 次分析),将自动发送趋势警报: ``` ⚠️ Score trend alert — owner/myrepo 7-day moving avg dropped: 83.2 → 71.5 (−11.7) Recent low-score analyses may need attention. ``` #### Bot 命令 关联你的 Telegram 账户(见下文)后,向 bot 发送这些命令: | 命令 | 描述 | |---------|-------------| | `/stats ` | 仓库的每周平均分、分析次数和主要问题 | | `/settings ` | 当前的 gate 模式、阈值和通知设置 | | `/connect ` | 将你的 Telegram 账户关联到你的 SCAManager 个人资料 | #### 关联你的 Telegram 账户(`/connect` OTP 流程) 1. 转到 **Settings → "Outbound Channels" 卡片 → Telegram Connection**,然后点击 **"🔗 Issue Code"** 2. 出现一个 8 位数的 OTP(有效期为 5 分钟) 3. 在 Telegram 中向 SCAManager bot 发送 `/connect 12345678` 4. bot 回复 "✅ Account linked" — 现在可以使用 bot 命令了 ### ⚡ PR Gate 引擎 基于评分的 PR 自动化。 ``` Analysis complete ├── [Auto mode] score ≥ approve_threshold → GitHub APPROVE │ score < reject_threshold → GitHub REQUEST_CHANGES │ ├── [Semi-auto mode] Send Telegram inline buttons → manual approve/reject │ └── [Auto Merge] score ≥ merge_threshold → squash merge (independent of approve_mode) ``` | 设置 | 行为 | |---------|----------| | `approve_mode="auto"` | 按阈值自动批准 / 请求更改 | | `approve_mode="semi-auto"` | 通过 Telegram 按钮手动决策 | | `auto_merge=true` | 满足阈值时执行 Squash merge | #### ♻️ 感知 CI 的自动合并重试 当 `auto_merge=true` 且由于 CI 仍在运行导致合并失败时(`mergeable_state=unstable` 或 `unknown`),SCAManager 会将 PR 排队等待重试,而不是直接放弃: - 首次入队:发送 Telegram "⏳ merge queued" 通知 (1×) - 在 24 小时内通过 `check_suite.completed` webhook 或 1 分钟的 cron 最多重试 30 次 - 最终结果:Telegram 成功/失败通知 (1×) ### 📊 可观测性 用于诊断和成本控制的生产级监控仪表。 | 层级 | 模块 | 捕获内容 | |-------|--------|------------------| | Claude API 成本 | `src/shared/claude_metrics.py` | 每次调用的 model · input/output tokens · USD 成本估算 · 延迟(结构化日志)。 | | Pipeline 耗时 | `src/shared/stage_metrics.py` `stage_timer` 上下文管理器为每个 pipeline 阶段发出 `duration_ms` + `status`。 | | 自动合并尝试 | `src/shared/merge_metrics.py` + `merge_attempts` 表 | 每次自动合并尝试(无论成功或失败)都会被持久化,并带有标准化的 `failure_reason` 标签(`branch_protection_blocked`, `unstable_ci`, `permission_denied`, …)+ `score`/`threshold` 快照。 | 这三个层级都会无条件发出结构化日志,因此任何日志转发器(Datadog, CloudWatch, Grafana Loki, Railway Logs)都可以解析它们。无需依赖外部 SaaS。 ### 🖥️ Web Dashboard 通过 GitHub OAuth 登录后,即可通过浏览器访问所有功能。 - **添加仓库** — 从 GitHub 下拉菜单自动创建 Webhook - **评分历史图表** — 基于 Chart.js 的可视化 - **分析详情** — AI review · 分类反馈 · 静态分析问题 - **设置页面** — 🚀 一键预设 · 6 卡片渐进式展开 (Quick Settings · PR Behavior Rules · Post-event automation · Outbound Channels · Integration & Auth · Danger zone) · 切换显示/隐藏 - **主题** — Dark / Light / Pastel / Catppuccin — 完整支持所有四种主题 ### 💻 CLI 代码审查 从终端立即运行本地代码审查。 ``` # 与最后一次 commit 进行比较(默认) python -m src.cli review # 与特定 branch 进行比较 python -m src.cli review --base main # 仅分析 staged changes python -m src.cli review --staged # JSON 输出 python -m src.cli review --json ``` ### 🪝 CLI Hook (本地 pre-push 自动审查) 一个在 `git push` 时自动运行代码审查的 Git Hook。 ``` # 在注册 repo 后运行一次 git pull bash .scamanager/install-hook.sh # 随后的每次 push 都会触发自动 review git push origin main # → AI review 打印到 terminal # → 自动保存到 SCAManager dashboard ``` - **需要 `ANTHROPIC_API_KEY`** — 该 hook 直接调用 Anthropic Messages API(它不再调用 `claude -p`;当 Agent SDK 的计费在 2025-06-15 被拆分时,该调用路径已被弃用) - 默认使用 `claude-haiku-4-5` 以保持每次 push 的低成本 — 可通过 `SCAMANAGER_REVIEW_MODEL` 覆盖 - 结果会同时显示在终端和 dashboard 中 - Push 永远不会被阻塞 — hook 总是以 `0` 退出 ## 🛠️ 技术栈 | 类别 | 技术 | |----------|------------| | **语言** | Python 3.12 | | **Web 框架** | FastAPI + Uvicorn | | **认证** | GitHub OAuth2 (authlib) + Starlette SessionMiddleware | | **数据库** | PostgreSQL · SQLAlchemy 2 · Alembic · FailoverSessionFactory | | **AI (服务端)** | Anthropic Claude API (claude-sonnet-4-6) | | **AI (本地 Hook)** | Anthropic Messages API (默认 `claude-haiku-4-5`,可通过 `SCAMANAGER_REVIEW_MODEL` 覆盖) | | **静态分析** | **Tier1 25 工具** — pylint · flake8 · bandit (Python) + Semgrep (22+) + ESLint + ShellCheck + cppcheck + slither + RuboCop + golangci-lint + 另外 15 个 (hadolint · ktlint · tflint · tsc · sqlfluff · yamllint · phpstan · swiftlint · stylelint · htmlhint · buf_lint · dart_analyze · psscriptanalyzer · dotnet_format · clippy) — 参见 [docs/reference/language-coverage.md](docs/reference/language-coverage.md) | | **测试** | pytest · pytest-asyncio · httpx TestClient | | **E2E 测试** | Playwright (Chromium) | | **Web UI** | Jinja2 · Chart.js · CSS 变量 (4 种主题) | | **通知** | Telegram · GitHub · Discord · Slack · Email · n8n · Webhook | | **部署** | Railway / 本地部署 (systemd · nginx · Docker Compose) | ## 🚀 快速开始 ### 📋 前置条件 - Python **3.12** 或更高版本 - PostgreSQL - GitHub OAuth App (Client ID / Client Secret) - (可选) Telegram Bot Token · SMTP 服务器 · ANTHROPIC_API_KEY ### ⬇️ 安装 ``` git clone https://github.com/xzawed/SCAManager.git cd SCAManager # 开发环境 — 一步完成 pip + npm(包含 pytest 和 Tailwind toolchain) make install # 🔴 每次全新 clone 后需运行一次:Tailwind bundle 是 build artifact 且被 gitignored, # 而 base.html 链接了 /static/css/dist/tailwind.css — 跳过此步骤将导致其返回 404。 # (在 Railway 上,相同的 build 在 railway.toml `buildCommand` 内运行。) make css-build # 🔴 Local guard hooks — .pre-commit-config.yaml 中的每个 hook(secret scan、docs-number parity、 # architecture-tree sync、config-layer sync 等)仅通过 pre-commit 运行。跳过此步骤, # guards 将在新机器上静默缺失;commits 仍会成功。需要两种 hook 类型 # (commit-msg 是一个单独的 stage)。详情:docs/runbooks/secret-prevention.md python -m pip install pre-commit python -m pre_commit install --hook-type pre-commit --hook-type commit-msg # 仅 Python deps(production image / 无 Node.js 可用) pip install -r requirements.txt # runtime pip install -r requirements-dev.txt # + pytest · Playwright ``` ### ⚙️ 环境变量 ``` cp .env.example .env ``` **必填项** | 变量 | 描述 | |----------|-------------| | `DATABASE_URL` | PostgreSQL 连接 URL (`postgres://` 会自动转换为 `postgresql://`) | | `TELEGRAM_BOT_TOKEN` | Telegram Bot API token | | `TELEGRAM_CHAT_ID` | 默认通知 Chat ID | | `GITHUB_CLIENT_ID` | GitHub OAuth App Client ID | | `GITHUB_CLIENT_SECRET` | GitHub OAuth App Client Secret | | `SESSION_SECRET` | Session cookie 签名密钥(**32 个以上的随机字符,必填**) | **推荐** | 变量 | 描述 | |----------|-------------| | `APP_BASE_URL` | 部署 URL (`https://your-app.railway.app`) — 应用于 OAuth 重定向 URI 和 Webhook URL | | `ANTHROPIC_API_KEY` | Claude AI review 密钥(如果省略,将应用中性默认值) | **可选** | 变量 | 描述 | |----------|-------------| | `API_KEY` | REST API 认证密钥 (X-API-Key 标头) | | `GITHUB_TOKEN` | 用于旧版仓库的 GitHub API token | | `GITHUB_WEBHOOK_SECRET` | 用于旧版仓库的 Webhook 密钥 | | `SMTP_HOST` / `SMTP_PORT` / `SMTP_USER` / `SMTP_PASS` | Email 通知 SMTP 设置 | | `DATABASE_URL_FALLBACK` | 用于故障转移的备选数据库 URL(如果未设置,则为单引擎模式) | | `DB_FAILOVER_PROBE_INTERVAL` | 主数据库恢复检查间隔(以秒为单位,默认为 30) | | `DATABASE_URL_WORKER` | 用于 RLS 角色分离选项 A 的仅后台数据库 URL(如果未设置,则重用 `DATABASE_URL` — 必须是具有 BYPASSRLS 权限的 worker 角色凭证) | | `DB_SSLMODE` | PostgreSQL SSL 模式 (`require` / `disable`) | | `DB_FORCE_IPV4` | 强制 IPv4 连接 (`true` — Railway 环境) | ### ▶️ 运行 ``` # Development server(自动运行 DB migration) uvicorn src.main:app --reload --port 8000 # 或通过 Make make run ``` ## 🧪 开发命令 ``` make install # Install dependencies (pip + npm) make test # Full test suite (compact output) make test-v # Full test suite (verbose output) make test-fast # Fast unit tests only (excludes tests/integration/, -m "not slow") make test-slow # Integration tests only (tests/integration/ — real subprocess) make test-file f=tests/path/test.py # Single file test make test-local # Windows-friendly — excludes slow subprocess tests, short tracebacks make test-perf # Perf marker tests (e2e/ -m perf, separate from test-e2e) make test-isolated # Isolated test run (stashes .env, unsets credentials) make test-cov # Tests + coverage report make lint # pylint + flake8 + bandit make lint-strict # pylint regression guard (fail if score < 9.90) make lint-js # ESLint on src/templates/**/*.html inline scripts make css-build # Build Tailwind v4 CSS (production minified) make css-dev # Watch and rebuild Tailwind v4 CSS (dev mode) make gate # Full phase gate — tests + lint in one command make review # CLI code review (HEAD~1) make run # Development server (port 8000) make migrate # Run DB migrations make revision m="desc" # Create new migration file make install-playwright # Install Playwright + Chromium make test-e2e # E2E tests (headless) make test-e2e-headed # E2E tests (with browser) make perf-report # Generate performance report (local + production) ``` ## 🌐 URL 路由 ``` /login → 🔑 GitHub OAuth login /repos/add → ➕ Add repository / → 📊 Repository overview dashboard /dashboard → 📈 KPI dashboard (avg score / security HIGH / auto-merge rate) /repos/{owner/repo} → 📈 Score history + analysis log /repos/{owner/repo}/analyses/{id} → 🔍 Analysis detail (AI review · feedback) /repos/{owner/repo}/settings → ⚙️ Gate · notifications · Hook settings ``` ## 📡 API Endpoints
展开完整的端点列表 **认证 (OAuth)** ``` GET /login 301 redirect → /auth/github (backward-compatible) GET /auth/github Start GitHub OAuth GET /auth/callback GitHub OAuth callback POST /auth/logout Logout ``` **Web Dashboard** ``` GET / Repository list GET /dashboard KPI dashboard (avg score / security / auto-merge rate) GET /repos/add Add repository page GET /repos/{repo} Repo detail (chart + history) GET /repos/{repo}/analyses/{id} Analysis detail GET /repos/{repo}/settings Settings page GET /insights 301 → /dashboard (deprecated) GET /insights/me 301 → /dashboard (deprecated) POST /repos/add Register repo + auto-create Webhook + Hook files POST /repos/{repo}/settings Save settings POST /repos/{repo}/reinstall-hook Re-commit CLI Hook files POST /repos/{repo}/reinstall-webhook Re-register Webhook POST /repos/{repo}/delete Delete repo (including Webhook + history) ``` **Webhook 接收器** ``` POST /webhooks/github GitHub Webhook (HMAC-SHA256 verified) POST /api/webhook/telegram Telegram Gate callback (HMAC auth) POST /webhooks/railway/{token} Railway deploy event (token auth) ``` **REST API** (需要 X-API-Key 标头 — fail-closed:如果未设置 `API_KEY`,除非为本地开发设置了 `API_AUTH_DISABLED=1`,否则每个请求都会收到 `503`) ``` GET /api/repos Repository list GET /api/repos/{repo}/analyses Analysis history (skip · limit pagination) PUT /api/repos/{repo}/config Update repo settings DELETE /api/repos/{repo} Delete repo (API mode — manual Webhook removal) GET /api/repos/{repo}/stats Score statistics · trends GET /api/analyses/{id} Analysis detail ``` **CLI Hook** (hook_token 认证) ``` GET /api/hook/verify Verify hook registration POST /api/hook/result Save code review result ``` **用户 API** (需要 OAuth session) ``` POST /api/users/me/telegram-otp Issue 8-digit OTP for Telegram /connect linking ``` **内部 Cron** (需要 INTERNAL_CRON_API_KEY) ``` POST /api/internal/cron/weekly Trigger weekly Telegram summary report POST /api/internal/cron/trend Trigger trend alert check (7-day moving avg) POST /api/internal/cron/scan-security Trigger GitHub Code/Secret Scanning alert poll POST /api/internal/cron/retry-pending-merges Trigger CI-aware auto-merge retry queue processing POST /api/internal/cron/sweep-orphans Surface & purge orphaned analysis_attempts (loss detection) POST /api/internal/cron/retention-sweep GC expired insight cache + terminal merge-retry rows ``` **健康检查** ``` GET /health {"status":"ok"} ```
## 🏗️ 架构 ``` GitHub Push/PR └─ POST /webhooks/github (HMAC-SHA256 verified, per-repo secret TTL-cached) └─ BackgroundTask: run_analysis_pipeline() ├─ Register repo in DB · SHA dedup check (idempotency) ├─ get_pr_files / get_push_files │ ├─ asyncio.gather() ── parallel execution │ ├─ analyze_file() × N (pylint · flake8 · bandit · semgrep · eslint · shellcheck · cppcheck · slither · rubocop · golangci-lint) │ └─ review_code() (Claude AI — 49-language checklists, token budget 8000) │ ├─ calculate_score() → score · grade ├─ Save Analysis to DB │ ├─ run_gate_check() [PR events only] │ ├─ pr_review_comment → GitHub PR comment │ ├─ approve_mode=auto → GitHub APPROVE / REQUEST_CHANGES │ ├─ approve_mode=semi → Telegram inline keyboard │ └─ auto_merge → squash merge │ └─ asyncio.gather(return_exceptions=True) ── independent notifications ├─ Telegram ├─ GitHub Commit Comment [push + commit_comment=on] ├─ GitHub Issue [score < threshold or bandit HIGH] ├─ Discord ├─ Slack ├─ Generic Webhook ├─ Email └─ n8n ``` ## ☁️ 部署 ### 🚂 Railway 1. 创建一个 Railway 项目并连接此仓库 2. 添加 **PostgreSQL 插件** (`DATABASE_URL` 会自动生成) 3. 在 **Variables** 标签页中设置环境变量 ``` TELEGRAM_BOT_TOKEN = TELEGRAM_CHAT_ID = GITHUB_CLIENT_ID = GITHUB_CLIENT_SECRET = SESSION_SECRET = APP_BASE_URL = https://your-app.up.railway.app ← required! ANTHROPIC_API_KEY = sk-ant-... ← recommended ``` 4. 部署 — 数据库迁移会在应用启动时自动运行 (lifespan) ### 🖥️ 本地部署 ``` # 基本启动命令(--proxy-headers:信任 reverse proxy IP) uvicorn src.main:app --host 0.0.0.0 --port 8000 --proxy-headers ``` **数据库故障转移** — 将 `DATABASE_URL_FALLBACK` 设置为备选数据库 URL,以便在主库发生故障时自动进行故障转移。无论哪个数据库处于活动状态,`/health` 端点都会返回 `{"status": "ok"}`。 有关详细信息,请参阅[本地部署迁移指南](docs/guides/onpremise-migration-guide.md)。 ## 🔧 GitHub OAuth App 设置 1. **GitHub → Settings → Developer settings → OAuth Apps → New OAuth App** 2. 填写字段: | 字段 | 值 | |-------|-------| | Application name | SCAManager | | Homepage URL | `https://your-domain` | | Authorization callback URL | `https://your-domain/auth/callback` | 3. 将 **Client ID** 和 **Client Secret** 设置为环境变量 ## ➕ 添加仓库 1. 登录 → dashboard → 点击 **+ Add Repo** 2. 从 GitHub 下拉菜单中选择仓库 3. 点击 **Create Webhook + Add Repo** - 自动创建 GitHub Webhook(带有 HMAC 密钥) - 自动提交 `.scamanager/config.json` 和 `install-hook.sh` 4. 在下次 Push 或 PR 时自动开始分析 ✅ ### Webhook URL 更改(例如:迁移部署 URL 后) **Settings → CLI Hook 卡片 → 🔗 Re-register Webhook** Webhook 将基于当前的 `APP_BASE_URL` 重新创建。 ### 安装 CLI Hook (本地 pre-push) ``` git pull bash .scamanager/install-hook.sh # 自动 code review 在随后的每次 git push 时运行 ``` ## 💻 GitHub Codespaces ``` # 容器启动后立即可用(无需 .env — 使用 SQLite 内存模式) make test # Full test suite make lint # Code quality check make run # Dev server (port 8000 auto-forwarded) # CLI code review(需要 ANTHROPIC_API_KEY) ANTHROPIC_API_KEY=sk-ant-... python -m src.cli review ``` ## 🤝 贡献 欢迎提交 Issue 和 pull request。从 **[CONTRIBUTING.md](CONTRIBUTING.md)** ([한국어](CONTRIBUTING.ko.md)) 开始 — 它涵盖了本仓库实际需要的本地设置(Tailwind 构建和两个 pre-commit hook 阶段很容易被忽略)、如何运行测试套件、分支和提交规范以及 PR 清单。 三件容易让首次贡献者踩坑的事情: | 陷阱 | 为什么重要 | |--------|----------------| | 在全新克隆后运行 `make css-build` | Tailwind bundle 是被 gitignore 的构建产物;跳过它会导致 `base.html` 为其样式表返回 404 | | `pre-commit install --hook-type pre-commit --hook-type commit-msg` | 每个本地检查(密钥扫描、文档数量一致性、架构树同步、配置层同步)**仅**通过 pre-commit 运行。跳过它提交仍然会成功 — 默默地失去保护 | | 双语代码注释 | 新的注释以韩语编写,下一行是英语。这是一项约定,而非强制执行的 hook。参见 [CONTRIBUTING.md § 代码注释](CONTRIBUTING.md#code-comments-bilingual) | ## 🔐 安全 请**不要为安全漏洞公开提交 issue。**请改用 [GitHub 的私人漏洞报告](https://github.com/xzawed/SCAManager/security/advisories/new) 。完整的政策 — 受支持的版本、范围、响应目标,以及离开你部署环境的准确数据列表 — 包含在 **[SECURITY.md](SECURITY.md)** ([한국어](SECURITY.ko.md)) 中。 SCAManager 会处理你的源代码,因此明确出口流量是值得的:自托管运行可将 pipeline、数据库和 dashboard 保留在你的基础设施上,但 AI review 会将 diff 发送到 Anthropic API,并且你启用的每个通知渠道都会将分析输出发送到该渠道的提供商。 [SECURITY.md § 代码去向](SECURITY.md#where-your-code-goes) 列出了每个目的地以及如何禁用它。 ## 📄 许可证 [MIT License](LICENSE) © 2026 xzawed
标签:AI代码审查, GitHub集成, 云安全监控, 安全专业人员, 测试用例, 特征检测, 跨平台, 逆向工具, 静态分析