敏捷开发版本迭代流程

本文介绍了 BasicAI 研发团队内部敏捷开发所采用的版本迭代流程,分为了内部项目和开源项目两大类,每类下面都包含了代码仓库和分支规范、开发流程,以及 Bug 修复或 Issue 解决流程。

敏捷开发版本迭代流程

内部项目

代码仓库和分支规范

代码仓库规范

  1. 一个项目的所有代码仓库放在一个 Group 下,项目 Group 下按前端(Frontend)、后端(Backend)、算法(Algorithm)等划分 Subgroup;
  2. 为方便后续修改,架构图等图表类文档需提交原始文档到文档仓库,统一使用 Google 出品的免费画图工具 Diagrams 来画图;
  3. 为了防止代码仓库过大,仓库里只能存放代码,不能存放库包、开发工具等大文件,这些文件需存放到外部存储(比如对象存储)里,构建的时候再去下载;

代码分支规范

  1. 每个代码仓库包含开发 dev、测试 test 和生产 main 三个主线分支,默认分支设为开发分支;
  2. 推荐使用特性分支来开发新功能,而不是直接提交到开发分支,特性分支命名遵循 feat-xxx
  3. 测试环境 Bug 修复分支命名遵循 fix-xxx,测试通过后需合并回开发分支;
  4. 生产环境 Bug 热修复分支命名遵循 hotfix-xxx,上线完成后需合并回测试分支和开发分支;

代码版本规范

  1. 需求评审时确定本轮迭代的版本号,版本号为三位,形如 1.2.3,其中 1 为大版本号,2 为小版本号,3 为 Bug 修复;
  2. 每个迭代版本测试完成之后需打版本 Tag,形如 v1.2.3
  3. 对于微服务架构应用,每轮迭代可能只会更新部分服务,因此会存在部署的各个微服务版本不是完全一致的情况;

版本开发流程

  1. 版本需求评审通过后,开发人员更新开发分支里代码的版本号为当前版本,然后在开发分支完成版本功能开发和自测;
  2. 开发人员在开发环境演示版本功能,测试和产品人员初验通过后可提测;
  3. 开发人员从开发分支拉取版本发布分支(比如 release-v1.0),提交合并版本发布分支到测试分支的 MR(Merge Request),填写提测申请;
  4. 测试人员依据提测申请,执行配置更新、库表升级、代码合并等操作来部署新版本到测试环境;
  5. 测试人员在测试环境完成测试;
  6. 测试通过之后,测试人员在测试分支上打版本 Tag(比如 v1.0),发布测试报告;
  7. 产品人员邮件发出上线申请;
  8. 运维人员合并版本 Tag 到生产分支(会触发构建镜像但发布需手动),依据提测申请在生产环境执行配置更新、库表升级、镜像更新等操作;
  9. 测试人员在生产环境验证功能是否都正常;

GitLab MR 合并时会包含源分支上的最新提交,而不是仅包含创建 MR 时的提交。提交 MR 时请勿勾选删除源分支,后续修复 Bug 时会继续使用版本发布分支,直到测试完成后才可以删除。

上线时如果有跳过中间版本,那么中间版本也需要依次发布,以免遗漏配置更新、库表升级等操作。比如生产环境版本为 v1.0,v1.1 测试后未发布,现在要发布 v1.2,那么需要先发布 v1.1。

各服务的部署文件位于 ops 目录下,包括数据库迁移文件,以及各环境的 Deployment 和 ConfigMap 文件。考虑到 ConfigMap 里包含了帐号密码等私密信息,只允许提交开发环境 ConfigMap 到代码仓库,其它环境需要在部署服务之前参考开发环境的 ConfigMap 来创建当前环境的 ConfigMap。

Bug 修复流程

测试环境 Bug 修复流程

  1. 开发人员在版本发布分支上修复 Bug,合并到开发分支来完成自测。如果没有版本发布分支,可以从测试分支拉取 Bug 修复分支 fix-xxx 来修复 Bug;
  2. 开发人员提交合并版本发布分支或 Bug 修复分支到测试分支的 MR 来送测 Bug 修复;
  3. 测试人员接受 MR 并测试 Bug 修复;
由于开发分支和测试分支的版本差异性,可能会导致 Bug 修复无法在开发环境进行自测。
Bug 修复分支和版本发布分支都是短线分支,在使用完(测试通过、合并到相关分支等)之后需及时删除掉,以避免分支数量膨胀。

生产环境 Bug 修复流程

  1. 开发人员从生产分支拉取 Bug 热修复分支 hotfix-xxx 来修复 Bug,合并到开发分支来完成自测;
  2. 开发人员提交合并热修复分支到测试分支的 MR 来送测 Bug 修复,MR 描述里需加上配置更新、库表升级等说明(如果有);
  3. 测试人员接受 MR 并测试 Bug 修复;
  4. 测试人员提交合并热修复分支到生产分支的 MR 来上线 Bug 修复,MR 描述里需加上配置更新、库表升级等说明(如果有);
  5. 运维人员接受 MR 并打热修复版本 Tag(更新版本号最后一位),然后发布生产分支到生产环境;
