--昨夜西风凋碧树,独上高楼,望尽天涯路
本文介绍了使用Jenkins及其主要特性Jenkins pipeline的基础知识。这个向导使用了“单机(原文是standalone)”Jenkins发行版,可以在本地运行。
Getting started
1.环境准备
搭建standalone版的Jenkins需要:
硬件需求:
256MB的RAM,最好是512MB
10GB的硬盘空间(存储Jenkins和Docker镜像)
软件需求:
Java 8(JDK或者JRE都是OK的)
Docker环境
2.下载以及运行Jenkins
2)进入下载后的目录,执行java -jar jenkins.war --httpPort=8080
3)访问 http://localhost:8080
4)按照Jenkins的提示安装Jenkins
创建一个Pipeline
Jenkins Pipeline(俗称Pipeline)是一套插件,它支持实现流水线(continuous delivery pipelines)并将其集成到Jenkins中
流水线可以自动完成从软件版本控制到服务部署
Jenkins Pipeline 提供了一组可以扩展的工具,可以用代码的方式来构建流水线。Jenkins Pipeline的定义通常被写入文本文件(称为jenkinsfile),然后将其放入项目的源代码管理存储库。
有关pipeline和jenkinsfile是什么的更多信息,请参考相应的管道,并使用User Handbook中的jenkinsfile部分
下面迅速创建一个Pipeline(基于Multibranch Pipeline):
1)编写一个名为Jenkinsfile
的文件存放在仓库(Git,SVN...),Jenkins提供了两种风格的方式编写脚本:
Declarative Pipeline:
Jenkinsfile (Declarative Pipeline)
pipeline {
agent { docker { image 'maven:3.3.3' } }
stages {
stage('build') {
steps {
sh 'mvn --version'
}
}
}
}
Scripted Pipeline
Jenkinsfile (Scripted Pipeline)
/* Requires the Docker Pipeline plugin */
node('docker') {
checkout scm
stage('Build') {
docker.image('maven:3.3.3').inside {
sh 'mvn --version'
}
}
}
2)点击新建任务创建一个新的Pipeline,输入Pipeline的名称以及选择多分支流水线(Multibranch Pipeline)
3)点击添加源,选择仓库的类型,填写凭证以及需要的策略,之后点击保存按钮保存:
设置好pipeline后,Jenkins将自动检测存储库中创建的任何新分支或请求,并开始为它们运行pipeline。
分步运行
Pipeline一般会由多个步骤组成,这些步骤中可以实现构建,测试和部署等过程。Jenkins Pipeline可以通过一种简单的方式组合这些步骤用来建立任何类型的自动化过程。每个步骤可以看作是执行单个操作的命令。当前一个步骤执行成功之后,才会移动到下一个步骤。当一个步骤无法执行时Pipeline执行失败。只有当Pipeline中所有的步骤都成功完成时,Pipeline才会成功执行。
例:
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'echo "Hello World"'
sh '''
echo "Multiline shell steps works too"
ls -lah
'''
}
}
}
}
Jenkinsfile (Scripted Pipeline)
node {
stage('Build') {
sh 'echo "Hello World"'
sh '''
echo "Multiline shell steps works too"
ls -lah
'''
}
}
Jenkins还提供了很多强大的wrap steps,这些steps可以包裹具体步骤。比如retry重试,timeout超时退出等:
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Deploy') {
steps {
retry(3) {
sh './flakey-deploy.sh'
}
timeout(time: 3, unit: 'MINUTES') {
sh './health-check.sh'
}
}
}
}
}
Jenkinsfile (Scripted Pipeline)
node {
stage('Deploy') {
retry(3) {
sh './flakey-deploy.sh'
}
timeout(time: 3, unit: 'MINUTES') {
sh './health-check.sh'
}
}
}
上面代码的意思是,在 "部署" 阶段如果flakey-deploy.sh脚本执行未成功会重试3次。如果health-check.sh在3分钟未完成Pipeline就会标记失败。
wrap steps也可以包含其他的步骤,下面脚本表示三分钟之内重试5次,如果还不成功,就标记为Pipeline失败:
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Deploy') {
steps {
timeout(time: 3, unit: 'MINUTES') {
retry(5) {
sh './flakey-deploy.sh'
}
}
}
}
}
}
Jenkinsfile (Scripted Pipeline)
node {
stage('Deploy') {
timeout(time: 3, unit: 'MINUTES') {
retry(5) {
sh './flakey-deploy.sh'
}
}
}
}
当Pipeline完成执行时,有时候还会运行清理步骤,或者根据Pipeline运行的结果执行一些操作。这些操作可以在POST部分执行:
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Test') {
steps {
sh 'echo "Fail!"; exit 1'
}
}
}
post {
always {
echo 'This will always run'
}
success {
echo 'This will run only if successful'
}
failure {
echo 'This will run only if failed'
}
unstable {
echo 'This will run only if the run was marked as unstable'
}
changed {
echo 'This will run only if the state of the Pipeline has changed'
echo 'For example, if the Pipeline was previously failing but is now successful'
}
}
}
Jenkinsfile (Scripted Pipeline)
node {
try {
stage('Test') {
sh 'echo "Fail!"; exit 1'
}
echo 'This will run only if successful'
} catch (e) {
echo 'This will run only if failed'
// Since we're catching the exception in order to report on it,
// we need to re-throw it, to ensure that the build is marked as failed
throw e
} finally {
def currentResult = currentBuild.result ?: 'SUCCESS'
if (currentResult == 'UNSTABLE') {
echo 'This will run only if the run was marked as unstable'
}
def previousResult = currentBuild.previousBuild?.result
if (previousResult != null && previousResult != currentResult) {
echo 'This will run only if the state of the Pipeline has changed'
echo 'For example, if the Pipeline was previously failing but is now successful'
}
echo 'This will always run'
}
}