4.7 完备记录,充分展现
说到与软件交付相关的各种工具,其大体上分为两类:一类是能够自动化地执行、自动化地往前推进流程的工具(我们前面讲过);另一类是辅助人工作的工具。怎么辅助呢?主要是把所有有用的信息都记录下来保存好,让想获得它们的人能够随时方便地查看。就好像我们日常生活离不开眼睛,组织团队共同协作也离不开各种记录和呈现:我们想知道当前进展,我们想知道下一步要做什么,我们想知道问题是在哪里发生的、是如何发生的。
不仅是“我们”想知道,“他们”也想知道。有些组织对预算执行情况有非常严格的审计制度,并且对过程成果物的数量和完整度也有很高的要求。如果“我们”工作的过程、状态、结果可以被自动化地记录下来,并被自动化地统计、整合、归档以供审计,那么就会节省很多额外的人工投入,而且自动记录比人工记录更客观、更可信。
4.7.1 任务及其执行情况
对于对工作项的记录和跟踪,比如缺陷、需求(如用户故事)、开发任务等,都是工作项。记录工作项的目标和内容、相关详细情况,然后跟踪它们,看它们的状态流转过程,直到完成。这是工作项管理工具(或称为变更请求管理工具)提供的基本能力。
当我们建立Scrum中的Sprint Backlog,并且以精益看板墙的形式展现它们时,计划和进度就变得透明、直观。
对于流程状态,在工作项管理中常会设置一些状态流转的规则,比如对开发人员标记为“已完成”状态的缺陷,只能执行“通过验证”操作到“关闭”状态,或者执行“重新打开”操作回到“待解决”状态。这其实已经有一些流程自动化的成分了。而在4.4节中提到的工作流和流水线,流程自动化的成分就更多了。然而,不论有多少流程自动化的成分,它们都还同时具有最基本的能力——记录和展现流程的状态:执行成功了还是失败了,执行到哪一步了,是否需要人工干预,等等。
对于执行细节的记录,不论是在开发人员的本地环境中还是在流水线上执行一次构建,当构建出错时,都要分析和定位问题出在哪里,此时构建的日志就很重要。类似地,部署的日志,以及自动化测试的日志和报告也很重要,它们都是用来帮助排查问题的。
软件运行的日志,特别是生产环境中软件运行的日志,在很大程度上也是为了在出现问题时方便定位和排查。在生产环境中还要配备各种监控,这不仅仅是为了告警,也是为了对问题进行定位和排查。对微服务间调用链路的记录,也有助于定位和排查问题。
总之,我们需要工具辅助记录工作项的目标和内容、进展情况、执行细节。
4.7.2 版本和配置信息
上面介绍的主要是关于软件的价值流动(或者说是变更请求流转)方面的信息,下面介绍关于软件内容本身的信息。
“源代码”需要被纳入版本控制中。这里的“源代码”加了引号,表示所有长得像源代码的,也就是由人写的、可以用文本文件记录并且可能会有版本变化的内容,都应该被纳入版本控制中。比如与构建、部署、环境相关的各类脚本和配置文件,数据库表结构或其变更脚本,测试用例和脚本等。典型的,如把它们放进Git或SVN这样的版本控制工具中管理。而当我们使用版本控制工具中的提交、分支、版本标签等功能时,要遵循相应的规范,以便日后进行各种查找。
纳入版本控制不一定是放到Git或SVN这样的版本控制工具中。简单记录下来是谁、什么时候、做了什么改动、改成了什么样子,也就具备了最基础的版本控制能力。典型的,如一个测试用例的修改变化历史、一条流水线的配置的修改变化历史、一个工作项的修改变化历史,可能分别是由测试用例管理工具、流水线、工作项管理工具本身提供的版本控制能力实现的。
相比之下,版本控制工具所能提供的高级能力是,可以把相关的众多文件内容纳入一个代码库中,放在一起管理,可以使用版本标签之类的方式标识整体的版本,可以使用分支来跟踪整体在不同方向上的分头演进。
如果要管理的资产不是由人写的,而是由“源代码”自动“构建”生成的,那么其对应的就是制品管理[2]。比如安装包、编译时用的库、Docker Image等,它们也有版本,也要遵循相应的规范。
制品管理工具就是专门用来管理制品的,它为制品提供了一个安全的存放地,并且由于其具备良好的存放结构,使得我们易于找到一个制品或它的特定版本,以便下载或者查看相关信息。
就像纳入版本控制不一定要将“源代码”存放到版本控制工具中一样,纳入制品管理也不一定要将制品放到制品管理工具中。比如代码自动扫描的报告、自动化测试的报告,通常就直接存放在相应工具的相应服务中,只要能安全地存放、易于找到,那么就算是对制品有了基本的管理。
注意,以上版本控制和制品管理的对象,不仅包括管理公司内部的资产,也包括外来的资产。常见的做法是把外来的资产纳入公司内部的代码库、制品库中,并且在纳入时要做一些质量与安全方面的控制。
版本控制和制品管理的对象是软件的内容,而对于它们是如何组成运行中的软件系统的,也需要记录和管理。例如,某个测试环境实例包括哪些微服务、每个微服务用的是哪个版本、部署在哪些服务器上、历史上是什么样子的,等等,这些都是需要记录和管理的。
4.7.3 关联关系
上面讨论的所有要记录的内容,它们之间有各种各样的关联关系,这些关联关系也应该被记录下来,最好是被自动记录下来。
比如,对源代码的修改应该和需求、缺陷等工作项相关联。进而,当在流水线上向测试环境中做部署时,应该能自动查询到所要部署的特定版本中包含了自上次发布以来哪些特性分支的合入,以及分别对应于哪些工作项。于是,测试人员就能知道所要测试的内容。类似地,在向生产环境中做部署前,也应该能看到相应的信息,检查所要部署的内容是否正确。
比如,测试用例或者自动化测试脚本(准确地讲,是对它们的改动)应该与用户故事之类的工作项相关联。于是,测试人员可以根据要测试的用户故事自动选择执行哪些测试用例。而在测试过程中发现的缺陷,应该与发现它的人工测试用例或者自动化测试脚本,以及当时的执行上下文相关联。这些关联关系都应该是自动建立的,而不是人工一项一项填写的。有了这些关联信息,就可以方便地查看该缺陷的所有相关信息,比如测试用例、相关需求描述、测试版本、测试日志等,找出问题所在。
4.7.4 单一可信源
不论记录和展现的是任务及其执行情况,还是版本和配置信息,抑或是各种关联关系,都需要遵循一个基本原则,即:单一可信源(Single Source Of Truth,SSOT)。在获取数据、信息、文件、制品时,不论是谁,想在哪个流程阶段、哪个环境中,通过人工还是自动方式,都应当从同一个地方获取,以保证总是获取到相同的内容,这个地方就是“单一可信源”。
当然,如果从不同的地方获取,但这些地方之间有很好的同步机制,共同信任一个单一可信源并保证总是与它的内容相同,那么也是满足单一可信源这个基本原则的。
4.7.5 相关支持
从权限的角度来看,上面讨论的所有要记录的内容,应该尽量让相关人员都能看到。为降低设置和管理权限本身的成本,可以考虑一般内容组织内部全员可见,只对重要的或敏感的信息做进一步的权限控制。
此外,在工具和服务层面,要注意做好数据备份。在版本控制服务中存放着源代码等重要内容,对它进行数据备份格外重要。对制品管理服务中存储的制品也要做好备份。工作项管理等工具中也保存了重要数据,需要做好备份。