当前位置: 首页 > news >正文

移动开发git版本控制经验之谈

移动开发git版本控制经验之谈

团队或应用规模是否会影响发布流程?这取决于具体情况。让我们来想象一下一个小型团队的创业公司。在这种情况下,通常是团队开发一个功能,然后直接发布。现在我们再来想象一个大型项目,比如一个银行应用程序,有很多团队在同时开发。在这种情况下,可能需要一套完整的流程、发布周期,甚至一些行政手续。如果没有这些,就会造成混乱。

那么,到底什么时候才能明确意识到需要为应用程序建立这样的流程呢?

在本文中,我将分享我们在Dodo Pizza应用程序(Android和iOS)中实施发布列车的经验,以及我们面临的问题,这些问题促使我们团队开始实施发布列车。

如果你是一个Android或iOS项目的团队负责人/技术负责人,并且你的项目正在快速发展,但尚未建立起有效的发布流程,我希望我们的经验可以对你有所帮助。

以前的情况

在2021年,我们的团队已经采用了主干式开发(Trunk-based Development,TBD)方法。我们使用功能开关覆盖代码,分解任务,运行单元测试和UI测试。我们的功能分支不会存在太长时间,同时我们也建立了持续集成(CI)环境。

发布流程非常简单:凡是准备好发布自己功能的人就可以进行发布。

理想情况

以下大致是我们的分支工作流程。多个团队(灰色、蓝色、橙色和绿色)同时开发不同的功能。由于我们采用主干式开发,每个功能可以经历多个连续的分支。例如,灰色团队在四个步骤中完成他们的功能,蓝色和橙色团队在一个步骤中完成他们的功能,绿色团队在两个步骤中完成他们的功能。

当一个团队完成了一个功能,他们可以发布一个版本。例如,如果蓝色团队完成了一个功能,他们就可以发布一个版本。然后橙色团队会完成一个功能,再发布另一个版本。

我们原本认为我们的流程是完美的。它一直运作得很好,但所有好事都有一个终点。

问题出现了:困难、拥挤和不可预测

庞然大物

我们遇到的第一个问题是发布版本开始积累了很多功能,变得过于庞大。

团队并不总是想立即发布他们的功能。发布和回归测试需要耗费时间,需要3-4天的时间。因此,如果你的功能很小而且不紧急,你并不总能自己发布它,因为可能其他团队很快就会发布一个版本,并且它将被包含在那个版本中。大致上看起来像这样:

这种安排非常脆弱,特别是当团队数量开始增长时。许多团队开发了许多小功能,每个新版本中的新代码总量变得巨大。当有人要发布他们的重要功能时,他们必须同时发布一个庞然大物。

庞然大物的版本发布导致了以下问题:

  • 延迟的回归测试;
  • 更高的回归错误风险;
  • 更高的生产环境中出现错误的风险。

我们需要使得即使像例子中的蓝色和橙色团队不想发布,发布仍然能够进行。

瓶颈

每个团队都是独特的,每个功能也都不同。有时候情况会以这样的方式发生,几个团队会在同一时间完成他们的功能。在这种情况下,会有很多“等我一下,我明天早上合并,我保证!”这样的情况发生。

最终,这些瓶颈导致了以下问题:

  • 发布变成了庞然大物;
  • 延迟的发布对发布团队的计划产生了负面影响,尤其是当其他人的需求都得到满足时。

我们需要进行两个关键的改变:

  1. 发布团队不应该需要等待任何人;
  2. 其他团队应该知道下一个发布的预计时间。

缺乏可预测性

想象一下,蓝色团队开发了一个小功能,并期望橙色团队很快发布。但是出了些问题,橙色团队由于自身的问题也没有进行发布。结果,蓝色团队告诉业务方该功能很快就会上线,但实际上却不够快。因此,无法预测该功能何时能够投入使用。

这并不意味着蓝色团队不负责任。如果他们有一个非常重要或紧急的功能,那么当然他们会自己发布。但在其他情况下,无法准确预测该功能何时对用户可用。

