Slide 1

Slide 1 text

JOBS AS CODE Jenkins Pipeline Jobs Sebastian Hempel 1

Slide 2

Slide 2 text

Sebastian Hempel IT-Consulting Hempel @ithempel [email protected] 2

Slide 3

Slide 3 text

Klassische Jobs XML-Dateien Erstellung und Konfiguration über GUI 3 . 1

Slide 4

Slide 4 text

PROBLEME DER JENKINS JOBS Dokumentation Reproduzierbarkeit automatische Erstellung Durchführung von Änderungen 3 . 2

Slide 5

Slide 5 text

Neue Job Typen Continuous Delivery Pipeline seit Jenkins 2 Realisierung durch Plugins 4 . 1

Slide 6

Slide 6 text

MERKMALE DER JENKINS PIPELINE Pipeline Domain Specific Language (DSL) Pipeline as Code Jenkinsfile in Git 4 . 2

Slide 7

Slide 7 text

VORTEILE DER PIPELINE Durable (robust) Pausable (Warten auf Benutzereingabe) Versatile (Schleifen, fork/join, parallel) Extensible (DSL ist erweiterbar) 4 . 3

Slide 8

Slide 8 text

SCRIPTED PIPELINE erste Realisierung Klassen und Funktionen für Groovy Anlehnung an Job DSL Plugin 4 . 4

Slide 9

Slide 9 text

DECLARATIVE PIPELINE zweite Generation Groovy DSL (domain specific language) deklarativer Syntax Resume-Able 4 . 5

Slide 10

Slide 10 text

STRUKTUR EINER PIPELINE Jenkinsfile pipeline Definition Direktiven 5 . 1

Slide 11

Slide 11 text

BEISPIEL EINER PIPELINE 1 Ausführung eines Shell Kommandos 2 Step, der vom JUnit plugin zur Verfügung gestellt wird pipeline { agent any stages { stage('Build') { steps { sh 'make' (1) } } stage('Test') { steps { sh 'make check' junit 'reports/**/*.xml' (2) } } 5 . 2

Slide 12

Slide 12 text

AGENT 1 Jenkins bestimmt den Executor 2 kein Executor 3 Auswahl eines Executors über ein Label agent any (1) agent none (2) agent { label 'linux' (3) } 5 . 3

Slide 13

Slide 13 text

STAGES 1 Definition der Stages der Pipeline 2 mindestens ein Stage muss definiert sein stages { (1) stage('Build') { (2) ... } } 5 . 4

Slide 14

Slide 14 text

STAGE 1 Definition eines anderen / eigenen Agents 2 beinhaltet steps stages { stage('Build') { agent { (1) label 'linux' } steps { (2) ... } } } 5 . 5

Slide 15

Slide 15 text

STEPS 1 Container um die Steps einer Stage 2 Steps / Kommandos der Stage stages { stage('Build') { steps { (1) echo "Building" (2) } } } 5 . 6

Slide 16

Slide 16 text

WEITERE DIREKTIVEN Environment Variablen Job Optionen Job Parameter Build Trigger Build Tools 6 . 1

Slide 17

Slide 17 text

ENVIRONMENT Setzen von Environment Variablen Kann in pipeline oder stage gesetzt werden. environment { JAVA_HOME = '/usr/java/openjdk8-latest' } 6 . 2

Slide 18

Slide 18 text

SECRETS AUS CREDENTIAL STORE REMOTE = secret REMOTE = user:password REMOTE_USR = user REMOTE_PSW = password environment { REMOTE = credentials('credential-id') } 6 . 3

Slide 19

Slide 19 text

OPTIONS 1 Direktive zur Definition / Festlegung der Optionen 2 Option für das Timeout der Pipeline options { (1) timeout(time: 1, unit: 'HOURS') (2) } 6 . 4

Slide 20

Slide 20 text

OPTIONS buildDiscarder(logRotator(numToKeepStr: '10')) disableConcurrentBuilds() skipStagesAfterUnstable() timeout(time: 1, unit: 'HOURS') retry(3) timestamps() 6 . 5

Slide 21

Slide 21 text

PARAMETER DEFINITION Setzen von Parametern Parameter PERSON vom Typ string Vorgabewert Mr Jenkins Beschreibung des Parameters für den Benutzer parameters { string(name: 'PERSON', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?') } 6 . 6

Slide 22

Slide 22 text

ZUGRIFF AUF PARAMETER Zugriff über das params Objekt Objekt stellt Parameter als Properties zur Verfügung. steps { echo "Hello ${params.PERSON}" } 6 . 7

Slide 23

Slide 23 text

TRIGGER Wie soll der Job automatisch ausgeführt werden? 1 Starte Job zeitgesteuert triggers { cron('H 4/* 0 0 1-5') (1) } 6 . 8

Slide 24

Slide 24 text

TRIGGER cron('H 4/* 0 0 1-5') pollSCM('H 4/* 0 0 1-5') upstream(upstreamProjects: 'job1,job2', threshold: hudson.model.Result.SUCC 6 . 9

Slide 25

Slide 25 text

TOOLS Buildtools zum PATH hinzufügen Unterstütze Tools: maven jdk gradle tools { maven 'apache-maven-3.5.0' } 6 . 10

Slide 26

Slide 26 text

ERSTELLEN VON PIPELINES Es gibt 2 Arten eine Pipeline zu erstellen: Textfeld in Jenkins Jenkinsfile 7 . 1

Slide 27

Slide 27 text

EINGABEFELD IN JOB 7 . 2

Slide 28

Slide 28 text

JENKINSFILE 7 . 3

Slide 29

Slide 29 text

SNIPPET-GENERATOR 7 . 4

Slide 30

Slide 30 text

PIPELINE STEPS Kommandos / Befehle innerhalb eines Stage Basis Steps von Jenkins weitere Steps von Plugins 8 . 1

Slide 31

Slide 31 text

STEP: SH Ausführen eines Shell Scripts (bash) sh 'build.sh' /* short form */ sh([script: 'build.sh']) /* long form */ 8 . 2

Slide 32

Slide 32 text

STEP: SH Speichern des Return Codes in einer Variablen 1 Die Variable status enthält den Resultcode des Kommandos status = sh([script: 'build.sh', returnStatus: true]) (1) 8 . 3

Slide 33

Slide 33 text

STEP: SSHAGENT Block mit aktivierten SSH-Agent ausführen 1 startet den SSH-Agent und lädt das angegebene Credential sshagent([credentials: ['publish']]) { (1) sh 'ssh -o StrictHostKeyChecking=no [email protected] publi } 8 . 4

Slide 34

Slide 34 text

STEP: SCRIPT "Wechsel" zu Scripted Pipeline 1 Innerhalb des script Blocks können Anweisungen der Scripted Pipeline ausgeführt werden script { (1) } 8 . 5

Slide 35

Slide 35 text

ARCHIV ENTPACKEN Entpacken eines Archivs im Workspace 1 Entpacken des Archivs im aktuellen Verzeichnis 2 Entpacken im Unterverzeichnis release_tmp unzip([zipFile: 'release.zip']) (1) unzip([zipFile: 'release.zip', dir: 'release_tmp']) (2) 8 . 6

Slide 36

Slide 36 text

ARCHIV PACKEN Erstellen eines Archivs 1 Erstellt eine ZIP-Archiv archive.zip mit dem Inhalt des Ordner release zip([zipFile: 'archive.zip', dir: 'release']) (1) 8 . 7

Slide 37

Slide 37 text

FEHLERBEHANDLUNG Prüfung nach jedem Step Abbruch der Pipeline bei Result != 0 Fehlerbehandlung pro Stage oder für gesamte Pipeline 8 . 8

Slide 38

Slide 38 text

FEHLEBEHANDLUNG IM STAGE 1 post Sektion für den Stage Build 2 Wenn der Stage des Status failed hat pipeline { agent any stages { stage('Build') { steps { sh 'make build' } post { (1) failure { (2) echo 'Error compiling sources!' } } } } } 8 . 9

Slide 39

Slide 39 text

FEHLERBEHANDLUNG DER PIPELINE 1 post Sektion für die gesamte Pipeline pipeline { agent any stages { stage('Build') { steps { sh 'make build' } } } post { (1) failure { echo 'Error executing pipe!' } } } 8 . 10

Slide 40

Slide 40 text

GLOBALE VARIABLEN Werden von Jenkins zur Verfügung gestellt params env currentBuild 8 . 11

Slide 41

Slide 41 text

ZUGRIFF AUF AKTUELLEN BUILD Eigenscha en number / id result / currentResult displayName / description 8 . 12

Slide 42

Slide 42 text

TEXT BESCHREIBUNG ÄNDERN 1 Name des Jobs ändern / überschreiben 2 Beschreibung des Runs setzen script { currentBuild.displayName = 'My Job' (1) currentBuild.description = 'This is as super duper run!' (2) } 8 . 13

Slide 43

Slide 43 text

PIPELINE ADVANCED erweiterte Sprachmöglichkeiten bedingte Ausführung parallele Ausführung Pipeline pro Branch 9 . 1

Slide 44

Slide 44 text

BEDINGTE AUSFÜHRUNG Prüfung einer Bedingung vor der Ausführung eines Stage 1 Block mit Bedingung 2 Bedingung die true ergeben muss, damit Steps ausgeführt werden stage('Deploy') { when { (1) // Bedingung (2) } steps { sh 'make something' } } 9 . 2

Slide 45

Slide 45 text

BEDINGUNG: ENVIRONMENT VARIABLEN Prüfung auf den Wert einer Environment Variablen 1 Die Environment Variable STAGE muss den Wert production haben when { environment name: 'STAGE', value: 'production' (1) } 9 . 3

Slide 46

Slide 46 text

BEDINGUNG: GROOVY EXPRESSION Auswertung eines Groovy Ausdrucks 1 Die Variable STAGE muss den regulären Ausdruck matchen when { expression { STAGE ==~ /(production|maintenance)/ } (1) } 9 . 4

Slide 47

Slide 47 text

BEDINGUNG: NEGATION Bedingung negieren 1 Die Environment Variable STAGE darf nicht den Wert production haben when { not { environment name: 'STAGE', value: 'production' } (1) } 9 . 5

Slide 48

Slide 48 text

BEDINGUNGEN: UND VERKNÜPFUNG Alle Bedingungen müssen zutreffen 1 Beide environment Bedingungen müssen zutreffen when { allOf { (1) environment name: 'STAGE', value: 'production' environment name: 'DEPLOY_TO', value 'production' } } 9 . 6

Slide 49

Slide 49 text

BEDINGUNGEN: ODER VERKNÜPFUNG Eine Bedingung muss zutreffen 1 Mindestens eine Bedingung muss zutreffen when { anyOf { (1) environment name: 'STAGE', value: 'production' environment name: 'DEPLOY_TO', value 'production' } } 9 . 7

Slide 50

Slide 50 text

SHARED LIBRARIES Ziele: gemeinsame Nutzung von Build Steps "Plugins" für Pipeline Jobs 9 . 8

Slide 51

Slide 51 text

SHARED LIBRARIES REPOSITORY Source Code Repository 1 Resourcen wie z.B. Datendateien 2 Groovy (Hilfs) Code (classpath) 3 Variablen (= custom build steps) . ├── resources (1) ├── src (2) └── vars (3) └── myMaven.groovy 9 . 9

Slide 52

Slide 52 text

BUILD STEP DEFINIEREN vars/myMaven.groovy 1 Funktion zur Ausführung des Build Steps Scripted Pipeline Syntax Verwendung von Groovy Code möglich def call(args) { (1) sh "${tool 'Maven v3.5'}/bin/mvn ${args}" } 9 . 10

Slide 53

Slide 53 text

HINZUFÜGEN ZU JENKINS Einbindung in Jenkins Name der Library VCS Parameter Standard Version (optional) 9 . 11

Slide 54

Slide 54 text

HINZUFÜGEN ZU JENKINS 9 . 12

Slide 55

Slide 55 text

LIBRARY LADEN 1 Annotation der Library - _ als Dummy Element 2 library Step (ab Version 2.7 Shared Groovy Libraries plugin) 3 vorgegebene Version überschreiben (Tag, Branch) @Library('my-shared-library') _ (1) library 'my-shared-library' (2) library '[email protected]' (3) 9 . 13

Slide 56

Slide 56 text

LIBRARY IMPLIZIT LADEN 9 . 14

Slide 57

Slide 57 text

ENTWICKLUNGSWERKZEUGE 10 . 1

Slide 58

Slide 58 text

SYNTAX HIGHLIGHTING Pipeline Code ist Groovy Code 10 . 2

Slide 59

Slide 59 text

PIPELINE LINTER Validierung eines Jenkinsfile ausgeführt auf Jenkins Server HTTP POST-Request 10 . 3

Slide 60

Slide 60 text

PIPELINE LINTER Anforderungen an POST-Request Secret Key aus Benutzerkonfiguration CRUMB für Request (CRSE Schutz) 10 . 4

Slide 61

Slide 61 text

PIPELINE LINTER pipelint.sh if [ $1 ] && [ -f $1 ] then JENKINSFILE=$1 else JENKINSFILE=Jenkinsfile fi # curl (REST API) User JENKINS_USER=myuser # Api key from "/me/configure" on my Jenkins instance JENKINS_USER_KEY=fe188e2e0c1d471895811f2ea9ad757b # Url for my local Jenkins instance. JENKINS_URL=https://$JENKINS_USER:[email protected] 10 . 5

Slide 62

Slide 62 text

REPLAY geändertes Jenkinsfile ausführen 10 . 6

Slide 63

Slide 63 text

VERWEISE Warum Jenkins Pipeline? Anwendungsfälle https://www.cloudbees.com/blog/need-jenkins- pipeline https://jenkins.io/blog/2017/07/05/continuousdelivery- devops-artifactory/ https://jenkins.io/blog/2017/04/18/continuousdelivery- devops-sonarqube/ 11

Slide 64

Slide 64 text

FRAGEN? by , any questions? Matthias Ripp CC-BY 12