返回文章列表
开发 | 医疗 | 互联网 | 人工智能 | 零售 2023-04-20

一种简洁又不失优雅的工作流:极狐 flow

极狐GitLab
一体化安全DevOps平台

我们提到的 Workflow 是指什么?

 

我们在日常开发工作中提到的 Workflow 通常是指通过 Git(版本控制工具)实现的分布式版本控制(distributed revision control),它允许多名软件开发者,在不同的网络环境下,参与同一个软件开发项目

 

这种工作模式,比集中式版本控制具有分布式的特性与增量版本的明显优势,已经成为行业内主流版本管理方法。

 

Git 除了最基本的推拉代码,还包括分支、tag、commit,其背后有很多最佳实践,例如:

 

  • 基于哪个分支派生出新分支?合并到哪里去?
  • 如何进行代码评审?
  • 使用快进、压缩还是直接合并?
  • 什么阶段,在哪个分支上创建 tag?
  • 怎样设置 Git commit 的格式规范?

 

这些最佳实践的集合被称为工作流(Workflow)

 

Git 在 2005 年诞生,最初目的是为了更好地管理 Linux 内核开发而设计。Git 最初只是作为一个可以被其他前端包装的后端应用而开发的,但后来 Git 内核已经成熟到可以独立地进行版本控制。

 

仅有版本控制功能还不足以胜任代码托管工作,随后一款基于 Git 的在线源代码托管服务平台 GitHub 于 2008 年 2 月上线。

 

随着 2007 年持续集成(Continuous Integration)和 2009 年 DevOps 概念的流行,一站式 DevOps 研发平台 GitLab 于 2011 年诞生。

 

主流 Workflow 有哪些?

 

近年来,Workflow 基于各类平台快速发展。

 

用于 Linux 的内核版本管理工具 Git 推荐的工作流是 Git flow,源代码托管平台 GitHub 推荐的是 GitHub flow,而 DevOps 研发平台 GitLab 的,则是 GitLab flow。

 

以上 3 个工作流并不存在好坏之分,只要可以帮助有效管理并行开发的软件版本、实现团队高效协同的,就是好的 Workflow。每个团队都应该基于不同类型的应用开发场景,选择最适合自己的

 

点击👉获取一对一咨询服务,选择合适的workflow,让研发工作事半功倍~
 

 

Git flow

 

Git flow 面向多版本长期维护多版本同时发的开发模式,比如框架(Spring 2 和 3 共存)、编程语言(Node.js 18 LTS 和 19 共存)、开放 API(v1 和 v2 共存)、多客户定制版。

 

Git flow 并行开发模式非常复杂,作者本人也在 2020 年宣布其「不适合持续交付」

 

并行开发模式如下图:

 

图 1:Git flow 并行开发分支模型

 

图中每个分支都有不同的使用场景和用途:

 

功能分支(Feature):开发人员以功能名称命名一个分支,独立于其他分支进行开发工作,完成开发后合并入共享开发分支。

 

共享开发分支(Develop):用于集成多个功能分支,一个版本全部功能开发完成后,可以拉出发布分支进行发布,而共享开发分支可以继续进行下一个版本的开发工作。

 

发布分支(Release):用于保存发布过程中产生的代码修改,发布后会将代码合并到共享开发分支和主分支。

 

热修复分支(Hotfix):当某个正式版本出现紧急 bug 需要修复时,从主分支的对应版本拉出 Hotfix 分支,进行紧急修复,发布后,合并回主分支。

 

主分支(Master):用于保存所有发布的版本。

 

GitHub flow

 

做为一个代码托管平台的分布式版本管理模型,GitHub flow 相对简单很多。

 

其经历过多个版本更迭,V1.0:主干开发、主干发布,V2.0:分支开发、主干发布。作为托管平台,GitHub Flow 对团队约束性较低,难以在团队内形成规范,适合人数较少的开源项目

 

图 2:GitHub flow 分支模型(上图为 V1.0,下图为 V2.0)

 

GitLab flow

 

作为一站式 DevOps 平台,GitLab 在分布式版本管理的能力与 CI/CD 能力,已有较多完善功能,且在并行开发模型和研发治理方面的能力都相对比较成熟。

 

图 3:GitLab 与 GitHub 功能成熟度比较

 

在持续集成方面,GitLab 推出了一系列功能保障主干分支的代码质量:

 

  • 对受保护分支的修改必须通过审批才能完成代码合并;
  • 通过代码扫码和自动化测试保证代码质量的同时引入代码评审,保证发布的每一行代码都是有质量保证的;
  • 通过二进制仓库作为 CI 与 CD 的衔接点,确保生产环境版本可追溯到对应源代码。

 

图 4:GitLab CI/CD 模式

 