正如你所猜测的,我们经常遇到这样的问题。无论功能的大小或紧急程度如何,我们都需要能够准确告知客户何时能够在生产环境中使用该功能。这三个问题(庞然大物的发布、瓶颈和缺乏可预测性)密切相关并相互补充。然而,其中最根本和最重要的问题可能是缺乏可预测性。它会引发其他问题。

发布列车

我们受够了,是时候进行改变了。发布列车应该帮助我们做到这一点。

发布列车这个术语有不同的含义:一个按计划进行的发布流程,或者一个专门负责管理发布流程的团队。在这里,我们将讨论按计划进行的发布流程。我喜欢马丁·福勒(Martin Fowler)在《代码分支管理的模式》一文中对发布列车的描述方式,还有Thoughtworks在他们的技术雷达中给出的定义(也许这个定义也属于马丁)。

这是我们为自己定义的发布列车:

发布列车是协调团队之间发布的过程。所有的发布都按照固定的时间表进行,不管功能是否准备就绪。列车不会等待任何人。如果你迟到了,就得等待下一班。

让我们通过几个使用我们的彩色团队进行示例来详细解释。

解决庞然大物问题

发布列车按计划进行,不依赖于谁将什么合并到主分支中。在下面的示例中,蓝色和橙色团队的功能将被发布。其余的功能将等待下一班列车。我们可以再等一会儿,但那样会变成庞然大物。

解决瓶颈问题

同时,发布列车帮助我们更有效地规划工作。假设蓝色团队最初计划稍后完成一个功能。但由于每个人都知道发布日期,他们可以稍微重新安排计划,提前完成该功能。或者相反,他们可以意识到他们绝对赶不上下一班列车,因此他们可以安全地完成该功能,因为他们知道整个时间表。

在下面的示例中,蓝色团队希望参与发布,并在发布之前合并了所有的更改。否则,可能会出现瓶颈。

最重要的是,发布列车通过设计为我们提供了可预测性。

这些示例对某些人可能显而易见,但我们在问题出现时解决问题。当发布没有问题时,我们就不会费心使用发布列车。当问题积累到一定程度时,我们意识到时机已经成熟。

发布列车的引入方式

我们做的第一件事是起草一份RFC(请求评论)。RFC既指流程本身,也指许多公司在开始项目前使用的设计文档。有些公司专门使用RFC,有些公司使用架构决策记录(ADR),有些只是用更通用的术语设计文档来称呼它们。在Dodo Engineering,我们同时使用RFC和ADR。

我们的RFC流程如下:

  • 起草RFC文档;
  • 在小组内进行讨论,收集意见并进行调整;
  • 然后将RFC传达给更广泛的团队;
  • 然后实施它;
  • 之后,我们收集反馈,跟踪指标并评估结果。

我们发布列车的RFC文件结构如下:

  • 发布列车流程的描述;
  • 涉及哪些团队以及他们正在做什么;
  • 时间表;
  • 指标。

在起草RFC时,我们依靠其他公司的经验:

  • SkyScanner
  • Soundcloud
  • Monzo
  • Facebook

第一次实施

首先,我们设计了这个流程:

  • 每周发布;
  • 在周三早上创建一个发布分支;
  • 在周五完成回归测试,并将应用程序发送给审核人员;
  • 在周一开始推出发布。

发布团队:

  • 一个功能团队中的一个iOS和一个Android开发人员;
  • 两个QA工程师。

在周三创建一个新的发布分支;

制定一个季度计划,说明何时轮到每个团队发布。一个季度后聚集在一起,延长时间表。

简而言之,我们的发布列车如下所示:

并不是一切顺利

一个月后,我们发现虽然最初的经验感觉很好,但是:

每周进行回归测试并在周五之前完成真的很难;
没有时间进行热修复,而有时这种情况确实发生了。

2021年,我们的回归测试平均需要3-4天。2022年,我们设法将其缩短到2-3天,但有时会超过这个时间范围。我们继续用e2e测试覆盖回归测试案例,但我们还没有100%的覆盖率。我们分别在每个平台上覆盖了大约70%和60%的回归测试案例。

