Slide 1

Slide 1 text

Creating a CI/CD Pipeline for Your Shared Libraries Roderick R. Randolph

Slide 2

Slide 2 text

© 2019 All Rights Reserved. 2

Slide 3

Slide 3 text

© 2019 All Rights Reserved. 3 https://jenkins.io/doc/book/pipeline-as-code/

Slide 4

Slide 4 text

© 2019 All Rights Reserved. 4 // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my-app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my-repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my-app:${version}" } } } } * Source code shown is simulated for demo purposes only

Slide 5

Slide 5 text

© 2019 All Rights Reserved. 5

Slide 6

Slide 6 text

© 2019 All Rights Reserved. 6 // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my-new-app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my-repo/my-new-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my-new-app:${version}" } } } } * Source code shown is simulated for demo purposes only

Slide 7

Slide 7 text

© 2019 All Rights Reserved. 7 // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } Project A Project B Project C * Source code shown is simulated for demo purposes only

Slide 8

Slide 8 text

© 2019 All Rights Reserved. 8

Slide 9

Slide 9 text

© 2019 All Rights Reserved. 9 // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg http_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg http_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } Project A Project B Project C * Source code shown is simulated for demo purposes only

Slide 10

Slide 10 text

© 2019 All Rights Reserved. 10

Slide 11

Slide 11 text

© 2019 All Rights Reserved. 11

Slide 12

Slide 12 text

© 2019 All Rights Reserved. 12 // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } // Jenkinsfile stage('Build') { node('docker') { sh "docker build -t /my-repo/my- app:${version} --build-arg https_proxy=http://:8080 ." def imageId = sh( script: "docker inspect /my- repo/my-app:${version} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) withCredentials([usernamePassword(...)]) { retry(3) { sh "docker push /my-repo/my- app:${version}" } } } } * Source code shown is simulated for demo purposes only

Slide 13

Slide 13 text

© 2019 All Rights Reserved. 13

Slide 14

Slide 14 text

© 2019 All Rights Reserved. 14 DRY!

Slide 15

Slide 15 text

© 2019 All Rights Reserved. 15 https://wiki.jenkins.io/display/JENKINS/Pipeline+Shared+Groovy+Libraries+Plugin

Slide 16

Slide 16 text

© 2019 All Rights Reserved. 16 ➜ ~ git init shared-libraries Initialized empty Git repository in shared-libraries/.git/ ➜ ~ cd shared-libraries ➜ shared-libraries git:(master) mkdir vars ➜ shared-libraries git:(master) vi vars/dockerBuild.groovy Creating A Shared Libraries Repository

Slide 17

Slide 17 text

© 2019 All Rights Reserved. 17 // vars/dockerBuild.groovy def call(Map params) { def registry = "" def image = params.image def proxy = params.withProxy ? '--build-arg https_proxy=http://:8080' : '' node('docker') { sh "docker build -t ${registry}/${image} ${proxy} ." if (params.withScan) { def imageId = sh( script: "docker inspect ${registry}/${image} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) } if (params.pushToRegistry) { withCredentials([usernamePassword(credentialsId: params.credentialsId)]) { retry(3) { sh "docker push ${registry}/${image}" } } } } } * Source code shown is simulated for demo purposes only

Slide 18

Slide 18 text

© 2019 All Rights Reserved. 18

Slide 19

Slide 19 text

© 2019 All Rights Reserved. 19 // Jenkinsfile library('shared-libraries') stage('Build') { dockerBuild( image: "my-repo/my-app:${version}", withProxy: true, withScan: true, credentialsId: "...", pushToRegistry: true, ) } * Source code shown is simulated for demo purposes only

Slide 20

Slide 20 text

