10

持续交付这点事

 3 years ago
source link: https://www.rowkey.cn/blog/2020/06/15/cd/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

持续交付这点事

Jun 15th, 2020

Posted by 飒然Hang in

manage

持续交付指的是在短周期内完成软件产品,以保证软件保持在随时可以发布的状态。让每一个变更都经过一条自动化的检验流水线,来检查每一个变更的质量,通过就进入下一个阶段。其不是一种工具,而是一种实践!

持续交付的共识和管理机制如下:

  • 不要阻塞开发人员,这是实现持续交付的本质理念
  • 为每个团队指定构建负责人或者发布工程师:优化交付流水线,提升交付效率
  • 项目状态应该对参与整个过程(包括构建、部署、测试和发布)的所有人都是可见的
  • 做好风险管理

    • 迭代增量式交付是有效风险管理的关键
    • 手工测试环境、试运行环境和生产环境总是需要严格的访问控制
    • 让风险识别成为每日立会的一部分
  • 做好审计

    • 手工测试环境、试运行环境和生产环境总是需要严格的访问控制:指定谁能够访问“特权”环境。
    • 要求每次部署都要进行审计,以确切知道到底修改了哪些内容。
    • 文档自动化、自文档

接下来先说明实现持续交付的一些基础设施和准备工作,然后从本地开发和自动化构建/部署流水线两方面说明持续交付的具体实现。

一. 基础设施和准备工作

1.1 基础设施和环境管理

让所有测试环境(包括持续集成环境)都要与生产环境相似

  • 开发人员要把运维人员当做重要用户
  • 切忌吞噬错误信息
  • 使用运维团队熟悉的技术:开发人员最早负责创建部署脚本,后面移交给运维团队负责维护
  • 把创建和维护基础设施需要的所有内容都进行版本控制
  • 以自动化方式进行配置和部署!
  • 像对待生产环境一样对待测试环境!
  • 容器化技术实现不可变基础设施

1.2 配置管理

版本控制、依赖管理、软件配置管理

  • 各个环境的手工配置 -> 自动化配置
  • 对所有内容进行版本控制
  • 指定依赖库的确切版本,不要用快照或者模式匹配版本
  • 配置文件与二进制文件分离

1.3 测试策略

  • 创建全面的自动化测试套件:单元测试、组件测试、验收测试,每一种测试的代码覆盖率都高于80%以上
  • 每次修改都能运行一次自动化测试集合

1.4 数据管理

  • 把创建和迁移数据库全部变成自动化过程,是部署流程的一个组成部分
  • 让测试自己创建它们所需的状态,并确保每个测试都独立于其他测试
  • 对数据库进行版本管理,使用DbDeploy这样的工具管理数据迁移过程的自动化。
  • 在大多数据情况下,不要在测试中使用生产数据集的副本。?
  • 数据库回滚和无停机发布

    • 大多数修改应该是增加操作(比如向数据库中增加新表或字段),尽可能不修改已存在的结构
  • 测试数据

    • 测试的独立性、原子性
    • 其他类型的测试,一定不要使用生产数据库的一个dump,除非有特殊情况
  • 部署流水线中的数据管理

    • 提交测试:快速运行,避免复杂的数据准备
    • 验收测试:后续阶段可以复用
    • 容量测试:为测试提供足够的输入数据,可以看做验收测试的重复利用

1.5 主干开发

主干开发的分支模式实现持续交付最好的模式,但为了在主干模式下保持应用可发布,需要做到

  • 每次创建分支,都要认识到它带来的成本
  • 频繁提交代码合并到主干
  • 新功能隐藏:功能开关统一管理达到特性隐藏的目的(Togglz?)
  • 增量开发:将所有的变更都变成一系列的增量式小修改,而且每次小的修改都是可发布的。
  • 抽象模拟分支(无法使用增量开发):修缮者模式,使用门面模式隔离待改造代码。
  • 使用组件,根据不同部分修改的频率对应用程序进行解耦。

二. 本地开发

让开发者不受阻塞、不受不必要的干扰 -> 持续开发

