Home | 简体中文 | 繁体中文 | 杂文 | 打赏(Donations) | Github | OSChina 博客 | 云社区 | 云栖社区 | Facebook | Linkedin | 知乎专栏 | Search | About

6.3. Jenkinsfile - Declarative Pipeline

https://jenkins.io/doc/pipeline/examples/

6.3.1. agent

agent 指令指定整个管道或某个特定的stage的执行环境。它的参数可用使用:

			
agent: 
any - 任意一个可用的agent
none - 如果放在pipeline顶层,那么每一个stage都需要定义自己的agent指令
label - 在jenkins环境中指定标签的agent上面执行,比如agent { label 'my-defined-label' }
node - agent { node { label 'labelName' } } 和 label一样,但是可用定义更多可选项
docker - 指定在docker容器中运行
dockerfile - 使用源码根目录下面的Dockerfile构建容器来运行				
			
			

6.3.1.1. label

				
	agent {
        label "java-8"
    }
				
				

6.3.1.2. docker

				
pipeline {
    agent { docker { image 'maven:3.3.3' } }
    stages {
        stage('build') {
            steps {
                sh 'mvn --version'
            }
        }
    }
}
				
				
				
pipeline {
    agent { docker { image 'php' } }
    stages {
        stage('build') {
            steps {
                sh 'php --version'
            }
        }
    }
}				
				
				

6.3.2. stages

			
pipeline {
    agent any

    stages {
        stage('Build') {
            steps {
                echo 'Building..'
            }
        }
        stage('Test') {
            steps {
                echo 'Testing..'
            }
        }
        stage('Deploy') {
            steps {
                echo 'Deploying....'
            }
        }
    }
}			
			
			

6.3.3. echo

			
    stage('Deploy') {
        echo 'Deploying....'
    }
			
			

6.3.4. sh

			
		stage("build") {
            steps {
                sh "mvn package -Dmaven.test.skip=true"
            }
        }
			
			
			
		steps {
        	script{
            	sh 'find /etc/'
			}
		}
			
			

6.3.5. junit

junit4

			
		stage("测试") {
            steps {
                echo "单元测试中..."
                // 请在这里放置您项目代码的单元测试调用过程,例如:
                sh 'mvn test' // mvn 示例
              	// sh './gradlew test'
                echo "单元测试完成."
                junit 'target/surefire-reports/*.xml' // 收集单元测试报告的调用过程
            }
        }			
			
			

junit5 测试报告路径与 junit4 的位置不同

			
		stage("测试") {
            steps {
                echo "单元测试中..."
              	sh './gradlew test'
                echo "单元测试完成."
              	junit 'build/test-results/test/*.xml'
            }
        }
			
			

6.3.6. 

			
node {
    sleep 10
    echo 'Hello World'
}			
			
			
			
sleep(time:3,unit:"SECONDS")			
			
			

6.3.7. 设置环境变量

environment定义键值对的环境变量

			
echo "Running ${env.BUILD_ID} on ${env.JENKINS_URL}"			
			
			
			
// Declarative //
pipeline {
    agent any
    environment {
        CC = 'clang'
    }
    stages {
        stage('Example') {
            environment {
                DEBUG_FLAGS = '-g'
            }
            steps {
                sh 'printenv'
            }
        }
    }
}			
			
			
			
// Declarative //
pipeline {
    agent any
    environment {
        CC = 'clang'
    }
    stages {
        stage('Example') {
            environment { 
                AN_ACCESS_KEY = credentials('my-prefined-secret-text') ③
            }
            steps {
                sh 'printenv'
            }
        }
    }
}			
			
			

6.3.8. parameters

参数指令,触发这个管道需要用户指定的参数,然后在step中通过params对象访问这些参数。

			




