3.Jenkins 2 权威指南 --- 流水线执行流程

1.触发任务
	指定流水线代码的触发事件,有如下3种不同的方法:
		1.如果Jenkins应用的本身就是流水线类型的任务,可以使用传统的方法通过web界面在项目的基本配置部分指定触发条件
		2.如果是创建了一个脚本式流水线,可以在代码中指定一个 properties 代码块(通常在流水线开始之前)来定义触发条件(
		注意,这个属性部分将会和 web 界面中定义的属性合并,并且web界面上定义的属性优先级先生效)。
		3.如果是创建了一个声明式流水线,有个特殊的 triggers 指令可以用来定义流水线的触发类型。


2.在其他项目构建后构建
	这种方式允许在一个或者多个其他项目之后开始你的项目构建。你可以选择其他项目构建的状态(稳定的,不稳定的或者失败的)。
	对于一个脚本式流水线,在任务 Job1 成功后构建你的流水线,其语法如下:
	properties([
		pipelineTriggers([
			upstream(
				threshold:hudson.model.Result.SUCCESS,
				upstreamProjects.'Job1'
			)
		])
	])
	如果你需要列出多个任务,可以使用逗号分隔。如果你需要指定一个任务的某个分支,在任务名称的后面添加斜线和分支名称(如 'Job1/master')


3.周期性构建
	这种方法提供了一种 cron 类型的功能,可以按照某个时间间隔启动任务。

	//周一到周五上午9点运行,脚本式流水线
	properties([pipelineTriggers([cron('0 9 * * 1-5')])])

	//声明式流水线语法
	triggers{ cron(0 9 * * 1-5)}

	cron 语法:
		triggers { cron(15 * * * *) } //在每小时的第15分钟启动一个流水线
		triggers { pollSCM(*/20 * * * *) }  //每20min间隔扫描一次 SCM 变化
		triggers { cron(H(0,30) * * * *) }  //在每小时前半小时的某个时间点启动流水线
		符号 H 可以用于任何字段。这个符号对于Jenkins而言有着特殊的意义。它告诉Jenkins,在一个范围内,使用该项目名称的散列值计算出一个
	唯一的偏移量。这个偏移量与范围最小值相加之后,用于定义范围的实际执行时间。目的是避免所有配置相同的 cron 的值的项目在同一时间启动。

4.使用 GitHub 钩子触发器进行 GitSCM 轮询
	如果一个GitHub项目被配置为Jenkins项目的代码源,就可以设置一个推钩来触发Jenkins项目。当设置好之后,当有代码推送到代码库时就会发射钩子
  触发Jenkins,进而调用Jenkins SCM 轮询相应的功能。所以必须设置 SCM 轮询,才能使用 GitHub 钩子触发工作。
    在一个脚本式流水线中,配置这个属性的语法如下:
    properties([pipelienTriggers[githubPush()]])
    声明式流水线中还不支持。


5.SCM 轮询
	这是标准的轮询功能,周期性的扫描源码版本控制系统的变更。这是比较昂贵的操作。
	//脚本式流水线,每30分钟轮询一次
	properties([pipelineTriggers([pollSCM('*/30 * * * *')])])

	//
	triggers{ pollSCM(*/30 * * * *) }


6.静默期
	这里指定的值将作为构建被触发和Jenkins真正执行构建之间的一个'等待时间'或者偏移量。


7.远程触发构建
	对于Jenkins系统上给定的任务,可以访问一个特定的URL来触发构建。


