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,咱们就能够全链路保障业务的疾速迭代、平安上线。