电子说
DevOps案例旨在帮助用户在实践中更好的运用DevOps。
问题描述
Jenkins2.0 Pipeline框架iPipeline(即plll库)对MergeCI的触发条件的设置为Change merged模式且固定不变,即需要由代码走查者+2分后,再由Core成员点击Submit按钮来将代码推入库,然后才来触发MergeCI流程,该过程的VerifyCI和MergeCI流程如下图所示:
结合上图我们可以发现,这里有个问题是: 一旦代码走查通过(+2分),然后Core成员通过(Submit)后,代码立即入库,然后触发MergeCI流程,此时若MergeCI运行出错,那错误此时已经入库并且影响后续开发人员合入代码。
再结合本项目协议开发自身的实际特点,很有可能VerifyCI通过后的MergeCI会和他人产生互相影响,这样便可能导致主干分支代码有错,开发人员之间互相影响,最终影响代码提交合入的效率。
基于此种情况,我们提出的一种模式是,MergeCI由代码审查人员在Gerrit上打出+2分来触发,只有到MergeCI运行通过,代码才会被推入库中,此种方式带来的一个最直接的好处就是主干分支上的代码永远正确的,而且不会因为MergeCI报错而影响他人合代码,而且该方法带来的另外一个好处便是无需设定关键角色来负责Submit代码入库,仅仅需要的是代码走查人员即可,这样也提高了自动化程度,节省人力。将该流程可以示意如下图:
因此plll库的这种MergeCI的设置方式并不满足本项目,因此我们决定扩充plll库对于MergeCI运行模式的支持。
优化实践
通过重载了plll库的属性设置函数,加入了根据CI类型来完成MergeCI不同触发条件的设置:
/**
* 工具名称:set_default_properties
* 工具描述:设置默认的参数
* 参数说明:
* - citype : CI类型
* - args : 参数列表
**/
def set_default_properties(citype, args){
def buildParameters =[]
def buildTriggers =[]
set_parameters_properties(buildParameters, args)
set_cron_properties(buildTriggers, args)
set_gerrit_properties(citype, buildParameters, buildTriggers, args)
/* --------参数------- */
properties([
[$class:'GitLabConnectionProperty', gitLabConnection:''],
[$class:'RebuildSettings', autoRebuild:false, rebuildDisabled:false],
buildDiscarder(logRotator(artifactDaysToKeepStr:'', artifactNumToKeepStr:'', daysToKeepStr:'14', numToKeepStr:'100')),
parameters(buildParameters),
pipelineTriggers(buildTriggers)
])
/* 清空临时变量 */
buildParameters=null
buildTriggers=null
return
}
/**
* 函数名称:设置gerrit属性
**/
def set_gerrit_properties(citype, buildParameters, buildTriggers, args)
{
// ...此处代码省略...
if("verifyci"=="${citype}"){
gerritEvents =[
patchsetCreated(
excludeDrafts:false,
excludeNoCodeChange:true,
excludeTrivialRebase:false
),
draftPublished()
]
// 如果CI类型是MergeCI,则设置器触发条件为Code-Review +2方式来触发
}elseif("mergeci"=="${citype}"){
gerritEvents =[
commentAdded(commentAddedTriggerApprovalValue:'+2', verdictCategory:'Code-Review')
]
}
// ...此处代码省略...
}
由代码可知,在set_gerrit_properties函数中,做了特殊判断,若是MergeCI,则单独将其触发条件设置为Code-Review +2,这样便可以满足需求。
使用举例:
在MergeCI的Jenkinsfile中调用plll.set_default_properties设置项目属性时明确指定mergeci类型即可,以本项目的Jenkinsfile代码中设置默认属性参数为例:
def set_default_properties(){
plll.set_default_properties("mergeci",[
/* 关联gerrit */
gerrit:[
server:"${env.GERRIT_SERVER_NAME}",
projects:[[project:"${env.GERRIT_PROJECT}", branch:"${plll.getJobBaseName()}"]]
],
/* 自定义参数 */
parameters:[
choice(choices:'yes\nno', description:'清空编译环境', name:'CLEAN_ALL'),
string(defaultValue:"${plll.getJobBaseName()}", description:'触发分支',name:'BRANCH_TAG')
],
]);
}
除此之外,还需要在Jenkins系统管理中MergeCI的Gerrit Trigger设置中作如下图所示的配置即可:
优缺点分析
1. 优点
开发人员互相独立,别人错误的代码无法入库,不影响他人
主干分支代码永远正确,不影响别人拉代码验证和正常合入代码
无需小组核心成员进行submit操作,MergeCI一旦运行正确,代码则自动入库
2. 缺点
原理决定了其无法并行,所以需要根据不同的项目情况酌情考虑。但是从本项目实际实践的整局来看,本项目VerifyCI支持数个任务同时并发执行,而MergeCI排队执行,但由于MergeCI执行较快,而且冲突很少,因此MergeCI的代码都能逐个顺利地合入,幸福感较以前有很大提升。
全部0条评论
快来发表一下你的评论吧 !