8.用户输入
	DSL 的 input 步骤就是让我们通过流水线获得用户输入的方式。在脚本式流水线中,这个步骤接受与普通Jenkins任务相同的参数类型。
  在声明式流水线中,有一个特殊的 parameters 指令,可以支持那些参数的子集。

  	输入:
  		input 'Continue to next stage ?'
  		默认的表单是打印一条消息和提供给用户一个选择,即继续执行(Proceed)或者中止(Abort)。请注意,当系统执行了一个 input 步骤时,
  	  相应节点上的进程会被暂停,这会导致系统资源被独占。会占用节点的执行器,直到input步骤完成。
  	    input 有几个参数:
  	    	1.消息(message)
  	    		显示给用户的消息
  	    	2.自定义ID(id)
  	    		input id:'ctns-prompt', message:'Continue to next stage ?'
  	    		然后可以通过 URL 请求 :
  	    		http://[jenkins-base-url]/job/[job_name]/[build_id]/input/Ctns-prompt/proceed
  	    		http://[jenkins-base-url]/job/[job_name]/[build_id]/input/Ctns-prompt/abort
  	    	3.OK按钮字母(ok)
  	    		input message:'<message text>', ok:'Yes'
  	    	4.允许的提交者(submitter)
  	    		input message:'<text>', submitter:'user1,user2'
  	    	5.存储批准提交者的参数
  	    		可以使用一个变量来存储批准执行的用户。为了使用这个批准提交者,你需要定义一个变量来保存 input 步骤的相应。
  	    		 stage ('Source') {
			       def resp = input id:'test-id', message:'Continue to next stage ?',ok:'YYY',submitterParamter:'test'
			       echo "${resp}"
			     }
  		
  	参数:
  		1.布尔类型(boolean)
  		def answer = input message:'<message>',parameters:[booleanParam (defaultValue:true, description:'Prerelease setting', name:'prerelease')]

  		2.选项型(choice)
  		def choice = input message:'<message>',
	    	parameters:[choice(choices:"a\n b\n c\n d\n")],
	    	description:'选择一个',
	    	name:'Options'

	    3.凭证(credential)
	    	def creds = input message:'<message>',
				parameters:[[$class:'CredentialsParameterDefinition', credentialType:'com.'],
				defaultValue:'jenkins2-ssh',
				description:'SSH key for access',
				name:'SSH',
				required:true
				]
			echo creds

		4.文件
			def selectedFile = input message:'<message>',
				parameters:[file(description:'choice file to upload',name:'local')]

		5.列出SVN 标签

		6.多行字符串
			node {
			   echo 'Hello World'
			   stage('Source') {
			        def lines = input message:'<message>',
				parameters:[text(defaultValue:''' line 1
				line 2
				line 3''', description:'',
				name:'Input Lines'
				)]
				echo lines
			   }
			}

			三引号是 Groovy 中的标准符号,用来跨越多行。

		7.密码
			def pw = input message:'<message>',
				parameters:[password(defaultValue:'',
				description:'Enter your password',name:'passwd'
				)]

		8.运行

		9.字符串
			def pw = input message:'<message>',
				parameters:[string(defaultValue:'', description:'Enter your string', name:'Response'
				)]

9.参数与声明式流水线
	1.使用 parameters 命令
	pipeline {
	    agent any
	    parameters {
	        string(name:'USERID', defaultValue:'',description:'Enter your userid')
	    }
	    stages {
	        stage('login') {
	            steps {
	                echo 'Active user is now ' + "${params.USERID}"
	            }
	        }
	    }
	}

	2.使用Jenkins应用来参数化构建
		在配置中勾选这个项目是参数化的(This project is parameterized)
		web表单里填写的参数获取方式:
		params.USERID
		或者
		"${params.USERID}"

	3.使用一个 script 代码块
		虽然声明式流水线一直在持续进化并添加更多的功能,但是仍然有些场景是声明式风格不支持的。对于这些情况,声明式语法支持一个 script 代码块。
		一个 script 代码块允许你在该代码块中使用非声明的语法。其中也就包括定义变量,而这在声明式流水线的 script 代码块外是不被允许的。这意味着
	  你不能在 script 代码块之外引用该代码块中定义的变量。
	    有一个变通的方法,你可以把返回值存储在一个环节变量中。
	    script {
	    	env.RESP1 = ...
	    }
	    echo "${env.RESP1}"

	4.使用外部代码
		把脚本式语句(类似调用输入语句)存放在外部共享库中或者存放在一个可以加载执行的外部 Groovy 文件中。
		//导入库 Utilities
		@Library('Utilities')_ 

