发布与分支

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

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

特性分支

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

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

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

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

其中单元测试的环节会包含编译、单元测试和打包;集成测试环节中会运行集成测试;发布环节中会进行部署。如果要对每个分支都建立一套这样的流水线,就会存在很多的重复配置,如果想要更改,则需要改多处;而且每个流水线是独立的,也很难有一个全貌能够让我知道现在都有哪些流水线。我曾经工作过的一个项目使用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中多分支持续集成的配置。

时间: 2024-10-24 00:30:41

发布与分支的相关文章

Git分支本地操作详解

引言 在上一节中我们对Git的常用本地操作的命令进行详解,而本节要讲解的是Git的分支, 在讲解之前补充两点概念性的东西: 第一个: 第一节中一个读者提出的疑问,Git和SVN在版本控制中存储方式版本信息的差异. 答:Git关心文件的整体是否发生变化,而SVN则关心的是文件内容的具体差异! SVN每次记录的是有哪些文件进行了修改,以及修改了哪些行的哪些内容: 如上图,比如版本2中记录的是文件A以及文件C的变化,而版本3中仅仅记录文件C 的变化这样,以此类推:而Git并不保存这些前后变化的差异数据

CRP中多分支持续集成的配置

在上一篇发布与分支中,我们讨论了几种经典的发布模式.如果你最终选择在发布中使用分支,那么就来看看CRP中对多分支持续集成的支持吧. 假设你有dev和hotfix两个分支,主要功能都在dev分支上开发,而对于线上的紧急bug,则走hotfix分支进行修复. 针对dev分支的持续交付线 先看一个针对dev分支的发布线配置: 触发器的配置: 单元测试stage的配置: 集成测试stage的配置: 发布stage的配置: 把hotfix也加进来 1.把第一个单元测试的stage拆分成两个: dev分支更

版本控制的分支策略及初步实践

这几天在网上查询了一些资料,了解到比较常见的版本控制分支策略有三种:不稳定主干策略.稳定主干策略.敏捷发布策略. 下面是对这几种策略的摘录: 不稳定主干策略 使用用主干作为新功能开发主线,分支用作发布. 被广泛的应用于开源项目. 比较适合诸如传统软件产品的开发模式,比如微软的office等. bug修改需要在各个分支中合并. 新代码在主干上开发,因此如果主干不能达到稳定的标准,就不可以进行发布. 这种策略的好处是没有分支合并的工作量,因此比较简单. 稳定主干策略 使用主干作为稳定版的发布. bu

分布式版本控制Git分支管理策略及使用规范流程

Git分支管理策略 目前最流行的"版本管理系统",非Git莫属. 相比同类软件,Git有很多优点.其中很显著的一点,就是版本的分支(branch)和合并(merge)十分方便.有些传统的版本管理软件,分支操作实际上会生成一份现有代码的物理拷贝,而Git只生成一个指向当前版本(又称"快照")的指针,因此非常快捷易用. 但是,太方便了也会产生副作用.如果你不加注意,很可能会留下一个枝节蔓生.四处开放的版本库,到处都是分支,完全看不出主干发展的脉络. Vincent Dr

详解Android的自动化构建及发布

在一个App从开发到测试的过程中,我有很长一段时间都是这样做的:打包,上传到tower,在tower上编写本次更新说明,通知测试.一般情况下,打包及上传的过程大概也就2分钟.除此之外,由于项目代码有作混淆,并且使用了bugly,因此在发出每个版本之后还需要将混淆的mapping.txt传到bugly上.当日复一日,并且有时还遇到网络较差的情况时,这种人工手动的工作方式就很影响工作效率及心情了.因此,自动化构建及发布就成了必须掌握的技能了. 本篇分享的是我在Android自动化构建的一些经验,涉及

RDBMS家族:商业推新,开源逆袭

目录: [RDBMS家族] Oracle 12c Release 2文档发布 12c Release 2特性解读 MySQL MySQL 5.7 新特性解读 MySQL分支Percona Percona 5.7.16-10发布 MySQL分支MariaDB MariaDB 10.1.19 发布 SQL Server SQL Server 2016 SP1补丁包发布 SQL Server  On Linux版本发布 PostgreSQL PostgreSQL 9.6发布 PostgreSQL 9.

DBAplus Newsletter:这也许是最全的技术圈动态解读

目录: [DBAplus Newsletter] 推出DBAplus Newsletter的想法 做Newsletter的目的 做Newsletter的底线 对Newsletter的态度 Newsletter发布周期 Newsletter简单声明 DB-Engines数据库排行榜解读 SQL.NoSQL及NewSQL的发展历程 [RDBMS家族] Oracle 12c Release 2文档发布 12c Release 2特性解读 MySQL MySQL 5.7 新特性解读 MySQL分支Per

Hadoop 版本 生态圈 MapReduce模型

(1) Apache Hadoop版本介绍 Apache的开源项目开发流程 : -- 主干分支 : 新功能都是在 主干分支(trunk)上开发; -- 特性独有分支 : 很多新特性稳定性很差, 或者不完善, 在这些分支的独有特定很完善之后, 该分支就会并入主干分支; -- 候选分支 : 定期从主干分支剥离, 一般候选分支发布, 该分支就会停止更新新功能, 如果候选分支有BUG修复, 就会重新针对该候选分支发布一个新版本;候选分支就是发布的稳定版本; 造成Hadoop版本混乱的原因 : -- 主要

《软件定义网络:基于OpenFlow的SDN》一一3.2 已有的实现方案

3.2 已有的实现方案 目前存在不同的OpenFlow(以及SDN)控制器实现方案,我们将把它们作为现有开源项目的组成部分,放在第8章中详细介绍.本章内容主要集中在NOX.POX.NodeFlow.Floodlight(派生自Beacon)和OpenDaylight方面,通过这些实现方案介绍若干OpenFlow控制器,以及在开发网络应用时各种可选的编程语言.3.2.1 NOX和POX 第一个OpenFlow控制器是用C++编写的NOX(www.noxrepo.org),它同时还提供了用于Pyth