localdev.png
  • 确保自动化测试、构建部署脚本都能够在开发机上运行
  • 本地自动化测试:预测试提交pretested commit/个人构建personal build/试飞构建preflight build【保证本地开发所有验证方式与流水线上的验证方式一致,提高开发人员在本地发现问题的能力】
  • 提交前在本地运行所有的提交测试,等提交测试通过后再继续工作
  • 在可控的环境上部署开发的应用程序
  • 修复破坏应用程序的任意修改是最高优先级的任务,构建失败后不要提交新代码

2.1 六步提交法

规范开发习惯。主动提前集成;小步提交、完整代码、不影响已有功能;关注代码规范、动静态扫描问题

  • 检出最近成功的代码
  • 第一次个人构建
  • 第二次个人构建: 拉取主干代码集成后本地测试
  • 提交代码到主干

提交不影响已有功能!!

  • 增量迭代开发
  • 抽象模拟分支

2.2 规范化、自动化核心步骤

localdev-detail.png
  • 提高开发环境的效率: 环境获取的服务化、自助化;环境的一体化、一致性

    • 本地开发环境

      • 共享机器池
      • Git提交日志插入截图:Share Bucket+Google Drive
      • 远程开发机器/Web IDE
      • 依赖的服务

        • 维护一个单独的环境,让开发环境接入
        • 服务虚拟化工具来模拟依赖的服务,Mountbank、WireMock
    • 联调环境:提供机器池,确保有两套空闲环境,自助化提供给开发者使用
  • 规范化、自动化本地检查

    • 语法检查、规范检查、单元测试:Maven/Gradle插件
  • 建设并自动化代码入库前的检查流程

    • 持续集成前的必要工作

2.3 代码审查

人工代码检查

  • 统一并明确代码审查标准
  • 统一并明确日志提交规范
  • 传达团队的代码规则、质量基准
  • LGTM(Looks good to me)

方式

  • 代码入库前的设计时检查:在设计阶段进行代码审查

    • 代码入库前门禁检查,需要考虑灵活性,提供绕过机制
    • 代码入库后检查
  • 工具辅助的线下异步审查:依赖于Gitlab、Gerrit、Code Climate Engines,一对一审查
  • 面对面审查:架构问题、结对编程
  • 代码增量审查/代码全量审查
  • 团队审查:适合专项讨论
  • 代码审查计入工作量和绩效考评

代码提交规范

  • 提交日志规范

原则

相关资料可见:谷歌代码审查指南

2.4 快速反馈、增量开发

边开发边验证

  • 提高运行静态检查和测试的方便性、灵活性:Maven/Gradle插件
  • 提供沙盒环境方便验证和测试

    • 小范围的增量构建和验证?
    • 测试数据:直接使用生产环境、生产数据的导出并脱敏
  • 实时检验工具:IDE实时检验、Liveload

三. 自动化构建/部署流水线

部署流水线就是对软件交付流程的建模。

deploy-pipeline.png

实现部署流水线的一些共识如下:

  • 流水线建设原则

    • 测试尽量完整,保证产品质量->完备的测试机制
    • 运行速度够快->尽早反馈、提高交付速度
    • 使用的所有环境尽量和生产环境一致->复现问题
  • 所有相关角色提供构建状态可视化:持续交付流水线大屏显示
  • 存储构建结果报告
  • 只要有环节失败,就停止整个流水线!
  • 制品库是特殊的版本控制系统,不需要保存所有版本。
  • 为部署流水线的每个阶段创建脚本:脚本是系统中的一等公民
  • 增量式实现流水线:如果流程中有手工操作部分,就在流水线中为它创建一个占位符。

接下来从流水线的各个阶段分别说明。

3.1 提交阶段

从技术角度上断言整个系统是可以工作的。

  • 编译、单元测试、组装打包、代码分析
  • 少于五分钟,一定不要超过十分钟
  • 提交测试:单元测试、组件测试
  • 只有在某个错误让提交阶段的其他任务无法执行时,才停下来否则就直至提交阶段全部运行完后,汇总所有的错误和失败报告
  • 此阶段的结果:结果报告、二进制包、元数据

