当“代码农”遇上“码农”:揭秘主干开发的那些事儿

这篇具有很好参考价值的文章主要介绍了当“代码农”遇上“码农”:揭秘主干开发的那些事儿。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前段时期我负责部门内部主干开发落地相关事宜,这个过程中,也真真切切的体会到了多人开发过程中,面对特性分支管理中,大家遇到的一些困扰,尤其面对敏捷迭代的开发方式,合并冲突,集成测试,代码重用等方面,都与高效两个字背离。当然,我在推进主干开发过程中,也遇到了一些问题和坎坷,在这里,集中的做一次分享。

1. 概述

主干开发,是指开发人员直接向主干(习惯上主干分支通常为:trunk 或 master)提交 / 推送代码。通常,开发团队的成员 1 天至少 1 次地将代码提交到主干分支。在到达发布条件时,从主干拉出发布分支(通常为 release),用于发布。若发现缺陷,直接在主干上修复,并根据需要 cherry pick 到对应版本的发布分支。

优点:

  • 分支模型简单高效,开发人员易于掌握不容易出现错误操作

  • 避免了分支合并、冲突解决的困扰

  • 随时拥有可发布的版本

  • 有利于持续集成和持续交付

缺点:

  • 基础架构要求高:合入到主干的代码若质量不过关将直接阻塞整个团队的开发工作,因此需要高效的持续集成平台进行把关;

  • 自动化测试要求高:需有完备单元测试代码,确保在代码合入主干前能在获得快速和可靠的质量反馈;

  • 最好有代码评审:若代码质量要求高,需要配套代码评审(CR)机制,在代码提交到主干时,触发 CR,通过 Peer Review 后才能正式合入;

  • 最好有特性开关:主干开发频发合入主干的情况下,特性拆分得很小,可能是半成品特性,需要配套特性开关(Feature Toggle),只有当特性整体开发完才通过灰度发布等手段逐步打开;

适用环境:

  • 对迭代速度要求高,希望需求快速交付上线

  • 基础架构强,持续集成工具高效;

  • 团队成员习惯 TDD(测试驱动开发),代码自动化测试覆盖率高(至少增量代码的自动化测试覆盖率高);

2. 整体架构

2.1 衡量主干开发的效果

可以通过执行以下操作来衡量主干开发的效果。

测试的因素 衡量的指标 目标
应用代码库中的活跃分支数。 衡量应用代码库版本控制系统中的活跃分支数,让所有团队都能看到此数字。然后跟踪目标状态的增量式进度。 不超过三个活跃分支。
代码冻结期。 衡量团队的代码冻结数及冻结时长。这些衡量指标还可以对合并冲突、代码冻结、稳定等方面所耗费的时间进行分类。 无人提交代码时,没有代码会被冻结。
将分支合并到主干的频率。 衡量合并的每个分支的二进制(是/否)值,或者衡量每天合并的分支的百分比。 每天至少合并一次。
查看审批代码更改所需的时间。 如果您异步执行代码审核,请衡量审批更改请求所需的平均时间,并特别关注所需时间大大超过平均值的请求。 设法使代码审核成为在开发过程中执行的同步活动。

2.2 常见误区