GitLab flow 有三种推荐的 flow 模式:

 

  • 环境分支 Environment branches with GitLab flow;
  • 产品分支 Production branch with GitLab flow ;
  • 发布分支 Release branches with GitLab flow。

 

 以环境分支为例:

 

图 5:环境分支模型

 

每个分支使用场景如下:

 

  • 主分支 Master:用于功能开发,每次代码合并主分支都有流水线进行质量看护,保证主分支随时可以发布到准生产环境;
  • 准生产环境 Pre-Production:用于进行功能与部署方法的测试,只有达到一定质量标准才能发布到生产环境;
  • 生产环境 Production:用于保存发布的软件版本。

 

似乎缺点什么不是吗?

 

对应以上三种主流 flow,基本可以覆盖各类不同复杂度的项目。

 

  • 复杂度 4,同时支持多个并行版本的成熟项目(Git flow):其作者文森特·德里森(Vincent Driessen)表示其过于复杂,不适合持续交付场景下使用;
  • 复杂度 3,支持 DevOps 实践与方法的多环境持续交付项目(GitLab flow):具备成熟的质量管控功能与持续交付能力;
  • 复杂度 1,开源软件的代码托管(GitHub flow):基于代码托管,模型比较简单,可以快速交付,但难以形成研发规范。

 

图 6:主流工作流复杂度对比

 

但,这全面了吗?

 

如果我的企业,既需要敏捷快速迭代(如 GitHub Flow),也需要一定的研发规范、确保安全可控(如 GitLab Flow)呢?

 

 

 

极狐 GitLab 研发团队根据多年实践经验,推出了「极狐 flow」(JiHu flow),既简单易上手(对应上图,复杂度为 2),又兼具团队研发规范性,非常适合在规范保障基础上、强调敏捷创新、快速迭代的项目

 

分支模型如下图:

 

  • 共享开发分支(Develop):用于集成功能分支的代码,由于设置了保护分支,所以应根据需求创建特性分支,通过自动化流水线进行质量看护,经代码评审后合入共享开发分支,同时默认删除特性分支;
  • 主分支(Master):用于正式版本和热修复版本发布。

 

图 7:极狐 flow 分支模型

 

极狐 flow 全景图

 

  • 项目计划:通过敏捷方式进行项目迭代;
  • 代码编写:提交规则进行需求与代码的关联,从 Develop 分支创建特性分支保存功能编码,代码更新后触发持续集成,符合质量要求的代码进入代码评审,减少质量风险,代码负责人可以保证关键代码修改的质量;
  • 开发环境部署:将代码合并到 Develop 分支,自动删除需求分支,通过容器方式进行构建,镜像存入二进制仓库,完成部署后进行集成测试;
  • 测试环境部署:将功能代码从 Develop 分支合并至 Master 分支,自动化测试保证功能完整,通过动态安全检查模拟安全演练,最后进行验收测试;
  • 生产环境发布:通过评审触发正式发布过程,所有软件发布的过程,环境配置都存储在代码仓库中,这是 GitLab 特有的 GitOps 实践。

 

图 8:JiHu flow 全景图

 

极狐 flow 最佳实践

 

分支命名规范

 

正则表达式(如果是小型项目,可省略 develop 分支):

main|develop|(\d+\-(feature|bugfix|hotfix)\-[A-Za-z0-9]+)

 

分支示例

master:主分支

develop:共享开发分支

1-feature-sms-deng-lu:需求分支

2-bugfix-sms-repeat:缺陷分支

3-hotfix-register-failed:热修分支

 

其中数字为需求/缺陷的 ID,所以应当先创建需求/缺陷,再写代码,杜绝「口头加需求」、「口头报 bug」的情况。通过需求分支和合并请求草稿功能,可以方便地为需求人员创建需求分支,暂存代码修改。

 

使用极狐 GitLab 创建需求/缺陷应使用「feature|bugfix|hotfix」开头,可以一键创建符合规范的分支,开发人员再也不用为分支命名发愁。另外中文需求(issue)可自动转化为拼音分支名,例如:Feature:SMS 登录变为 1-feature-sms-deng-lu。

 

 

分支来源与合并

 

feature 和 bugfix 分支来自 develop,完成开发后应合并到 develop,且在合入后自动删除 feature 和 bugfix 分支,减少过多的分支数量。

 

hotfix 分支来自 main,完成开发后应合并到 main,且在合入后自动删除 hotfix 分支。

 

发布时,将功能代码从 develop 合并到 main,合并后不会删除分支。

 

如果是小型项目,无 develop 分支,则 feature、bugfix 和 hotfix 分支都来自 main,也会合入到 main,合并后自动删除多余分支。

 

