©	2016	CloudBees,	Inc.		All	Rights	Reserved
©	2016	CloudBees,	Inc.		All	Rights	Reserved
©	2016	CloudBees,	Inc.		All	Rights	Reserved
©	2016	CloudBees,	Inc.		All	Rights	Reserved
Continuous Delivery as Code
Pipeline and Jenkins 2
©	2016	CloudBees,	Inc.		All	Rights	Reserved
Continuous Delivery
Continuous delivery (CD) is a software engineering approach in
which teams produce software in short cycles, ensuring that
the software can be reliably released at any time. It aims at
building, testing, and releasing software faster and more
frequently. The approach helps reduce the cost, time, and risk
of delivering changes by allowing for more incremental
updates to applications in production. A straightforward and
repeatable deployment process is important for continuous
delivery.
https://en.wikipedia.org/wiki/Continuous_delivery
©	2016	CloudBees,	Inc.		All	Rights	Reserved
Meet Jenkins 2
jenkins.io/2.0
©	2016	CloudBees,	Inc.		All	Rights	Reserved
Jenkins 2 Themes
Pipeline as code: front and center
Improved “out of the box” user
experience
User interface improvements
©	2016	CloudBees,	Inc.		All	Rights	Reserved
Jenkins 2 Themes
Pipeline as code: front and center
Improved “out of the box” user
experience
User interface improvements
©	2016	CloudBees,	Inc.		All	Rights	Reserved
Pipeline as code
• Introduce “Pipeline” as a new type in Jenkins
• Codify an implicit series of stages into an explicit
pipeline definition (Jenkinsfile) in source control
• Resumability/durability of pipeline state
• Extend the DSL to meet organizational needs
©	2016	CloudBees,	Inc.		All	Rights	Reserved
Creating a Pipeline
©	2016	CloudBees,	Inc.		All	Rights	Reserved
Creating a Pipeline
©	2016	CloudBees,	Inc.		All	Rights	Reserved
Creating a Pipeline
©	2016	CloudBees,	Inc.		All	Rights	Reserved
Creating a Pipeline
©	2016	CloudBees,	Inc.		All	Rights	Reserved
Jenkinsfile
node('java8')	{	
stage('Checkout')	{	
checkout	scm	
}	
stage('Build')	{	
sh	'mvn	clean	install'	
}	
stage('Test')	{	
sh	'mvn	test'	
}	
archiveArtifacts	artifacts:	'target/**/*.jar',	fingerprint:	true	
}
©	2016	CloudBees,	Inc.		All	Rights	Reserved
Pipeline Documentation
jenkins.io/doc
©	2016	CloudBees,	Inc.		All	Rights	Reserved
Pipeline Documentation
©	2016	CloudBees,	Inc.		All	Rights	Reserved
Snippet Generator localhost:8080/job/niagara/pipeline-syntax
©	2016	CloudBees,	Inc.		All	Rights	Reserved
Snippet Generator localhost:8080/job/niagara/pipeline-syntax
©	2016	CloudBees,	Inc.		All	Rights	Reserved
DSL Reference localhost:8080/job/niagara/pipeline-syntax/html
©	2016	CloudBees,	Inc.		All	Rights	Reserved
Pipeline Plugins
Extending Pipeline
©	2016	CloudBees,	Inc.		All	Rights	Reserved
Pipeline Stage View plugin
©	2016	CloudBees,	Inc.		All	Rights	Reserved
Pipeline Multibranch plugin
• Represent pipelines for multiple branches in one "Folder"
• Automatically scan a repository for each branch which contains a
Jenkinsfile
©	2016	CloudBees,	Inc.		All	Rights	Reserved
GitHub Organization Folder plugin
©	2016	CloudBees,	Inc.		All	Rights	Reserved
Blue Ocean jenkins.io/projects/blueocean
©	2016	CloudBees,	Inc.		All	Rights	Reserved
Docker Pipeline plugin
def	imageName	=	'jenkinsciinfra/bind'



