Jenkins遷移之pipeline共享庫的實踐示例
背景
我們一直使用的 jenkins 服務還是 2.0 以下不支持 pipeline 的版本。平時創(chuàng)建任務多數使用 maven 項目,構建后的 shell 部署命令都是在各個 job 中獨立維護。這種方式的缺點就是:
1.腳本維護麻煩 (環(huán)境對應的服務器變更,構建入參更新等等狀況);
2.不利于后期功能擴展 (例如 java 服務想接入覆蓋率服務);
3.不利于 jenkins 項目遷移 (例如磁盤不足等原因)。
剛好上述原因都遇到了,所以計劃遷移到新的 Jenkins 服務中,所有 job 都通過 pipeline 來管理。在使用 pipelin 之后的感覺用 2 個字來形容:真香
順便感謝一下大佬,但是不知道他的 id,所以直接貼一下他的gitee 共享庫項目地址
我的共享庫項目中縫合了大佬很多代碼,寫的太好了,忍不住借鑒一下
初期需求
遷移之初,參考了網上很多的 pipeline 使用教程。首先肯定不想在每個項目中,維護大量的 Jenkinsfile 文件 (萬一需要修改,那不是得改到吐,雖然也可以用 git 項目來統(tǒng)一管理 jenkinsfile),最終采用了 Multibranch Pipeline with defaults(多分支流水線) + Pipeline: Multibranch with defaults 插件的方式,通過維護簡單的 default jenkinfile 文件來實現 pipeline 的使用。第二個考慮的問題就是,后期對腳本的維護和擴展希望盡可能的簡單,這自然就想到 pipeline 共享庫的使用。
成果展示
先展示下目前的成果:
1.創(chuàng)建 job
這里是說在 Jenkins 中配置簡單,其實還有一些信息配置的,是保存在文件或者數據庫中

2.job 參數配置

default jenkinsfile 文件的維護 (僅僅負責調用共享庫,所有的實現均在共享庫項目中完成)

共享庫
共享庫結構
├─resources │ app.json │ base.json │ host_info.json ├─src │ │ │ └─com │ │ common_util.groovy │ │ exec_shell.groovy │ │ Log.groovy │ │ │ ├─beans │ │ AppJobInfo.groovy │ │ HostInfo.groovy │ │ JavaJobInfo.groovy │ │ JobInfo.groovy │ │ │ ├─build │ │ androidBuild.groovy │ │ build.groovy │ │ gradleBuild.groovy │ │ mavenBuild.groovy │ │ npmBuild.groovy │ │ yarnBuild.groovy │ │ │ ├─deploy │ │ deploy.groovy │ │ │ ├─enums │ │ BuildType.groovy │ │ PipelineType.groovy │ │ ToolsType.groovy │ │ │ ├─qikqiak │ │ GlobalVars.groovy │ │ │ └─services │ JacocoHandle.groovy └─vars defaultPipeline.groovy initParamsStage.groovy loadPipeline.groovy testPipeline.groovy unknownPipeline.groovy
入口代碼: loadPipeline.groovy
def call(PipelineType pipelineType) {
JobInfo jobInfo = creatJobInfo()
switch (pipelineType) {
case PipelineType.DefaultPipeline:
defaultPipeline jobInfo
break
case PipelineType.TestPipeline:
testPipeline jobInfo
break
default:
unknownPipeline null
break
}
}
參數使用 jobInfo 對象管理
/**
針對不同類型的項目,使用不同的jobInfo:JavaJobInfo/AppJobinfo
*/
class JobInfo {
/**
* 頁面入參
*/
String jobName
String env
BuildType buildType
String branchName
JobInfo(Map map){
this.jobName = map.job_name
this.env = map.env
this.buildType = BuildType.getBuildTypeByKey(map.buildType)
this.branchName = map.branchName
}
/**
* 配置參數
*/
//通用字段
String groupName
ToolsType toolsType
Map<String, String> envMap
def setConfigParams(Map map){
this.groupName = map.groupName
this.toolsType = com.enums.ToolsType.getToolsTypeByKey(map.toolsType)
this.envMap = map.env_map
}
def getEnvKeyList(){
return this.envMap.keySet().toList()
}
def getHost(){
return this.envMap.get(this.env)
}
//默認項
/**
* 是否為自動構建
*/
boolean isAutoBuild = false
/**
* 自動構建時,默認構建的環(huán)境:加入構建指令需要環(huán)境參數時
*/
String defaultEnv = "test"
/**
* 默認構建方式:僅構建
*/
BuildType defaultBuildType = BuildType.BUILD
@NonCPS
def setAutoBuildParams(){
this.env = defaultEnv
this.buildType = defaultBuildType
}
@Override
@NonCPS
public String toString() {
return "JobInfo{" +
"jobName='" + jobName + '\'' +
", env='" + env + '\'' +
", buildType=" + buildType +
", branchName='" + branchName + '\'' +
", groupName='" + groupName + '\'' +
", toolsType=" + toolsType +
", envMap=" + envMap +
", isAutoBuild=" + isAutoBuild +
", defaultEnv='" + defaultEnv + '\'' +
", defaultBuildType=" + defaultBuildType +
'}';
}
}
pipeline 結構:defaultPipeline.groovy

