【阅读笔记】《持续交付2.0》中理解分支、发布策略

news2024/11/24 18:46:07

文章目录

    • 1. 前言
      • 1.1 分支、发布 管理上解耦
    • 2. 主干 (Trunk) 和分支 (Branch)
      • 2.1 Trunk 开发 Trunk 发布
        • 2.1.1 Trunk 开发 Trunk 发布需要解决:重构的需求
        • 2.1.2 Trunk 开发 Trunk 发布需要解决:未开发完成的功能被带入发布版本
      • 2.2 Trunk 开发 Branch 发布
        • 2.2.1 Trunk 开发 Branch 发布较好的应用场景
        • 2.2.2 Trunk 开发 Branch 发布需要解决:开发窗口期割裂
      • 2.3 Branch 开发 Trunk 发布
        • Branch 开发 Trunk 发布需要解决:冲突频出
    • 3. 分支演进
      • 3.1 三驾马车 分支模式
      • 3.2 GitFlow 分支模式
      • 3.3 GitHubFlow 分支模式
    • 4. 发布模式
      • 4.1 项目制发布模式
      • 4.2 发布火车模式
      • 4.3 城际快线
    • 5. 怎么选分支模式和发布策略
      • 5.1 为什么这么选?
        • 5.1.1 业务上
        • 5.1.2 代码管理上
        • 5.1.3 技术更替上
        • 5.1.4 流水线构建
      • 5.2 其他选择
    • 6. 后记
    • 7. 参考

1. 前言

这本书扫盲了 “交付” 的方法论。之前工作过的公司都不会仅仅用一种方法。包括但不限于敏捷、极限编程。所有理论都是因地制宜的,公司往往不会是纯粹的xx理论遵循者,比如团队中既有 Scum master 角色(来自敏捷),也用 User Story 管理需求 (来自极限编程)。方法都是发展过来的,永远保持学习的心态。本文主要整理下书中出现的分支策略,并加以理解。如果分支策略更好的支持持续交付,则认为这种策略是有前景的。另外,分支策略的选择和发布方式也紧密相关,文章最后会给出个综合策略,以后会持续维护这篇文章,有更新的想法会更新到后记去。

1.1 分支、发布 管理上解耦

  • 语义维度
    • 主干可以发布到 UAT 环境 、预发环境、生产环境。
    • 分支同样可以发布到以上的三种环境。
  • 发布与分支质量相关
    • 多久一次发布,会决定分支的存活时间,从而影响分支合入后的冲突情况。

把 分支、发布 管理分开来,有利于自由组合成公司理想的运作方式。

2. 主干 (Trunk) 和分支 (Branch)

  • Trunk
    用这个单词表示主干,团队中可能也用master表示主干,这里用 Trunk 统一一下语义,不再提master

  • Branch
    区分于主干的其他分支,都称为 Branch

2.1 Trunk 开发 Trunk 发布

所有人都基于 Trunk 检出自己的私有分支,并且上线前合入 Trunk 。

2.1.1 Trunk 开发 Trunk 发布需要解决:重构的需求

该模式的明显缺点是,如果私有分支长时间未合入或者改动范围过大、则有可能再也合不进了。如 2011 年百姓网的失败案例:从 Trunk 检出重构的专有分支用于重构某个重要模块,但是一周后发现与当前 Trunk 冲突过多,最终放弃合入。

  • 后文将提到抽象分支的管理技术,让重构更好落地

2.1.2 Trunk 开发 Trunk 发布需要解决:未开发完成的功能被带入发布版本

该模式另外一个缺点是,Trunk 发布前工程师不好提交其他迭代的代码,如果未经测试的代码被发布,安全隐患十分大。

  • 后文将抽象分支、开关技术可以解决

2.2 Trunk 开发 Branch 发布

开发人员将写好的代码提交到 Trunk,当 Trunk 分支上的代码符合发布规范后,从 Trunk 检出一个 Branch 用于发布, Branch 上的 bugfix 都提交到自身上去,决定是否合入 Trunk 看是不是公用的功能。这么做的好处是,尽量不携带未开发完成的功能进行发布,同时 Branch 检出后,其他人还能在 Trunk 上面增量开发。

2.2.1 Trunk 开发 Branch 发布较好的应用场景

  • 开源项目
    没有发布时间的压力

  • 系列化产品族 + 个性化定制
    不同产品族的代码可能不需要再合入 Trunk