如需全面采用主干开发,需要避免以下常见障碍:

  • 繁琐的代码审核流程。许多组织的代码审核流程都较为繁琐,需要多次审批才能将更改合并到主干中。如果代码审核很费力并且需要数小时或数天才能完成,开发者会避免小批量工作,改为进行大批量更改。因为大批量代码审核十分复杂,因此审核人员的审核时间会延长,进而造成恶性循环。

  • 这样的结果是开发者避免使用合并请求,从而导致合并请求经常受到冷落。由于很难通过检查来推导大规模更改对系统的影响,因此审核人员很可能会忽略缺陷,主干开发的优势也就减弱了。

  • 异步执行代码审核。如果您的团队实行结对编程,那么该代码已由第二个人审核。如果需要进一步审核,则应该同步执行:开发者准备提交代码时,应立即让团队中的其他人员审核代码。开发者不应该要求进行异步审核,例如向工具提交请求,然后在等待审核时启动新任务。合并延迟时间越长,就越有可能发生合并冲突和相关问题。如果执行同步审核,需要团队同意优先审核彼此的代码而不是处理其他工作。

  • 在提交代码之前未运行单元测试或者自动化测试。为了确保主干保持工作状态,在提交前对代码更改运行测试非常重要。此操作可以在开发者工作站完成,许多工具也提供针对本地更改远程运行测试,然后在通过测试后自动提交更改的功能。如果开发者知道自己无需大量繁杂流程即可将代码提交到主干,那么就会小批量更改代码,这些更改易于理解、审核、测试,并且可以更快地迁移到生产环境。

2.3 改进主干开发的Tip

  • 小批量开发。主干开发最重要的推动因素之一就是团队学习如何小批量开发。这需要为开发团队提供培训和组织支持。

  • 执行同步代码审核。如前所述,转换为同步代码审核或至少确保开发者优先进行代码审核,有助于确保所做的更改不必等待数小时甚至数天即可合并到主干中。

  • 执行全面的单元测试和自动化测试。确保您拥有全面而实用的自动化单元测试套件,并在每次提交之前运行这些测试工具。

  • 快速构建。构建和测试过程应在几分钟内执行。目标是将测试环境的jdos部署串联到整个CI的自动化流水线之中

2.4 主干开发流程说明

当“代码农”遇上“码农”:揭秘主干开发的那些事儿

如图所示,研发小伙伴基于master分支开发,当每次merge时,都会触发流水线验证过程。在流水线验证中:

1.EOS代码扫描,该扫描会扫描代码中不规范的情况,按照代码规约不同,会有不同的级别,包括 WARNING, MAJOR, CRITICAL, BLOCKER四种级别,基于不同级别可以设置拦截规则,如果代码不符合设定的拦截规则,将不予merge。

2.代码评审会触发代码评审邀请,可以根据设定,邀请组内研发,leader,或者测试人员参与代码评审,通过设定规则,如果代码评审通过,才允许merge。

3.现在自动进行maven打包和单元测试工作,如果单元测试不通过,将不予merge。

4.流水线会自动将单元测试通过的jar包发布到测试的JOS分组进行部署,部署完成后自动调取线上自动化测试流程,只有所有接口通过自动化测试,才允许merge。

3. 落地方案

3.1 单元测试

应用架构: 基于spring boot junit 编写单元测试。

我们可以将测试按照模块划分,放在不同的目录之下,可以分为集成测试和单元测试。这样做的原因是,当我们的项目边的越来越大的时候,写的测试会越来越多,当所有测试都放在一个目录下的时候,跑一次集成测试时间会很长。具体目录如下:

主开发目录 测试开发目录 测试模块 描述 测试父类命名
src/ test/ init 初始化测试模块 InitTestBase
unit service单元测试模块 UnitTestBase
jpa 持久化层测试模块 JPATestBase
mvc controller层测试 MvcTestBase

所有测试模块集成对应的父类,然后类名必须以对应模块+Test结尾,例如:ShipperStatisticUnitTest

  1. 引入单元测试依赖 spring-boot-starter-test
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
</dependency>


