文章目录
0、概述
脚本式语法是Jenkins最开始实现的流水线即代码方式。
是一种命令式风格,也就是在流水线脚本中定义逻辑和程序流程。
更依赖于Groovy语言和结构,特别是对于错误检查和异常处理来说。
优点
- 更少的代码段落和弱规范要求。
- 更强大的程序代码能力。
- 更像编写代码程序。
- 传统的流水线即代码模型, 用户熟悉并向后兼容性。
- 更灵活的自定义代码操作。
- 能够构建更复杂的工作流和流水线。
缺点
- 普遍要求更高的编程水平。
- 语法检查受限于Groovy语言及环境。
- 和传统Jenkins模型有很大差异。
- 与声明式流水线的实现相比, 同一工作流会更复杂。
一、语法
timestamps {
properties ([
parameters ([
string(name: 'NEW_BRANCH', defaultValue: '' , description:'', trim: true),
choice(choices: ['mysql', 'oracle'], description: '''选择数据库类型''', name: 'DATABASE', trim: true),
])
])
node('cs') {
//定义变量
def db_ip = '192.168.1.2'
try {
step([$class: 'WsCleanup']) //清理工作空间
stage('git pull') {
gitClone(branch)
}
//并行构建
parallel(
'npm web': {
stage('npm') {
sh """
shell命令
"""
}
},
'mvn': {
stage('mvn') {
sh """
shell命令
"""
}
}
)
} catch (e) {
throw e
} finally { //无论前面失败还是成功都会执行
}
}
}
//定义函数
def gitClone(branch) {
sh "git config --global http.sslVerify false"
for (gitProductName in gitProductList) {
sh "git clone --depth=1 -b ${branch} git地址"
}
}
二、定义变量
在if语句里面定义的变量,在函数中可以直接调用
dbDriver = "com.mysql.jdbc.Driver" //可以直接在函数中使用
def dbDriver = "com.mysql.jdbc.Driver" //函数中不能直接使用,需要当作实参传入给函数
三、properties属性
参数化构建
properties ([
parameters ([
string(name: 'NEW_BRANCH', defaultValue: '' , description:'', trim: true),
text(name: 'DOCKER_HOST',defaultValue: this.DOCKER_HOST, description: '''填写Docker主机的IP地址,多个地址用逗号分隔。
如:192.168.1.2,192.168.1.3''',trim: true),
choice(choices: ['mysql', 'oracle'], description: '''选择数据库类型''', name: 'DATABASE', trim: true),
booleanParam(defaultValue: true, description: '默认升级数据库', name: 'DATABASE'),
listGitBranches(branchFilter: '.*/feature.*||.*/dev', credentialsId: 'a2b624d4-567d-4ff2',
defaultValue: '', name: 'BRANCH', quickFilterEnabled: true, remoteURL: 'https://192.168.1.2/devops.git', selectedValue: 'NONE',
sortMode: 'DESCENDING_SMART', tagFilter: '*', type: 'PT_BRANCH') //列出git分支
])
])
多选参数
需安装Extended Choice Parameter plugin插件
参考文章:Jenkins参数化构建如何设置多选框
extendedChoice(description: '跳过指定的git工程', multiSelectDelimiter: ',', name: 'SKIP_GIT_PRODUCT', quoteValue: false, saveJSONParameterToFile: false,type: 'PT_CHECKBOX', value: 'a,b,c',visibleItemCount: 3),
定时构建
properties ([
pipelineTriggers([
cron('H/30 * * * *')
])
])
指定执行节点
node用于指定Jenkins应该在哪个节点上运行这部分流水线。
node后面的名称需在Jenkins管理节点界面中提前创建
node可以使用标准逻辑运算符来指定多个标签,例如
node("linux && changsha") {
}
stage—阶段
阶段必须指定 name ,用来描述这个阶段的职责。
现有的阶段实质上并没有在脚本中做什么事情,仅在运行流水线时在输出中标识出这个阶段的位置。
一个通用的实践是创建阶段来模仿传统流水线中的任务片段。例如,我们可以设计 一个阶段来获取源码,一个阶段来编译源码, 一个阶段来执行单元测试, 一个阶段来执行集成测试等
并行执行
方法一
parallel (
'master': {node('master') { //可以指定节点
sh "echo '在master执行'"
}},
'java': { //不指定就用全局node指定的节点
stage('mvn') {
sh 'mvn'
}
},
'web': {
stage('npm') {
sh 'npm'
}
},
//failFast: true //当并行执行的所有阶段中,有一个阶段执行报错,则其它阶段也被终止
)
方法二
Map parallelMap = ["name1":{value1},"name2":{value2}] //定义一个hashMap
parallel(parallelMap) //name1和name2的内容并行执行
sshCommand到远程主机执行命令
def mysqlRemote = getMysqlRemote(mysqlIp, mysqlSshUser, mysqlSshPassword)
sshCommand remote: mysqlRemote, failOnError: false, command: """
shell命令
"""
def getMysqlRemote(mysqlIp, mysqlSshUser, mysqlSshPassword) {
def remote = [:]
remote.name = 'mysqlServer'
remote.host = mysqlIp
remote.allowAnyHosts = true
remote.user = mysqlSshUser
remote.password = mysqlSshPassword
return remote
}
触发其它job
wait:是否等待下游job构建完成。默认为true
propagate:继承下游job的构建状态,如果下游job报错,则自己也报错
build(job: '下游job名', parameters: [string(name: 'VERSION', value: env.VERSION)], propagate: true, wait: true)
异常处理
捕获异常
方式一:try-catch-finally
try {
//代码块
} catch (e) {
throw e
} finally { //无论前面失败还是成功都会执行
}
方式二:catchError
如果一个代码块抛出了一个异常,那 么这个构建 被标记成失败状态。但是,流水线中从 catchError 代码块往后的语句可以继续执行
catchError {
//stage
}
//发送邮件通知的步骤
抛出异常
throw new Exception("This Is Error")或者
error("This Is Error")
注意事项
变量定义
def modifyConfig() {
def jdbcUrl //最好定义
if(dbType == "mysql") {
jdbcUrl = "jdbc:mysql://${dbIP}:${dbPort}/${dbSchema}?useUnicode=true\\&characterEncoding=utf-8"
} else if(dbType == "oracle") {
jdbcUrl = "jdbc:oracle:thin:@${dbIP}:${dbPort}/${dbName}"
} else {
throw new Exception("*******modifyConfigNot Surpport Db Type:${dbType}")
}
sh """
sed -ri "s|\\{\\{ JDBC_URL \\}\\}|${jdbcUrl}|g" application-dev.yml
"""
}
如果不事先定义jdbcUrl为null,那么在并行任务中的值jdbcUrl会串
比如:我并行执行的两个stage传入的dbSchema的名字分别为test1和test2,发现在sh方法里两个stage获取的值都是test2,感觉就是stage2中的test2串到了stage1中,因此最好在前面定义好变量jdbcUrl。
串行执行时不存在这个问题
参考
文章:《Jenkins2权威指南》