这表明,只要回归测试需要几天才能完成,每周运行一个发布周期可能会不太舒适。

最终的解决方案

我们最终转向两周发布周期,现在发布列车看起来像这样:

  • 每两周发布一次;

  • 在周三早上创建发布分支;

  • 在周五进行回归测试,并将应用程序发送给审核人员;

  • 在周一开始推出发布。

  • 发布团队:
    一个功能团队中的一个iOS和一个Android开发人员;
    两个QA工程师。

  • 制定一个季度计划,说明何时轮到每个团队发布。一个季度后聚集在一起,延长时间表。

  • 逐步推出发布;

  • 如果需要,现在可以进行热修复;

  • 一周后的周三创建一个新的发布分支。

这是如果一切按计划进行的流程。
整个流程看起来像是一个每周的周期,除了有足够的时间来处理潜在的热修复。以下是在回归测试时间延长的情况下的流程示意:

也没什么大不了的,甚至还有时间处理热修复。

新流程对可预测性的影响如何?

我们的主要目标是提高可预测性。这可以分为两个部分:

  1. 应用程序何时发布;
  2. 我的功能将在哪个版本中发布。

我们通过实施发布列车流程回答了“何时会有发布”的问题。现在,每个团队都可以在规划和评估功能时独立地回答“我的功能将在哪个版本中发布”的问题。以前无法确定地回答这个问题,因为另一个团队可能会或可能不会进行发布。现在一切都只取决于该团队自己的计划。

为了进一步确认这一点,我们在移动开发人员、质量保证和产品经理之间进行了调查,除了其他问题外,我们还问了以下问题:

  • 下一次发布是什么时候?(100%回答了这个问题)。
  • 发布列车是否帮助您规划团队合作?(75%回答积极,但有些人即使没有发布列车,也能很好地预测他们的工作)。

发布列车还帮助我们进行了代码冻结和发布冻结。除了新年前夕(例如9月1日和一些节假日),我们还有其他几个冻结日期。现在,有了发布列车,我们不需要根据这些日期调整创建发布分支、回归测试等工作。发布按计划进行,我们只是稍后在应用商店中打开它们。

对指标的影响

除了解决问题,我们还测量了一些指标。让我们看一下主要的指标。

交付时间

我们测量的第一个重要指标是从提交到发布的交付时间。

这是图表的样子。我用箭头标出了我们开始使用发布列车流程的点。

图表显示交付时间降至约6天左右。6天是长时间还是短时间?

谷歌的基准
对于这个指标,谷歌有一些基准,但主要是针对后端。按照他们的尺度,他们区分以下几组:

  • 精英:少于一个小时
  • 高级:1小时至1周
  • 中级:1周至6个月
  • 低级:6个月或更长时间

我认为对于标准移动应用程序,交付时间理想情况下应该瞄准发布周期的一半。这相当于每天将任务合并到主分支。也就是说,如果发布周期为14天,交付时间应该瞄准7天。

回归中每个缺陷

我们追踪的另一个指标是每个回归中的缺陷数。它描述了发布候选的稳定程度。如果上一个发布很久以前,那么我们可能创建了很多新代码,可能包含大量的错误,我们可能需要花费更多的时间进行回归和修复。

有一段时间这个指标降至三个错误。具体的数字并不是那么关键,但总体上可以看到趋势已经下降。

更多指标

我将简要介绍作为发布列车一部分监测的其他指标。

  • 无崩溃。我们始终关注这个指标。有一个假设是由于我们试图将回归适应更紧密的时间框架,它可能会下降。但实际上没有下降发生。
  • 我们想知道频繁(每周)发布是否会对客户流失和删除应用程序产生影响。结果,我们没有发现任何影响。

实施、改进

