banshee86vr/snorlx

GitHub: banshee86vr/snorlx

一款自托管的 GitHub Actions CI/CD 仪表盘,提供跨仓库与组织的流水线可视化、成本追踪及代码质量评分。

Stars: 26 | Forks: 4

# Snorlx - GitHub Actions 的 CI/CD 仪表盘 [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/banshee86vr/snorlx/actions/workflows/ci.yml) [![安全扫描](https://github.com/banshee86vr/snorlx/actions/workflows/security.yml/badge.svg)](https://github.com/banshee86vr/snorlx/actions/workflows/security.yml) 一个全面的、自托管的仪表盘,提供针对分布在多个仓库和组织中的 GitHub Actions 流水线、性能指标和成本的集中可视化。 ![仪表盘预览](https://raw.githubusercontent.com/banshee86vr/snorlx/main/docs/preview.png) ## 功能 - **集中可视化**:跨所有仓库的工作流运行的单一视图 - **仓库评分**:根据安全性、测试、CI/CD、文档、代码质量、维护和社区等维度,将仓库评为金/银/铜等级 - **实时更新**:通过 WebSocket 获取实时流水线状态 - **GitHub OAuth**:使用 GitHub 登录;无需设置 GitHub App - **成本追踪**:针对单个工作流和单个仓库的成本分析 - **多仓库支持**:监控跨多个仓库和组织的各项流水线 - **美观的 UI**:现代、响应式的设计,支持深色/浅色模式 - **两种存储模式**:可使用内存模式快速启动,或使用 PostgreSQL 数据库实现持久化 ## 架构 ![架构图](https://raw.githubusercontent.com/banshee86vr/snorlx/main/docs/architecture.jpg) ## 快速开始 ### ⚡ TL;DR - 5 分钟内开始运行 **无数据库(内存模式):** ``` # 克隆并安装 git clone https://github.com/banshee86vr/snorlx.git && cd snorlx && pnpm install # 配置(使用你的 GitHub 凭据编辑 .env) cp env.example .env # 在 .env 中设置 STORAGE_MODE=memory(默认) # 同时启动 frontend 和 backend pnpm run dev ``` **使用 PostgreSQL 数据库:** ``` # 克隆并安装 git clone https://github.com/banshee86vr/snorlx.git && cd snorlx && pnpm install # 启动 PostgreSQL (Docker) docker run --name snorlx-postgres \ -e POSTGRES_DB=snorlx \ -e POSTGRES_USER=postgres \ -e POSTGRES_PASSWORD=postgres \ -p 5432:5432 -d timescale/timescaledb:latest-pg16 # 配置(使用你的凭据和 DATABASE_URL 编辑 .env) cp env.example .env # 在 .env 中设置 STORAGE_MODE=database 和 DATABASE_URL # 同时启动 frontend 和 backend pnpm run dev ``` 访问地址:http://localhost:5173 ### 前置条件 - Go 1.26+ - Node.js 20+ - pnpm 或 npm - 带有 TimescaleDB 的 PostgreSQL 14+(可选 - 仅用于数据库模式) - GitHub OAuth App(请参阅[设置指南](#github-oauth-app-setup)) ## 🚀 本地开发(无需 Docker) ### 选项 1:内存模式(无数据库) **非常适合测试和开发!** 几分钟即可启动,无需配置数据库。 1. **克隆并安装依赖** ``` git clone https://github.com/banshee86vr/snorlx.git cd snorlx pnpm install ``` 2. **配置环境变量** ``` # 复制示例环境文件 cp env.example .env ``` 编辑 `.env` 并填入你的凭证: ``` # 开发模式(跳过 GitHub OAuth 验证) DEV_MODE=true # Storage Mode - 使用 memory 以便快速开始(无需数据库) STORAGE_MODE=memory # GitHub OAuth(创建地址:https://github.com/settings/developers) GITHUB_CLIENT_ID=your_oauth_client_id GITHUB_CLIENT_SECRET=your_oauth_client_secret # Session Security(生成命令:openssl rand -base64 32) SESSION_SECRET=your_random_32_character_secret_string # URLs PORT=8080 FRONTEND_URL=http://localhost:5173 ``` 3. **启动应用** ``` # 从项目根目录 - 同时启动 frontend 和 backend pnpm run dev ``` 应用将会启动: - Frontend: http://localhost:5173 - Backend API: http://localhost:8080 **或者分别启动:** ``` # 仅 backend pnpm run dev:backend # 仅 frontend(在另一个终端) pnpm run dev:frontend ``` ### 选项 2:数据库模式(持久化存储) 适用于在生产环境中进行持久化数据存储。 #### 步骤 1:安装依赖 ``` git clone https://github.com/banshee86vr/snorlx.git cd snorlx pnpm install ``` #### 步骤 2:配置 PostgreSQL + TimescaleDB **使用 Docker(推荐)** ``` docker run --name snorlx-postgres \ -e POSTGRES_DB=snorlx \ -e POSTGRES_USER=postgres \ -e POSTGRES_PASSWORD=postgres \ -p 5432:5432 \ -d timescale/timescaledb:latest-pg16 ``` **使用本地 PostgreSQL(macOS 配合 Homebrew)** ``` # 安装 TimescaleDB brew install postgresql@16 timescaledb # 启动 PostgreSQL brew services start postgresql@16 # 创建数据库 psql postgres -c "CREATE DATABASE snorlx;" ``` #### 步骤 3:配置环境变量 ``` cp env.example .env ``` 编辑 `.env`: ``` # 开发模式 DEV_MODE=true # Storage Mode - 使用 database 实现持久化 STORAGE_MODE=database DATABASE_URL=postgresql://postgres:postgres@localhost:5432/snorlx?sslmode=disable # GitHub 配置 GITHUB_CLIENT_ID=your_oauth_client_id GITHUB_CLIENT_SECRET=your_oauth_client_secret # Session Security SESSION_SECRET=your_random_32_character_secret_string # URLs PORT=8080 FRONTEND_URL=http://localhost:5173 ``` #### 步骤 4:启动应用 ``` # 从项目根目录 - 同时启动 frontend 和 backend # Migrations 在 backend 启动时自动运行 pnpm run dev ``` 访问地址:http://localhost:5173 ## 🐳 Docker Compose 设置 适用于将所有服务容器化的生产环境部署。 1. **配置环境变量** ``` cp env.example .env # 使用你的生产环境设置编辑 .env # 确保为 Docker 设置 STORAGE_MODE=database ``` 2. **启动所有服务** ``` docker compose up -d ``` 仪表盘将通过 http://localhost:5174 (frontend) 和 http://localhost:3001 (backend API) 提供。 3. **查看日志** ``` docker compose logs -f ``` 4. **停止服务** ``` docker compose down ``` ## 仓库评分 系统会基于七个类别的检查,为仓库提供一个总体百分比和等级(金 / 银 / 铜)进行评分: | 类别 | 权重 | 示例 | | ---------- | ---- | -------------------------------------- | | 安全性 | 25% | 分支保护、Dependabot、代码扫描 | | 测试 | 20% | 测试配置、覆盖率、CI 测试任务 | | CI/CD | 15% | 工作流、部署、状态检查 | | 文档 | 15% | README、CONTRIBUTING、Issue 模板 | | 代码质量 | 10% | 代码检查工具、代码所有者 | | 维护 | 10% | 近期活跃度、描述 | | 社区 | 5% | 社区健康文件 | 同步一个仓库,并在其详情页使用 **刷新等级** 来计算或更新其分数。仪表盘摘要将显示所有仓库的平均分。 ## GitHub OAuth App 设置 本项目使用 GitHub OAuth App 进行用户身份验证(比 GitHub App 更简单)。 ### 步骤 1:创建 OAuth App 1. 前往 [GitHub Developer Settings](https://github.com/settings/developers) 2. 点击 **OAuth Apps** → **New OAuth App** 3. 填写详细信息: - **Application name**:`Snorlx Dashboard`(或你偏好的名称) - **Homepage URL**:`http://localhost:5173`(或你的生产环境 URL) - **Authorization callback URL**:`http://localhost:8080/api/auth/callback` 4. 点击 **Register application** ### 步骤 2:获取凭证 1. 复制 **Client ID** 2. 点击 **Generate a new client secret** 并复制它 ### 步骤 3:配置环境变量 将其添加到你的 `.env` 文件中: ``` GITHUB_CLIENT_ID=your_client_id_here GITHUB_CLIENT_SECRET=your_client_secret_here ``` ### OAuth 作用域 应用会请求以下 OAuth 作用域: - `read:user` - 读取用户个人资料信息 - `user:email` - 访问用户邮箱地址 - `repo` - 访问仓库(用于获取工作流数据) - `read:org` - 读取组织成员身份 ### 可选:Webhooks 要通过 webhook 获取实时更新,请在你的仓库/组织设置中配置 webhook: 1. 前往 Repository → Settings → Webhooks → Add webhook 2. **Payload URL**:`https://your-domain.com/api/webhooks/github` 3. **Content type**:`application/json` 4. **Secret**:生成一个安全的密钥,并作为 `GITHUB_WEBHOOK_SECRET` 添加到 `.env` 中 5. 选择事件:`Workflow runs`、`Workflow jobs`、`Deployments` ## 配置说明 ### 环境变量 #### 存储配置 | 变量 | 必填 | 默认值 | 描述 | | ------------------- | ---------------------- | -------- | -------------------------------------------- | | `STORAGE_MODE` | 否 | `memory` | `memory` 或 `database` | | `DATABASE_URL` | 仅在 `database` 模式下 | - | PostgreSQL 连接字符串 | | `POSTGRES_PASSWORD` | 仅在 `database` 模式下 | - | PostgreSQL 密码(由 Docker Compose 使用) | #### 服务器配置 | 变量 | 描述 | 默认值 | | ---------------- | -------------------------------------- | ----------------------- | | `PORT` | 服务器端口 | `8080` | | `LOG_LEVEL` | 日志级别(debug, info, warn, error) | `info` | | `SESSION_SECRET` | 会话加密密钥 | 必填 | | `FRONTEND_URL` | 用于 CORS 的前端 URL | `http://localhost:5173` | | `VITE_API_URL` | 前端使用的后端 API URL | `http://localhost:8080` | #### GitHub OAuth 配置 | 变量 | 描述 | 必填 | | ---------------------- | -------------------------- | ---------------------- | | `GITHUB_CLIENT_ID` | GitHub OAuth App Client ID | 是 | | `GITHUB_CLIENT_SECRET` | GitHub OAuth App Client Secret | 是 | | `GITHUB_WEBHOOK_SECRET` | Webhook 签名密钥 | 否(仅用于 webhook) | | `DEV_MODE` | 跳过 GitHub OAuth 验证 | 否 | #### 同步配置 | 变量 | 必填 | 默认值 | 描述 | | ------------ | ---- | ----------- | ----------------------------------- | | `SYNC_LIMIT` | 否 | `0`(全部) | 限制同步的仓库数量 | | `SYNC_REPOS` | 否 | - | 以逗号分隔的指定要同步的仓库列表 | ## API 端点 ### 健康检查 - `GET /health` - 健康检查端点 ### 身份验证 - `GET /api/auth/login` - 发起 GitHub OAuth - `GET /api/auth/callback` - OAuth 回调 - `POST /api/auth/logout` - 退出登录 - `GET /api/auth/status` - 检查认证状态 ### 组织 - `GET /api/organizations` - 列出所有组织 - `GET /api/organizations/:id` - 获取组织详情 ### 仓库 - `GET /api/repositories` - 列出所有仓库 - `GET /api/repositories/:id` - 获取仓库详情 - `GET /api/repositories/scores` - 列出最新的仓库评分(所有仓库) - `GET /api/repositories/:id/score` - 获取某个仓库的最新评分 - `POST /api/repositories/sync` - 触发仓库同步 ### 工作流 - `GET /api/workflows` - 列出所有工作流 - `GET /api/workflows/:id` - 获取工作流详情 - `PATCH /api/workflows/:id` - 更新工作流 - `GET /api/workflows/:id/runs` - 获取工作流运行记录 ### 运行记录 - `GET /api/runs` - 列出所有运行记录(支持过滤) - `GET /api/runs/:id` - 获取运行详情 - `GET /api/runs/:id/jobs` - 获取运行的任务 - `GET /api/runs/:id/logs` - 获取运行的日志 - `GET /api/runs/:id/annotations` - 获取运行的注解 - `GET /api/runs/:id/workflow-definition` - 获取工作流的 YAML 定义 - `POST /api/runs/:id/rerun` - 重新运行工作流 - `POST /api/runs/:id/cancel` - 取消正在运行的工作流 ### 任务 - `GET /api/jobs/:id/logs` - 获取任务日志 ### 仪表盘 - `GET /api/dashboard/summary` - 获取仪表盘摘要 - `GET /api/dashboard/trends` - 获取趋势数据 ### 实时更新 - `GET /ws` - 用于实时更新的 WebSocket 端点 ### Webhooks - `POST /api/webhooks/github` - GitHub webhook 接收器 ## 项目结构 ``` ├── .github/workflows/ # CI and Security GitHub Actions ├── frontend/ # React frontend │ ├── src/ │ │ ├── components/ # UI components (layout, protected routes) │ │ ├── context/ # React contexts (auth, theme, socket, sync, sidebar) │ │ ├── lib/ # Utility functions │ │ ├── pages/ # Page components │ │ ├── services/ # API client │ │ ├── styles/ # Global styles │ │ ├── test/ # Test setup │ │ └── types/ # TypeScript types │ └── ... ├── backend/ # Go backend │ ├── cmd/server/ # Main entry point │ ├── internal/ │ │ ├── config/ # Configuration │ │ ├── database/ # Database migrations and setup │ │ ├── github/ # GitHub client │ │ ├── handlers/ # HTTP handlers │ │ ├── models/ # Data models │ │ ├── scorer/ # Repository scoring (gold/silver/bronze) │ │ ├── storage/ # Storage layer (memory/database) │ │ └── websocket/ # WebSocket hub for real-time updates │ └── ... ├── helm/ # Kubernetes Helm charts └── docker-compose.yml # Docker configuration ``` ## 故障排除 ### 常见问题 **后端无法启动:需要 GitHub OAuth 凭证** - 在你的 `.env` 文件中设置 `DEV_MODE=true` 以便进行本地开发(将跳过 OAuth) - 或者从一个 [GitHub OAuth App](#github-oauth-app-setup) 提供 `GITHUB_CLIENT_ID` 和 `GITHUB_CLIENT_SECRET` **数据库连接错误** - 确认 PostgreSQL 正在运行:`psql -U postgres -d snorlx` - 检查 `.env` 中的 `DATABASE_URL` 是否与你的数据库凭证匹配 - 确保已安装 TimescaleDB 扩展 **端口已被占用 (EADDRINUSE)** - 后端 (8080) 或 前端 (5173) 端口已被占用 - 查找进程:`lsof -i :8080` 或 `lsof -i :5173` - 终止进程:`kill -9 ` - 或者在 `.env` 中更改端口 **内存模式数据丢失** - 这是正常的!内存模式在重启之间不会持久化数据 - 使用 `STORAGE_MODE=database` 进行持久化存储 **“Too many requests” 错误** - 触发了速率限制。请稍后重试 - 在生产环境中,这可以防止滥用 ## CI/CD 本项目包含两个 GitHub Actions 工作流: ### CI (`ci.yml`) 在向 `main` 分支推送代码和提交 Pull Request 时运行: - **后端**:Go vet、带有竞态检测和覆盖率的测试、二进制构建 - **前端**:Lint、带有覆盖率的测试、生产环境构建 ### 安全 (`security.yml`) 在向 `main` 分支推送代码、提交 Pull Request 以及每周(UTC 时间周一 08:00)运行: - **CodeQL 分析**:针对 Go 和 JavaScript/TypeScript 的静态分析 - **Trivy 扫描**:文件系统漏洞扫描,以及对后端和前端的 Docker 镜像扫描 - **依赖审查**:在 PR 上标记新引入的易受攻击的依赖项 - **Go 安全**:针对 Go 特定漏洞执行 govulncheck 和sec - **npm Audit**:检查 Node 包中已知的漏洞 ## 12-Factor App 合规性 本应用遵循 [12-Factor 方法论](https://12factor.net/): 1. **代码库**:在 Git 中跟踪的单一仓库 2. **依赖项**:在 `go.mod` 和 `package.json` 中明确声明 3. **配置**:使用环境变量进行所有配置 4. **后端服务**:通过 URL 将数据库视为附加资源 5. **构建、发布、运行**:带有语义化版本控制的 Docker 镜像 6. **进程**:无状态;会话存储在 storage 中 7. **端口绑定**:自包含的 HTTP 服务器 8. **并发**:通过副本进行水平扩展 9. **易处理**:在收到 SIGTERM 信号时优雅关闭 10. **开发/生产环境一致性**:Docker Compose 映射生产环境 11. **日志**:JSON 格式输出到 stdout,由平台收集 12. **管理进程**:迁移作为启动过程的一部分运行 ## 许可证 MIT License - 详情请参阅 [LICENSE](LICENSE)。
标签:EVTX分析, GitHub Actions, MITM代理, 成本分析, 日志审计, 测试用例, 监控面板, 自动笔记, 请求拦截