发布与分支

简介: 首先来说一下发布的概念,发布的是什么呢,是故事(story)吗?不是,是特性(feature)! 特性由一个或多个故事组成,单个故事可以验收,但是不能单独上线。比如当你做完了购物车的故事,是不能把单独把它上线的,因为你无法在购物车中进行结算。从用户体验的角度来说,这两个故事要么一起上,要么都不上。

首先来说一下发布的概念,发布的是什么呢,是故事(story)吗?不是,是特性(feature)!

特性由一个或多个故事组成,单个故事可以验收,但是不能单独上线。比如当你做完了购物车的故事,是不能把单独把它上线的,因为你无法在购物车中进行结算。从用户体验的角度来说,这两个故事要么一起上,要么都不上。而且也不是一个特性完成了就可以立马上线的,比如圣诞大促的功能做完了,也要等到圣诞节来了才能上。

特性分支

一种管理特性发布的模式是使用特性分支,对每一个特性都会拉出一个分支,完全开发结束之后再合并回来。比如下面这个图,点击这里查看原文。

然而这种模式是有风险的,Martin Fowler对这种模式进行了论述。

Martin Fowler在文章中提到了很多点,这里只强调一点,即多分支下的持续集成问题。假设现在存在三个并行的特性分支,那么加上develop分支就存在四个活跃的分支。持续集成流水线应该去监控哪个分支呢?如果只监控develop分支,其它分支的提交就无法得到持续集成的验证,也就是说大部分情况下开发人员享受不到持续集成的好处。

那么如果每开一个分支就为它建立一个持续集成呢?首先它不是真正的持续集成,因为并不是所有的代码都集成在了一起;其次这么做的代价也会比较大。一个基本的部署流水线应该包括编译、单元测试、打包、功能/集成测试、发布这些步骤,如下图所示:

one_pipeline

其中单元测试的环节会包含编译、单元测试和打包;集成测试环节中会运行集成测试;发布环节中会进行部署。如果要对每个分支都建立一套这样的流水线,就会存在很多的重复配置,如果想要更改,则需要改多处;而且每个流水线是独立的,也很难有一个全貌能够让我知道现在都有哪些流水线。我曾经工作过的一个项目使用Jenkins做持续集成,因为持续集成配置过于复杂,我们甚至编写了一个脚本调用Jenkins的API来复制一整套流水线,如果使用CRP来做这件事情的话,就简单多了,我会在下一篇文章会讨论CRP中多分支持续集成的配置

主干开发加release分支

另一种常见的模式是只有两个分支:developrelease。所有开发人员都在develop上进行开发,项目进行周期性发布。在每次发布之前,开发人员应该完成所有功能,然后从develop上拉出一个release分支,在上面进行测试和bug fix(这些bug fix也应该及时合回到主干)。一旦release分支稳定了,则打个tag,进行发布。

如果线上出现bug要如何处理呢?从上次打的tag拉出一个临时的hotfix分支,修复之后合并到release分支进行发布。

这里也需要管理两个分支,所以持续集成流水线也应该有两套,还是存在重复。但同样的,有了CRP对多分支持续集成的支持 ,就可以把这部分成本省掉。

这种模式可以避免分支过多的问题,但也会有两个限制:

  1. 需要进行周期性发布。因为所有功能都在一个分支上,不加限制的话,任何时刻总会存在开发到一半的功能。所以必须有一个发布周期,在发布周期开始时做好计划,确定要发布的内容,然后在周期结束之前把计划的功能全都完成才能开始上线流程。如果发布的特性在一个发布周期内完不成,则需要延迟发布。更夸张的情况是如果在圣诞节前半个月就完成了圣诞大促的功能,那么在圣诞节前的这两周内,都不能做任何发布。
  2. 需要限制hotfix分支的使用。hotfix只能用来处理一些可以快速修复的线上问题,而对于有一定工作量的紧急需求则不适用,否则就又会出现一个分支上的代码长时间得不到集成的问题。而且如果在一个紧急需求完成之前,再开始做一个紧急需求的话,则又变回了特性分支的模式。

主干开发加功能开关

为了解决上述的第一个限制,可以考虑引入特性开关。即每个特性都可以通过简单的修改被隐藏掉,这样所有的特性可以同时存在于主干上,但是又互相不影响对方的发布。