© 2019 All Rights Reserved. 20 // Jenkinsfile library('shared-libraries') stage('Build') { dockerBuild( image: "my-namespace/my-app:${version}", withProxy: true, withScan: true, credentialsId: "...", pushToRegistry: true, ) } // Jenkinsfile library('shared-libraries') stage('Build') { dockerBuild( image: "my-namespace/my-app:${version}", withProxy: true, withScan: true, credentialsId: "...", pushToRegistry: true, ) } // Jenkinsfile library('shared-libraries') stage('Build') { dockerBuild( image: "my-namespace/my-app:${version}", withProxy: true, withScan: true, credentialsId: "...", pushToRegistry: true, ) } // Jenkinsfile library('shared-libraries') stage('Build') { dockerBuild( image: "my-namespace/my-app:${version}", withProxy: true, withScan: true, credentialsId: "...", pushToRegistry: true, ) } // Jenkinsfile library('shared-libraries') stage('Build') { dockerBuild( image: "my-namespace/my-app:${version}", withProxy: true, withScan: true, credentialsId: "...", pushToRegistry: true, ) } // Jenkinsfile library('shared-libraries') stage('Build') { dockerBuild( image: "my-namespace/my-app:${version}", withProxy: true, withScan: true, credentialsId: "...", pushToRegistry: true, ) } // Jenkinsfile library('shared-libraries') stage('Build') { dockerBuild( image: "my-namespace/my-app:${version}", withProxy: true, withScan: true, credentialsId: "...", pushToRegistry: true, ) } // Jenkinsfile library('shared-libraries') stage('Build') { dockerBuild( image: "my-namespace/my-app:${version}", withProxy: true, withScan: true, credentialsId: "...", pushToRegistry: true, ) } // Jenkinsfile library('shared-libraries') stage('Build') { dockerBuild( image: "my-namespace/my-app:${version}", withProxy: true, withScan: true, credentialsId: "...", pushToRegistry: true, ) } // Jenkinsfile library('shared-libraries') stage('Build') { dockerBuild( image: "my-namespace/my-app:${version}", withProxy: true, withScan: true, credentialsId: "...", pushToRegistry: true, ) } * Source code shown is simulated for demo purposes only

Slide 21

Slide 21 text

© 2019 All Rights Reserved. 21

Slide 22

Slide 22 text

© 2019 All Rights Reserved. 22

Slide 23

Slide 23 text

© 2019 All Rights Reserved. 23

Slide 24

Slide 24 text

© 2019 All Rights Reserved. 24

Slide 25

Slide 25 text

© 2019 All Rights Reserved. 25 Shared Jenkins Pipeline Library

Slide 26

Slide 26 text

© 2019 All Rights Reserved. 26 Shared Jenkins Pipeline Library https://www.cloudbees.com/blog/ensuring-corporate-standards-pipelines-custom-marker-files

Slide 27

Slide 27 text

© 2019 All Rights Reserved. 27 Shared Jenkins Pipeline Library https://www.cloudbees.com/blog/ensuring-corporate-standards-pipelines-custom-marker-files

Slide 28

Slide 28 text

© 2019 All Rights Reserved. 28 Shared Jenkins Pipeline Library def libVersion = getLibraryVersion() echo "Using shared library version: ${libVersion}" library("jenkins-pipeline-library@${libVersion}") def pipeline = readTrusted 'Jenkinsfile' evaluate pipeline * Source code shown is simulated for demo purposes only the bootstrap script

Slide 29

Slide 29 text

© 2019 All Rights Reserved. 29 def libVersion = getLibraryVersion() echo "Using shared library version: ${libVersion}" library("jenkins-pipeline-library@${libVersion}") def pipeline = readTrusted 'Jenkinsfile' evaluate pipeline Shared Jenkins Pipeline Library * Source code shown is simulated for demo purposes only

Slide 30

Slide 30 text

© 2019 All Rights Reserved. 30 def libVersion = getLibraryVersion() echo "Using shared library version: ${libVersion}" library("jenkins-pipeline-library@${libVersion}") def pipeline = readTrusted 'Jenkinsfile' evaluate pipeline Shared Jenkins Pipeline Library * Source code shown is simulated for demo purposes only

Slide 31

Slide 31 text

© 2019 All Rights Reserved. 31 def libVersion = getLibraryVersion() echo "Using shared library version: ${libVersion}" library("jenkins-pipeline-library@${libVersion}") def pipeline = readTrusted 'Jenkinsfile' evaluate pipeline Shared Jenkins Pipeline Library * Source code shown is simulated for demo purposes only this is the developer's Jenkinsfile

Slide 32

Slide 32 text

© 2019 All Rights Reserved. 32 def libVersion = getLibraryVersion() echo "Using shared library version: ${libVersion}" library("jenkins-pipeline-library@${libVersion}") def pipeline = readTrusted 'Jenkinsfile' evaluate pipeline Shared Jenkins Pipeline Library * Source code shown is simulated for demo purposes only

Slide 33

Slide 33 text

© 2019 All Rights Reserved. 33 TO PIN, OR NOT TO PIN, that is the question

Slide 34

Slide 34 text

© 2019 All Rights Reserved. 34 Benefits of Latest... ● Bugs and other major issues are resolved quicker ● New features and capabilities are available for immediate use ● Reduces the painful software upgrade "headaches"

Slide 35

Slide 35 text

© 2019 All Rights Reserved. 35 Shared Jenkins Pipeline Library Daily Releases

Slide 36

Slide 36 text

© 2019 All Rights Reserved. 36 Shared Library Guiding Principles Keep changes small & digestible Always maintain backwards compatibility Design clean API interfaces

Slide 37

Slide 37 text

© 2019 All Rights Reserved. 37 // Jenkinsfile library('shared-libraries') stage('Build') { dockerBuild( image: "my-repo/my-app:${version}", pushToRegistry: true, ) } * Source code shown is simulated for demo purposes only

Slide 38

Slide 38 text

© 2019 All Rights Reserved. 38 // Jenkinsfile library('shared-libraries') stage('Build') { dockerBuild( image: "my-repo/my-app:${version}", pushToRegistry: true, withArtifactoryRegistry: true, ) } * Source code shown is simulated for demo purposes only

Slide 39

Slide 39 text

© 2019 All Rights Reserved. 39 Shared Library Branching Strategy master v0.1.0 Merge the PR Run the Jenkins pipeline Create release Address PR feedback Open a Pull Request Run the Jenkins pipeline Add some commits

Slide 40

Slide 40 text

© 2019 All Rights Reserved. 40 Build Test Release Rollback Checkpoint End Start The CI/CD Pipeline

Slide 41

Slide 41 text

© 2019 All Rights Reserved. 41 The CI/CD Pipeline Build Test Release Rollback Checkpoint End Start

Slide 42

Slide 42 text

© 2019 All Rights Reserved. 42 The CI/CD Pipeline - Build // build.gradle plugins { id 'groovy' id 'jacoco' id 'codenarc' } sourceSets { main { groovy { srcDirs = ['src'] } resources { srcDirs = ['resources'] } } } dependencies { testCompile(group: 'com.lesfurets', name: 'jenkins-pipeline-unit', version: '1.0') testCompile(group: 'junit', name: 'junit', version: '4.12') testCompile(group: 'org.assertj', name: 'assertj-core', version: '3.13.2') } * Source code shown is simulated for demo purposes only

Slide 43

Slide 43 text

© 2019 All Rights Reserved. 43 The CI/CD Pipeline - Build // Jenkinsfile stage('Build') { steps { sh './gradlew assemble' } } * Source code shown is simulated for demo purposes only

Slide 44

Slide 44 text

© 2019 All Rights Reserved. 44 The CI/CD Pipeline Build Test Release Rollback Checkpoint End Start

Slide 45

Slide 45 text

© 2019 All Rights Reserved. 45 // vars/dockerBuild.groovy def call(Map params) { def registry = "" def image = params.image def proxy = params.withProxy ? '--build-arg https_proxy=http://:8080' : '' node('docker') { sh "docker build -t ${registry}/${image} ${proxy} ." if (params.withScan) { def imageId = sh( script: "docker inspect ${registry}/${image} -f '{{.ID}}'", returnStdout: true, ) scanImageForVulns(imageId: imageId) } if (params.pushToRegistry) { withCredentials([usernamePassword(credentialsId: params.credentialsId)]) { retry(3) { sh "docker push ${registry}/${image}" } } } } } * Source code shown is simulated for demo purposes only

Slide 46

Slide 46 text

© 2019 All Rights Reserved. 46 The CI/CD Pipeline - Test https://github.com/jenkinsci/JenkinsPipelineUnit

Slide 47

Slide 47 text

© 2019 All Rights Reserved. 47 // src/test/jenkinsfiles/dockerBuild/Jenkinsfile #!groovy stage('Build') { dockerBuild( image: 'my-namespace/my-app:0.1.0', pushToRegistry: true, ) } The CI/CD Pipeline - Test * Source code shown is simulated for demo purposes only this is a mocked Jenkinsfile

Slide 48

Slide 48 text

© 2019 All Rights Reserved. 48 // src/test/jenkinsfiles/dockerBuild/Jenkinsfile #!groovy stage('Build') { dockerBuild( image: 'my-namespace/my-app:0.1.0', pushToRegistry: true, ) } The CI/CD Pipeline - Test * Source code shown is simulated for demo purposes only

Slide 49

Slide 49 text

© 2019 All Rights Reserved. 49 // src/test/groovy/DockerBuildTest.groovy import static com.lesfurets.jenkins.unit.MethodCall.callArgsToString import static org.assertj.core.api.Assertions.assertThat import com.lesfurets.jenkins.unit.BasePipelineTest import org.junit.Test public class DockerBuildTest extends BasePipelineTest { // ... @Test void shouldPushToRegistry() { loadScript('dockerBuild/Jenkinsfile') printCallStack() assertThat(helper.callStack.findAll { call -> call.methodName == 'sh' }.any { call -> callArgsToString(call).contains('docker push /my-repo/my-app:0.1.0') }).isTrue() assertJobStatusSuccess() } } * Source code shown is simulated for demo purposes only

Slide 50

Slide 50 text

© 2019 All Rights Reserved. 50 // src/test/groovy/DockerBuildTest.groovy import static com.lesfurets.jenkins.unit.MethodCall.callArgsToString import static org.assertj.core.api.Assertions.assertThat import com.lesfurets.jenkins.unit.BasePipelineTest import org.junit.Test public class DockerBuildTest extends BasePipelineTest { // ... @Test void shouldPushToRegistry() { loadScript('dockerBuild/Jenkinsfile') printCallStack() assertThat(helper.callStack.findAll { call -> call.methodName == 'sh' }.any { call -> callArgsToString(call).contains('docker push /my-repo/my-app:0.1.0') }).isTrue() assertJobStatusSuccess() } } * Source code shown is simulated for demo purposes only loads our mocked Jenkinsfile

Slide 51

Slide 51 text

© 2019 All Rights Reserved. 51 // src/test/groovy/DockerBuildTest.groovy import static com.lesfurets.jenkins.unit.MethodCall.callArgsToString import static org.assertj.core.api.Assertions.assertThat import com.lesfurets.jenkins.unit.BasePipelineTest import org.junit.Test public class DockerBuildTest extends BasePipelineTest { // ... @Test void shouldPushToRegistry() { loadScript('dockerBuild/Jenkinsfile') printCallStack() assertThat(helper.callStack.findAll { call -> call.methodName == 'sh' }.any { call -> callArgsToString(call).contains('docker push /my-repo/my-app:0.1.0') }).isTrue() assertJobStatusSuccess() } } * Source code shown is simulated for demo purposes only prints the call stack to make troubleshooting easier

Slide 52

Slide 52 text

© 2019 All Rights Reserved. 52 // src/test/groovy/DockerBuildTest.groovy import static com.lesfurets.jenkins.unit.MethodCall.callArgsToString import static org.assertj.core.api.Assertions.assertThat import com.lesfurets.jenkins.unit.BasePipelineTest import org.junit.Test public class DockerBuildTest extends BasePipelineTest { // ... @Test void shouldPushToRegistry() { loadScript('dockerBuild/Jenkinsfile') printCallStack() assertThat(helper.callStack.findAll { call -> call.methodName == 'sh' }.any { call -> callArgsToString(call).contains('docker push /my-repo/my-app:0.1.0') }).isTrue() assertJobStatusSuccess() } } * Source code shown is simulated for demo purposes only confirms the docker push command would be invoked correctly

Slide 53

Slide 53 text

© 2019 All Rights Reserved. 53 // src/test/groovy/DockerBuildTest.groovy import static com.lesfurets.jenkins.unit.MethodCall.callArgsToString import static org.assertj.core.api.Assertions.assertThat import com.lesfurets.jenkins.unit.BasePipelineTest import org.junit.Test public class DockerBuildTest extends BasePipelineTest { // ... @Test void shouldPushToRegistry() { loadScript('dockerBuild/Jenkinsfile') printCallStack() assertThat(helper.callStack.findAll { call -> call.methodName == 'sh' }.any { call -> callArgsToString(call).contains('docker push /my-repo/my-app:0.1.0') }).isTrue() assertJobStatusSuccess() } } * Source code shown is simulated for demo purposes only confirms the job completed without an error

Slide 54

Slide 54 text