3.2 自动化验收测试

验证一个用户故事或需求的验收条件是否被满足。针对业务!

  • 配置环境、部署二进制文件、冒烟测试、验收测试
  • 令验收测试失败的构建版本不能被部署
  • 先部署再测试,重用部署脚本。
  • 类生产环境运行验收测试:大部分是功能验收测试,关注功能正确性
  • 开发人员能够在自己的开发环境中运行自动化验收测试
  • 测试的关注点在系统的行为,而非数据本身。所以抵制使用生产数据的备份做为验收测试
  • 验收测试的性能不是主要考虑问题,重点在测试的全面性。
  • 正确地做验收测试:不要幼稚地对照着验收测试条件,盲目地把所有东西都自动化。
  • 验收测试可以看作所有后续测试阶段(包括容量测试)的某种模板:从部署准备开始,然后核实环境和应用程序都已被正确配置和部署,最后执行测试。

3.3 后续测试

  • 手工测试:探索性测试、易用性测试
  • 非功能测试:性能、安全、可维护、可扩展

3.4 部署发布

此阶段的触发不需要自动,测试或者运维人员可以做到自服务即可

  • 对不同环境采用同一部署方式:使用同样的脚本向所有环境部署,包括开发机器
  • 一键式部署是对环境进行修改的唯一途径。
  • 部署测试:对部署进行冒烟测试,验证部署是否成功,证明其部署的可靠性
  • 确保部署流程是幂等的
  • 只有通过了自动化构建、测试和部署的那些修改才能发布!
  • 明确每个环境的部署和发布都是由谁负责
  • 发布计划:第一次发布,产出一些文档、自动化脚本或其他形式的流程步骤
  • 首次部署:首个迭代的主要目标之一就是在迭代结束时,让部署流水线的前几个阶段可以运行,实现部署流水线的“抽水泵”。

    • 部署流水线的提交阶段。
    • 一个用于部署的类生产环境。
    • 通过一个自动化过程获取在提交阶段中生成的二进制包,并将其部署到这个类生产环境中。
    • 一个简单的冒烟测试,用于验证本次部署是正确的,并且应用程序正在运行。
  • 对发布过程进行建模并让构建晋级

    • 为了达到发布质量,一个构建版本要通过哪些测试阶段
    • 每个阶段需要设置什么样的晋级门槛或需要什么样的签字许可。
    • 对于每个晋级门槛来说,谁有权批准让某个构建通过该阶段。
  • 将每次已通过验收测试的变更版本部署在试运行环境中
  • 紧急修复: 紧急修复版本也要走完标准的部署流水线,与其他代码变更没什么区别。

    • 有时候回滚比部署新的修复版本更划算。
  • 持续部署:每当有版本通过自动化测试之后,就将其部署到生产环境中。【需要依赖强大的自动化测试机制】

3.5 度量

每次提交后都产生关于这些度量的报告和可视化效果并保存起来

  • 周期时间(cycle time),从决定要做某个特性开始,直到把这个特性交付给用户的这段时间
  • 自动化测试覆盖率
  • 代码库特征
  • 提交版本库次数
  • 构建失败次数
  • 构建所花时间

4.1 DevOps

Devops是这些年很流行的一个概念,其目的就是打通研发和运维环节,以达到全员目标一致,保障软件高效交付。

devops.png
  • 职能团队提供平台和工具,让全栈工程师能够自己处理端到端的工作,实现DevOps。
  • 全栈开发:工程师不再只是对某一个单一职能负责,而是对最终产品负责。

4.2 信息溯源

打通研发流程中流动的多种标识信息,以方便相关人员快速获取需要的信息,提高工作效率。包括任务工单、代码提交号、版本号、代码审查 ID、测试用例 ID、Bug ID。

  • 制品与源代码版本管理:放置在制品包中的元数据,体现源代码版本号。
  • 源代码与需求/Bug的版本关联: 提交代码时需要在注释里注明需求ID、测试用例ID等。

五. 参考资料


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK