
Jenkins-Tutorial: Jobs erstellen mit der Jenkins Job DSL

Artikelserie: Jenkins-Tutorial
Teil 1: Build- und Release-Jobs
Teil 2: Jenkins Job DSL
Teil 3: Programmierung eines Seed-Jobs
(Melde dich für den HappyCoders-Newsletter an, um sofort über neue Teile informiert zu werden.)
Im ersten Teil dieser dreiteiligen Artikelserie habe ich dir gezeigt, wie man Jenkins per Ansible als Docker-Container installiert und grundlegend konfiguriert – und wie man Build- und Release-Jobs für Maven-Projekte über das User Interface von Jenkins anlegt.
In diesem zweiten Teil zeige ich dir, wie du die gleichen Jobs über die Jenkins Job DSL als Programmcode erstellst und in Jenkins importierst. Außerdem zeige ich dir, wie du sogenannte Views für die übersichtliche Gestaltung der Job-Liste manuell und programmatisch erstellst.
Den in diesem Artikel erstellten Code findest du in meinem GitLab-Repository unter https://gitlab.com/SvenWoltmann/jenkins-tutorial-demo.
Einführung in die Jenkins Job DSL
In diesem Kapitel erkläre ich dir, was die Jenkins Job DSL ist. Ich zeige dir, wie du IntelliJ konfigurieren kannst, um das Schreiben eines Jobs durch Autovervollständigung zu erleichtern, wie du einen minimalen Job als Code aufsetzt und wie du diesen in Jenkins importierst.
Was ist die Jenkins Job DSL?
Die Jenkins Job DSL ermöglicht die programmatische Erstellung von Jenkins-Jobs mittels Groovy-Code. Diesen kannst du in deinem Git-Repository mit ablegen und somit Änderungen nachverfolgbar machen und Jenkins-Jobs automatisiert generieren. Die DSL wird über das Job DSL Plugin bereitgestellt und ist im Job DSL API Viewer ausführlich dokumentiert.
Job DSL-Support in IntelliJ IDEA aktivieren
IntelliJ IDEA unterstützt von Haus aus Groovy. Mit einem sogenannten GroovyDSL-Skript können wir darüber hinaus IntelliJ mit konkreten DSLs vertraut machen. Dies ermöglicht Autovervollständigung und eine bessere Syntaxhervorhebung.
Die hierfür unter https://github.com/jenkinsci/job-dsl-plugin/wiki/IDE-Support zur Verfügung gestellte Dokumentation ist nicht sehr verständlich und erfordert eine Installation von Gradle. Ich zeige dir jetzt, wie es auch ohne Gradle geht:
Zunächst legen wir in IntelliJ ein neues Maven-Projekt oder -Modul an. Da ich in meinem Demo-Code bisher mit einem Monorepo gearbeitet habe, lege ich das Projekt im Unterverzeichnis jenkins-jobs/
an. Über die pom.xml
definieren wir eine Abhängigkeit zur job-dsl-core
Library, die im öffentlichen Jenkins-Repository liegt:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>eu.happycoders.jenkins-tutorial-demo</groupId>
<artifactId>jenkins-jobs</artifactId>
<version>1.0-SNAPSHOT</version>
<repositories>
<repository>
<id>jenkins</id>
<url>https://repo.jenkins-ci.org/public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>job-dsl-core</artifactId>
<version>1.76</version>
</dependency>
</dependencies>
</project>
Code-Sprache: HTML, XML (xml)
Unter src/main/resources/
legen wir eine Datei idea.gdsl
mit folgendem Inhalt an:
def jobPath = /.*/jobs/.*.groovy/
def ctx = context(pathRegexp: jobPath)
contributor(ctx, {
delegatesTo(findClass('javaposse.jobdsl.dsl.DslFactory'))
})
Code-Sprache: Groovy (groovy)
Das durch den Projekt-Generator von IntelliJ erzeugte Verzeichnis src/test/
kannst du löschen, dieses werden wir nicht benötigen.
Stattdessen legen wir ein neues Verzeichnis src/jobs/
an. In diesem Verzeichnis werden wir die Jenkins-Jobs speichern. Zum Test des Setups erstelle ich eine Groovy-Datei Test.groovy
und gebe "maven" ein. Die Autovervollständigung zeigt mir zwei mavenJob()
-Methoden aus der Klasse MavenJob
des Job DSL-Plugins an; somit ist das Setup erfolgreich abgeschlossen.

Grundstruktur des Codes für einen Jenkins-Jobs
Zunächst zeige ich an einem minimalen Beispiel, wie du einen Job schreibst und in Jenkins importierst. In meinem im vorherigen Abschnitt angelegten jobs/
-Verzeichnis erstellen wir dafür eine Datei SimpleDSLJob.groovy
mit folgendem Inhalt:
mavenJob('Jenkins Tutorial Demo - Simple DSL Job') {
description 'A very simple demo for the Jenkins Job DSL'
}
Code-Sprache: Groovy (groovy)
Die Methode mavenJob()
ist hierbei der Einstiegspunkt, durch den der Jenkins-Job generiert wird. Wer Groovy nicht kennt, hier eine kurze Erklärung der Syntax: Der Code in geschweiften Klammern ist eine Closure (das was in Java ein Lambda ist), also eine Funktion, die als Parameter übergeben wird. Wohin wird diese Methode übergeben? Jetzt wird es etwas verrückt: Die Closure ist neben dem Job-Namen der zweite Parameter der mavenJob()
-Methode. Wenn der letzte Parameter eines Methodenaufrufs eine Closure ist, kann diese außerhalb der Klammern übergeben werden. Klammern können ebenso komplett weggelassen werden, wie es bei der description()
-Methode der Fall ist. Der Code oben ist also gleichbedeutend mit:
mavenJob('Jenkins Tutorial Demo - Simple DSL Job', {
description('A very simple demo for the Jenkins Job DSL')
})
Code-Sprache: Groovy (groovy)
Die Java-Entsprechung dieses Codes wäre:
mavenJob("Jenkins Tutorial Demo - Simple DSL Job", () -> {
description("A very simple demo for the Jenkins Job DSL");
});
Code-Sprache: Groovy (groovy)
Soweit dieser kleine Groovy-Exkurs. Wenn du am Ende dieses Tutorials überlegst, wie der bis dahin entstandene Groovy-Code in Java aussehen würde, wirst du feststellen, dass die Groovy-Darstellung deutlich lesbarer ist.
Import eines mit der Job DSL programmierten Jobs in Jenkins
Prüft bitte vorab, ob du die Jenkins-Plugins "Job DSL" und "Authorize Project" installiert hast und hol dies ggf. nach. Ich hatte diese Plugins im ersten Teil des Artikels ursprünglich nicht aufgelistet und sie erst nachträglich hinzugefügt.
Um den Job in Maven zu importieren, klickst du zunächst auf der Startseite auf "New Item":
Wichtig ist nun zu wissen, dass du nicht den eigentlichen Job anlegst, sondern einen Job, der den in der DSL geschriebenen Job importiert. Als Namen geben wir "Project Jenkins Tutorial Demo - Simple DSL Job Creator" ein. Als Projekttyp wählen wir "Freestyle project" und klicken auf "OK":
Auf der folgenden Seite scrollen wir hinunter zu "Build" (oder klicken auf den entsprechenden Tab) und wählen dort aus dem "Add build step"-Dropdown den Punkt "Process Job DSLs" aus:
In dem sich öffnenden Formular wählen wir "Use the provided DSL script" und kopieren das kurze Stück Code in das entsprechende Feld. Vielleicht wunderst du dich, dass das Feld so klein ist. Dies liegt daran, dass wir DSL-Jobs eigentlich nicht auf diese Art importieren, sondern automatisiert, wie ich es im weiteren Verlauf des Tutorials beschreiben werde. An dieser Stelle wollen wir erstmal nur sehen, dass wir unseren minimalen Job zum Laufen bringen.
Wir klicken auf "Save" und danach – auf der Job-Seite – auf "Build Now", um den Job zu starten:
Nachdem der Job durchgelaufen ist, können wir links unten in der Build History den Job anklicken:
Wir sehen nun den Status des Creator-Jobs: wann er ausgeführt wurde, wie lange er gebraucht hat, und wir bekommen unter "Generated Items" einen Link zum neu erstellten Job angezeigt:
Wir folgen den Link zum neu erstellen Job und sehen hier Titel und Beschreibung, wie wir sie im Programmcode festgelegt haben. Wir klicken auf "Configure", um uns die Konfiguration anzusehen:
In der Konfiguration sehen wir außer Namen und Beschreibung erstmal nichts weiter. Mehr haben wir im DSL-Code ja auch nicht definiert:
Auf der Jenkins-Startseite sollten jetzt neben den Jobs aus dem ersten Artikel sowohl der Creator-Job als auch der erstellte "Simple DSL Job" angezeigt werden:
Job-Konfiguration per Jenkins Job DSL für Maven-Projekte
In diesem Kapitel zeige ich dir, wie du die im ersten Teil manuell erstellten Build- und Release-Jobs eins zu eins in Jenkins Job DSL Programmcode überführst.
Jenkins Build-Job per Job DSL programmieren
Für das Maven-Projekt "library1" erstellen wir im jobs/
-Verzeichnis eine Datei BuildJobLibrary1.groovy
mit folgendem initialen Inhalt, wie du sie aus dem vorherigen Kapitel kennst.
mavenJob('Jenkins Tutorial Demo - Library 1 (DSL)') {
description 'Build job for Jenkins Tutorial / Library 1'
}
Code-Sprache: Groovy (groovy)
Mit folgendem Code fügen wir die Einstellung hinzu, dass nur die letzten fünf Builds aufgehoben werden:
logRotator {
numToKeep 5
}
Code-Sprache: Groovy (groovy)
Als nächstes fügen wir die Abfrage des Parameters für den Git-Branch hinzu. Die User-Interface-Einstellungen, für die im letzten Artikel zwei Screenshots nötig waren, lassen sich mit nur fünf Code-Zeilen darstellen:
parameters {
gitParam('Branch') {
description 'The Git branch to checkout'
type 'BRANCH'
defaultValue 'origin/master'
}
}
Code-Sprache: Groovy (groovy)
Als nächstes müssen wir den Sparse-Checkout implementieren für das Repository "[email protected]:SvenWoltmann/jenkins-tutorial-demo.git" auf den Branch "$Branch" und für das Verzeichnis "library1/". Dieses mal wird der Code etwas länger; das liegt daran, dass wir den Sparse Checkout Path und den Polling-Filter über sogenannte "Extensions" konfigurieren müssen. Die Jenkins Job DSL unterstützt diese Features nicht nativ, da sie durch das Git-Plugin hinzugefügten wurden. Wenn du kein Multirepo verwendest und das komplette Repository auschecken willst, dann kannst du den mit "// Add extensions..." markierten Block weglassen.
scm {
git {
remote {
url '[email protected]:SvenWoltmann/jenkins-tutorial-demo.git'
}
branch '$Branch'
// Add extensions 'SparseCheckoutPaths' and 'PathRestriction'
def nodeBuilder = NodeBuilder.newInstance()
def sparseCheckout = nodeBuilder.createNode(
'hudson.plugins.git.extensions.impl.SparseCheckoutPaths')
sparseCheckout
.appendNode('sparseCheckoutPaths')
.appendNode('hudson.plugins.git.extensions.impl.SparseCheckoutPath')
.appendNode('path', 'library1/')
def pathRestrictions = nodeBuilder.createNode(
'hudson.plugins.git.extensions.impl.PathRestriction')
pathRestrictions.appendNode('includedRegions', 'library1/.*')
extensions {
extensions << sparseCheckout
extensions << pathRestrictions
}
}
}
Code-Sprache: Groovy (groovy)
Für die Konfiguration der Extensions gäbe es auch eine elegantere und besser lesbare Variante:
configure {
it / 'extensions' / 'hudson.plugins.git.extensions.impl.SparseCheckoutPaths' / 'sparseCheckoutPaths' {
'hudson.plugins.git.extensions.impl.SparseCheckoutPath' {
path 'library1/'
}
}
it / 'extensions' / 'hudson.plugins.git.extensions.impl.PathRestriction' {
includedRegions 'library1/.*'
}
}
Code-Sprache: Groovy (groovy)
Diese funktioniert allerdings nicht innerhalb der sogenannten "Groovy Sandbox", die wir im späteren Verlauf des Tutorials benötigen werden.
Es folgt der Build-Trigger, der alle 15 Minuten prüft, ob sich der Code in GitLab geändert hat und das Projekt ggf. neu baut:
triggers {
scm 'H/15 * * * *'
}
Code-Sprache: Groovy (groovy)
Schließlich legen wir noch den Pfad der Root-POM und die Maven-Build-Parameter fest:
rootPOM 'library1/pom.xml'
goals 'clean install'
Code-Sprache: Elixir (elixir)
Damit ist der Job fertig programmiert. Hier ist noch einmal der vollständige Code (den du auch im GitLab-Repository findest):
mavenJob('Jenkins Tutorial Demo - Library 1 (DSL)') {
description 'Build job for Jenkins Tutorial / Library 1'
logRotator {
numToKeep 5
}
parameters {
gitParam('Branch') {
description 'The Git branch to checkout'
type 'BRANCH'
defaultValue 'origin/master'
}
}
scm {
git {
remote {
url '[email protected]:SvenWoltmann/jenkins-tutorial-demo.git'
}
branch '$Branch'
// Add extensions 'SparseCheckoutPaths' and 'PathRestriction'
def nodeBuilder = NodeBuilder.newInstance()
def sparseCheckout = nodeBuilder.createNode(
'hudson.plugins.git.extensions.impl.SparseCheckoutPaths')
sparseCheckout
.appendNode('sparseCheckoutPaths')
.appendNode('hudson.plugins.git.extensions.impl.SparseCheckoutPath')
.appendNode('path', 'library1/')
def pathRestrictions = nodeBuilder.createNode(
'hudson.plugins.git.extensions.impl.PathRestriction')
pathRestrictions.appendNode('includedRegions', 'library1/.*')
extensions {
extensions << sparseCheckout
extensions << pathRestrictions
}
}
}
triggers {
scm 'H/15 * * * *'
snapshotDependencies true
}
rootPOM 'library1/pom.xml'
goals 'clean install'
}
Code-Sprache: Groovy (groovy)
Hier auch noch ein Screenshot aus meiner IDE. Wie du siehst, bietet IntelliJ ein Syntax-Highlighting und zeigt bei Methodenaufrufen die Variablennamen an (was hier allerdings oft überflüssig ist, da viele Parameter genauso heißen wie die Methoden):
Den Code importieren wir exakt auf die gleiche Art und Weise, wie ich es im Abschnitt Import eines mit der Job DSL programmierten Jobs in Jenkins gezeigt habe. Den Creator-Job nennen wir "Jenkins Tutorial Demo - Library 1 (DSL) Creator". Wir führen ihn aus und erhalten den neuen Job "Jenkins Tutorial Demo - Library 1 (DSL)". Auf dem Screenshot siehst du an dem blauen Punkt, dass dieser bereits erfolgreich ausgeführt wurde (über den 15-Minuten-Trigger):
Wenn du nun zwei Browser-Fenster öffnest, eines mit dem manuell erstellten Job und eines mit dem automatisch erstellten, und in beiden auf "Configure" klickt, kannst du die Jobs Zeile für Zeile vergleichen und werdet feststellen, dass diese identisch sind:
Analog erstellen wir für das Maven-Projekt "application1" eine Datei BuildJobApplication1.groovy
, in dem wir die eben erstellte Datei BuildJobLibrary1.groovy
kopieren und im Code "library" durch "application" ersetzen. So brauchen wir deutlich weniger Zeit, um den Job für die Application zu erstellen, als es bei der manuellen Konfiguration der Fall war.
Jenkins Release-Job per Job DSL programmieren
Da der Release-Job viele Ähnlichkeiten mit dem Build-Job hat, kopieren wir die Datei BuildJobLibrary1.groovy
nach ReleaseJobLibrary1.groovy
. Wir passen Job-Namen und Description an. Da Releases nur vom Master-Branch erstellt werden, entfernen wir den parameters
-Block und ersetzen in der Methode branch()
den Parameter-Wert $Branch
durch origin/maste'
. Da Releases immer manuell gestartet werden, entfernen wir den trigger
-Block. Der Code sieht nun so aus:
mavenJob('Jenkins Tutorial Demo - Library 1 - Release (DSL)') {
description 'Release job for Jenkins Tutorial / Library 1'
logRotator {
numToKeep 5
}
scm {
git {
remote {
url '[email protected]:SvenWoltmann/jenkins-tutorial-demo.git'
}
branch 'origin/master'
// Add extensions 'SparseCheckoutPaths' and 'PathRestriction'
def nodeBuilder = NodeBuilder.newInstance()
def sparseCheckout = nodeBuilder.createNode(
'hudson.plugins.git.extensions.impl.SparseCheckoutPaths')
sparseCheckout
.appendNode('sparseCheckoutPaths')
.appendNode('hudson.plugins.git.extensions.impl.SparseCheckoutPath')
.appendNode('path', 'library1/')
def pathRestrictions = nodeBuilder.createNode(
'hudson.plugins.git.extensions.impl.PathRestriction')
pathRestrictions.appendNode('includedRegions', 'library1/.*')
extensions {
extensions << sparseCheckout
extensions << pathRestrictions
}
}
}
rootPOM 'library1/pom.xml'
goals 'clean install'
}
Code-Sprache: Groovy (groovy)
Anstelle des entfernten Branch
-Parameters fügen wir die Parameter releaseVersion
und nextSnapshotVersion
hinzu (unter logRotator
):
parameters {
stringParam('releaseVersion', '',
'The release version for the artifact. If you leave this empty, ' +
'the current SNAPSHOT version will be used with the ' +
'"-SNAPSHOT" suffix removed (example: if the current version ' +
'is "1.0-SNAPSHOT", the release version will be "1.0").')
stringParam('nextSnapshotVersion', '',
'The snapshot version to be used after the release. If you leave ' +
'this empty, the minor version of the release will be ' +
'incremented by one (example: if the release is "1.0", the ' +
'next snapshot version will be "1.1-SNAPSHOT").')
}
Code-Sprache: Groovy (groovy)
Der folgende Code fügt die Source Code Management Action "Check out to specific local branch" mit dem Branch-Namen "master" hinzu. Ohne die würde das Maven Goal scm:checkin
fehlschlagen. Der Code-Block wird am Ende des Blocks git
, also direkt hinter configure
eingefügt:
extensions {
localBranch('master')
}
Code-Sprache: Groovy (groovy)
Nun fügen wir den Pre-Build Step vom Typ "Execute system Groovy script" ein, der die Variablen releaseVersion
und nextSnapshotVersion
setzt, sofern der User diese beim Start des Jobs nicht ausgefüllt hat. Den folgende Code fügen wir hinter dem scm
-Block ein:
preBuildSteps {
systemGroovyCommand '''
import hudson.model.StringParameterValue
import hudson.model.ParametersAction
def env = build.getEnvironment(listener)
String releaseVersion = env.get('releaseVersion')
String nextSnapshotVersion = env.get('nextSnapshotVersion')
if (!releaseVersion) {
String pomPath = build.workspace.toString() + '/library1/pom.xml'
def pom = new XmlSlurper().parse(new File(pomPath))
releaseVersion = pom.version.toString().replace('-SNAPSHOT', '')
println "releaseVersion (calculated) = $releaseVersion"
def param = new StringParameterValue('releaseVersion', releaseVersion)
build.replaceAction(new ParametersAction(param))
}
if (!nextSnapshotVersion) {
def tokens = releaseVersion.split('\\.')
nextSnapshotVersion =
tokens[0] + '.' + (Integer.parseInt(tokens[1]) + 1) + '-SNAPSHOT'
println "nextSnapshotVersion (calculated) = $nextSnapshotVersion"
def param1 = new StringParameterValue('releaseVersion', releaseVersion)
def param2 = new StringParameterValue('nextSnapshotVersion',
nextSnapshotVersion)
build.replaceAction(new ParametersAction(param1, param2))
}
'''.stripIndent()
}
Code-Sprache: Groovy (groovy)
Es folgen (innerhalb des preBuildSteps
-Blocks im Anschluss an systemGroovyCommand
) die drei Pre-Build Steps zum Setzen der Versionsnummer, Umstellen auf Release-Dependencies und Prüfung auf SNAPSHOT-Versionen in der pom.xml
:
maven {
mavenInstallation 'Latest'
goals 'versions:set ' +
'-DnewVersion=${releaseVersion} ' +
'-DgenerateBackupPoms=false'
rootPOM "library1/pom.xml"
}
maven {
mavenInstallation 'Latest'
goals 'versions:use-releases ' +
'-DgenerateBackupPoms=false ' +
'-DprocessDependencyManagement=true'
rootPOM "library1/pom.xml"
}
shell '''
if find library1/ -name 'pom.xml' | xargs grep -n "SNAPSHOT"; then
echo 'SNAPSHOT versions not allowed in a release'
exit 1
fi
'''.stripIndent()
Code-Sprache: Groovy (groovy)
Zuletzt müssen noch die vier Post-Build Steps angelegt werden: Commit der Release-Version in Git, Tagging der Release-Version, Ändern der Versionsnummer auf die nächste Snapshot-Version und Commit der Snapshot-Version in Git. Die Posts-Build Steps fügen wir ganz am Ende der Datei, hinter goals
, ein:
postBuildSteps {
maven {
mavenInstallation 'Latest'
goals 'scm:checkin ' +
'-Dmessage="Release version ' +
'${project.artifactId}:${releaseVersion}" ' +
'-DdeveloperConnectionUrl=scm:git:' +
'[email protected]:SvenWoltmann/jenkins-tutorial-demo.git'
rootPOM "library1/pom.xml"
}
maven {
mavenInstallation 'Latest'
goals 'scm:tag ' +
'-Dtag=${project.artifactId}-${releaseVersion} ' +
'-DdeveloperConnectionUrl=scm:git:' +
'[email protected]:SvenWoltmann/jenkins-tutorial-demo.git'
rootPOM "library1/pom.xml"
}
maven {
mavenInstallation 'Latest'
goals 'versions:set ' +
'-DnewVersion=${nextSnapshotVersion} ' +
'-DgenerateBackupPoms=false'
rootPOM "library1/pom.xml"
}
maven {
mavenInstallation 'Latest'
goals 'scm:checkin ' +
'-Dmessage="Switch to next snapshot version: ' +
'${project.artifactId}:${nextSnapshotVersion}" ' +
'-DdeveloperConnectionUrl=scm:git:' +
'[email protected]:SvenWoltmann/jenkins-tutorial-demo.git'
rootPOM "library1/pom.xml"
}
}
Code-Sprache: Groovy (groovy)
Da der fertige Code der ReleaseJobLibrary1.groovy
ziemlich lang ist, verzichte ich an dieser Stelle darauf ihn anzuzeigen. Du findest ihn in meinem GitLab-Repository. Der Code wird analog zu den vorherigen Projekten importiert und ausgeführt, so dass Jenkins schließlich einen neuen Job "Jenkins Tutorial Demo - Library 1 - Release (DSL)" erstellt:
Wir legen uns noch einmal zwei Browser-Fenster nebeneinander und vergleichen den manuell mit dem automatisiert erstellen Job. Wir stellen zufrieden fest, dass die Jobs nahezu identisch sind. Lediglich die "Additional Behaviours" im Source Code Management haben eine andere Reihenfolge, was aber keine Bedeutung hat.
Analog erstellen wir wieder eine Datei ReleaseJobApplication1.groovy
für das "application1"-Projekt, in dem wir die eben erstellte Datei kopieren und im Code "library" durch "application" ersetzen. Insgesamt brauche ich knapp eine Minute, um den Release-Job für die Applikation zu erstellen, in Jenkins zu importieren und ihn auszuführen.
Zwischenfazit nach der Erstellung der Jenkins-Jobs als Code
Wir haben insgesamt vier Groovy-Dateien erstellt. Allerdings fällt auf, dass wir eine ganze Menge Code dupliziert haben. Eine Tatsache, die gegen das "Don't Repeat Yourself"-Grundprinzip der Programmierung verstößt. Wie können wir das verhindern? Mit der bisherigen Art und Weise, wie wir den Code in Jenkins importiert haben, geht das nicht. Von dieser Methode wollen wir uns jetzt auch verabschieden – sie war nur ein Zwischenziel.
In den folgenden Kapiteln zeige ich dir, wie wir Jenkins dazu bringen den Code aus dem Git-Repository zu laden und wie wir gemeinsam verwendeten Code extrahieren können.
Jenkins-Jobs in Views organisieren
Die Job-Liste ist mittlerweile ziemlich lang und unübersichtlich geworden. Glücklicherweise bietet Jenkins die Möglichkeit die Jobs in sogenannten "Views" zu organisieren. Diese Views werden als Tabs am oberen Rand der Job-Liste angezeigt.
Jenkins-View manuell erstellen
Damit wir es einmal per Hand gemacht haben, legen wir für die vier Jobs aus dem ersten Artikel der Serie manuell eine View an. Dazu klicken wir auf das Plus-Zeichen neben dem "All"-Tab:
Als Name tragen wir "Part I" ein und als Typ wählen wir "List View". Mit "OK" gelangen wir zu nächsten Schritt.
Wir wählen die vier im ersten Artikel manuell erstellten Jobs aus und klicken auf "OK":
Damit ist die erste View "Part I" fertig:
Jenkins-View per Code erstellen
Die View für die in diesem Artikel über die Job DSL angelegten Jobs erstellen wir selbstverständlich auch als Code. Wir erstellen hierfür, wieder im jobs/
-Verzeichnis des Git-Repositories die Datei ViewDSLJobs.groovy
mit folgendem Inhalt:
listView('Part II - DSL') {
jobs {
regex '.+\(DSL\).*'
}
columns {
status()
weather()
name()
lastSuccess()
lastFailure()
lastDuration()
buildButton()
}
}
Code-Sprache: Groovy (groovy)
In dieser View geben wir keine konkreten Jobs an. Stattdessen verwenden wir einen regulären Ausdruck, der alle Jobs filtert, die den String "(DSL)" enthalten. Über die columns()
-Funktion wird angegeben, welche Spalten in der View angezeigt werden sollen. Lässt man diese Funktion weg, wird nicht etwa eine Standardauswahl an Spalten angezeigt, sondern gar keine. Wir erstellen wieder einen Creator-Job, nennen ihn "View Creator (DSL)", kopieren den DSL-Code hinein und führen ihn aus. Mit wenigen Zeilen Code und ein paar Klicks ist die neue View "Part II - DSL" fertig:
Fazit und Ausblick
In diesem Teil haben wir die Build- und Release-Jobs, die wir im ersten Teil manuell angelegt haben, programmatisch mit der Jenkins Job DSL erzeugt und die Liste der Jobs durch – zunächst manuell und später programmatisch erstellte – Views übersichtlicher gestaltet.
Im dritten und letzten Teil werde ich dir zeigen, wie du mehrfach verwendeten Groovy-Code in Utility-Klassen extrahieren kannst (dazu muss das Skript-Sicherheitssystem konfiguriert werden) und wie du einen sogenannten Seed-Job erstellst, der vollautomatisch Jenkins-Jobs für alle Java-Projekte im Git-Repository (also auch neu hinzukommende) generiert.
Wenn dir dieser Artikel gefallen hat, hinterlasse mir gerne einen Kommentar und teile ihn über einen der Share-Buttons am Ende.
Möchtest du informiert werden, wenn neue Artikel auf HappyCoders.eu veröffentlicht werden? Dann klick hier, um dich für den HappyCoders.eu Newsletter anzumelden.