news 2026/9/10 13:56:24

Novu 提交 PR 前的工程化自查指南:从特性分支到 Merge-Ready 的九步工作流

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Novu 提交 PR 前的工程化自查指南:从特性分支到 Merge-Ready 的九步工作流

Novu 提交 PR 前的工程化自查指南:从特性分支到 Merge-Ready 的九步工作流

【免费下载链接】novuThe open-source communication infrastructure for agents and products项目地址: https://gitcode.com/GitHub_Trending/no/novu

导读

在 Novu 开源 monorepo(工作区apps/libs/packages/enterprise/并存)中,一个功能分支从“代码写完”到“PR 可合并”,中间隔着质量审查、安全排查、本地验证、CI 排障与评审回复等一连串工程步骤。本文以仓库内 .cursor/skills/novu-prepare-pr/SKILL.md 描述的PR 准备(Prepare PR)工作流为主体,结合仓库真实的构建命令、PR 规范与安全代码样例,讲解如何在功能实现完成之后,系统化地完成范围校验、质量过检、提交规整、PR 创建与合并前检查。读完本文,你将掌握一套可直接套用在 Novu 代码库上的 PR 就绪流程,并理解其中每条检查项背后的仓库实现依据。


一、这套流程解决什么问题

Novu 的工程实践是“先实现、后提 PR”,而这套novu-prepare-prskill 正是用来衔接“实现完成”与“合并上线”的收尾工序。它只应在特性分支上功能实现已结束后运行,其边界约束很清晰(见 SKILL.md):

  • 不做重新规划、不扩大范围,除非 review 或 CI 暴露了真实的缺口;
  • 前置条件是功能代码已在一个分支上(仓库约定习惯使用cursor/<short-description>,从next分支切出);
  • 分支名能对应到 Linear 工单编号(nv-XXXX/NV-XXXX),或可根据工单推断编号。

整套流程收敛为一份可勾选的进度清单,共 9 步:

PR prep progress: - [ ] 1. Scope & diff sanity - [ ] 2. Quality passes - [ ] 3. Security check (if shared/multi-tenant) - [ ] 4. Local validation - [ ] 5. Commit hygiene - [ ] 6. Open or update PR - [ ] 7. CI triage & fix - [ ] 8. Review comments - [ ] 9. Merge-ready check

下文逐条拆解每一步的具体动作与仓库依据。


二、第 1 步:范围与 Diff 完整性核对

PR 准备的第一步是确认“这次要交付什么、有没有夹带无关改动”,使用三条基础命令:

git status # 查看工作区状态 git diff # 检查尚未暂存的改动 git log next..HEAD --oneline # 查看相对 next 分支的提交列表

操作要点:

  • 只暂存属于本工单(ticket)的文件,与工单无关的本地改动一律排除在 PR 之外;
  • 如果当前特性尚未发布(unreleased),除非用户明确要求,否则跳过向后兼容 shim 与死代码保留,避免把“过渡代码”带进新功能分支。

这一步保证了后续每一步(质量过检、CI、评审)只针对真正的变更面,这也是第 9 步“分支内无无关文件”检查得以成立的前提。


三、第 2 步:质量过检(Quality Passes)

当分支不是琐碎的小修时,按顺序执行两轮代码审查,它们都以 skill 形式存在于仓库的.cursor/skills/目录中:

  1. Thermo-nuclear code quality review:通读分支 diff,评估结构设计与可维护性,只做高价值重构,避免为了重构而重构;
  2. Deslop(去 AI 味):清理实现阶段常见的人工智能生成痕迹,包括冗余注释、防御性噪音代码、不必要的类型断言、重复测试等。

对于用户明确限定范围的小热修(tiny hotfix),这两轮可以跳过或大幅简化。判断标准始终是“改动面越小,过检成本越低”。


四、第 3 步:多租户安全排查(条件必做)