推荐使用快进式(Fast-forward)合并,而不推荐使用常规合并(产生一条冗余 commit)。

 

如果 commit 有多条调试记录,则应压缩为一条,不得强制使用压缩。

 

可通过极狐 GitLab「设置 → 合并请求」进行设置:

 

 

保护分支

 

所有的公共分支都必须被保护,包括公共开发分支 develop。

 

常见错误:保护了 master,而未保护 develop,大家随意提交 develop,最后 develop 合并到 master,导致未经审核的代码进入生产环境。

 

可通过极狐 GitLab「设置 → 仓库 → 受保护分支」进行限制:

 

 

代码评审

 

禁止将修改代码直接合入分支,必须通过合并请求,由至少另一位开发者进行代码评审,同意后才可合并。

 

评审必须在合并之前,合并后、上线后的评审只能称为「技术分享」,而非「代码评审」。

 

只在临时分支(feature、bugfix、hotfix)合并到公共分支时进行评审,而不评审公共分支的互相合并(比如 develop 合并到 main,单向合并减少评审工作量)。

 

可通过极狐 GitLab「设置 → 合并请求 → 合并请求批准」实现代码管控:

 

 

业务代码中应使用规范扫描工具和配置文件,必须配置本地钩子 .Git/hooks/pre-commit 执行扫描,进行强制检查代码规范。

 

如果项目配置了持续集成流水线,则应该用和本地一致的代码规范进行检查,持续集成流水线必须成功,才可以合并,这也是安灯实践的要求。

 

 

代码评审提出的评审建议,需要全部解决,才可以合并。

 

提交信息规范

 

Git commit 采用 Angular 规范,正则表达式

(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert): #\d+ .+

 

正确示例

feat: #1 sms 登录

fix: #2 sms repeat

fix: #3 register failed

 

英文前缀固定,后半部分可以写汉字等多种语言的文字。

 

其中数字为需求/缺陷的 ID,所以必须先创建需求/缺陷,再写代码,杜绝「口头加需求」、「口头报 bug」的情况。

 

可通过极狐 GitLab「设置 → 仓库 → 推送规则」中,设置正则表达式进行限制:

 

 

提交人员身份检查

 

Git commit 时读取了 Git config user.name 与 user.email,推送到服务器时必须至少校验 email,杜绝「个人邮箱推送到公司项目」的情况。

 

可通过极狐 GitLab「设置 → 仓库 → 推送规则」进行验证:

 

 

禁止提交垃圾文件

 

禁止提交第三方包(比如 jar、node_modules、vendor)、编译打包结果(比如 apk、exe、zip),以及任何大于 4MB 的文件。

 

建议使用 .Gitignore 进行配置,或者可通过极狐 GitLab「设置 → 仓库 → 推送规则」进行限制:

 

 

tag 与版本号规范

 

采用 npm 和语义化规范,版本号不使用 v 前缀,而 Git tag 使用 v 前缀,避免纯数字导致的问题,正则表达式

v(\d+\.){1,2}\d+

 

示例

v0.1

v1.2.0

v2.0.0

 

当提取 Git tag 用作 Docker、maven、npm 等版本号时,应在使用时去除 v 前缀,比如:

https://Github.com/nodejs/node/releases/tag/v19.1.0
 

 

docker pull node:19.1.0

maven se.bjurr.violations:violations-maven-plugin:1.50.4

 

部署

 

推荐使用 GitOps 进行部署,即:

 

  • 遵循「基础设施即代码」的理念,将 K8s yaml、微服务编排配置文件、Terraform 等文件保存于 Git 中,与业务代码分开;
  • 优先使用拉取式部署(无需公网 IP,更安全)而不是推送式部署;
  • 借助 Git 的合并请求进行上线审批,记录可追溯。

 

功能开关

 

多个需求的代码合并之后,在上线之前可能会遇到一个需求代码有严重问题,来不及修复的情况,或者尚未到达业务部门的发布时间(发布会、节日促销等)。此问题不应该从 git 角度解决,因为无论是剔除代码,还是需求分支迟迟不合并,两者的成本都比较高。此时推荐使用功能开关(Feature Flags)。 

 

功能开关可以实现「AB 测试」「先部署,后发布」。研发人员提前部署,将产品功能发布的权力,交给业务部门,提高了协作效率。 

 

 

通过以上 10 个实践,希望帮助所有创新类型的产品进行快速迭代,而又不必牺牲规范性与质量。如果是内部使用产品也可以进一步简化分支模型,只使用 master 分支进行功能开发和版本发布即可。

 

推荐阅读

 

https://docs.Gitlab.cn/
 
 

极狐GitLab 一体化DevOps平台 专为中国用户研发,免费试用60天专业版高级功能
售前咨询
联系电话
在线支持
预约演示