10.流程控制选项
	1.超时(timeout)
		允许你限制等待某个行为发生时脚本所花费的时间。语法如下:
			timeout(time:60, unit:'SECONDS') {
				//该代码块中的过程被设置为超时
			}
			默认是 min。如果超时,将抛出一个异常。

			最佳的做法是,使用 timeout 对任何可能造成流水线暂停的步骤进行封装。这样做的结果是,即使出现差错导致在限定的时间内没有得到期望的输入,你的
		流水线也会继续执行。
		//超过10秒,抛出异常
		node {
			def response
			stage('input') {
				timeout(time:10, unit:'SECONDS') {
					response = input message:'User',
						parameters:[string(defaultValue:'user1'),
						description:'Enter Userid:', 
						name:'userid'
						]
				}
				echo 'Username = ' + response
			}
		}

		node {
			def response
			stage('input') {
				try {
					timeout(time:10, unit:'SECONDS') {
						response = input message:'User',
							parameters:[string(defaultValue:'user1'),
							description:'Enter Userid:', 
							name:'userid'
							]
					}
					echo 'Username = ' + response
				}
				catch(err) {
					response = 'user1'
				}
			}
		}

	2.重试(retry)
		将代码封装为一个步骤,当代码中有异常发生时,该步骤可以重试过程 n 次。这里的 n 表示你传入的数值。其语法如下:
		retry(<n>) {
			//代码
		}

	3.睡眠(sleep)
		这是一个基本延迟的步骤。它接收一个数值并且延迟相应的时间后再继续执行。默认的时间单位是s。语法如下:
		sleep time:5, unit:'MINUTES'

	4.等待直到(waitUnitl)
		这个步骤会导致整个过程一直等待某事的发生。这里的某事指的是可以返回 true的闭包。
		如果代码块中返回 false,那么这个步骤会在等待更长的时间后进行下一次尝试,过程中抛出的任何异常都会导致这个步骤立即退出并抛出一个错误。
		timeout(time:120,unit:'SECONDS') {
			waitUntil {
				try {
					return true
				}
				catch(exception) {
					return false
				}
			}
		}


11.并发处理
	1.使用 lock 步骤对资源加锁
		//提供资源的名字作为默认参数
		lock('worker_node1') {
			//...
		}

		//标签,资源的数量
		lock(label:'doker-node', quantity:3) {
			//..
		}

	2.使用 milestone 来控制并发构建
		milestone label:'After build', ordinal:1

	3.在多分支流水线中限制并发
		//脚本式语法
		properties([disableConcurrentBuilds()])
		//声明式语法
		options {
			disableConcurrentBuilds()
		}

	4.并发的运行任务
		1.传统的并行语法
		stash 和 unstash (跨节点共享文件)
			在Jenkins的 DSL中,stash 和 unstash 函数允许在流水线的节点间和/或阶段间保存和获取文件。它们的格式是:
			stash name:"<name>" [includes:"<pattern>" excludes:"<pattern>"]
			unstash "<name>"	

		2.声明式流水线中的替代并行语法
			stage('Unit Test') {
				parallel {
					stage('Util unit tests') {
						agent { label 'worker_node1' } 
						steps {
							...
						}
					}
					stage('API unit tests') {
						agent { label 'worker_node2' } 
						steps {
							...
						}
					}
				}
			}

		parallel 和 failFast : 如果一个分支失败了,就退出所有的步骤


12.有条件的执行功能
	条件性构建步骤插件(Conditional BuildStep plugin)可以让用户在Jenkins自由风格类型的任务中添加一些有条件的执行功能。
	if ((条件1) && (条件2))

	//声明式流水线
	会采用一个 when 形式来测试一个或者多个 expression 代码块是否为 true。如果为 true,阶段中剩下的代码才会被执行。否则不执行。
	pipeline {
		agent any
		parameters {
			...
		}
		stages {
			stage('...') {
				when {
					allof {
						expression {params.BRANCH_NAME=='master'}
						expression {params.BUILD_TYPE=='release'}
					}
				}
				steps {
					echo '...'
				}
			}
		}
	}


13.构建后处理
	1.脚本式流水线构建后处理
		没有内置支持构建后处理,通常依靠 Groovy 程序结构提供此功能。我们会使用 try-catch-finally 机制。
		然后,Jenkins DSL 包含了另外一个步骤,可以作为 try-catch-finally 功能的快捷方法:catchError
		def err=null
		try {
			node ('node1') {
				stage('first stage') {
					...
				}
			}
		}
		catch(err) {
			...
		}
		finally {
			...
		}

		catchError :
			使用 catchError结构,如果一个代码块抛出了一个异常,那么这个构建会被标记为失败状态。但是,流水线中从 catchError 代码块
		往后的语句可以继续执行。这样做的有点是,在处理失败后,你依然可以做一些类似发送通知的事情。
		node('node1') {
			catchError {
				stage('first stage') {
					...
				}
			}
			//发送邮件
			...
		}


	2.声明式构建与构建后处理
		声明式流水线中有一个专门的部分用于构建后处理。这个部分被称为构建后操作(post)。一个 post 部分可以放在一个阶段的结尾或者一个流水线的结尾,
	  或者同时放在这2个地方。
	  post {
	  	always {
	  		...
	  	}
	  	failure {
	  		...
	  	}
	  	success {
	  		...
	  	}
	  }

 

 

 

 

 

 

 

 

 

 

 

 

展开阅读全文

没有更多推荐了,返回首页