由于开发分支、测试分支和生产分支的版本差异性,可能会导致 Bug 热修复无法在开发环境和测试环境进行自测和测试。

开源项目

开源项目相比于内部项目的最大区别在于,开源项目无需发布到生产环境,但还是需要交付镜像、发布包等产物。同时开源项目无需像内部项目那样的快速迭代节奏,因此分支和流程的设计上都适当做了简化。

代码仓库和分支规范

  1. 每个 GitHub 上的开源仓库都有一个对应的内部 GitLab 仓库,并配置自动同步,所有修改只能在 GitHub 开源仓库上进行;
  2. 每个代码仓库只包含开发 dev 和生产 main 两个分支,其中开发分支不稳定,更新频繁但测试不充分,生产分支比较稳定,会定期将经过充分测试后的开发分支合并到生产分支;
  3. 开发分支会同时部署到开发和测试环境,只不过开发环境为自动,测试环境为手动;

合并修改到生产分支必须通过提交 PR 来完成,开发分支可以直接合并。

版本开发流程

  1. 版本需求评审通过后,开发人员从开发分支拉取版本分支 vx.y 来开发功能,然后合并到开发分支完成自测;
  2. 开发人员在开发环境演示版本功能,测试和产品人员初验通过后可提测;
  3. 测试人员依据提测申请,执行配置更新、库表升级等前置操作,然后手动确认 CI Job 来部署最新的开发分支到测试环境;
  4. 测试人员在测试环境完成测试,并发布测试报告;
  5. 产品人员邮件发出发布申请;
  6. 运维人员提交 PR 来合并开发分支到生产分支,在 GitHub 上新增一个版本发布(同时会打版本 Tag),打完 Tag 后构建的发布包需要添加到版本发布的附件里,发布说明可找产品提供,同时构建支持多平台的版本镜像并推送到 Docker Hub(同时更新最新镜像);
  7. 测试人员验证镜像、发布包等交付产物是否正确;

由于开源仓库里包含了多个服务的代码,为了提升构建效率,只有相关服务的代码发生了修改,才会触发该服务的包和镜像的构建。不过对于打 Tag 触发的构建,为了方便发布,每次都会构建所有服务的包和镜像,即便是该版本中没有任何修改的服务,也会执行构建。

内部 Issue 解决流程

内部 Issue 解决流程适合于对官方仓库有直接提交权限的组织内成员(不限于公司员工),分为了“非紧急”和“紧急”两种 Issue 解决流程。

非紧急 Issue

  1. 开发人员在开发分支上修复 Bug,并在开发环境自测;
  2. 自测通过后等待下个版本一起发布上线;

紧急 Issue

  1. 开发人员从生产分支拉取特性分支 feat-xxx 来解决 Issue;
  2. (可选)开发人员合并特性分支到开发分支来完成自测,文档类的修改可以不用;
  3. (可选)如果需要测试介入,测试人员手动发布最新开发分支到测试环境验证 Issue 是否已解决;
  4. (可选)如果需要产品介入,产品人员在开发环境或测试环境验证 Issue 是否已解决;
  5. 开发人员提交 PR 来申请合并特性分支到生产分支;
  6. 审核人员审核并接受 PR,然后执行一次生产分支到开发分支的合并,以把特性分支的修改同步到开发分支;
  7. (可选)如果需要发布版本,开发人员修改所有文档、代码和部署脚本里的版本号,运维人员新建一个版本发布,并发布版本镜像;

对于 README 等文档更新,为了及时发布,可走“紧急 Issue”流程,但不需要测试、产品和运维介入。文档更新可能会比较零碎,为了形成干净的提交记录,建议在接收 PR 时合并特性分支的所有提交记录为一个。

外部 Issue 解决流程

外部 Issue 解决流程适合于对官方仓库没有直接提交权限的外部贡献者,需要通过 Fork 官方仓库来进行修改。一般来说,外部贡献者的改动不大,Fork 时勾选生产分支 main(默认选择)来修改即可,少数情况可以勾选开发分支 dev 来修改,注意提交 PR 时目标分支需要选择对应的。

基于生产分支修改

  1. 外部贡献者 Fork 官方仓库的生产分支来解决 Issue;
  2. 外部贡献者提交合并个人仓库生产分支修改到官方仓库生产分支的 PR;
  3. 审核人员审核并接受 PR,然后执行一次生产分支到开发分支的合并,以把外部贡献者的修改同步到开发分支;
  4. (可选)如果需要发布版本,审核人员请求发布人员发布一个新版本;

基于开发分支修改

  1. 外部贡献者 Fork 官方仓库的开发分支来解决 Issue;
  2. 外部贡献者提交合并个人仓库开发分支修改到官方仓库开发分支的 PR;
  3. 审核人员审核并接受 PR,然后等待下个版本一起发布;