Pipeline As Code With Jenkins2.0
Jenkins2.0 Pipeline导入Pipeline as Code是Jenkins 2.0版本的精华所在,是帮助Jenkins实现从CI到CD华丽转身的关键工具。 所谓Pipeline,简单来说,就是一套运行于Jenkins上的工作流框架,将原本独立运行于单个或者多个节点的任务连接起来,实现单个任务难以完成的复杂发布流程
Pipeline的实现方式是一套Groovy DSL(类似Gradle),任何发布流程都可以表述为一段Groovy脚本,并且Jenkins支持从代码库直接读取脚本,从而实现了Pipeline as Code的理念。 注: 本文首发于 My 公众号 CodeSheep ,可 长按 或 扫描 下面的 小心心 来订阅 ↓ ↓ ↓
为什么要使用Jenkins2.0 Pipeline这里主要结合我自己对传统Jenkins Job使用的一些痛点来说:
我想这些理由应该足以让我们把目光转向Jenkins2.0的Pipeline! Pipeline的功能和优点:
3.更灵活的并行执行,更强的依赖控制,通过groovy脚本可以实现step,stage间的并行执行,和更复杂的相互依赖关系。
Pipeline原理与流程Pipeline为用户设计了三个最最基本的概念:
一个典型的Stage View如下图所示:
从图中可以十分方便地看到哪些Stage通过,哪些Stage失败,以及构建的时间。 Jenkins2.0的Pipeline搭建使用的是Groovy脚本,通过Groovy脚本实现工作流管理的步骤如下:
实际上更常用的是MultiBranch Pipeline,上面的图中截图没有包含,但与普通Pipeline基本类似。
上图的实例脚本如下: node { stage('Checkout Code') { // for display purposes // Get some code from a GitHub repository git 'https://github.com/jglick/simple-maven-project-with-tests.git' } stage('Build') { // Run the maven build if (isUnix()) { sh "'${MAVEN_HOME}/bin/mvn' -Dmaven.test.failure.ignore clean package" } else { bat(/"${MAVEN_HOME}binmvn" -Dmaven.test.failure.ignore clean package/) } } stage('Unit test') { junit '**/target/surefire-reports/TEST-UT.xml' archive 'target/*.jar' } }
构建过程的stage View如下:
很明显可以看出,这里显示的和Groovy脚本中格式化的代码是一致的,会实时显示各个工作流的执行进度和结果,直观易懂。鼠标移上去,能看到日志信息的缩略图,单击可以调到对应stage的console中。 总而言之,一切都是那么地优雅! Jenkins2.0 Pipeline关键DSL语法及示例在这里总结一下Pipeline中的关键DSL语法,利用Groovy对其进行组合可以完成任何一项复杂的CI/CD流程,熟悉它们大有裨益。
归档文件,举例: archiveArtifacts 'target/*.jar'
执行windows平台下的批处理文件,如 bat "call example.bat"
触发构建一个jenkins job,如 build 'TEST_JOB'
从SCM系统中checkout repo,如: checkout([$class: 'SubversionSCM',additionalCredentials: [],excludedCommitMessages: '',excludedRegions: '',excludedRevprop: '',excludedUsers: '',filterChangelog: false,ignoreDirPropChanges: false,includedRegions: '',locations: [[credentialsId: '30e6c1e5-1035-4bdd-8a44-05ba8f885158',depthOption: 'infinity',ignoreExternalsOption: true,local: '.',remote: 'svn://xxxxxx']],workspaceUpdater: [$class: 'UpdateUpdater']])
从workspace中删除当前目录
切换目录,如 dir('/home/jenkins') { // 切换到/home/jenkins目录中做一些事情 // some block }
打印信息,如 echo 'hello world'
利用Jenkins发送邮件,内容、主题全都可以自定义,如 emailext body: 'Subject_test',subject: 'Subject_test',to: 'hansonwang99@163.com.cn' // 邮件的正文body,主题subject,收件人to等可以进行自定义
抛出一个错误信号,可以自行在代码里抛出,如 error 'read_error'
检查工作空间某个路径里是否存在某个file,举例: fileExists '/home/test.txt' // 检查是否存在test.txt
等待外界用户的交互输入,举例: input message: '',parameters: [string(defaultValue: '默认值',description: '版本号',name: 'version')] // 在某一步骤,等待用户输入version参数才能往下执行
用于判断当前任务是否运行于Unix-like节点上,举例: def flag = isUnix() if( flag == false ) { // 可以据此进行判断 echo "not run on a unix node !" }
调用一个外部groovy脚本,举例: load 'D:jenkinsworkspacetest.groovy'
分配节点给某个任务运行,举例: node('节点标签') { // 在对应标签的节点上运行某项任务 Task() }
并行地执行任务,可以说是最实用高效的工具了,举例: parallel( //并行地执行android unit tests和android e2e tests两个任务 'android unit tests': { runCmdOnDockerImage(androidImageName,'bash /app/ContainerShip/scripts/run-android-docker-unit-tests.sh','--privileged --rm') },'android e2e tests': { runCmdOnDockerImage(androidImageName,'bash /app/ContainerShip/scripts/run-ci-e2e-tests.sh --android --js','--rm') } )
设置Job的属性,举例: properties([parameters([string(defaultValue: '1.0.0',name: 'VERSION')]),pipelineTriggers([])]) // 为job设置了一个VERSION参数
从工作空间中读取文件,举例: def editionName = readFile '/home/Test/exam.txt'
重复body内代码N次,举例: retry(10) { // some block }
执行shell脚本,如:sh "sh test.sh"
延时,如延时2小时:sleep time: 2,unit: 'HOURS'
创建任务的stage,举例: stage('stage name') { // some block }
存放文件为后续构建使用,举例: dir('target') { stash name: 'war',includes: 'x.war' }
将stash步骤中存放的文件在当前工作空间中重建,举例: def deploy(id) { unstash 'war' sh "cp x.war /tmp/${id}.war" }
时间限制,举例 timeout(time: 4,unit: 'SECONDS') { // some block }
timestamps { // some block }
创建文件,举例: touch file: 'TEST.txt',timestamp: 0
unzip dir: '/home/workspace',glob: '',zipFile: 'TEST.zip'
检查给定的文件是否包含一个有效的Declarative Pipeline,返回T或者F validateDeclarativePipeline '/home/wospace'
等待,直到条件满足 waitUntil { // some block }
使用凭据 withCredentials([usernameColonPassword(credentialsId: 'mylogin',variable: 'USERPASS')]) { sh ''' set +x curl -u $USERPASS https://private.server/ > output ''' }
设置环境变量,注意近本次运行有效! withEnv(['MYTOOL_HOME=/usr/local/mytool']) { sh '$MYTOOL_HOME/bin/start' }
写文件到某个路径 writeFile file: '/home/workspace',text: 'hello world'
写JSON文件,用法基本同上
创建zip文件 zip dir: '/home/workspace',zipFile: 'TEST.zip'
自定义工作空间,在其中做一些工作,效果类似于Dir命令,举例: ws('/home/jenkins_workspace') { // some block } 后记
作者更多的SpringBt实践文章在此:
如果有兴趣,也可以抽点时间看看作者一些关于容器化、微服务化方面的文章:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |