# committer_app **Repository Path**: stavewu/committer_app ## Basic Information - **Project Name**: committer_app - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-10-21 - **Last Updated**: 2026-10-22 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # committer_app — openEuler Kernel Committer 维护平台(Next.js 版) 将 committer_web(Flask 版)的完整需求移植到 **Next.js 15** 技术栈, 支持在**腾讯云 EdgeOne Pages** 一键部署(也可自托管 `next start`)。 - **数据源**:`hulk-robot/hulk_robot_test` 的 `openEuler/conf/committers.json` (约 4200 个配置节点)、`openeuler/community` 的 `sig/Kernel/sig-info.yaml` (已登记 committer 名单)、内核文件清单(可选,约 11 万条路径)。 - **产出**:审批通过后生成 2 个 PR — 1. `hulk-robot/hulk_robot_test`:更新 `committers.json`(标题 `conf: update committers`); 2. `openeuler/community`:仅当涉及未登记的新 committer 时,在 `sig/Kernel/sig-info.yaml` 的 kernel 块 committers 列表末尾插入条目(最小 diff)。 - PR 仍走社区既有评审流程,平台不自动合入。 ## 功能(与 Flask 版一致) | 页面 | 说明 | | --- | --- | | `/` 预览 | 全部内核文件 × 三列:文件路径 / committer(主责)/ fallback 责任链(`zqiao216 → oekernel`,逐级兜底) | | `/` 查询 | 按路径查责任链与最近配置祖先;按 committer 查显式配置节点、主责/兜底覆盖文件数及文件列表 | | `/` 提交改动 | 路径购物车式编辑:增删 committer、设 UNMAINTAINED、清除配置(继承);未知 id 需补姓名/邮箱(sig-info 登记用) | | `/` 改动记录 | 所有请求的状态与 PR 链接(公开可查) | | `/admin` | 密码登录 → 待审批列表 → 详情(逐路径 before→after、与最新上游的实时对比、覆盖文件数、冲突预警)→ 批准/驳回/重试/删除;dry-run 产物在线查看/下载 | 改动采用**最终态模型**:提交 `{path, owners_after}`,审批时对比**当时**上游 master 的实际状态应用(抗提交到审批之间的漂移);全部路径均无实际变化时会报错而非生成空 PR。 ## 与 Flask 版的实现差异(语义不变) | 原版(Flask) | 本版(Next.js) | | --- | --- | | 本地 git clone + push(依赖 git 二进制) | 纯 GitCode REST API:fork 同步 → 建分支 → API 提交 → 建 PR → 交叉链接(无 git 依赖,适配 serverless) | | 后台线程定时刷新数据 | TTL + stale-while-revalidate:过期后第一个请求触发后台刷新,单飞防并发 | | 决策后后台线程生成 PR,前端轮询 | 决策接口内同步生成(整体 50s 预算,EdgeOne Node Function 上限经 edgeone.json 调至 60s),期间状态为 generating 供前端轮询 | | SQLite 单文件 | 三后端:自托管 SQLite(node:sqlite,Node ≥ 22.5)/ EdgeOne KV / EdgeOne Pages Blob(备用) | | Flask session | 无状态 HMAC 签名 Cookie(7 天) | | dry-run 产物写磁盘目录 | 产物入库(SQLite 表 / KV / Blob 键),管理端在线查看报告 + 下载 | ## 本地开发(SQLite 后端) ```bash npm install cp .env.example .env.local # 填 ADMIN_PASSWORD 等 npm run dev # http://127.0.0.1:3000 管理端 /admin ``` 首次启动会拉取上游 committers.json / sig-info.yaml(无 token 也可读公共仓), 未配置 `FILELIST_URL` 时预览自动降级为"仅已配置节点"模式并在页面提示。 数据缓存于 `data/`(已 gitignore)。 ### 单元测试 ```bash npm test ``` `tests/` 是原 Python 测试套件的完整移植:fallback 链语义(UNMAINTAINED 弹出、 同层去重)、最终态编辑、`json.dumps(indent=4)` 字节级一致、sig-info 定位/插入 最小 diff。本机存在 `/Volumes/Coding/hulk_robot_test` 与 `/Volumes/Coding/community` 真实数据时会额外执行逐例对照(否则自动跳过)。 ## 部署到腾讯云 EdgeOne Pages 1. **推送代码到 Git 仓库**(GitCode / GitHub / Gitee 均可),仓库根目录即本项目。 2. **创建 Pages 项目**:控制台选择 "导入 Git 仓库",框架自动识别为 Next.js (Node.js 选 22.x,构建命令 `npm run build`,已在 `edgeone.json` 固化)。 3. **存储后端二选一**: - **EdgeOne KV**:Pages → KV 存储 → 创建命名空间 → 关联本项目, **绑定变量名必须为 `kv_store`**(与 `edge-functions/kvstore.js` 对应)。 - **EdgeOne Pages Blob(备用,KV 申请失败时)**:环境变量显式设置 `STORE_BACKEND=blob` 即可。无需 KV 命名空间与 edge function 代理, `@edgeone/pages-blob` SDK 在部署内自动鉴权(构建时注入部署凭证); 可选配置 `BLOB_STORE_NAME`(命名空间,缺省 `committer-app`,首次使用 自动创建)。若初始化报 Missing deployCredential,改配 API Token 模式: `BLOB_PROJECT_ID` + `BLOB_TOKEN`(成对出现)。免费版单账户 1GB 配额, 本项目当前数据量约数 MB 级,充裕。 4. **配置环境变量**(生产环境): | 变量 | 必需 | 说明 | | --- | --- | --- | | `GITCODE_TOKEN` | ✅ | GitCode token(建分支/提交/PR) | | `ADMIN_PASSWORD` | ✅ | 管理端密码 | | `KV_PROXY_SECRET` | KV 时✅ | 随机长串(Node 侧 ↔ KV 代理的共享密钥) | | `STORE_BACKEND` | blob 时✅ | 显式设 `blob` 启用 Blob 备用后端 | | `BLOB_STORE_NAME` | | Blob 命名空间(缺省 `committer-app`,自动创建) | | `BLOB_PROJECT_ID` / `BLOB_TOKEN` | | Blob API Token 模式(函数外访问/凭证未注入时成对配置) | | `SECRET_KEY` | 建议 | 会话签名密钥(随机长串) | | `FORK_OWNER` | | PR 使用的 fork 账号(默认 stavewu,须已 fork 两个上游仓) | | `ADMIN_NAME` / `ADMIN_EMAIL` | | PR Signed-off-by | | `DRY_RUN` | | `true` = 只生成产物不实际建 PR | | `FILELIST_REPO` / `FILELIST_PATH` | | 内核文件清单 GitCode 仓(见下节,优先) | | `FILELIST_URL` | | 内核文件清单 txt URL(见下节) | | `SITE_URL` | | 站点地址(如 https://xxx.edgeone.app;不配则取请求 origin) | 5. **部署**:控制台触发,或 CLI: ```bash npm i -g edgeone edgeone pages deploy ``` ### 部署架构 ``` 浏览器 ──> EdgeOne Pages ├─ Next.js(Node Functions,maxDuration=60s) │ ├─ 前台/管理端页面 + /api/**(全部业务逻辑) │ └─ 存储(三选一): │ ├─ SQLite(自托管,本地磁盘) │ ├─ EdgeOne KV:HTTP 回访同站 /kvstore(Bearer KV_PROXY_SECRET) │ └─ Blob(备用):@edgeone/pages-blob SDK 直连(部署内自动鉴权) ├─ edge-functions/kvstore.js(Edge Function:KV 代理;Blob 后端不需要) │ └─ EdgeOne KV(绑定变量 kv_store:请求记录/快照缓存/dry-run 产物) └─ 出网:GitCode API(读上游 + fork 同步/分支/提交/PR)、Pages Blob ``` - EdgeOne KV 只能在 Edge Functions 中访问,故由 `edge-functions/kvstore.js` 做同站代理;Edge Function 请求体上限 1MB,大值(committers.json ~1.3MB、 文件清单 ~2.5MB)由 Node 侧按 UTF-8 字节分片存储(`_c0..n` + `_m` 清单)。 - Blob 后端无上述限制:Node 直连(与 GitCode API 相同的出网路径),单对象 无 1MB 限制、大值整体读写不分片;对象布局 `req/.json`(请求行)、 `dryrun/.json`(产物)、`snapshot/`(快照缓存)。 - `edgeone.json`:`/api/*` 边缘缓存关闭(cacheTtl=0)、Node Functions 上限 60s。 ### 内核文件清单(FILELIST_REPO / FILELIST_URL) 原版从本地 kernel clone 的 4 个维护分支并集生成。serverless 下改为外部来源, 两种方式(`FILELIST_REPO` 优先): - `FILELIST_REPO`(GitCode 托管,推荐):`owner/repo` + `FILELIST_PATH`(默认 `filelist.txt`),走 contents API——匿名读取失败自动带 `GITCODE_TOKEN` 重试, **私有仓可读**。注意 `raw.gitcode.com` 拒绝匿名访问(403),GitCode raw URL 不能直接用作 `FILELIST_URL`。 - `FILELIST_URL`:任一**可公网匿名访问**的 txt(每行一个路径),如对象存储。 例如 CI 定期生成并提交到数据仓: ```bash git ls-tree -r --name-only origin/OLK-6.6 > filelist.txt # 单分支;多分支取并集后排序去重 ``` 两者均未配置时预览降级为"仅已配置节点",其余功能不受影响。 ### 一致性模型(EdgeOne) - KV 写入即时生效,但**全局读取最终一致**(官方 ≤60s);Node 侧另有 30s 进程内读缓存。多个边缘实例并发审批同一请求存在竞态窗口(与原单机版相比 的新增限制),实际使用为单管理员串行审批,风险可忽略。 - Blob 后端所有读操作带 `consistency: "strong"`(绕过边缘缓存直读主存), 跨实例决策状态即时可见,无 KV 的 ≤60s 全局窗口;但 Node 侧同样保留 30s 进程内行缓存,竞态窗口与 KV 一致(单管理员串行审批可忽略)。 - 数据快照每实例独立缓存 + TTL 刷新,管理端"立即刷新数据"为同步强制刷新。 ## 验证流程(dry-run) 上线前建议先以 `DRY_RUN=true` 走一遍完整链路: 1. 环境变量设 `DRY_RUN=true`; 2. 游客页提交一条测试改动(如为某目录添加一个测试 id,填入姓名/邮箱); 3. 管理端审批通过 — 状态变为"已通过"但不建 PR,详情页出现"查看 dry-run 产物"; 4. 在线核对 `committers.json` / `sig-info.yaml` / report(可下载后 diff), 应与手工流程结果一致; 5. 确认无误后改回 `DRY_RUN=false`。 ## 安全与防滥用 - 游客可编辑任意人是**需求本身**(管理员审批是安全兜底); - 提交频率限制(默认每 IP 5 次/小时)、待审批总量上限(默认 100)、payload ≤ 512KB; - 路径/ID 正则校验(`^[A-Za-z0-9_.+-]+$` / `^[A-Za-z0-9_][A-Za-z0-9_.-]{0,39}$`), 每请求 ≤50 路径、每路径 ≤10 owners; - 管理端密码登录(错误尝试限速 + 0.5s 延时),会话 7 天(HMAC 签名,无服务端状态); - KV 代理仅接受 `Bearer KV_PROXY_SECRET` 鉴权且 key 白名单字符校验; - 前端无外部 CDN 依赖(内网可用)。