2.2.2 Trunk 开发 Branch 发布需要解决:开发窗口期割裂

Branch V1.0 要被检出用于发布前,Branch V2.0 是不好在 Trunk 上面增加代码的。V1.0 和 V2.0 的开开发窗口不能有重合。


2.3 Branch 开发 Trunk 发布

笔者(博客)所经历的公司都是用这种模式。每个特性都从 Trunk 检出一个 Branch ,每个Branch互不干扰。Branch 验收通过后,合入 Trunk,将 Trunk 发布。

Branch 开发 Trunk 发布需要解决:冲突频出

每个 Branch 互不干涉,并且上线前都不会合入 Trunk,两个 Branch 相继合入可能会发生冲突,并且冲突存在的时间可能已经很久了,解决起来会比较棘手。


3. 分支演进

上文提到了 Trunk 和 Branch 的区别,文章后文把 Trunk 和 Branch 的概念都融入进 “分支” 里了,比如发布分支其实指的就是上文的 Trunk。

3.1 三驾马车 分支模式

常用于客户端软件。开发 Branch 会把commit 都 cherry-pick 到 预发 Branch 上,在预发上进行bug修复等工作,修复完成后会把预发 Branch 依次发布为 Alpha 版本给极少的用户使用,Alpha验收完成后接着发布为 Beta版本。Beta验收通过后,把预发 Branch merge 进 发布分支。

3.2 GitFlow 分支模式

实质上是Develop 作为开发分支,Release 作为预发分支,Master 作为发布分支。是三驾马车的演进版本。新增的 Hotfix 用于支撑快速的bug修复,Feature 用于区分不同特性,让开发分支接收更频繁的合入,把冲突暴露到更早的时候。
在这里插入图片描述

  • Hotfix
    直接从 Master 检出,解决bug后合入 Master 和 Develop

  • Develop
    所有特性分支的载体,同时保持 Hotfix 都要存在 ,避免特性分支检出的是带bug的代码。

  • Feature
    从 Develop 检出并合入 Develop

  • Release
    Develop 中阶段性的所有 Feature 都达到可发布的状态,则检出一个 Release

  • Master
    用于发布 Release 或者接收 Hotfix


3.3 GitHubFlow 分支模式

是 Trunk 开发 Trunk 发布的落地方案。
在这里插入图片描述
比起 GitFlow ,这种方案简单不少。笔者(博客)在公司里主要也是用这种,直接从Master 检出多个Featrue 分支,Featrue 需要上线的话,提交 Pull Request,leader 控制 merge 这个 Request 后即可把 Master 发布了 (发布到UAT环境或者是PRODUCT环境)。

4. 发布模式

发布模式,是想体现什么指标完成后必须要发布一个版本。具体指标

  • 项目制 (里程碑)
  • 时间(迭代周期)
  • 特性数

4.1 项目制发布模式

交付周期较长,参与的人较多。常常需要一个里程碑作为版本的描述,比如:“供应商入驻版本”。

4.2 发布火车模式

严格按照迭代周期走,一个月一个版本或者两周一个版本,无论迭代周期参生了多少个需求、特性。

4.3 城际快线

比发布火车更频繁,一周或者一天的迭代,所有特性都可以选择搭乘某一个 “快线” 进行发布。城际快线更符合持续交付2.0的思想。

5. 怎么选分支模式和发布策略

书中认为的最佳实践:

  • GitHubFlow 分支模式 + 城际快线发布。

5.1 为什么这么选?

5.1.1 业务上

鼓励把需求拆分的很细,持续的与客户进行交流,了解客户的真实需求。得到的反馈越早,需求价值越高。

5.1.2 代码管理上

避免分支代码存在太久造成冲突无法解决。也避免分支层级过多造成管理上的困难 (如GitFlow多达5种的分支类型)

5.1.3 技术更替上

把重构任务分散到许多小的发布上,可以很好利用积少成多的特点把重构逐步完成,避免重构分支创建出来,经历的迭代太多而造成冲突无法合入主干,这也就是书中提到的 “抽象分支”。

5.1.4 流水线构建

有多少个环境就建立多少个流水线。

  • Master 分支用于发布的,建立一条流水线 (1)
  • Master 检出 Feature 分支
    • 针对 Feature 分支 可以创建 SIT 的流水线 (2)
    • 争对 Feature 分支 可以创建 UAT 的流水线 (3)

5.2 其他选择