動態(tài)參數:initParamsStage.groovy
stage("init params step"){
script{
log.info("start init params...")
/**
* 先根據構建工具,來構建不同的構建參數
* 后期如果同一個構建工具,針對不同的job,入參類型不同,那么在根據job處理
*/
switch (jobInfo.toolsType){
case ToolsType.MVN:
properties([
parameters([
choice(name:'env', choices:env_list, description:'選擇構建環(huán)境'),
booleanParam(defaultValue:false, name: 'isCollectCoverage',description: '是否啟用jacoco收集代碼覆蓋率'),
choice(name:'buildType', choices:['buildAndDeploy', 'build', 'deploy'],
description:'選擇部署方式:編譯并部署、僅編譯、僅部署')
])
])
break
case ToolsType.GRADLE:
if(jobInfo instanceof AppJobInfo){
properties([
parameters([
choice(name:'env', choices:env_list, description:'選擇構建環(huán)境'),
choice(name:'buildType', choices:['buildAndDeploy', 'build', 'deploy'],
description:'選擇部署方式:編譯并部署、僅編譯、僅部署')
])
])
}else{
properties([
parameters([
choice(name:'env', choices:env_list, description:'選擇構建環(huán)境'),
booleanParam(defaultValue:false, name: 'isCollectCoverage',description: '是否啟用jacoco收集代碼覆蓋率'),
choice(name:'buildType', choices:['buildAndDeploy', 'build', 'deploy'],
description:'選擇部署方式:編譯并部署、僅編譯、僅部署')
])
])
}
break
default:
properties([
parameters([
choice(name:'env', choices:env_list, description:'選擇構建環(huán)境'),
choice(name:'buildType', choices:['buildAndDeploy', 'build', 'deploy'],
description:'選擇部署方式:編譯并部署、僅編譯、僅部署')
])
])
}
}
}
共享庫的擴展示例
java 服務增加 jacoco 覆蓋率功能
1.維護 JavaAppInfo 對象
class JavaJobInfo extends JobInfo{
boolean isCollectCoverage
JavaJobInfo(Map map) {
super(map)
this.isCollectCoverage = map.isCollectCoverage
}
//Jacoco相關屬性
String jacocoPort
String projectId //jacoco覆蓋率服務中,coverage_app表中的project_id字段
String commitId
String includes //需要增強類的通配符表達式
String excludes //需要排除增強類的通配符表達式
}
2.在部署時,啟動 jacoco
def exec_jar(JavaJobInfo jobInfo){
def util = new common_util()
def log = new Log()
def jacocoHandle = new JacocoHandle()
//判斷是否要啟用jacoco服務
if(jobInfo.isCollectCoverage){
//先獲取jacoco port
jacocoHandle.getJacocoPort(jobInfo)
//在獲取本次構建代碼最新的commit id
jacocoHandle.getCommitId(jobInfo)
def shell_str = "ssh root@${jobInfo.getHost()} '/home/deployscripts/deploy.sh -d jar //省略 "
if(jobInfo.includes !=""){
shell_str += " -I ${jobInfo.includes}"
}
if(jobInfo.excludes != ""){
shell_str += " -E ${jobInfo.excludes}"
}
shell_str += "'"
sh "${shell_str}"
}else{
sh "ssh root@${jobInfo.getHost()} '/home/deployscripts/deploy.sh -d jar //省略 "
}
}以上就是Jenkins遷移之pipeline共享庫的實踐示例的詳細內容,更多關于Jenkins遷移共享庫pipeline的資料請關注腳本之家其它相關文章!
相關文章
Validation of viewstate MAC failed.的解決方法
Validation of viewstate MAC failed.的解決方法...2007-10-10

