代码审阅是保证代码满足一定的质量下限标准的关键环节。主要关注无法通过自动化方式检查的清单、规范、标准和流程的执行情况。
为了使做法更具参考价值,我们先将代码审阅局限在每一次代码变更请求即 pull/merge request 环节。对于其他场景如审计等,可以在本文基础上扩展、变通。
以下的内容均基于 github pull request 功能,及与之相关的名词、概念、做法等。基于其他平台、形式的流程可以在本文基础上变通。
提交者通常是代码的作者,是最了解代码详情的人。在代码审阅过程中,提交者必须与其他参与者进行讨论、合理回应其他参与者的要求。
提交者同时也是第一审阅者,因此也应当履行审阅者的绝大部分职责,且在对具体内容的审视上,提交者应当执行比其他审阅者更严格的标准。
审阅者需要根据自己的专业知识、对现状的了解程度,审视待合并的变动。
在以下方面,审阅者必须确保其符合最低限度的质量标准,我们标记为 p0
事项:
- 正确性及确保正确性的环节,如测试用例的覆盖范围等
- 团队内执行的标准
同时,审阅者应当在以下方面执行严格的标准,我们标记为 p1
事项:
- 能够降低产生分歧的可能性的环节,如模块、类型、值、函数的命名等
- 能够降低协作难度的环节,如注释内容等
- 能够降低后续维护复杂度的环节,如 commits 的影响范围等
- 团队内执行的规范
此外,审阅者可以在以下方面提出建议,我们标记为 p2
事项:
- 代码编写方式
- 未作为规范引入的最佳实践
- 文档的措辞、拼写错误
- 优化、扩展性或类似的、影响未得到证明的环节
- 其他不涉及正确性的环节
对于事项划分、和针对不同事项的解决方式,参考 事项规范。
合并者通常就是最后一位审阅者,也可以是专职的管理者。
合并者必须确保所有阻塞合并的事件被正确解决,如 review approved、checks passed 等。 同时合并者应当在合并完成后执行适当的清理工作,如源分支的清理等。
其他参与者是指在代码审阅过程的某个局部环节,被提交者或审阅者引入的第三方。
其他参与者应当履行知情、反馈、提供必要协助等职责。
注意,审阅者因对代码整体产生质疑——如设计思路、实现方式等——而引入的第三方,应当视为新的审阅者。
- 此流程在 pr 开启至 pr 被 merge/close 的过程中可能会多次循环/中止。
- 任何一个提交
review approval
结果的审阅者,都必须确保以下内容被完整检查,出现的问题都被解决。
-
检查
head branch
(pr 的源分支) 和base branch
(pr 的目标分支);p0 -
检查关联的
issues
:-
联动语法是否正确;p0
参考 Linking a pull request to an issue using a keyword;
这是为了避免出现代码合并而关联issue未关闭的情况;
注意:联动的 pr 只有在同时满足:
- 目标分支为当前代码库默认分支
- 联动文本位于 PR 的 description(创建 PR 时的描述信息;PR 合并前,通过 edit 更新有效)中时才能正确地联动关闭。
-
issue 涉及的范围和本 pr 解决的范围是否一致;p0
这是为了避免只解决部分,甚至完全未解决issue却联动关闭的情况
-
关联的 issue 是否全面;p2
-
-
检查是否存在未解决的
conversation
;p0 解决方式和解决者参考 事项规范-解决
- 确认 commits 涵盖的内容与 pr 要解决的问题匹配;p0
- 确认 commits 和 pr 的粒度划分合理;p1
- 确认 commit messages 符合规范;p1 参考 commit-message风格规范
以下会针对不同类型的内容,罗列常见的审阅项清单,实际审阅过程中,可能不局限于以下罗列的项目。
审阅过程中对于辅助工具的使用可以参考 审阅辅助工具使用规范。
- 实现
- 是否符合需求定义;p0
- 是否存在与以下内容相同或相近的逻辑,p1
- 标准库
- 常用开源库
- 团队内其他项目中的库
- 本项目已有的实现
- 其他不涉及正确性的细节:
- 公开项(类型、量、方法等)的命名;p1
- 可见性划分;p2
- 算法和实现细节;p2
- 未包含在代码格式化和风格规范内的最佳实践;p2
- 修复
- 是否完整覆盖了异常场景;p0
- 是否引入了其他明显可见的缺陷;p1
- 重构、优化
- 是否能通过原始逻辑测试;p0
- 是否引入了逻辑变化;p1
- 必要性;p2
- 测试用例:
- 存在与否是否符合团队规范和标准;p0
- 用例的覆盖是否完整;p1
- 随机源是否合理;p1
对于 markdown 及其他可以以渲染结果查看的文档格式,应当通过 View file
的方式进行审阅,避免直接阅读源文件。
- 关键内容的准确性:
- 关键性描述;p0
- 链接;p0
- 重要的格式如表格等;p0
- 段落、层级、缩进设置合理;p1
- 其他不影响正确性的主观判断;p2
- 拼写错误
- 措辞准确
- 语句通顺
- 其他格式的使用,如:
- 粗体
- 斜体
- 代码框
- 检查自动生成的过程是否被包含在 Checks 中,且针对文件变化进行了检查;p0
- 不必检查具体的自动生成内容;
- p0 事项必须完整罗列
- p1 事项应当尽可能罗列,或经罗列后,可以得出某种“原则性”规范
- p2 事项可以仅罗列少量具有标志性的内容
- p0 事项必须在本 pr 中解决,解决结果由发起的审阅者确认
- 在经过团队一致认可的情况下,p0 事项的解决方式也可以降级等同 p1,但优先级或严重程度方面不得降低
- p1 事项最好在本 pr 中解决,也可以在得到审阅者认可的情况下延后解决,但必须开列新的 issue 并与此 pr 关联
- p2 事项解决与否由发起者自决,如果选择解决,则解决结果需要得到审阅者的认可
-
Conversation
-
p0 事项应当由提出的审阅者确认后点
Resolve conversation
-
其他级别的事项可以由提出者或解决者点
-
由于代码提交而自动解决的 Conversation,审阅者需要逐一复查
如果解决结果存疑,应当发起新的 conversation。
-
-
Viewed 标记:已经完成内容审阅的文件应当进行标记,以便观察审阅进度,并避免干扰。
-
行内评论(Comment):
- 应当通过有疑问的行行首的
+
号开启 - 审阅者必须以
Start a review
/Add a review comment
的方式进行评论,而不应使用Add single comment
- 应当通过有疑问的行行首的
-
Review changes 面板的使用规范
-
本次审阅中如果产生了评论,则必须统一提交
如果存在
p0
、p1
事项,进行Request changes
提交,否则进行Comment
提交 -
所有事项都完成检查或得到解决的情况下,应当进行
Approve
提交此时通常没有评论,审阅者应当在本面板的评论框中显式标注
LGTM
或其他等效的短语
-
以下为结合事项规范和审阅辅助工具的一个范例:
-
发起 conversation
flowchart TD s([发现问题行]) --> review_comment[发起 review comment] --> is_p2{是 p2 事项} is_p2 --> |no|review_select_request_changes[选择 Request changes] --> e([Submit review]) is_p2 --> |yes|review_select_comment[选择 Comment] --> e
-
解决 conversation
flowchart TD s([开始解决]) --> read_comment(阅读评论内容) --> get_agreed{达成一致} get_agreed --> |no| add_comment(追加评论) --> read_comment get_agreed --> |yes| submit_changes(提交修改) --> comment_changes(评论已修改) --> changes_agreed{修改符合预期} changes_agreed --> |no| add_comment changes_agreed --> |yes| resolve_conversation([Resolve conversation])