我们喜欢当前的流程,因为我们认为它已经实现了自己的目标。同时,我们也知道如何进一步改进它:

  • 我们继续致力于自动化回归,使它更简单、更快速。
  • 到目前为止,我们留下了工作自动化(分支脚本)的部分,但这也将是未来增长的一个重要点。
  • 我们的应用程序在20个国家运行,需要将应用程序翻译成许多不同的语言。虽然有一个内部服务来完成这个过程,但开发人员仍然需要在发布之前手动参与这个过程。自动化这个过程可能会进一步改进发布周期。

结论

当我们规模相对较小时,我们不需要发布列车。当我们面临不能预测发布、发布数量和大小的事实时,我们决定实施发布列车。起初,我们尝试了每周发布周期,但由于耗时的回归测试,我们不得不转向两周发布周期。从那以后,我们一直以这种方式生活。

现在我们有了发布的可预测性,指标显示出积极的动态。我们计划增加端到端测试的回归覆盖率,自动化分支处理过程,并优化翻译流程。

我希望这篇文章和我们的经验能够帮助你,尤其是如果你已经面临了类似的问题,并让你思考发布流程。

相关文章:

  • npm使用详解(好吧好吧是粗解)
  • YZ系列工具之YZ03:高版本Excel的自定义菜单
  • B树和B+树的区别
  • 在树莓派Ubuntu 23.10上编译opencv3.4.14
  • 手把手教你使用 PyTorch 搭建神经网络
  • 前端必备的 web 安全知识手记
  • 解决ios编译swift报错pcm was built: mtime changed
  • idea 注入mapper报错报红的几种解决方案
  • JVM初识-----01章
  • VUE前端导出文件之file-saver插件
  • 面试算法73:狒狒吃香蕉
  • 2024 年 22 款顶级免费数据恢复软件比较 [Windows 和 Mac]
  • INFINI Gateway 如何防止大跨度查询
  • Linux开发工具——gcc篇
  • npm error code EINTEGRITY 问题的解决方法之一
  • 【剑指offer】让抽象问题具体化
  • bearychat的java client
  • Hexo+码云+git快速搭建免费的静态Blog
  • If…else
  • Java 网络编程(2):UDP 的使用
  • java第三方包学习之lombok
  • React Native移动开发实战-3-实现页面间的数据传递
  • 创建一个Struts2项目maven 方式
  • 从零开始在ubuntu上搭建node开发环境
  • 复习Javascript专题(四):js中的深浅拷贝
  • 学习JavaScript数据结构与算法 — 树
  • 用mpvue开发微信小程序
  • HanLP分词命名实体提取详解
  • ​flutter 代码混淆
  • ​secrets --- 生成管理密码的安全随机数​
  • ​一文看懂数据清洗:缺失值、异常值和重复值的处理
  • ​一些不规范的GTID使用场景
  • (rabbitmq的高级特性)消息可靠性
  • (力扣)循环队列的实现与详解(C语言)
  • (四)图像的%2线性拉伸
  • (五)IO流之ByteArrayInput/OutputStream
  • (五)Python 垃圾回收机制
  • (转)创业家杂志:UCWEB天使第一步
  • .NET 8 中引入新的 IHostedLifecycleService 接口 实现定时任务
  • .NET Core 通过 Ef Core 操作 Mysql
  • .Net CoreRabbitMQ消息存储可靠机制
  • .NET MVC之AOP
  • .Net 访问电子邮箱-LumiSoft.Net,好用
  • .NET/C# 使用 SpanT 为字符串处理提升性能
  • .Net8 Blazor 尝鲜
  • []Telit UC864E 拨号上网
  • [AIGC] 使用Curl进行网络请求的常见用法
  • [DM复习]关联规则挖掘(下)
  • [git] windows系统安装git教程和配置
  • [Machine Learning] Learning with Noisy Labels
  • [Machine Learning] 领域适应和迁移学习
  • [MAUI]集成高德地图组件至.NET MAUI Blazor项目
  • [mvc] 简单的forms认证
  • [NOI2012]迷失游乐园
  • [opencvsharp]C#基于Fast算法实现角点检测