// Declarative //
pipeline {
    agent any
    parameters {
        string(name: 'PERSON', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?')
    }
    stages {
        stage('Example') {
            steps {
                echo "Hello ${params.PERSON}"
            }
        }
    }
}			
			
			

6.3.9. options

还能定义一些管道特定的选项,介绍几个常用的:

			
skipDefaultCheckout - 在agent指令中忽略源码checkout这一步骤。
timeout - 超时设置options { timeout(time: 1, unit: 'HOURS') }
retry - 直到成功的重试次数options { retry(3) }
timestamps - 控制台输出前面加时间戳options { timestamps() }			
			
			

6.3.10. triggers

触发器指令定义了这个管道何时该执行,就可以定义两种cron和pollSCM

			
cron - linux的cron格式triggers { cron('H 4/* 0 0 1-5') }
pollSCM - jenkins的poll scm语法,比如triggers { pollSCM('H 4/* 0 0 1-5') }

// Declarative //
pipeline {
    agent any
    triggers {
        cron('H 4/* 0 0 1-5')
    }
    stages {
        stage('Example') {
            steps {
                echo 'Hello World'
            }
        }
    }
}			
			
			

一般我们会将管道和GitHub、GitLab、BitBucket关联, 然后使用它们的webhooks来触发,就不需要这个指令了。

6.3.11. tools

定义自动安装并自动放入PATH里面的工具集合

			
// Declarative //
pipeline {
    agent any
    tools {
        maven 'apache-maven-3.5.0' ①
    }
    stages {
        stage('Example') {
            steps {
                sh 'mvn --version'
            }
        }
    }
}		
			
			

注:① 工具名称必须预先在Jenkins中配置好了 → Global Tool Configuration.

6.3.12. post

post section 定义了管道执行结束后要进行的操作。支持在里面定义很多Conditions块: always, changed, failure, success 和 unstable。 这些条件块会根据不同的返回结果来执行不同的逻辑。

			
always:不管返回什么状态都会执行
changed:如果当前管道返回值和上一次已经完成的管道返回值不同时候执行
failure:当前管道返回状态值为”failed”时候执行,在Web UI界面上面是红色的标志
success:当前管道返回状态值为”success”时候执行,在Web UI界面上面是绿色的标志
unstable:当前管道返回状态值为”unstable”时候执行,通常因为测试失败,代码不合法引起的。在Web UI界面上面是黄色的标志

// Declarative //
pipeline {
    agent any
    stages {
        stage('Example') {
            steps {
                echo 'Hello World'
            }
        }
    }
    post {
        always {
            echo 'I will always say Hello again!'
        }
    }
}			
			
			

失败发送邮件的例子

			
    post {
        failure {
            mail to: "${email}",
            subject: "Failed Pipeline: ${currentBuild.fullDisplayName}",
            body: "Something is wrong with ${env.BUILD_URL}"
        }
    }			
			
			

6.3.13. when 条件判断

			
branch - 分支匹配才执行 when { branch 'master' }
environment - 环境变量匹配才执行 when { environment name: 'DEPLOY_TO', value: 'production' }
expression - groovy表达式为真才执行 expression { return params.DEBUG_BUILD } }

// Declarative //
pipeline {
    agent any
    stages {
        stage('Example Build') {
            steps {
                echo 'Hello World'
            }
        }
        stage('Example Deploy') {
            when {
                branch 'production'
            }
            echo 'Deploying'
        }
    }
}			
			
			

6.3.14. script

			
// Declarative //
pipeline {
    agent any
    stages {
        stage('Example') {
            steps {
                echo 'Hello World'
                script {
                    def browsers = ['chrome', 'firefox']
                    for (int i = 0; i < browsers.size(); ++i) {
                        echo "Testing the ${browsers[i]} browser"
                    }
                }
                script {
                    // 一个优雅的退出pipeline的方法,这里可执行任意逻辑
                    if( $VALUE1 == $VALUE2 ) {
                       currentBuild.result = 'SUCCESS'
                       return
                    }
                }
            }
        }
    }
}			
			
			

6.3.15. Jenkins pipeline 中使用 sshpass 实现 scp, ssh 远程运行

			
pipeline {
    agent {
        label "java-8"
    }
    stages  {

     	stage("环境") {
            steps {
                parallel "Maven": {
                  	script{
                      	sh 'mvn -version'
                  	}
                }, "Java": {
                    sh 'java -version'
                }, "sshpass": {
                  	sh 'apt install -y sshpass'
                    sh 'sshpass -v'
                }
            }
          
        }
        
        stage("检出") {
            steps {
                checkout(
                  [$class: 'GitSCM', branches: [[name: env.GIT_BUILD_REF]], 
                  userRemoteConfigs: [[url: env.GIT_REPO_URL]]]
                )
            }
        }

        stage("构建") {
            steps {
                echo "构建中..."
              	sh 'mvn package -Dmaven.test.skip=true'
                archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true
                echo "构建完成."
            }
        }

        stage("测试") {
            steps {
                parallel "单元测试": {
                    echo "单元测试中..."
                    sh 'mvn test'
                    echo "单元测试完成."
                    junit 'target/surefire-reports/*.xml'
                }, "接口测试": {
                    echo "接口测试中..."
                    // 请在这里放置您项目代码的单元测试调用过程,例如 mvn test
                    echo "接口测试完成."
                }, "测试敏感词":{
                    echo "Username: ${env.username}"
            		echo "Password: ${env.password}"
                }

            }
          
        }
      	stage("运行"){
      		steps {
            	sh 'java -jar target/java-0.0.1-SNAPSHOT.jar'
    	    }
    	}
      	stage("部署"){
      		steps {
              parallel "上传": {
                    sh 'sshpass -p Passw0rd scp target/*.jar root@dev.netkiller.cn:/root/'
                }, "运行": {
                    sh 'sshpass -p Passw0rd ssh root@dev.netkiller.cn java -jar /root/java-0.0.1-SNAPSHOT.jar'
                }
            	
    	    }
    	}
    }
}