笔者经历的其他实践:

  • GitHubFlow 分支模式 + 发布火车发布
    需求都要集中验证的情况下,特别是迭代周期较长,只需要一个开发分支即可。

  • GitFlow 分支模式 + 城际快线发布
    不同需求的迭代周期不同,则每个需求都会有一个开发分支。

6. 后记

分支、发布策略的组合都是管理者的考量,其实是各有特点的,不需要排斥。在至少有测试环境(UAT)、生产环境并存的情况下。笔者认为,在 GitHubFlow 分支模式下添加个用于测试环境流水线的 Dev分支更加合理。综上,笔者总结的策略如下:

  • 一个 Master 分支用于发布线上环境
  • 一个 Dev 分支用于发布到测试环境
  • 基于 Master 检出多个 Feature 分支用于开发新功能 (迭代周期长可以多人共用一个Feature)
  • 基于 Master 检出多个 Bugfix 分支用于紧急修复
  • Feature 、Bugfix 分支要合入 Dev 并发布到测试环境验证
  • Feature 分支验证通过后合入 Master 最终发布到线上环境

7. 参考

Git flow分支管理策略

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/114709.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

leetcode:6272. 好分区的数目【思维转换(正难则反) + dp定义 + 背包问题 + 选or不选】

目录题目截图题目分析ac code总结题目截图 题目分析 先特判&#xff0c;如果sum(nums) < 2 * k显然不可能成功&#xff01;返回0出现Mod大概率就是dp1000的话提示我们用平方复杂度的dp这种取子序列的问题&#xff0c;本质就是选or不选的问题如果我们只考虑一维dp,dp[i]肯定…

Linux--信号

目录1. 信号概念2. 信号产生前2.1 信号产生的各种方式3. 信号产生中信号保存的方式3.1 阻塞信号3.2 信号屏蔽字4. 信号产生后信号处理的方式4.1 信号集操作函数4.2 sigprocmask函数4.3 sigpending函数4.4 sigaction函数5. 信号是什么时候被处理的1. 信号概念 信号是进程之间事…

golang访问KingbaseES V8R6

概述 本文介绍go语言连接KingbaseES V8R6数据库的步骤 测试环境 操作系统&#xff1a;CentOS 7.2.1511 数据库版本&#xff1a;KINGBASE (KingbaseES) V008R006C007B0012 go版本&#xff1a;go version go1.19.4 linux/amd64 KingbaseES go驱动获取 go连接kingbase数据库需…

MySQL为什么使用B+树为索引结构

目录 1、什么是索引 2、索引的类型 3、为什么要用索引 4、索引的使用场景 5、索引为什么要用B树&#xff0c;为什么不能用二叉树、红黑树、B树&#xff1f; 介绍一款可以帮助理解数据结构的网站&#xff08;很好用&#xff09;&#xff1a;Data Structure Visualization …

hadoop生产调优之Hadoop-Yarn 生产经验(参数调优)

一、常用的调优参数 1&#xff09;调优参数列表 &#xff08;1&#xff09;Resourcemanager 相关 yarn.resourcemanager.scheduler.client.thread-count ResourceManager 处理调度器请求的线程数量 yarn.resourcemanager.scheduler.class 配置调度器&#xff08;2&#xff0…

js中ArrayBuffer和node中Buffer的关系和区别

ArrayBuffer 对象用来表示通用的、固定长度的原始二进制数据缓冲区。 它是一个字节数组&#xff0c;通常在其他语言中称为“byte array”。你不能直接操作 ArrayBuffer 中的内容&#xff1b;而是要通过类型化数组对象或 DataView 对象来操作&#xff0c;它们会将缓冲区中的数据…

C++、python、VS code插件安装与SSH使用

下载按照VS coda 官网&#xff1a;https://code.visualstudio.com 1.安装相关插件 1.中文插件&#xff08;可选&#xff09; MS-CEINTL.vscode-language-pack-zh-hans 2.C插件&#xff08;必选&#xff09; ms-vscode.cpptools 3.ssh 远程&#xff08;必选&#xff09; ms-vs…

数据结构——快排的三种实现方式

坚持看完&#xff0c;结尾有思维导图总结 这里写目录标题什么是快排&#xff1f;如何实现递归单次的排序要如何实现hore 的办法![在这里插入图片描述](https://img-blog.csdnimg.cn/40b2ac63f2424bd1828a45f8509ff116.gif#pic_center)坑位法双指针法总结什么是快排&#xff1f;…

线程池(一)

