Groovy 背景
Jenkins 流水线(Pipeline 是 Jenkins2.X 最核心的特性,帮助 Jenkins 实现从 CI 到 CD 与DevOps 的转变,可支持复杂流程的编排与可视化) 是一套插件,可通过 Jenkinsfile 执行,支持脚本式(Script)和声明式(Declarative)两种,其中脚本式可通过 Groovy 语法编写执行过程,声明式需要用 script {}包裹使用 Groovy 语句。
声明式指令简介
1.最外层必须由 pipline{ //do something }来进行包裹
2.不需要分号作为分隔符,每个语句独占一行
3.不能直接使用 groovy 语句(例如循环判断等),需要被 script {}包裹
- pipeline :声明其内容为一个声明式的 pipeline 脚本
- agent:执行节点(支持 any,none,label,docker,dockerfile)
- stages:阶段集合,包裹所有的阶段(例如:打包,部署等各个阶段)
- stage:阶段,被 stages 包裹,一个 stages 可以有多个 stage
- steps:步骤,为每个阶段的最小执行单元,被 stage 包裹
// 示例
pipeline {
agent any
stages {
stage(‘Example‘) {
steps {
echo ‘Hello World‘
}
}
}
}
environment
- 在 pipline 块内,为全局变量,对所有阶段和步骤生效
- 在 stage 阶段内,为局部变量,只对阶段和步骤生效
withEnv
- 一般使用在子步骤下
// 示例
pipeline {
agent any
stages {
stage(‘Example‘) {
environment {
deploy = ‘testing‘
}
steps {
echo env.NAME
echo "${NAME}"
echo "${deploy}"
echo "$CC"
withEnv([‘name=tester‘]) {
echo "$name"
}
}
}
}
environment {
CC = ‘clang‘
}
}
post (通常定义在 pipeline 末端)
- always: 始终执行
- aborted: 终止时执行
- failure: 失败时执行
- success: 成功是执行
- unsuccessful :不成功时执行
- cleanup :其他 post 过程执行完毕后执行
// 示例
pipeline {
agent any
stages {
stage(‘Example‘) {
steps {
error ‘构建失败:这是一个自定义的错误信息‘
}
}
}
post {
failure {
echo "this is a error"
}
}
}
when (使用在 stage 内)
- branch: 分支匹配时执行(when { branch ‘master‘ })
- branch: 分支匹配时执行(when { branch ‘master‘ })
- environment: 变量为给定值时执行(when { environment name: ‘DEPLOY_ENV‘, value: ‘production‘ })
- expression: Groovy表达式求值为true时执行(when { expression { return params.DEBUG_BUILD } })
- not: 嵌套条件为false时执行(when { not { branch ‘master‘ } })
- allOf: 嵌套的条件都为真时执行(when { allOf { branch ‘master‘; environment name: ‘DEPLOY_ENV‘, value: ‘production‘ } })
- anyOf: 至少一个嵌套的条件为真时执行(when { anyOf { branch ‘master‘; branch ‘staging‘ } })
// 示例
pipeline {
agent any
stages {
stage(‘DEPLOY_ENV‘) {
when { environment name: ‘DEPLOY_ENV‘, value: ‘production‘ }
steps {
echo "production 环境正在执行"
}
}
}
}
Parallel (并行)
// 示例
pipeline {
agent any
stages {
stage(‘Parallel Stage‘) {
when {
branch ‘master‘
}
parallel {
stage(‘testing‘) {
steps {
echo "depoly testing"
}
}
stage(‘staging‘) {
steps {
echo "depoly staging"
}
}
}
}
}
}
options (选项)
- 常用的有 timeout()、retry()
// 示例
pipeline {
agent any
options {
retry(3) // 重试
timeout(time:10, unit:"SECONDS") // 超时
}
stages {
stage(‘demo‘){
steps{
sh ‘echo hello‘
sleep(15)
}
}
}
}
steps 中的一些操作
- error:抛出异常,中断整个pipeline
- timeout: 超时
- waitUntil: 循环运行闭包内容,直到返回true,通常与timeout一起使用
- retry:失败重试
- sleep:睡眠,默认单位秒
// 示例
pipeline{
agent any
stages{
stage(‘stash‘){
parallel(‘测试‘) {
stage(‘轮询‘) {
steps{
timeout(time:10, unit:"SECONDS"){
waitUntil{
script{
def rs = sh script: ‘docker version‘, returnStatus: true
return (rs == 0)
}
}
}
}
}
stage(‘重试‘) {
steps{
retry(3){
script{
sh script: ‘curl https://www.baidu.com‘, returnStatus: true
}
sleep(3)
}
}
}
stage(‘错误‘) {
steps{
retry(3){
error("执行失败")
}
}
}
}
}
}
}
input (暂停执行,等待确认)
// 示例
pipeline {
agent any
stages {
stage(‘Example‘) {
input {
message ‘Should we continue?‘
parameters {
string(name: ‘PERSON‘, defaultValue: ‘Mr Jenkins‘, description: ‘Who should I say hello to?‘)
}
}
steps {
echo "Hello, ${PERSON}, nice to meet you."
input(message: ‘是否继续执行构建‘, parameters: [ choice(name:‘depoly‘,description:‘部署环境‘,choices:[‘testing‘,‘staging‘,‘production‘])])
}
}
}
}
script (脚本使用)
// 示例
def test = "test"
pipeline {
agent any
stages {
stage(‘环境变量‘) {
steps {
sh ‘pwd‘
sh "echo ${NAME}"
script {
if ("${NAME}" == "/root/test") {
echo "pass"
} else if ("${NAME}" == "${test}") {
echo "pass"
} else {
error("环境变量有误 ${NAME}")
}
}
}
}
}
}
脚本式案例
- 最外层有 node{} 包裹
// 示例
def TEST_PROJECT_NAME=""
def deployments = ["testing", "staging", "production"]
def run(stepName) {
retry(3){
TEST_PROJECT_NAME = sh(script: "openssl rand -hex 4",returnStdout: true).trim()
sh (
script: "echo ${TEST_PROJECT_NAME}",
label: "开始 ${stepName} 环境API测试"
)
}
}
node {
deployments.each{ param ->
stage("$param") {
run("$param")
}
}
}
拓展
build
- build 用法,支持触发另一个 job 构建
// 示例
pipeline {
agent any
stages {
stage(‘Example‘) {
steps {
echo ‘Hello World‘
}
}
}
post {
success {
script {
println "执行成功"
jobB = build job: ‘pipeline‘
println("构建状态: "+jobB.getResult())
}
}
}
}