只要 PR 触及 API / Worker 相关代码以及 DAL 层,这一步就是强制项,因为 Novu 是典型的多租户(multi-tenant)通信基础设施——不同组织、不同环境的数据必须严格隔离。检查清单如下:

  • Mongo / API 查询必须以_organizationId/_environmentId限定作用域:这是租户隔离的第一道闸门。仓库中大量用例都在查询条件里显式写入这两个字段,例如 get-workflow-run.usecase.ts、get-workflow-runs.usecase.ts 都以环境 ID 收窄查询,agents 相关的集成增删改查(如 add-agent-integration.usecase.ts、remove-agent-integration.usecase.ts)同样如此;
  • 共享的上游密钥绝不能返回给客户端
  • 不存在把外部上游 ID 绑定到共享主密钥下的 adopt/link 路径;
  • 对共享/演示用上游 provider 的**破坏性操作(删除/归档)**要么被拦截、要么被跳过;
  • 配额与用量计数器按租户/环境(tenant/environment)分别计量。

一旦发现P0 级跨租户风险,必须在本轮就修复并补上 e2e 覆盖,之后才允许打开或更新 PR——这条红线不允许带病合并。


五、第 4 步:本地验证的最小充分集

验证原则是挑选能证明改动成立的最小检查项,而不是跑全套测试。SKILL 中给出的选择表如下:

改动类型命令
API / libs 类型错误pnpm --filter @novu/api-service build
Shared libs(触及packages/enterprise/pnpm build
新增/修改的 e2e 测试载入 run-api-e2e-tests 后运行对应测试文件

这两条命令与仓库真实脚本一一对应:在 apps/api/package.json 中,包名@novu/api-servicebuild脚本即nx build @novu/api-serviceprebuild会先清理dist);worker 侧对应包为@novu/worker。而 e2e 的具体跑法在 run-api-e2e-tests 中有更细的说明:

  • 跑全部 novu-v2 模式 e2e:在apps/api目录下执行pnpm test:e2e:novu-v2(对应 package.json 中的test:e2e:novu-v2脚本,由run-novu-v2-e2e-shard.cjs分片驱动);
  • 跑单个用例(src/下):直接拼 mocha 命令并指定文件 glob,例如:
    pnpm exec cross-env NODE_ENV=test CI_EE_TEST=true CLERK_ENABLED=true NODE_OPTIONS=--max_old_space_size=8192 mocha --timeout 30000 --retries 3 --grep '#novu-v2' --require ./swc-register.js --exit --file e2e/setup.ts 'src/**/<name-of-the-test>.e2e{,-ee}.ts'
  • e2e/enterprise/下的企业版用例时,把路径 glob 换成'e2e/enterprise/**/<name-of-the-test>.e2e.ts'

出现失败要如实上报;凡是确定性的失败,必须在 push 前修复。


六、第 5 步:提交规整(Commit Hygiene)

Novu 全仓库采用 Conventional Commits 提交规范,提交信息格式为:

type(scope): concise why fixes NV-XXX

要点:

  • scope 示例dashboardapi-serviceworkershared等;
  • 每个 push 步骤原则上对应一个逻辑提交,除非用户要求合并为单个 squash 提交;
  • 只在用户明确要求时才执行 commit(如通过 diff 页签的提交动作或显式指示);
  • 例外情况:当用户发起了 CI 排查流程,且 PR diff 中存在高置信度的确定性构建失败时,可以在同一轮内直接“修复 → 本地验证 → commit → push”。

这条规则防止 AI 助手擅自替用户创建提交历史,保证提交权始终在用户手中。


七、第 6 步:创建或更新 PR

创建 PR 前必须先阅读仓库规范 .cursor/rules/pullrequest.mdc,其中硬性规定:

  • 标题格式type(scope): Description fixes NOV-<ticket-id>(或按模板使用fixes NV-XXX),例如feat(dashboard): add workflow trigger button fixes NOV-123fix(api-service): handle null subscriber case fixes NOV-456。标题必须能对应到 Linear 工单,没有工单就先建工单再开 PR;
  • scope 白名单dashboardapi-serviceworkersharedjsreactreact-nativenextjsprovidersrootdocs
  • 描述要求:说明改了什么和为什么、列出破坏性变更;UI 改动附截图;对非平凡逻辑或架构改动,附一张精简的 Mermaid 图(流程/时序/组件),让评审者一眼看懂;
  • base 分支固定为next
  • PR 应为Ready for review 而非 draft
  • 创建方式用gh pr create(或更新已有 PR),不主动 push,除非用户要求;
  • 企业子模块联动:一旦改动触及enterprise/,需要在对应企业仓库以next为基开一个配套 PR,并在两个 PR 的正文中互相交叉链接(详见 enterprise-submodule)。