个人博客地址&#xff1a; http://xiaohe-blog.top/index.php/archives/14/ 文章目录1. 为什么要使用线程池2. Executor3. ThreadPoolExecutor3.1 七个参数3.2 任务队列3.3 拒绝策略4. 创建线程池5. Executors5.1 CachedThreadPool5.2 FixedThreadPool5.3 SingleThreadExecutor…

SAP UI5 应用里一些容器控件的介绍

sap.m.Shell 控件可用作应用程序的根元素。 它可以包含 App 或 SplitApp 控件。 Shell 为整个应用程序提供了一些总体功能&#xff0c;并负责在桌面浏览器平台上进行视觉适配&#xff0c;例如应用程序周围的框架。 sap.m.App: 该 App 继承自 sap.m.NavContainer 并因此提供其导…

VUEElement 学习笔记

1 VUE 1.1 示例 新建test_vue.jsp <% page contentType"text/html;charsetUTF-8" language"java" %> <html> <head><title>Title</title> </head> <body><div id"app"><input name"…

三、SpringBoot启动流程及自动化配置

一、Springboot启动流程 图一:Springboot项目的启动流程 首先,针对上图中自己不太明确的两个知识点,这里做如下总结: 1.Banner:参考这篇文章:SpringBoot之Banner介绍 - MarkLogZhu - 博客园 (cnblogs.com) ; 2.钩子方…

【Javassist】快速入门系列07 当检测到字段被访问时使用语句块替换访问

系列文章目录 01 在方法体的开头或结尾插入代码 02 使用Javassist实现方法执行时间统计 03 使用Javassist实现方法异常处理 04 使用Javassist更改整个方法体 05 当有指定方法调用时替换方法调用的内容 06 当有构造方法调用时替换方法调用的内容 07 当检测到字段被访问时使用语…

一个最基本的lLinux驱动开发框架和编译驱动方式

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言一、编写驱动文件1.相关头文件2.驱动入口 &出口3.申明完整代码二、编译驱动的方式三、编译驱动1. 和内核一起编译&#xff1a;2. 编译成驱动模块&#xff1a…

Kafka消息写入流程

Kafka消息写入流程 0,写入消息简要流程图 1,从示例开始 在Kafka中,Producer实例是线程安全的,通常一个Producer的进程只需要生成一个Producer实例. 这样比一个进程中生成多个Producer实例的效率反而会更高. 在Producer的配置中,可以配置Producer的每个batch的内存缓冲区的大小…

如何下载最新的NDVI数据?需要翻墙,安装MRT,如何处理下载的NDVI数据?

一、下载NDVI数据 参照网站&#xff1a; https://www.zhihu.com/question/48176218 1、先在网站https://modis.gsfc.nasa.gov/data/dataprod/mod13.php查看要下载的数据 其实没什么要看的&#xff0c;就看下面这个图就可以了&#xff0c;根据下图找到自己要下载的数据简称&am…

Python实现猎人猎物优化算法(HPO)优化支持向量机分类模型(SVC算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 猎人猎物优化搜索算法(Hunter–prey optimizer, HPO)是由Naruei& Keynia于2022年提出的一种最新的优…

Hibernate-Validator的使用(一)

文章目录学习建议全部的约束注解关于NotEmpty和NotBlank的注意事项关于Size的注意事项约束注解可以放的位置JavaBeanValidator接口约束注解的继承性普通方法和构造方法入参和返回值ExecutableValidator 接口约束注解的继承性错误信息国际化显示定义message使用的消息key定义Val…

模仿现实生活中的通讯录(2)

距离第一篇已经过去很久&#xff0c;我之所以暂时放下通讯录&#xff0c;是因为学业颇多&#xff0c;无暇顾及。现在放假已经有一段时间了&#xff0c;脱离每天忙碌的生活后&#xff0c;我只想享受一下整日无事&#xff0c;浑浑噩噩过一天的感觉&#xff0c;只不过差点没收得住…

leetcode150/155. 逆波兰表达式求值、最小栈;剑指 Offer 31. 栈的压入、弹出序列

目录 题目链接与简介 题目一 1.算法思路 2.总结心得 3.可执行代码 题目二 1.算法思路 2.总结心得 3.可执行代码 题目三 1.算法思路 2.总结心得 3.可执行代码 题目链接与简介 1.逆波兰表达式求值 2.最小栈 3.剑指 Offer 31. 栈的压入、弹出序列 题目一 LeetCod…