2. 引入 surefile 插件

 <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.2</version>
                <configuration>
                    <skip>false</skip>
                    <includes>
                        <include>**/unit/*Test.java</include>
                    </includes>
                </configuration>
</plugin>


3. 配置测试配置文件路径

 <resources>
        <testResources>
            <testResource>
                <directory>src/test/resources</directory>
                <!--①-->
                <excludes>
                    <exclude>application*.properties</exclude>
                </excludes>
            </testResource>
            <testResource>
                <directory>src/test/resources</directory>
                <filtering>true</filtering>
                <includes>
                    <include>application.properties</include>
                    <include>important.properties</include>
                    <include>application-${activatedProperties}.properties</include>
                </includes>
            </testResource>

        </testResources>


3.2 JaCoCo代码覆盖率扫描

该处可以先串联到流水线中,但不做门禁设置,等后期确定标准后,再打开门禁设置。

3.3 EOS静态代码扫描

在主干开发模式中,因为EOS静态代码扫描,配置代码合并门禁,确保代码编码规范。配置如下图所示例子:

当“代码农”遇上“码农”:揭秘主干开发的那些事儿

3.4 代码线上评审

代码评审通过Coding内置的评审规则实现,规则设定如下:

1.评审分支为master分支,并在push时创建代码评审,并阻塞代码直接合入目标分支。

2.评审人需要达到两人及以上通过后,才能触发随后的操作。

3.不允许自评。

4.不允许特定成员跳过自动化检查。

当“代码农”遇上“码农”:揭秘主干开发的那些事儿

3.5 特性开关

遇到此情况,一般是多版本同时开发的情况

此处跟业务强相关,需要具体问题具体分析。不过保证如下几个原则:

  • 代码开发尽量保证高内聚低耦合,保证类的封闭性,同时可以用常用设计模式,保证功能的业务代码解耦,有利于特性区分。

  • 个别情况,可以引入ducc配置中心,实现特性开关。

3.6 流水线配置

在行云流水线中,主要包括如下几个节点:

当“代码农”遇上“码农”:揭秘主干开发的那些事儿

其中有一个配置上有一个小坑就是下载代码。为什么这么说呢?

因为我们流水线的触发条件是跟coding上的代码评审配合使用,当主干分支发生merge请求时,这个时候会触发流水线,但拉取的代码并不能直接填写主干分支名称(如:master), 原因是当前的commit快照并没有合并到master上,而是处于等待状态,只有当流水线通过后才会真正合并到主干分支,这是如果下载代码里拉取的主干分支就是不包含当前提交内容的快照,并不能满足我们的诉求。

那么,我们该如何配置呢?

好在Webhook中会带一些系统内置全局参数,其中globalParams.user.WEBHOOK_ATTR_COMMIT_ID,代表的就是当前提交请求所包含的 commit快照,所以,我们只需要配置这个全局参数即可,如图所示:

配合如上配置,我们在触发设置中,只需要设置MR created/Updated事件即可。如下图所示:

当“代码农”遇上“码农”:揭秘主干开发的那些事儿

4. 总结

于许多开发者而言,主干开发是一项重大变革,您很可能会遇到一些阻碍。许多开发者根本无法想像如何采用这种方式工作。一项好的做法是找到曾采用这种方式工作的开发者,让他们指导其他开发者。让一些团队转为采用主干开发方式工作也很重要。实现此目标的一种方法是将大量具有主干开发经验的开发者召集到一起,这样至少有一个团队遵循主干开发做法。然后,如果您确信遵循此做法的团队发挥预期的作用,则可以将其他团队转换为这种风格。

当然主干开发也不是银弹,他也会有一些自己的弊端,比如在处理需求变更,或者同时多版本并行开发时,也需要建立多个临时分支支持,想做到纯粹的主干开发,也是过于理想化的结果。

作者:京东物流 赵勇萍

来源:京东云开发者社区文章来源地址https://www.toymoban.com/news/detail-474181.html

到了这里,关于当“代码农”遇上“码农”:揭秘主干开发的那些事儿的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Redis那些事儿(一)

            说到redis大家都不陌生,其中包括:共有16个数据库,默认为第0个数据库;数据以key-value键值的形式存储;数据类型包括String、List、Hash、Set等,其中最常用的是字符串;是单线程的、基于内存的,主要受内存和网络带宽的影响… 这些都是基于Redis的基础理论知识

    2024年02月05日
    浏览(56)
  • Redis那些事儿(三)

            接着上一篇Redis那些事儿(二) ,这一篇主要介绍Redis基于Geo数据结构实现的地理服务,它提供了一种方便的方式来存储和处理与地理位置相关的数据。Geo数据结构是Redis的一种特殊数据类型,用于存储地理位置信息,每个地理位置被表示为经度和纬度的坐标,可

    2024年02月05日
    浏览(61)
  • 【C++11那些事儿(一)】

    在2003年C++标准委员会曾经提交了一份技术勘误表(简称TC1),使得C++03这个名字已经取代了C++98称为C++11之前的最新C++标准名称。不过由于TC1主要是对C++98标准中的漏洞进行修复,语言的核心部分则没有改动,因此人们习惯性的把两个标准合并称为C++98/03标准。从C++0x到C++11,C++标

    2023年04月14日
    浏览(40)
  • [apue] 进程环境那些事儿

    众所周知,main 函数为 unix like 系统上可执行文件的\\\"入口\\\",然而这个入口并不是指链接器设置的程序起始地址,后者通常是一个启动例程,它从内核取得命令行参数和环境变量值后,为调用 main 函数做好安排。main 函数原型为: 这是 ISO C 和 POSIX.1 指义的,当然还存在下面几种

    2024年02月11日
    浏览(47)
  • 面试的那些事儿

    假如你是网申,你的简历必然会经过HR的筛选,一张简历HR可能也就花费10秒钟看一下,然后HR 就会决定你这一关是Fail还是Pass。 假如你是内推,如果你的简历没有什么优势的话,就算是内推你的人再用心,也无能为力。 另外,就算你通过了筛选,后面的面试中,面试官也会根

    2024年01月18日
    浏览(49)
  • 关于BGP安全那些事儿

    文| 宙斯盾DDoS防护团队 Rocky 导语 美国时间10月4日中午,Facebook公司网络出现重大故障,故障持续了6个小时后才恢复。官方给出的故障原因,简单来说是一次误操作引发了连锁反应。 (复杂点就是:在例行网络维护中,发送的一条命令无意中关闭了其全球骨干网的所有BGP连

    2023年04月08日
    浏览(50)
  • 账号安全那些事儿

    随着《网络安全法》正式成为法律法规,等级保护系列政策更新,“安全” 对于大部分企业来说已成为“强制项”。然而,网络空间安全形势日趋复杂和严峻。账号安全,也在不断的威胁着企业核心数据安全。 根据最新的 IBM 全球威胁调查报告《X-Force威胁情报指数2020》,受

    2024年01月21日
    浏览(53)
  • 边缘计算那些事儿—边缘智能技术

            边缘智能是边缘计算中一个非常重要的方向。它将边缘计算和人工智能算法结合起来,在边缘设备上就近处理目标检测、物体跟踪,识别等任务。这种处理方式可以降低时延,减少数据上送云端对回传网络的冲击,同时保证数据的隐私和安全性。但是,我们要面对一

    2023年04月22日
    浏览(48)
  • kafka消费者那些事儿

    消息的消费一般有两种模式,推模式和拉模式。推模式是服务端主动将消息推送给消费者,而拉模式是消费者主动向服务端发起请求来拉取消息。kakfa采用的是拉模式,这样可以很好的控制消费速率。那么kafka消费的具体工作流程是什么样的呢?kafka的位移管理又是怎么样的呢

    2024年02月07日
    浏览(39)
  • 【C++那些事儿】类与对象(1)

    君兮_的个人主页 即使走的再远,也勿忘启程时的初心 C/C++ 游戏开发 Hello,米娜桑们,这里是君兮_,我之前看过一套书叫做《明朝那些事儿》,把本来枯燥的历史讲的生动有趣。而C++作为一门接近底层的语言,无疑是抽象且难度颇深的。我希望能努力把抽象繁多的知识讲的生

    2024年02月05日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包