特性开关不仅仅是一个技术问题,更是一个业务问题。比如一个新特性做完了,但是产品经理不确定用户是否需要它,所以需要先发布出去试运行一下。如果发现用户其实不需要它,则需要去除该功能。这个时候,开发人员就需要花费一些时间来仔细地把嵌入在代码库中的与该特性有关的逻辑都去除掉。但如果有了特性开关,就可以快速又安全地关掉这个功能。

特性开关,听起来容易,但其实要做的事情还是很多的。这里只强调两点:

  1. 特性开关在发布前默认关闭,这时不仅要保证所有其它的特性(包括没有开关控制的特性和开关已经打开的特性)都是正常工作的。还要保证这个特性没有暴漏出去。
  2. 当准备要发布时,会打开开关。这时也要保证在发布之后,如果我关闭开关,能够真正把这个特性隐藏掉,以便能够在需要时快速下掉这个功能。

这两点都需要更多的工作量,具体做法请参看这篇文章

那么在这种模式下,如果有线上bug要紧急修复该怎么做呢?是否可以直接在主干上进行修复,然后发布呢?理论上来说是可行的的,当然前提是你按照上述文章中的做法对软件的各种开关处在不同状态时进行了充分的测试。如果对已有的自动化测试不够有信心,还是可以保留一个hotfix的分支,从而可以有信心快速对问题进行修复,并上线。

总结

总结一下,分支过多会引入一些问题,而使用特性开关可以避免过多的分支,当然也会引入额外的很多代价。如果你的测试做的充分,就可以潇洒地只使用一个分支;但保留一个hotfix分支可以让你的线上问题修复更加从容。

只保留一个分支不一定是最好的做法,有多个分支也并非一定是坏掉,要根据自己的实际情况作出明智的选择。如果你决定要使用超过一个分支,请参看CRP中多分支持续集成的配置

目录
相关文章
|
安全 jenkins 持续交付
Jenkins针对不同的项目视图对不同的用户进行权限分配
Jenkins创建用户并分配不同视图的权限 根据不同的部门分配不同的角色,角色成员只能看到自己部门视图内部的jenkins job Jenkins版本:2.249 因安装了中文包的原因,语言大多以中文的方式显示,但不影响配置使用
2330 0
Jenkins针对不同的项目视图对不同的用户进行权限分配
|
前端开发 网络协议 Dubbo
超详细Netty入门,看这篇就够了!
本文主要讲述Netty框架的一些特性以及重要组件,希望看完之后能对Netty框架有一个比较直观的感受,希望能帮助读者快速入门Netty,减少一些弯路。
93024 32
超详细Netty入门,看这篇就够了!
|
XML SQL Java
mybatis-plus异常记录:org.apache.ibatis.binding.BindingException Invalid bound statement
mybatis-plus异常记录:org.apache.ibatis.binding.BindingException Invalid bound statement
2406 0
mybatis-plus异常记录:org.apache.ibatis.binding.BindingException Invalid bound statement
|
小程序 开发工具 Android开发
mpaas小程序问题之在x86模拟器下会打不开如何解决
mPaaS小程序是阿里巴巴移动平台服务(mPaaS)推出的一种轻量级应用解决方案,旨在帮助开发者快速构建跨平台的小程序应用;本合集将聚焦mPaaS小程序的开发流程、技术架构和最佳实践,以及如何解决开发中遇到的问题,从而助力开发者高效打造和维护小程序应用。
168 3
mpaas小程序问题之在x86模拟器下会打不开如何解决
|
机器学习/深度学习 人工智能 搜索推荐
人工智能在医疗诊断中的作用是医疗领域中的一个重要应用方向。
人工智能在医疗诊断中的作用是医疗领域中的一个重要应用方向。
阿里云香港云服务器有什么好处?最新价格是多少?
本文介绍了选择阿里云香港云服务器的一些好处以及香港地域云服务器的最新价格
716 0
阿里云香港云服务器有什么好处?最新价格是多少?
|
SQL 关系型数据库 数据库
PostgreSQL 如何潇洒的处理每天上百TB的数据增量
本文主要介绍并测试一下PostgreSQL 在中高端x86服务器上的数据插入速度,帮助企业用户了解PostgreSQL在这种纯插入场景的性能。(例如运营商网关数据,金融行业数据,产生量大,并且要求快速插入大数据库中持久化保存。) 测试结果写在前面:每32K的block存储89条记录, 每条记录约3
39971 131
|
Oracle 关系型数据库 Linux
|
程序员
缺陷(bug)管理
理论上软件的缺陷是可修复的,不过有的修复成本比较高,不能追求软件的完美,根据风险来确定是否修复缺陷
|
Java