node('docker')	{

	 checkout	scm

//	Compute	a	unique	image	tag

	 def	imageTag	=	"build-${env.BUILD_NUMBER}"

//	The	`docker`	variable	introduced	by	the	plugin

	 stage('Build')	{

	 	 def	whale	=	docker.build("${imageName}:${imageTag}")	
}

//	Publish	this	image	to	Docker	Hub

	 stage('Deploy')	{

	 	 whale.push()	
}	
}
©	2016	CloudBees,	Inc.		All	Rights	Reserved
Docker Pipeline plugin
node('docker')	{	
//	The	`docker`	variable	introduced	by	the	plugin.	
//	
//	Invoking	our	Gradle	build	inside	a	freshly	spun	up	
//	Docker	container	with	JDK8	
docker.image('openjdk:8-jdk').inside	{	
	 checkout	scm	
	 sh	'./gradlew	--info'	
	 archiveArtifacts	artifacts:	'build/libs/**/*.jar',	fingerprint:	true	
}	
}
©	2016	CloudBees,	Inc.		All	Rights	Reserved
Integration with existing plugins
Pipeline + ??? = Profit.
©	2016	CloudBees,	Inc.		All	Rights	Reserved
Plugins that support Pipeline
• A few plugins which provide custom steps for Pipeline scripts:
– Tooling: Credentials binding, SSH Agent, Parallel Test
– Reporters: JUnit, Brakeman, HTML Publisher, Cucumber Test Result
– Notifiers: Slack, HipChat, email-ext
– Wrappers: Timestamper
• Plugins work within Pipelines
– SCM: Git, SVN, Mercurial, P4, CVS
– Wrappers: Ansi Color, NodeJS
– Build steps: Ant, etc
• More defined in COMPATIBILITY.md
©	2016	CloudBees,	Inc.		All	Rights	Reserved
Steps added by plugins
node	{	
	 /*	other	work	happened	up	here	*/	
	 timestamps	{	
	 	 sh	'mvn	clean	package'	
	 	 junit	'**/target/surefire-reports/*.xml'	
	 }	
if	(env.BRANCH_NAME	==	'master')	{	
sshagent(credentials:	['my-credential-id'])	{	
	 sh	'./run-ssh-deploy-script'	
	 	 }	
	 }	
}
©	2016	CloudBees,	Inc.		All	Rights	Reserved
Build Steps
©	2016	CloudBees,	Inc.		All	Rights	Reserved
Build Wrappers
github.com/jenkinsci/pipeline-examples
©	2016	CloudBees,	Inc.		All	Rights	Reserved
Abstracting Pipeline
Sharing code, best practices and templates for success
©	2016	CloudBees,	Inc.		All	Rights	Reserved
Pipeline Shared Libraries
//	The	call()	method	in	any	file	in	pipeline-library.git/vars	is	exposed	as	a

//	method	with	the	same	name	as	the	file.

def	call(def	mavenOptions)	{	
docker.image('maven').inside	{	
	 timestamps	{	
	 sh	"mvn	clean	install	-Dmaven.test.failure.ignore=true	$
{mavenOptions}"	
}	
junit	'**/target/surefire-reports/**/*.xml'	
}

}
runMaven.groovy
github.com/jenkinsci/pipeline-examples
©	2016	CloudBees,	Inc.		All	Rights	Reserved
node	{	
	 checkout	scm	
	 stage('Build')	{	
//	Loads	runMaven	step	from	the	Shared	Library	and	invokes	it.	
	 	 runMaven	
	 }	
	 stage('Acceptance	Tests')	{	
	 	 git	'git://git.example.com/selenium-tests.git'	
	 	 sh	'./run-selenium.sh'	
	 }	
	 stage('Deploy')	{	
	 	 sh	'./deploy.sh'	
	 }	
}
Pipeline Shared Libraries
Jenkinsfile
github.com/jenkinsci/pipeline-examples
©	2016	CloudBees,	Inc.		All	Rights	Reserved
load step
//	Methods	in	this	file	will	end	up	as	
object	methods	on	the	object	that	load	
returns.

def	lookAtThis(String	whoAreYou)	{

				echo	"Look	at	this,	${whoAreYou}!	You	
loaded	something	from	another	file!"

}	
externalMethod.groovy
github.com/jenkinsci/pipeline-examples
//	If	there's	a	call	method,	you	can	just	
load	the	file,	say,	as	"foo",	and	then	
invoke	that	call	method	with	foo(...)	

def	call(String	whoAreYou)	{

				echo	"${whoAreYou},	say	thanks	to	the	
call(...)	method."

}	
externalCall.groovy
node	{	
		//	Load	the	file	from	the	current	
directory,	
		//	into	a	variable	called	"externalMethod"	
		def	externalMethod	=	
load("externalMethod.groovy")



		//	Call	the	method	we	defined

		externalMethod.lookAtThis("Steve")



		//	Now	load	'externalCall.groovy'.

		def	externalCall	=	
load("externalCall.groovy")



		//	We	can	just	run	it	with	
`externalCall()`

		externalCall("Steve")

}	
Jenkinsfile
©	2016	CloudBees,	Inc.		All	Rights	Reserved
Continuous Delivery as Code
Final Thoughts
©	2016	CloudBees,	Inc.		All	Rights	Reserved
• A new pipeline “type” has been introduced
• Previously implicit pipelines, chained jobs, can now be
made explicit and committed to SCM
• Pipelines have state associated with them and can be
resumed
• It’s code. It can be modified and extended
Final Thoughts
©	2016	CloudBees,	Inc.		All	Rights	Reserved
©	2016	CloudBees,	Inc.		All	Rights	Reserved
Questions/Answers
jenkins.io/2.0
jenkins.io/doc
@jenkinsci

7 Habits of Highly Effective Jenkins Users