Git 提供了丰盛的分支策略和工作流形式,咱们在深刻学习业界 Git 工作流时,每种工作流都设计的十分好,仿佛都能使用到团队实际。但在引入 Git 工作流标准开发时要注意:Git 工作流仅仅是整个研发流程中的一环。上游项目管理/缺点追踪零碎虎视眈眈,上游 CD (Continuous Delivery) 嗷嗷待哺,还得思考团队规模、产品状态、发版形式等等因素。因而,在团队中落地 Git 工作流标准并不是一件能轻松决定的事。
字节跳动 Git 仓库无效的 CR (Code Review) 覆盖率 70%,仍有晋升空间,通过调研,团队中又以 GitHub Flow 模式居多。随着字节研发效力建设愈发欠缺,GitHub Flow 已无奈充分利用研发设施进行提效并保障工程质量,很多团队均意识到这点并着手建设流程标准。
本文通过介绍业界 Git 工作流和公司研发设施现状,力求从仓库状态、部署流程等多角度进行剖析,给出一些制订工作流标准的倡议。
业界 Git 工作流介绍
Git Flow
高级 Git 开发者,面对这满图的分支和 merge 指向,几乎想手撕作者。高级 Git 开发者要将这个流程使用实际也大感头疼。
Git Flow 有不少长处:
- 分支各司其职,笼罩大部分开发场景。
- 预期 master 分支中任何 commit 都是可部署的。
- 严格依照流程执行,呈现重大事故的情景会大大降低。
毛病也不少:
- 过于繁琐,无奈要求所有团队成员依照这个流程严格执行。
- 违反 git 提倡的 short-lived 分支准则。
- master 分支历史记录并不洁净,只能通过打 Tag 标记哪些是 master 真正要部署的。
- 对继续部署和 monorepo 仓库不敌对。
GitHub Flow
GitHub Flow 是一个基于分支的轻量级工作流。它突出了 CR 的重要性,有助于咱们把握 CR 的开发模式,但它没有解答部署、环境、公布、集成等问题。
GitLab Flow
GitLab Flow 并不像 Git Flow, GitHub Flow 一样具备显著的标准,它更多是在 GitHub Flow 根底上,综合思考环境部署、项目管理等问题而得出的一种实际。
基于环境:
基于公布打算:
Trunk-based Flow
和“基于公布打算”的 GitLab Flow 相似,有一个骨干分支承受所有开发者的 commit,并为后续 CI/CD 提供要害助力。
依照官网文档形容:「你能够抉择间接向骨干分支提交代码的形式(实用于小团队)或者采纳 Pull-Request 的形式,只有保障个性分支不能长期存在,并且产品是独立存在的。(the product of a single person.)」,trunk 分支提交是比拟随便的(不肯定可部署),但也须要走 CR,能够采纳 Fast-forward 模式的 merge 保障骨干是一条线,到了适合的工夫点,checkout release-* 分支,执行正式上线操作。
一旦发现 release 分支有 hotfix 需要,则先在 trunk 分支上进行 fix 开发,测试实现后,cherry-pick 到 release- 分支,确保修复代码即在 release- 中上线,又能被下一个 release 周期蕴含。
Aone Flow
按阿里云开发者社区形容:Aone Flow「根底玩法是将每条公布分支与具体的环境绝对应,比方 release/test 分支对应部署测试环境,release/prod 分支对应线上正式环境」,这种公布形式可保障每个feature 都被测试,但不能保障 release/test CI 通过的 feature,能在 release/prod 环境也通过(feature pick 组合不同)。
「进阶点的玩法是将一个公布分支对应多个环境,比方把灰度公布和正式公布串在一起,两头加上人工验收的步骤」。本质是将根底玩法中的“release/test”,“release/prod” 改成 “release/combine-feature”,固定了 feature pick 组合,保障 features 在各个环境测试的一致性。
Aone Flow 的 pick 模式,适宜简单仓库大团队继续上线,防止了 Trunk-based Flow 引入未实现 feature 的问题。但仿佛不适宜周期发版的要求。一个发版周期内会创立多个 feature ,上一个发版周期可能遗留若干 feature,随着时间推移,feature 数越来越多,最终发版人在 pick feature 过程中疯掉。
公司实际
字节跳动的 Web 服务都跑在公有云 CE (Compute Engine) 中,部署产物则由对立的代码编译公布和版本治理平台散发,每个构建产物都有一个 AR (Artifact Repository) 治理。
多环境部署现状
服务端视角
服务端微服务跑在 CE 上,代码编译由 AR 实现,CE 和 AR 是 1:N 的关系,一个利用的运行依赖多个 AR,在进行环境治理时,须要以 CE 为纬度来辨别。
从 CE 视角来看,公司有 5 类环境(以国内产品为例):
通过 headers -H 'x-env-tag:{env}'
将流量导向不同环境,满足“开发测试”、“QA测试”、“预发测试”、“小流量测试”、“全量上线” 各阶段的测试需要。
CE 测试环境服务示例:
前端视角
前端和服务端有差别,一个 URL path 拜访的资源通常由一个 AR 产出,URL paths 和 AR 是 N:1 关系,所以前端部署以 AR 版本来辨别环境:
前端部署可为测试环境和产品预览环境生成独立的域名进行测试,也可通过设定 headers -H 'x-env-tag:{env}'
进行环境导流。
团队实际的 Git 工作流
联合前后端的环境现状,可整顿三类研发流程:
- 功能测试流程(测试环境)
- QA 提测流程(测试环境)
- 上线公布流程(测试、预发、灰度、线上环境)
公司内目前有三种 Git 工作流与之对应:
- 小步快跑:单骨干
- 周期发版:双骨干
- 周期发版:三骨干
比照”双骨干“和”单骨干“,
有分割:
- 处于 MR 状态的迭代分支 ≈≈ 研发骨干 Dev
- 单骨干 Master ≈≈ 公布骨干 Master
也有区别:
- 单骨干的“研发分支”不存在一个固定的测试环境(相较于双骨干 dev 分支)
- 多个 feature 同时发测试环境时须要组合成新分支,治理不便
- 单骨干迭代分支在 MR /非 MR 状态下的 CI 流水线有差别
单骨干实际
前端微服务治理平台
字节前端微服务平台属于成熟业务,只需做大量 feature/fix 开发,在工作流上采纳单骨干模式。
本地测试后,不再通过功能测试环境测试。发动 Merge Request,CR 通过合码后,上测试基准环境进行测试,如发现问题,回滚,进入下一轮 CR。
尽管小修小改影响危险小,但流程不足进入功能测试环境的流程,还是存在隐患,有可能影响测试环境的业务方应用,不是很好的实际。
单骨干只适应于业务规模小,成熟度高无大改变的我的项目。但无论业务规模如何,执行上线公布流程前,都必须先通过线下环境验证。
双骨干实际
公有云平台
云平台的 Git 工作流是由繁入简的过程。最开始为每个部署环境设定了一个部署分支。feature 分支的 commit 点须要和三个环境的部署分支产生 merge,起不到串联测试的目标。
通过改良后,采纳规范的 Trunk-based Flow,仍能满足 online/sandbox/boe 三个环境的部署要求。
云平台参加业务方有上百个(相似阿里云平台),尽管图中仅展现了三个环境,但实际上5大环境的应用都融入了日常开发中。
某业务中台
某业务中台的 Git 工作流重点论述了同一个我的项目多人合作开发时会遇到的问题:
- 多个 feature 各自独立提测, 邻近上线合码时有较多抵触, 可能导致线上 bug
- 提测前和提测中, 如果 master 更新了, 可能没有及时同步下来, 上线前合入 master 可能会导致抵触或 bug
- 在流程设计上,master 作为公布分支,release-* 为提测分支,联合了单骨干的便捷(hotfix 间接和 master 交互)和双骨干对 feature 的治理
- 和 Trunk-based Flow 刚好相同,主分支是公布分支,提测分支是短期的
- 另一个比拟有特点的是,在 release 测试过程中,发现某个 feature 的 bug, 间接从 release 分支 checkout 进去进行修复,并再次合入 release
Jupiter 工作流标准
Jupiter 是字节 Web 开发引擎,笼罩 Web、组件库、BFF、SSR 等前端开发畛域。Jupiter 举荐 Trunk-based Flow 相似的 Flow,并从 CI/CD 角度登程,在开发新需要、hotfix 等机会给出 Git 操作倡议。
- 有重叠人员参加的各我的项目之间有统一的流程和模式,防止减少认知累赘,防止同一个人在不同我的项目之间切换时混同和蛊惑,也能集中力量做实际和改良,共享教训和根底建设。
- 上线节奏要灵便。既关照晚期的我的项目,也关照规模化落地的我的项目,思考到我的项目在谋求不同里程碑时,上线频率会有变动。所以每周上线一次、每天上线一次(适宜人多、稳定性要求高的我的项目)、一天内分屡次上线多个 feature,都有可能,不能限定一个固定的节奏。任何人,在任何时候都能够发动上线。
- 反对 monorepo。不同方向不同人参加的我的项目,可能会共用一个仓库,不便复用代码和基础设施。所以仓库中不同我的项目可能有不一样的上线节奏和上线需要。
- 激励继续集成(CI),集成不等同于部署,发 MR 集成代码的时候不必有压力,不会在不知情的状况下被上线。也激励继续部署(CD),部署不等于公布,不能公布的代码,在正式上线前有机会关掉。
- 上线过程必须是固定、反复、能对立改良,能逐渐减少自动化的,不能每次上线时从新、长期布局或批改上线办法,减少累赘和老本。
- CI 是 CD 的前提,没通过 CI 的批改不能进入 CD 环节。
- 不能有任何批改不通过 staging(预公布,尽可能跟线上统一)测试,间接上线。
- CI 和 CD 的历史记录要相对牢靠、可追溯,只能减少,不能缩小和批改。
- 尽可能减少手动操作环节,防止在特定的集体机器上做上线操作。
三骨干实际
亿级 App
App 发版应该是目前为止最为简单的分支治理场景了。客户端安装包一旦下发到渠道被用户下载,如果无奈通过热更新修复,将重大影响 App 用户留存。
App 发版具备更标准的发版法则,Feature Toggle 必不可少,当咱们感觉 CR,CI/CD 麻烦时,比照开发上线一个影响上亿用户的 App feature,是不是感觉做 Web 的 CI/CD 简略多了?
总结
本文尽可能从多角度论述 Git 工作流的应用姿态,心愿对大家有帮忙。Git 工作流是为了上线有保障,上线过程中充沛测试必不可少,良好的 Git 工作流能保障测试是渐进且牢靠的。环境治理和 Git 工作流联合在头条外部也造成了很多标准,包含「环境部署」、「流量调度」、「连通性测试」等应用标准;「限定场景容许」、「临时场景容许」、「限定流程容许」等环境束缚标准。再联合 CI/CD,咱们就能够全链路保障业务的疾速迭代、平安上线。