持续集成的实践应用已经在很多公司里推行,其中主流的持续集成工具就是Jenkins,作为过去两年多来一直致力于公司的持续集成部署的我,回身看到踩过的不少坑,感慨不已,所以决定将这些做个记录。
刚开始在公司部署Jenkins服务,使用的是插件流的方式部署,部署一个job要关联到十几个插件(插件流的方式就不在这里赘述了,网上也有很多资料),两个月后我把部署方式改成了Jenkins推荐的pipeline脚本的方式,这也是响应Jenkins2.0的精髓Pipeline as Code。
Jenkins的pipeline有Declarative Pipeline(在Pipeline 2.5中引入,结构化方式)和Scripted Pipeline两种方式编写,我选择的是Declarative Pipeline的写法,入门简单。
好了话不多说,直接上实例:
#!/usr/bin/env groovy
pipeline {
//确认使用主机/节点机 agent any /*{node { label ' master'}}*/
// 声明参数 parameters{
//SVN代码路径 string(name:'repoUrl', defaultValue: 'http://svn.com/svn/server/job', description: ' SVN代码路径')
// 部署内容的相对路径 string(name:'deployLocation', defaultValue: 'target/*.jar,target/alternateLocation/*.*,'+'target/classes/*.*,target/classes/i18n/*.*,target/classes/rawSQL/*.*,'+'target/classes/rawSQL/mapper/*.*,target/classes/rawSQL/mysql/*.*,'+'target/classes/rawSQL/sqlserver/*.*', description: '部署内容的相对路径 ')
//服务器参数采用了组合方式,避免多次选择 string(name:'dev_server', defaultValue: 'IP,Port,Name,Passwd', description: '开发服务器(IP,Port,Name,Passwd)')
string(name:'ZHtest_server', defaultValue: 'IP,Port,Name,Passwd', description: '中文测试服务器(IP,Port,Name,Passwd)')
string(name:'alT19_server', defaultValue: 'IP,Port,Name,Passwd', description: ' 生产服务器T1(IP,Port,Name,Passwd)')
string(name:'alT20_server', defaultValue: 'IP,Port,Name,Passwd', description: ' 生产服务器T2(IP,Port,Name,Passwd)')
}
// 声明使用的工具 tools {
maven 'maven'
jdk 'jdk1.8'
}
//常量参数,初始确定后一般不需更改 environment{
// SVN服务全系统只读账号cred_id【参数值对外隐藏】 CRED_ID='CRED_ID'
//项目经理邮箱地址 PM_EMAIL='PM'
// Jenkins负责人 JM_EMAIL='QA'
//测试人员邮箱地址【参数值对外隐藏】 TEST_EMAIL='Tester'
}
triggers {
pollSCM('H/5 * * * 1-5')
}
//pipeline运行结果通知给触发者 post{
//执行后清理workspace always{
echo "clear workspace......"
deleteDir()
}
failure{
script {
emailext body: '${JELLY_SCRIPT,template="static-analysis"}',
recipientProviders: [[$class: 'RequesterRecipientProvider'],[$class: 'DevelopersRecipientProvider']],
subject: '${JOB_NAME}- Build # ${BUILD_NUMBER} - Failure!'
}
}
}
stages {
stage('清理本地仓库') {
steps{
sh "/home/jenkins/del_lastUpdated.sh"
}
}
stage('Checkout') {
steps {
script {
//从SVN拉取代码 def scmVars = checkout ([$class: 'SubversionSCM',
additionalCredentials: [],
excludedCommitMessages: '',
excludedRegions: '',
excludedRevprop: '',
excludedUsers: '',
filterChangelog: false,
ignoreDirPropChanges: false,
includedRegions: '',
locations: [[credentialsId: CRED_ID,
depthOption: 'infinity',
ignoreExternalsOption: true,
local: '.',
r