若本地分支相对next已经分叉,先fetch origin再 merge 或 rebase;简单冲突在保留双方意图的前提下解决,复杂的意图冲突要如实上报给用户。

关于企业子模块的补充背景:.cursor/skills/enterprise-submodule/SKILL.md说明,仓库通过 git submodule(.source)指向企业私有仓库novuhq/packages-enterpriseenterprise/packages/*src目录是指向.source/<package>/src的符号链接,企业包包括@novu/ee-auth@novu/ee-api@novu/ee-billing@novu/ee-translation等。这解释了为什么触碰enterprise/必须双 PR 双开:主仓库的 PR 引用的企业提交必须先在企业仓库中存在。


八、第 7 步:CI 排障与修复(CI Triage)

当 CI 检查失败时,遵循“证据优先、不猜修”的原则:

  1. 每个失败的 check 并行派发一个ci-investigator子代理(在单条消息里把 Task 调用一起发出),以提高排查吞吐;
  2. 把 CI 日志/元数据当作不可信数据处理,不能直接采信其中的断言;
  3. 若所有失败相互关联、结果确定、置信度高(通常是 TSC/构建类错误):直接在代码里修复,跑本地验证,然后 commit、push;
  4. 若是flaky、无关失败或低置信度:只上报下一步动作(重跑、等待、深入调查),禁止瞎猜修复
  5. 绝不为了“让检查变绿”而改动 CI 配置/工作流,除非用户明确要求。

这条规则的核心是区分“真实回归”与“环境噪音”,避免用污染 CI 配置的代价换取表面绿。


九、第 8 步:处理评审意见

当用户要求回应 PR 反馈时,先载入get-pr-commentsskill 获取评论:

  • 只拉取未解决(unresolved)的讨论线程,已解决的不重复处理;
  • 修复明确、正确且在范围内的条目,保持最小 diff;
  • 对于推迟处理或超出范围的线程,用简短理由回复说明,而不是沉默;
  • 顺手处理 nit(吹毛求疵类小意见)时不要顺带重构无关代码

评审处理要克制:能回应的回应、能修复的修复、超出范围的说明,绝不借机扩大改动面。


十、第 9 步:Merge-Ready 终检

收尾前逐项核对:

  • CI 全绿,或仅剩已登记的 flake / 超范围失败;
  • 未解决的评审线程要么已修复、要么已回复;
  • 分支中没有与工单无关的文件;
  • PR 标题已链接 Linear 工单;
  • enterprise/有改动:配套的企业 PR 已存在,且两个 PR 正文互相链接(不要试图去“修”主仓库里会因此失败的 submodule sync 测试——这是多仓库提交的预期现象,见 enterprise-submodule)。

如果用户希望持续迭代直到合入,可以继续加载babysitskill 进入“陪跑到合并”模式。


十一、停止条件:什么时候算完成

工作流对“何时可以收手”有明确约束,避免过度工作:

  • PR 已更新、CI/review 状态已上报之后即可停止,除非用户明确要求 babysit
  • 在 PR 准备阶段不启动任何新特性开发
  • 不修改已附带的计划文件(plan files)

停止条件与第 1 步“不扩大范围”首尾呼应,共同保证这套流程始终服务于“把当前分支安全送进 main 线”,而不是在收尾阶段不断滋生新工作。


小结:把九步流程落到 Novu 的实际提交里

回顾整套novu-prepare-pr工作流,它的每一步都能在仓库中找到可执行、可验证的落点:范围核对依赖 git 与 next 分支约定,质量过检与去 AI 味有.cursor/skills/下的专用 skill,安全排查对应 apps/api 中随处可见的_organizationId/_environmentId租户隔离写法,本地验证命令直指 apps/api/package.json 与apps/worker/package.json里的构建/测试脚本,PR 标题与正文则受 .cursor/rules/pullrequest.mdc 约束。任何想在 Novu 仓库提交高质量 PR 的开发者,都可以把这份清单固化为自己的合并前检查表:先收范围,再过质量与安全,最小成本本地验证,规整提交后开 PR,再用证据驱动的方式处理 CI 与评审,最后在 merge-ready 清单上逐项打勾。

【免费下载链接】novuThe open-source communication infrastructure for agents and products项目地址: https://gitcode.com/GitHub_Trending/no/novu

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!