Continuous Delivery Pipeline as code
Continuous Delivery Pipeline as code
Mike van VendelooSoftware Craftsman at JPoint
TU Delft - Computer Science
Scrum master
Assignments at customers like KLM, Rabobank, Government, de Persgroep.
Focus on improvement of software development process and quality
Hobb: Korfball, domotica
@mikevanvendeloo
Agenda• Definitions CI/CD/Pipeline
• Jenkins 2: Pipeline as code
• Pipeline snippets
• Reuse with pipeline libraries
• Declarative pipelines
• Blue Ocean
• Demo
Definitions
Definitions - Continuous Integration“Continuous Integration is a software development practice where members of a team integrate their work frequently, usually each person integrates at least daily - leading to multiple integrations per day. Each integration is verified by an automated build (including test) to detect integration errors as quickly as possible.“
Martin Fowler
Continuous Delivery: Automate everything“If it hurts, do it more frequently, and bring the pain forward.” ― Jez Humble, Continuous Delivery
Definitions - Continuous Delivery“Continuous Delivery is the ability to get changes of all types—including new features, configuration changes, bug fixes and experiments—into production, or into the hands of users, safely and quickly in a sustainable way.”
Definitions - Continuous Deployment
Definitions - PipelineA pipeline is a set of stages to bring functionality from developer to the end user.
Jenkins pipeline as code
Jenkins 1
Jenkins 2 - Pipeline as code
Sample basic pipeline stages➔ Checkout
Source code checkout from repository
➔ BuildCompile & Unit test
➔ QACode style check & integration testing
➔ DeployDeploy to a server
Basic pipeline definition#!/usr/bin/groovy
node('linux') { stage('Checkout') { checkout scm }
stage('Build') { sh "mvn clean deploy" junit allowEmptyResults: true, testResults: 'target/surefire-reports/*.xml' }
stage('Deploy') { build "Deployer" }}
Pipeline snippets
Error handlingnode { stage('Doing my thing') { try { sh 'exit 1' } catch (someException) { echo 'Something failed, somebody should be notified!' throw someException } finally {
hipchatSend color: 'BLUE', credentialId: 'hipChat', message: “Build result ${env.BUILD_RESULT}”, room: 'BuildResults' } }}
Pipeline properties - cleanupproperties( [buildDiscarder( logRotator( artifactDaysToKeepStr: '', artifactNumToKeepStr: '', daysToKeepStr: '7', numToKeepStr: '25') ), pipelineTriggers([]) ])
Pipeline properties - Parametersproperties( [parameters( [choice( choices: ['dev', 'test', 'acc', 'prod'], description: 'Kies de omgeving', name: 'omgeving')] ), pipelineTriggers([]) ])
Parallel tasksparallel ‘test’: { sh ‘mvn clean test’ }, ‘mutation-test’: { Sh ‘mvn org.pitest:pitest-maven:mutationCoverage’ }, failFast: true
Share information between nodes/executorsnode { stage(‘Build’) sh(“mvn -B clean package”) stash excludes:’target/’, includes: ‘**’, name: ‘source’}
stage (‘test’) { unstash ‘source’ }}
Notificationsdef notify(String colorCode, String color, String summary) slackSend (color: colorCode, message: summary)
hipchatSend (color: color, notify: true, message: summary)
emailext (
to: [email protected]',
subject: “Build ${env.JOB_NAME} [${env.BUILD_NUMBER}] result ${currentBuild.result}”
body: “<a href='${env.BUILD_URL}'>${env.JOB_NAME} [${env.BUILD_NUMBER}]</a>”,
recipientProviders: [[$class: 'DevelopersRecipientProvider']]
)
}
Pipeline libraries
Reuse between pipelines: libraries
Library implementationpackage vanvendeloo.jenkins
def checkout(String repositoryName) { git “[email protected]:vanvendeloo/${repositoryName}”}def updateVersion() {
sh “mvn build-helper:parse-version versions:set -DnewVersion=\\\${parsedVersion.majorVersion}.\\\${parsedVersion.minorVersion}.\\\${parsedVersion.nextIncrementalVersion} versions:commit”}// Return the contents of this script as object so it can be re-used in Jenkinsfiles.return this
Use the library: @Library@Library(‘pipeline-library’)
node { pipelineSteps = new PipelineSteps() stage(‘Preparation’) { pipelineSteps.checkout(‘my-service’) pipelineSteps.updateVersion() }}
Catch: Groovy Sandbox
org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: ↵ Scripts not permitted to use method java.lang.String replaceAll java.lang.String java.lang.String
1. Go to Manage Jenkins > In-process Script Approval
2. Review the pending signatures and click Approve to add them to the whitelist
3. Re-run your job; it should no longer fail (for this particular method call)
Declarative pipelines
Declarative Pipelinesnode { stage(‘Checkout’) { checkout scm } stage(‘Build’) { withEnv(["PATH+MAVEN=${tool 'M3'}/bin"]) { try { sh 'mvn clean install' } catch (e) { currentBuild.result = 'FAILURE' }
} }
pipeline { agent any tools { maven 'M3' } stages { stage('Checkout') { steps { checkout scm } } stage(Build) { steps { sh ‘mvn clean install’ } post { success { junit '**/surefire-reports/**/*.xml' } } } }
Blue Ocean
Blue Ocean
Pipeline result
ConclusionsPipeline evaluates with your code
Reuse in libraries keeps your Jenkinsfile clean and simple
BlueOcean definately an improvement, but need to get used to it
Pipeline editor very cool feature!
http://github.com/mikevanvendeloo
https://jenkins.io/doc/book/pipeline/syntax/
https://jenkins.io/blog/2017/02/07/declarative-maven-project/
Resources
@mikevanvendeloo