开发者学堂课程【ALPD 云架构师系列-云原生 DevOps36计:如何设计或选择合适的研发模式】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/82/detail/1285
如何设计或选择合适的研发模式
内容介绍:
一、如何选择研发模式
二、常见的实践案例
三、研发模式的落地
一、如何选择研发模式
通过上节课我们知道了一些常见的分支和它的一些优劣性,以及设计和选择分支的一些原则。那么该怎么设计它选择一个适合我们自己的研发模式呢?
假设现在遇到自己的一个工作情况、团队情况或者产品的交付情况,要怎么去做这个选择呢?下图所示的表格简单的给大家一个参考。
可以看出我们需要通过产品形态和它的发布方式,团队规模和协作成熟度来去选择相应的分支模式。如果你的团队规模很小,协作成熟度很高,那直接用主干开发就足够。
类似这种服务端开发方式,如果可以做到持续部署。那么这时的发布方式就可以通过Github-flow 去做或者 TBD ,因为你的发布并不需要做一些隔离。
如果你的团队规模适中,也就是说有一定的规模,开发的时候可能需要做一些隔离。另外,如果协作成熟度一般的话,那就用 github-flow ,很高的话就用 TBD 。
另外一个,就是说像有一些具有一定的发布窗口,然后它是按版本的方式来去发布的。这样我们建议用相应的 release 分支来去做一些隔离。
所以说通过这样的一个选择策略,我们就能通过你的产品类型,团队规模,协作成熟度,判断你需要用什么样的分支方式。
当然,这只是说通过主流的这些分支方式来去给大家一些推荐,实际过程中,我们应该尽可能的根据自己实际的产品和团队情况去制定合适的一个分支规则,比如说下面的这个例子。
这是一个团队的一个协作方式,上面是需求价值流。就是说他们开发的时候是一个需求,一个需求的做。做完了一个需求,再做另外一个需求,所以说它从需求的角度来说,交付是持续交付的方式。然后针对一个需求,它会对应它的代码变更流,也就说针对这个需求需要做相应的一些代码的一个变更,那么这个过程它其实是持续发布的方式,那么它的方式是什么样的呢?
看下图所示。
它的方式基本上就是 github-flow ,就是说在做特性开发的时候要做相应的一些特性之间的隔离,但是我的发布可以做到持续发布、持续部署,所以为可以直接在 master 上做,因为它一直都是在 master 上去发布的。而且不会同时有两个发布存在,所以说这里的分支模式和本身发布流水线之间是强相关的,因为发布流水线会基于不同的分支来去做相应的一些事情。
比如说我的特性分支已经发生变化,那么就需要去做相应的一些触发,比如说只针对这个特性分支去做相应的一些集成和验证,完成之后才可以合到 master 上去做集成,集成做完之后做相应的 SIT ,比如说系统级别的一些验证,然后再做相应的发布。所以我们发现分支模式和发布流水线之间是强相关的,这就是持续发布方式。
另外一个常见的,就是说作为一个客户端的比如 ios ,安卓这种,我们知道这些不可能持续发布,所以这个时候我们发现和上面分支方式多了一个 release 分支, release 分支是用来做版本用的,所以这时候就增加了一个 release 分支,那么从整体来看这个分支模式相对来说还是比较简单的。
我们发现其实分支模式或者说研发模式是为了减少代码协作当中的冲突跟等待创造的,那么代码之间的协作的冲突有两种,一种是开发过程当中的隔离,另外一个是发布过程当中的隔离,所以会是开发时候多分支然后主干发布,分支开发主干发布,分支开发分支发布,要不就主干开发分支发布,其实就是简单的一个二乘二的组合。
二、常见的实践案例
我们简单了解之后,来看一些常见的实践案例。
看上图这个例子,初看上去跟 git-flow 好像一模一样。但是仔细看会发现,相对 git-flow 来讲少了 release 分支,它的发布是以主干上 tag 的形式去发布的。第二个,他的 hotfixes 不是合回主干,而是直接在 hotfixes 上以 tag 方式发布的。这样的话就少了一个 release 的分支,少了 hotfixes 跟 master 之间的一个同步。所以整个分支模式就会形成这样一个特点,它有四种分支 feature 分支, develop 分支, master 分支和 hotfixes 分支。里面的 develop 和 master 是长期分支。
Feature 和 hotfixes 临时分支,临时分支就是开始开发的时候我会拉一个 feature 分支,最后合并进去之后就把它消亡掉。接下来,如果我是热修复,我会拉一个 hotfixes 分支,它一直都会在 Tag 上创建,创建完之后创建 tag 的分支就会消亡。所以会发现就真正的主干分支只有两个,大部分的情况下不用 hotfixes 的话,其实就只有 feature 分支。所以整个流程比 git-flow 简化了很多。
那么像这样的一个模式在云效上,要怎么去做一个落地呢?
三、研发模式的落地
这里就以云效为例,来看一下怎么去把一个研发模式具体的落地下来。
我们首先拿这个 alpd-bot-query 这个应用做例子。
第一步。先设置分支规则。我们知道在模式里面 develop 和 master 是属于两个长期分支,它是不能直接提交的。Master 应该从 develop 分支合过来,develop 分支应该从 feature 分支合过来。所以这个地方创建两条分支保护规则。
Master 分支保护规则:
在这个地方有个推送规则。这里可以限制是无,必须是合并。那么允许合并的话,可以开启开发者或者只允许管理员。master 比较严格,只能管理员合并。并且必须要经过代码评审和敏感信息检测。然后点击确定。
相比较于 master ,develop 的规则跟 master 类似,但是可以放宽一些。有了这两条规则之后,这两个分支就会保护起来了,就不能直接 push 进去。或者说只有经过特定的权限和流程才能把代码合进去。
然后要做流水线的配置,这里我们分三种,如果加上 hotfixes 就是四种流水线。
第一种就是开发阶段的流水线,在 feature 分支上。集成阶段流水线在 develop 分支上,还有一种就是发布阶段流水线在 Master 分支上。我们这里不打算讲解 hotfixes 的流程。看一下,正常的开发集成发布是什么样子?
首先看开发流水线。特点是它是代码提交触发的,并且这个触发分支是 Feature 分支,所以我们在这里配置了 feature-.* 的正则表达式之后,任何向 feature 分支的提交就会触发这个流水线。
回到 develop 分支的流水线。作为一个集成流水线,它跟开发流水线很像。唯一的不同就是他的触发分支是 develop 。同时在这里的测试阶段会比开发的阶段多一些,可能会做安全扫描、工程测试,测试环境的部署等。这里为了节约时间,只配置了简单的测试任务。
假设集成也通过了,接下来就是发布流水线,它同样是代码提交触发,触发分支是 master。当代码从 develop 到master 之后,他会按照研发模式的规范,在代码合到 master 的时候呢,他需要打tag。表明在做发布了,并且把这个发布固定下来。
所以第一步就是创建一个 Tag。点击上图中代码 Tag 中的创建标签。
这里用 BUILD_NUMBER 作为那个标签。
那么,当有了这个 Tag 之后,需要跟镜像做一个绑定和关联,点击发布流水线中的阿里云镜像构建。
在镜像构建的这个步骤里面。用 BUILD_NUMBER 作为镜像的标签。这样发布的镜像的版本就是这个标签的名字,这样就对应起来了。
现在来实际的做一下,看看会发生什么。
创建一个 feature 分支。他是从 master 创建的,确定之后。
里面又这样的一行代码:_DEFAULT_API_KEY=”77cf288474984dad92334c822b2097c3”
代码里面的 _DEFAULT_API_KEY 是有安全隐患的。所以要把它删掉。
def _g
e
t_api_key
(
self
)
:
If
n
o
t
o
s.path.exists(_"
W
EATHEA_API_KEY_FILE
):
return
_
DEFA
U
LT_API_Kes default key
whit
open
(
_
W
EATHER_AP
I
_KEY_FILE.“r") as fp
:
return fp. Read
()
同时把上面所示代码中的 _DEFAULT_API_KEY 改成None。
完了之后点击保存。
更新 Weather.py ,这个时候相当于又向 Feature 分支进行了一次提交,那它会发生什么呢?
我们先看一下流水线。我们发现开发的流水线被触发了。然后他开始进行代码扫描和单元测试。
在它运行的中间,我们继续假设这个问题已经修复了,那现在我需要去把它做集成,所以我会创建一个合并请求。
从 feature 分支到 develop 分支。
然后可以指定一个评审人。
我们发现它会自动的去跑流水线和敏感信息扫描,我们可以看到流水线跟敏感信息扫描的结果。如果这些都通过了,就可以把它合并。
点击合并的时候,这个 Feature 分支的代码就合到 develop 分支。而且合并里面有好几种方式。
默认会创建一个合并节点,但是我们更倾向于最后一个就是 Fast-forward-only 方式。也就是如果要合到 develop 分支,意味着当前的 feature 分支需要包含 develop 分支上所有的commit 。相当于合过去之后和之前的代码是一样的。
点击Fast-forward-only,这里因为源分支是个短分支,不在需要了,所以把它删掉,点击提交。
这个时候 Develop 分支就有了一次 merge 进化来的 commit 。然后我们应该可以看到集成流水线被触发起来了。在他执行的中间,我们继续创建一个合并请求。
我们希望把这个修复发布。所以还是创建合并请求,选择评审人。这个地方的关联内容说明我们是可以跟需求以及缺陷做关联的,这样当修复一个缺陷的时候可以在缺陷里边及时的更新,甚至做一个正态的绑定。这里不是我们今天的重点,所以就不赘述了。
点击确定。由于它是同一个 commit 的,所以我们看到。
它会绑定到所有的流水线的结果上,而这个也就是我们用 fast- forward-only 方式的一个优点。因为他的 commit 信息是一样的。我给你通过。点击合并同样采用这种方式,
这里因为这个 develop 是保护分支,所以不能删掉,直接点击提交就可以了。
然后刷新云效的流水线。
可以看到发布流水线也被触发起来了。
那么他做的第一个事情,就是创建 tag 。等到 tag 创建完,进行镜像构建,然后发布。这样就完成了。如果说我们有另外一个 feature 在开发,那么它显然可以走自己的开发的一个分支,走自己的开发流水线,走自己的集成,走自己的发布,这样通过流水线和分支保护这两个手段。
加上我们的一些安全卡口和测试策略。我们就把之前提到的研发模式做了一个云效上的一个落地。