© 2019 All Rights Reserved. 54 ➜ shared-libraries git:(master) ./gradlew test DockerBuildTest > shouldPushToRegistry STANDARD_OUT Loading shared library shared-libraries with version master Jenkinsfile.run() Jenkinsfile.stage(Build, groovy.lang.Closure) Jenkinsfile.dockerBuild({credentialsId=..., image=my-namespace/my-app:0.1.0, pushToRegistry=true, withProxy=true, withScan=true}) dockerBuild.node(docker, groovy.lang.Closure) dockerBuild.sh(docker build -t /my-repo/my-app:0.1.0 --build-arg https_proxy=http://:8080 .) dockerBuild.sh({returnStdout=true, script=docker inspect /my-repo/my-app:0.1.0 -f '{{.ID}}'}) dockerBuild.usernamePassword({credentialsId=...}) dockerBuild.withCredentials([null], groovy.lang.Closure) dockerBuild.retry(3, groovy.lang.Closure) dockerBuild.sh(docker push /my-repo/my-app:0.1.0) Gradle Test Executor 47 finished executing tests. > Task :test Generating HTML test report… Finished generating test html results (0.002 secs) BUILD SUCCESSFUL in 4s 4 actionable tasks: 4 executed Stopped 1 worker daemon(s). * Source code shown is simulated for demo purposes only

Slide 55

Slide 55 text

© 2019 All Rights Reserved. 55 The CI/CD Pipeline - Test // Jenkinsfile stage('Build') { steps { sh './gradlew assemble' } } stage('Test') { steps { sh './gradlew test' } } * Source code shown is simulated for demo purposes only

Slide 56

Slide 56 text

© 2019 All Rights Reserved. 56

Slide 57

Slide 57 text

© 2019 All Rights Reserved. 57 The CI/CD Pipeline - Test // Jenkinsfile library("shared-libraries@${env.BRANCH_NAME}") stage('Test') { steps { gradleBuild(tasks: 'test') ... } } * Source code shown is simulated for demo purposes only

Slide 58

Slide 58 text

© 2019 All Rights Reserved. 58 The CI/CD Pipeline - Test // Jenkinsfile library("shared-libraries@${env.BRANCH_NAME}") stage('Test') { steps { gradleBuild(tasks: 'test') ... } } * Source code shown is simulated for demo purposes only

Slide 59

Slide 59 text

© 2019 All Rights Reserved. 59 // Jenkinsfile library("shared-libraries@${env.BRANCH_NAME}") stage('Test') { steps { gradleBuild(tasks: 'test') ... } } The CI/CD Pipeline - Test * Source code shown is simulated for demo purposes only gradleBuild() is a custom library function!

Slide 60

Slide 60 text

© 2019 All Rights Reserved. 60 // Jenkinsfile library("shared-libraries@${env.BRANCH_NAME}") stage('Test') { steps { gradleBuild(tasks: 'test') evaluate(readTrusted('test/dockerBuild/Jenkinsfile')) } } The CI/CD Pipeline - Test * Source code shown is simulated for demo purposes only executes a Jenkinsfile with library methods against the library itself!

Slide 61

Slide 61 text

© 2019 All Rights Reserved. 61 // Jenkinsfile library("shared-libraries@${env.BRANCH_NAME}") stage('Test') { steps { gradleBuild(tasks: 'test') evaluate(readTrusted('test/dockerBuild/Jenkinsfile')) } } The CI/CD Pipeline - Test * Source code shown is simulated for demo purposes only executes a Jenkinsfile with library methods against the library itself!

Slide 62

Slide 62 text

© 2019 All Rights Reserved. 62 The CI/CD Pipeline Build Test Release Rollback Checkpoint End Start

Slide 63

Slide 63 text

© 2019 All Rights Reserved. 63 The CI/CD Pipeline - Release

Slide 64

Slide 64 text

© 2019 All Rights Reserved. 64 The CI/CD Pipeline - Release ➜ curl -s https:///api/v3/repos///releases/latest | jq '.tag_name' "v0.3.95" * Source code shown is simulated for demo purposes only

Slide 65

Slide 65 text

© 2019 All Rights Reserved. 65 The CI/CD Pipeline - Release * Source code shown is simulated for demo purposes only def libVersion = getLibraryVersion() echo "Using shared library version: ${libVersion}" library("jenkins-pipeline-library@${libVersion}") def pipeline = readTrusted 'Jenkinsfile' evaluate pipeline the bootstrap script

Slide 66

Slide 66 text

© 2019 All Rights Reserved. 66 The CI/CD Pipeline - Release def getLibraryVersion() { def response = httpRequest( url: 'https:///api/v3/repos///releases/latest', httpMode: 'GET', contentType: 'APPLICATION_JSON', validResponseCodes: '200', ) return readJSON(text: response.content).tag_name } * Source code shown is simulated for demo purposes only

Slide 67

Slide 67 text

© 2019 All Rights Reserved. 67 The CI/CD Pipeline - Release * Source code shown is simulated for demo purposes only def libVersion = getLibraryVersion() echo "Using shared library version: ${libVersion}" library("jenkins-pipeline-library@${libVersion}") def pipeline = readTrusted 'Jenkinsfile' evaluate pipeline the bootstrap script

Slide 68

Slide 68 text

© 2019 All Rights Reserved. 68 def libVersion = "v0.3.95" echo "Using shared library version: ${libVersion}" library("jenkins-pipeline-library@${libVersion}") def pipeline = readTrusted 'Jenkinsfile' evaluate pipeline The CI/CD Pipeline - Release * Source code shown is simulated for demo purposes only the bootstrap script

Slide 69

Slide 69 text

© 2019 All Rights Reserved. 69 The CI/CD Pipeline - Release master v0.1.0 latest

Slide 70

Slide 70 text

© 2019 All Rights Reserved. 70 The CI/CD Pipeline - Release master v0.1.0 v0.1.1 latest

Slide 71

Slide 71 text

© 2019 All Rights Reserved. 71 The CI/CD Pipeline - Release v0.1.0 v0.1.1 latest master

Slide 72

Slide 72 text

© 2019 All Rights Reserved. 72 The CI/CD Pipeline - Release v0.1.0 v0.1.1 v0.1.2 latest master

Slide 73

Slide 73 text

© 2019 All Rights Reserved. 73 The CI/CD Pipeline - Release v0.1.0 v0.1.1 v0.1.2 latest master

Slide 74

Slide 74 text

© 2019 All Rights Reserved. 74 The CI/CD Pipeline - Release v0.1.0 v0.1.1 v0.1.2 v0.1.3 latest master

Slide 75

Slide 75 text

© 2019 All Rights Reserved. 75 The CI/CD Pipeline - Release v0.1.0 v0.1.1 v0.1.2 v0.1.3 latest master

Slide 76

Slide 76 text

© 2019 All Rights Reserved. 76 The CI/CD Pipeline - Release v0.1.0 v0.1.1 v0.1.2 v0.1.3 v0.1.4 latest master

Slide 77

Slide 77 text

© 2019 All Rights Reserved. 77 The CI/CD Pipeline - Release v0.1.0 v0.1.1 v0.1.2 v0.1.3 v0.1.4 latest master

Slide 78

Slide 78 text

© 2019 All Rights Reserved. 78 The CI/CD Pipeline - Release Canary release is a technique to reduce the risk of introducing a new software version in production by slowly rolling out the change to a small subset of users before rolling it out to the entire infrastructure and making it available to everybody. https://martinfowler.com/bliki/CanaryRelease.html “ “

Slide 79

Slide 79 text

© 2019 All Rights Reserved. 79 The CI/CD Pipeline - Release Users Jenkins Instances 30% 70%

Slide 80

Slide 80 text

© 2019 All Rights Reserved. 80 The CI/CD Pipeline - Release Users Jenkins Instances latest stable

Slide 81

Slide 81 text

© 2019 All Rights Reserved. 81 The CI/CD Pipeline - Release v0.1.0 latest stable master

Slide 82

Slide 82 text

© 2019 All Rights Reserved. 82 The CI/CD Pipeline - Release v0.1.0 v0.1.1 latest stable master

Slide 83

Slide 83 text

© 2019 All Rights Reserved. 83 The CI/CD Pipeline - Release v0.1.0 v0.1.1 latest - 30% stable master

Slide 84

Slide 84 text

© 2019 All Rights Reserved. 84 The CI/CD Pipeline - Release v0.1.0 v0.1.1 latest - 30% stable - 70% master

Slide 85

Slide 85 text

© 2019 All Rights Reserved. 85 The CI/CD Pipeline - Release v0.1.0 v0.1.1 v0.1.2 latest - 30% stable - 70% master

Slide 86

Slide 86 text

© 2019 All Rights Reserved. 86 The CI/CD Pipeline - Release v0.1.0 v0.1.1 v0.1.2 latest - 30% stable - 70% master

Slide 87

Slide 87 text

© 2019 All Rights Reserved. 87 The CI/CD Pipeline - Release v0.1.0 v0.1.1 v0.1.2 latest - 30% stable - 70% master

Slide 88

Slide 88 text

© 2019 All Rights Reserved. 88 The CI/CD Pipeline - Release v0.1.0 v0.1.1 v0.1.2 v0.1.3 latest - 30% stable - 70% master

Slide 89

Slide 89 text

© 2019 All Rights Reserved. 89 The CI/CD Pipeline - Release v0.1.0 v0.1.1 v0.1.2 v0.1.3 latest - 30% stable - 70% master

Slide 90

Slide 90 text

© 2019 All Rights Reserved. 90 The CI/CD Pipeline - Release v0.1.0 v0.1.1 v0.1.2 v0.1.3 latest - 30% stable - 70% master

Slide 91

Slide 91 text

© 2019 All Rights Reserved. 91 The CI/CD Pipeline - Release v0.1.0 v0.1.1 v0.1.2 v0.1.3 v0.1.4 latest - 30% stable - 70% master

Slide 92

Slide 92 text

© 2019 All Rights Reserved. 92 The CI/CD Pipeline - Release v0.1.0 v0.1.1 v0.1.2 v0.1.3 v0.1.4 latest - 30% stable - 70% master

Slide 93

Slide 93 text

© 2019 All Rights Reserved. 93 The CI/CD Pipeline - Release v0.1.0 v0.1.1 latest - 30% stable - 70% v0.1.2 v0.1.3 v0.1.4 master

Slide 94

Slide 94 text

© 2019 All Rights Reserved. 94 The CI/CD Pipeline - Release * Source code shown is simulated for demo purposes only def libVersion = getLibraryVersion() echo "Using shared library version: ${libVersion}" library("jenkins-pipeline-library@${libVersion}") def pipeline = readTrusted 'Jenkinsfile' evaluate pipeline the bootstrap script

Slide 95

Slide 95 text

© 2019 All Rights Reserved. 95 The CI/CD Pipeline - Release def getLibraryVersion() { if (env.JENKINS_URL =~ /|/) { def response = httpRequest( url: 'https:///api/v3/repos///releases/latest', httpMode: 'GET', contentType: 'APPLICATION_JSON', validResponseCodes: '200', ) return readJSON(text: response.content).tag_name } return 'stable' } * Source code shown is simulated for demo purposes only

Slide 96

Slide 96 text

© 2019 All Rights Reserved. 96 The CI/CD Pipeline Build Test Release Rollback Checkpoint End Start

Slide 97

Slide 97 text

© 2019 All Rights Reserved. 97 The CI/CD Pipeline - Rollback Checkpoint // Jenkinsfile stage('Rollback Checkpoint') { steps { timeout(time: 4, unit: 'HOURS') { input(message: "Rollback v${version}?", ok: 'Yes') } ... } } * Source code shown is simulated for demo purposes only

Slide 98

Slide 98 text

© 2019 All Rights Reserved. 98 The CI/CD Pipeline - Rollback Checkpoint

Slide 99

Slide 99 text

© 2019 All Rights Reserved. 99 The CI/CD Pipeline - Rollback Checkpoint def sendDatadogMetrics(def metrics) { try { httpRequest( url: 'https://app.datadoghq.com/api/v1/series, httpMode: 'POST', contentType: 'APPLICATION_JSON', requestBody: "{[\"series\": ${metrics}]}", validResponseCodes: '200,201,202,204', ) } catch (e) { null } } [ "job_name:${env.JOB_NAME}", "job_status:${currentBuild.currentResult}", "library_version:${libVersion}", "failure_exception_class:${error.getClass().getName()}", ] Tags * Source code shown is simulated for demo purposes only

Slide 100

Slide 100 text

© 2019 All Rights Reserved. 100 The CI/CD Pipeline - Rollback Checkpoint v0.3.95 released hudson.AbortException

Slide 101

Slide 101 text

© 2019 All Rights Reserved. 101

Slide 102

Slide 102 text

© 2019 All Rights Reserved. 102 The CI/CD Pipeline - Rollback Checkpoint

Slide 103

Slide 103 text

© 2019 All Rights Reserved. 103 The CI/CD Pipeline - Rollback Checkpoint

Slide 104

Slide 104 text

© 2019 All Rights Reserved. 104 The CI/CD Pipeline - Rollback Checkpoint

Slide 105

Slide 105 text

© 2019 All Rights Reserved. 105 The CI/CD Pipeline - Rollback Checkpoint v0.1.0 v0.1.1 latest - 30% stable - 70% master

Slide 106

Slide 106 text

© 2019 All Rights Reserved. 106 The CI/CD Pipeline - Rollback Checkpoint v0.1.0 v0.1.1 latest - 30% stable - 70% 4 hours master

Slide 107

Slide 107 text

© 2019 All Rights Reserved. 107 The CI/CD Pipeline - Rollback Checkpoint v0.1.0 v0.1.1 v0.1.2 latest - 30% stable - 70% master

Slide 108

Slide 108 text

© 2019 All Rights Reserved. 108 The CI/CD Pipeline - Rollback Checkpoint v0.1.0 v0.1.1 v0.1.2 latest - 30% stable - 70% master

Slide 109

Slide 109 text

© 2019 All Rights Reserved. 109 The CI/CD Pipeline - Rollback Checkpoint v0.1.0 v0.1.1 v0.1.2 latest - 30% stable - 70% 4 hours master

Slide 110

Slide 110 text

© 2019 All Rights Reserved. 110 The CI/CD Pipeline - Rollback Checkpoint v0.1.0 v0.1.1 v0.1.2 latest - 30% stable - 70% master

Slide 111

Slide 111 text

© 2019 All Rights Reserved. 111 The CI/CD Pipeline - Rollback Checkpoint

Slide 112

Slide 112 text

© 2019 All Rights Reserved. 112 The CI/CD Pipeline - Rollback Checkpoint

Slide 113

Slide 113 text

© 2019 All Rights Reserved. 113 The CI/CD Pipeline - Rollback Checkpoint

Slide 114

Slide 114 text

© 2019 All Rights Reserved. 114 The CI/CD Pipeline - Rollback Checkpoint v0.1.0 v0.1.1 v0.1.2 latest - 30% stable - 70% master

Slide 115

Slide 115 text

© 2019 All Rights Reserved. 115 The CI/CD Pipeline - Rollback Checkpoint v0.1.0 v0.1.1 v0.1.2 latest - 30% stable - 70% master

Slide 116

Slide 116 text

© 2019 All Rights Reserved. 116 The CI/CD Pipeline - Rollback Checkpoint

Slide 117

Slide 117 text

© 2019 All Rights Reserved. 117 The CI/CD Pipeline - Rollback Checkpoint v0.1.0 v0.1.1 v0.1.2 latest - 30% stable - 70% master

Slide 118

Slide 118 text

© 2019 All Rights Reserved. 118 The CI/CD Pipeline - Rollback Checkpoint v0.1.0 v0.1.1 v0.1.2 latest - 30% stable - 70% master

Slide 119

Slide 119 text

© 2019 All Rights Reserved. 119 The CI/CD Pipeline - Rollback Checkpoint v0.1.0 v0.1.1 v0.1.2 latest - 30% stable - 70% master

Slide 120

Slide 120 text

© 2019 All Rights Reserved. 120 The CI/CD Pipeline - Rollback Checkpoint v0.1.0 v0.1.1 v0.1.2 latest - 30% stable - 70% v0.1.3 master

Slide 121

Slide 121 text

© 2019 All Rights Reserved. 121 The CI/CD Pipeline - Rollback Checkpoint v0.1.0 v0.1.1 v0.1.2 latest - 30% stable - 70% v0.1.3 4 hours master

Slide 122

Slide 122 text

© 2019 All Rights Reserved. 122 The CI/CD Pipeline - Rollback Checkpoint v0.1.0 v0.1.1 v0.1.2 latest - 30% stable - 70% v0.1.3 master

Slide 123

Slide 123 text

© 2019 All Rights Reserved. 123 The CI/CD Pipeline - Rollback Checkpoint v0.1.0 v0.1.1 v0.1.2 latest - 30% stable - 70% v0.1.3 master

Slide 124

Slide 124 text

© 2019 All Rights Reserved. 124 The CI/CD Pipeline - Rollback Checkpoint v0.1.0 v0.1.1 v0.1.2 latest - 30% stable - 70% v0.1.3 v0.1.4 master

Slide 125

Slide 125 text

© 2019 All Rights Reserved. 125 The CI/CD Pipeline - Rollback Checkpoint v0.1.0 v0.1.1 v0.1.2 latest - 30% stable - 70% v0.1.3 v0.1.4 master

Slide 126

Slide 126 text

© 2019 All Rights Reserved. 126 The CI/CD Pipeline - Rollback Checkpoint v0.1.0 v0.1.1 v0.1.2 latest - 30% stable - 70% v0.1.3 v0.1.4 master

Slide 127

Slide 127 text

© 2019 All Rights Reserved. 127 The CI/CD Pipeline Build Test Release Rollback Checkpoint End Start

Slide 128

Slide 128 text

© 2019 All Rights Reserved. 128 In closing...

Slide 129

Slide 129 text

© 2019 All Rights Reserved. 129 In closing... https://wiki.jenkins.io/display/JENKINS/Pipeline+Shared+Groovy+Libraries+Plugin

Slide 130

Slide 130 text

© 2019 All Rights Reserved. 130 In closing... Build Test Release Rollback Checkpoint End Start

Slide 131

Slide 131 text

© 2019 All Rights Reserved. 131

Slide 132

Slide 132 text

© 2019 All Rights Reserved. 132 Roderick R. Randolph linkedin.com/in/roderickrandolph capitalonecareers.com Distinguished Engineer Reimagining the software delivery experience for our engineers.

Slide 133

Slide 133 text

Thank You!