Von Continuous Integration zu Continous Delivery

Groove your Jenkins: Wir bauen eine Deployment-Pipeline mit dem Jenkins Workflow-Plug-in

Jan Stamer, René Grohmann

©iStock / nikkytok

Beim Thema Continuous Integration gehört Jenkins nach wie vor zu den Besten. Aber den Takt geben immer öfter andere an. Wir geben ihm den Groove zurück. Wir zeigen, wie man mit der Groovy-Job-DSL Builds erstellt und komplexe Abläufe mit der Groovy-Workflow-DSL beschreibt. So let’s get groovy!

Die Capitol Versicherung setzt auf Java zur Entwicklung ihrer Backoffice-Anwendungen. Schon vor Jahren hat sie die erste Anwendung ReBeTol für die Reiseversicherung als Java-Webanwendung realisiert, damals mit Jenkins als Build-Server. Der Fachbereich drängte auf immer kürzere Releasezyklen, der Projektleiter setzte utopischere Zeitpläne, und die Entwickler gingen jeden Tag pünktlich nach 7,5 Stunden nach Hause und alles war gut. Bis der Abteilungsleiter zum Monatsersten den neuen Entwickler Steve W. anschleppte.

Der kam frisch von der Uni und kannte jemanden dessen Mitbewohner mal ein Praktikum bei Google gemacht hatte. Dort, so hatte er aufgeschnappt, liefern sie zehnmal am Tag aus und nennen es „Continuous Delivery“. Dies drang bis zur Führungsriege durch und verlieh Steve augenblicklich den Ruf als High Potential aus dem Silicon Valley. Sofort wurde inoffiziell ein Krisenstab aus erfahrenen Entwicklern und Architekten einberufen, die sich nach Dienstschluss trafen, um zu besprechen, wie mit den Flausen des neuen Lieblings vom Chef zu verfahren sei. Man entschloss sich zu einer Flucht nach vorne, bestellte drei Exemplare des Buchs „Continuous Delivery“ [1] und gründete eine Arbeitsgruppe, um dem jungen Hüpfer zu zeigen, dass sie es ebenfalls draufhaben.

Für die Webanwendung ReBeTol wird Jenkins als Build-Server genutzt. Der Kommentar von Steve dazu: „Na immerhin macht ihr schon Continuous-Integration.“ Für ReBeTol gibt es zwei Jenkins-Jobs. Der Job rebetol-build kompiliert die Anwendung und führt die Unit-Tests aus. Der andere rebetol-acceptance-test installiert die Anwendung auf einer Testumgebung und lässt dort die Integrationstests laufen. Die Jenkins-Jobs hat das Team von Hand erstellt und nutzt dabei diverse Plug-ins, die im Jenkins installiert sind.

DevOpsCon Whitepaper 2018

Free: BRAND NEW DevOps Whitepaper 2018

Learn about Containers,Continuous Delivery, DevOps Culture, Cloud Platforms & Security with articles by experts like Michiel Rook, Christoph Engelbert, Scott Sanders and many more.

Builds als Infrastruktur, Infrastruktur als Code

Die Arbeitsgruppe stellt fest, dass die Jenkins-Jobs für das Projekt ReBeTol zur Infrastruktur des Projektes gehören. Infrastruktur, so haben sie sich schlau gemacht, ist auch als Code zu betrachten und wie solcher zu behandeln. Was heißt das konkret? Die Konfiguration der Jobs gehört wie Code in die Versionskontrolle. Änderungen an der Konfiguration werden eingecheckt und dann automatisch in die Infrastruktur übernommen. Oha! Erstes Stirnrunzeln in der Arbeitsgruppe.

In der Zwischenzeit beschloss der Vorstand, auch für die Lebensversicherung eine neue Backoffice-Anwendung zu entwickeln und startete das Projekt LeBeTol. Hierfür sollte auf bewährte Verfahren und Technologien aus dem Projekt ReBeTol zurückgegriffen werden. Also wurde ein neues Projekt aufgesetzt, und im Jenkins wurden weitere Jobs für das neue Projekt eingerichtet. Dazu wurden die vorhandenen Jobs von ReBeTol kopiert und angepasst. Damit hat es die Arbeitsgruppe nun schon mit vier Jobs zu tun, wobei sich die Jobs für ReBeTol und LeBeTol nur durch den Namen und den Pfad in der Versionskontrolle unterscheiden. Im Grunde genommen gibt es also nur zwei Arten von Jobs, nämlich Build-Jobs und Jobs für die Integrationstests.

Die Arbeitsgruppe wünscht sich, dass Änderungen an den Jobs immer für beide Projekte übernommen werden. Sie fragen sich, wie sie das erreichen können. Idealerweise sollten die Gemeinsamkeiten der Jobs herausgezogen und parametrisiert werden. Denn so würden sie das auch im normalen Programmcode tun. Sie suchen also nach einer einfachen Möglichkeit, Jenkins-Jobs zu beschreiben und zu erzeugen. Bei ihren Recherchen stoßen sie auf die Jenkins-Job-DSL. Mit der Jenkins-Job-DSL lassen sich Jobs mit einer Groovy-DSL beschreiben. Wie das geht, schauen wir uns nun an. Im Anschluss daran kommen wir auf unsere Arbeitsgruppe zurück und schauen, ob Ihnen das weiterhilft.

Jenkins-Jobs per Groovy-Job-DSL

Mit der Job-DSL [2] können Jenkins-Jobs in einem Groovy-Skript beschrieben werden, anstatt sie einzeln von Hand anzulegen und bei jeder Änderung einzeln zu aktualisieren. Wie das aussieht, zeigt Listing 1. Dort wird ein Job erstellt, der ein Git Repository klont und mit Maven baut. Die einfachste Art, diese Jobs auszuführen, ist wiederum ein Jenkins-Job mit einem Build-Step für die Job-DSL einzurichten. Dazu wird zunächst ein Freestylejob (Abb. 1) mit einem Build-Step Process Job DSLs erstellt (Abb. 2). In der Konfiguration gibt es dann die Möglichkeit, mit Use the provided DSL script direkt ein Skript einzugeben (Abb. 3). Die Jobbeschreibung ist ein gewöhnliches Groovy-Skript, in dem Ausdrücke der Job-DSL verwendet werden können. Das bedeutet, es können Schleifen, Variablen und Klassen genutzt werden, um Jenkins-Jobs zu erstellen. So zeigt Listing 2, wie für eine Liste von Projekten Maven-Jobs im Jenkins angelegt werden. Auch REST-Zugriffe sind mit Groovy möglich, wie Listing 3 zeigt. Dort wird aus GitLab eine Liste von Projekten abgefragt und für jedes Projekt ein Jenkins-Job erstellt.

job('rebetol-build') { 
  scm { 
    git('git://capitol.de/rebetol.git') 
  } 
  triggers { 
    scm('*/15 * * * *') 
  } 
  steps { 
    maven('clean verify') 
  } 
}
Abb. 1: Freestylejob erstellen

Abb. 1: Freestylejob erstellen

Abb. 2: Job-DSL „Build Step“ einrichten

Abb. 2: Job-DSL „Build Step“ einrichten

Abb. 3: „Build Step“ mit Job-DSL-Skript

Abb. 3: „Build Step“ mit Job-DSL-Skript

def projects = ['rebetol', 'lebetol'] 
projects.each { project -> 
  maven("${project}-build") { 
    scm { 
      git("git://capitol.de/${project}.git") 
    } 
    goals('clean verify') 
  } 
}
def projectsApi = new URL("http://gitpro.capitol.de/api/v3/projects") 
def projectsJson = new groovy.json.JsonSlurper().parse(projectsApi.newReader()) 
projectsJson.each { 
   def project = it.name 
  maven("${project}-build") { 
    scm { 
      git("git://capitol.de/${project}.git") 
    } 
    goals('clean verify') 
  } 
}

Die Job-DSL unterstützt Freestyle- und Maven-Jobs, Build-Pipeline-Views und vieles mehr. Kurzum: Die meisten Arten von Jobs und Views werden unterstützt. Eine vollständige Dokumentation findet sich auf Github. Auch Trigger, Publisher oder Wrapper können über die DSL konfiguriert werden. In Listing 1 haben wir bereits die Konfiguration eines Triggers gesehen. Für einen Job kann eine bestimmte Maven-Version mit mavenInstallation(‚M3‘) angegeben werden, oder ein JDK mit jdk(‚jdk1.8‘). Soll ein Jenkins-Plug-in verwendet werden, für das keine direkte Unterstützung durch die DSL existiert, so ist das letzte Mittel den dafür notwendigen XML-Schnipsel von Hand über die Job-DSL zu konfigurieren.

Mit der Job-DSL wird aus dem Jenkins-Job ein Groovy-Skript, und wir sind dem Ziel, Builds als Code zu behandeln, einen Schritt näher gekommen. Jetzt gehören die Groovy-Skripte nur noch in ein Git Repository. Auch das unterstützt die Job-DSL. Anstatt die Groovy-Skripte direkt im Jenkins-Job anzugeben, können sie auch aus dem Dateisystem gelesen werden. Wird dann der Jenkins-Job so konfiguriert, dass er ein Git Repository klont, haben wir unsere Jenkins-Jobs in Form von Groovy-Skripten als Code in einem Git Repository abgelegt. Dazu erstellen wir wie zuvor einen Jenkins-Job mit dem Build-Step Process Job DSLs. Nur wählen wir diesmal die Variante Look on Filesystem (Abb. 4).

Geben wir dort das Muster *.groovy an, verarbeitet die Job-DSL alle im Workspace vorhandenen Groovy-Skripte. Nun kann für Jobs und Views noch eingestellt werden, was passieren soll, falls ein über die DSL erzeugter Job oder eine View wegfällt. Es gibt die Möglichkeit, dies zu ignorieren, den Job oder die View zu deaktivieren oder zu entfernen. Letzteres ist besonders praktisch, da so erzeugte Jobs und Views einfach mit den eingecheckten Groovy-Skripten synchronisiert bleiben.

Abb. 4: Job-DSL-Skripte aus Dateisystem

Abb. 4: Job-DSL-Skripte aus Dateisystem

Job-DSL bei der Capitol Versicherung

Unsere Arbeitsgruppe kann die Jenkins-Jobs der Capitol Versicherung mit der Job-DSL in Form von Groovy-Skripten ablegen. Dazu erstellt sie ein Groovy-Skript, das in einer Schleife pro Projekt zwei Jobs per Job-DSL erzeugt, siehe Listing 4. Der erste Job ${project}-build kompiliert die Anwendung und führt die Unit-Tests aus. Der zweite Job ${project}-acceptance-tests installiert die Anwendung auf einer Testumgebung und lässt die Integrationstests laufen. Das Groovy-Skript wird in Git eingecheckt und vom Jenkins-Job capitol-jenkins-seed verarbeitet. Änderungen an den Builds werden ausschließlich im Groovy-Code vorgenommen. Diese Änderungen werden dann durch einen Build des Jobs capitol-jenkins-seed verarbeitet, und die Jenkins-Jobs aller Projekte werden automatisch aktualisiert. Also geht doch, denkt die Arbeitsgruppe. Nun hat sie Feuer gefangen. Mal schauen, wo das endet.

def projects = ['rebetol', 'lebetol'] 
projects.each { project -> 

  maven("${project}-build") { 
    scm { 
      git("git://capitol.de/${project}.git") 
    } 
    goals('clean verify') 
  } 

  maven("${project}-acceptance-test") { 
    scm {et 
      git("git://capitol.de/${project}.git") 
    } 
    goals('jboss-as:deploy integration-test') 
  } 
}

Auf dem Weg zur Deployment-Pipeline

Sechs Monate später steht das nächste Treffen unserer Arbeitsgruppe an. Die Nutzung der Job-DSL zur Anlage neuer Jenkins-Jobs hat sich inzwischen etabliert und wird von allen als sehr positiv betrachtet. Aber Stillstand bedeutet ja bekanntermaßen Rückschritt, denkt sich unsere Arbeitsgruppe. Und stand in dem Buch über Continuous Delivery nicht noch irgendetwas von Deployment-Pipelines? Frank, Mitglied unserer Arbeitsgruppe und bisher eher für seine Zurückhaltung bekannt, wird hellhörig und wittert seine Chance, endlich auch mal für Aufsehen zu sorgen. Er hat gerade vor Kurzem einen Artikel im Java Magazin zum Thema Docker und Jenkins gelesen, und da wurde am Rande etwas über ein Workflow-Plug-in berichtet. Das müsste doch in etwa passen, denkt er sich, und überzeugt die Arbeitsgruppe, das Plug-in zu evaluieren.

Jenkins-Workflows per Groovy-DSL

Mit dem Jenkins-Workflow-Plug-in können komplexe Build-Abläufe in einer Groovy-DSL beschrieben werden. Damit lassen sich zum Beispiel Deployment-Pipelines einfacher und eleganter realisieren als dies mit normalen Jenkins-Bordmitteln möglich wäre.

Ein Jenkins-Job mit dem Workflow-Plug-in, wird, wie in Abbildung 5 gezeigt, angelegt. Danach wird der Workflow wie in Abbildung 6 dargestellt konfiguriert. Im Feld Definition wird festgelegt, ob das Skript direkt als Text in der Konfiguration hinterlegt oder aus dem Repository geladen wird. Ganz im Sinne von „Infrastructure as Code“ entscheiden wir uns selbstverständlich für die Repository-Variante. Um die Konfiguration abzuschließen, muss neben den Standardparametern für den Git-Zugriff mindestens noch der Script-Path eingestellt werden, der den Pfad zum Groovy-Skript angibt.

Abb. 5: Anlage eines Workflowjobs

Abb. 5: Anlage eines Workflowjobs

Abb. 6: Konfiguration eines Workflowjobs

Abb. 6: Konfiguration eines Workflowjobs

Workflow zur Verkettung von Jenkins-Jobs

Zum Einstieg zeigt Listing 5 einen einfachen Workflow, der zwei bestehende Jenkins-Jobs nacheinander ausführt.

node('master') { 
  build job: "rebetol-build" 
  build job: "rebetol-acceptance-test" 
}

Im Beispiel wird zunächst ein Node-Block deklariert, der auf dem Masterknoten des Jenkins ausgeführt werden soll. Ein Node-Block im Skript erzeugt während seiner Ausführung einen eigenen Auftrag in der Build-Queue des angegebenen Knotens. In einem Workflow lassen sich beliebig viele Node-Blöcke deklarieren. Jeder Block erhält während seines Ablaufs einen eigenen Workspace auf dem Knoten. In unserem Beispiel werden dann mithilfe des Befehls build job die beiden über die Job-DSL angelegten Jenkins-Jobs aufgerufen. Damit ist unser erster kleiner Workflow fertig und kann ausgeführt werden.

Eine erste Deployment-Pipeline

Für den Anfang gar nicht schlecht, denkt sich Frank, aber irgendwie muss da doch noch mehr gehen. Er versucht sich an einem ersten Entwurf einer einfachen Deployment-Pipeline (Abb. 7). In der Commit-Stage wird der aktuelle Code gebaut, Unit-Tests und Codeanalysen durchgeführt und im Erfolgsfall eine neue Version im Git und Maven Repository erzeugt. Den zugehörigen Code zeigt Listing 6.

Abb. 7: Aufbau einer einfachen Deployment-Pipeline

Abb. 7: Aufbau einer einfachen Deployment-Pipeline

def majorVersionNumber = 1.0
def version = "${majorVersionNumber}.${env.BUILD_NUMBER}"

node('master') {
  def mvnHome = tool 'M3'
  env.PATH = "${mvnHome}/bin:${env.PATH}"

  stage 'Commit Stage' 
  git url: 'git@myhost:cap/continuous-delivery-example.git'

  // Create release branch
  sh "git checkout -b ${releaseBranch}"
  // Set build version
  sh "mvn versions:set -DnewVersion=${version}"
  try {
    // Execute maven build
    sh "mvn -f ${webAppHome} verify"
    commitAndPushReleaseBranch()
    deployToArtifactRepository(mvnHome)
  } catch(e) {
    // Delete release branch if the maven build fails
    deleteReleaseBranch()
    error "BUILD FAILED"
  }
}

Im ersten Teil des Node-Blocks wird zunächst mithilfe des Befehls tool das Maven-Home-Verzeichnis ermittelt. Dies ist notwendig, um für spätere Shell-Aufrufe den Pfad zu Maven bekannt zu machen. Als Nächstes wird mit dem Befehl stage die Commit-Stage eingeleitet. In einem Workflow definiert eine Stage einen bestimmen Abschnitt eines Builds, wir kommen hierauf nochmal im Kontext der Acceptance-Test-Stage zurück. Als ersten Schritt des Abschnitts wird nun das Git Repository geklont. Während man für das Klonen eines Repositories direkt den Befehl git verwenden kann, wird für die restlichen Teile dieses Blocks im Wesentlichen der Befehl sh verwendet, um direkt Kommandos auf der Shell auszuführen.

So wird zum Beispiel ein neuer Release-Branch im lokalen Repository angelegt. Mithilfe des Versions-Maven-Plug-ins wird dann die Versionsnummer des Beispielprojekts aktualisiert, damit jeder Build eine neue und eindeutige Version erzeugt. Dazu wird die Build-Nummer des Jenkins-Jobs, die unter ${env.BUILD_NUMBER} im Skript verfügbar ist, als dritte Stelle der Maven-Versionsnummer übernommen. Danach wird mit mvn verify ein Build gestartet. Hierdurch werden in unserem Beispielprojekt der Code kompiliert, die Tests ausgeführt und dabei über JaCoCo die Testabdeckung ermittelt. Natürlich wären an dieser Stelle auch weitere Schritte denkbar, zum Beispiel zur statischen Codeanalyse. War der Build erfolgreich, wird der aktuelle Stand eingecheckt und ins Remote-Repository zurückgespielt. Zum Abschluss der Commit-Stage werden das generierte Artefakt und die unter target/site befindlichen Analyseergebnisse zu JaCoCo in ein Maven Repository zwecks Archivierung übertragen.

Aber was passiert eigentlich, falls bei der Ausführung eines Aufrufs ein Fehler auftritt? In diesem Fall wird wie in Groovy üblich, eine Exception geworfen, die über einen ganz normalen Try-Catch-Block behandelt werden kann. In unserem Beispiel würde ein fehlgeschlagener Maven Build dazu führen, dass das Shell-Kommando mvn verify einen Return-Code ungleich null zurückliefert, was dann automatisch zu einer Exception führen würde. Im Catch-Block wird in diesem Fall der lokale Release-Branch entfernt und der Build mithilfe des Befehls error als fehlerhaft gekennzeichnet.

Staging zur Einschränkung von parallelen Ausführungen

Mithilfe einer Stage-Deklaration lassen sich Einschränkungen bezüglich der parallelen Ausführung eines Workflowabschnitts definieren. Listing 7 zeigt den Code für eine Acceptance-Test-Stage, innerhalb derer die in der Commit-Stage erstellten Artefakte in einem Docker-Container mit Tomcat deployt und die integrativen Tests gegen diesen Container ausgeführt werden. Zum Abschluss wird der Docker-Container wieder heruntergefahren.

stage name: 'Acceptance Test Stage', concurrency: 3
node('master') {
  def mvnHome = tool 'M3'
  deployOnDockerTomcat("tomcat-cd-auto-${version}", '')
  try {
    runTestsOnDockerTomcat(mvnHome, "tomcat-cd-auto-${version}")
  } finally {
    sh "docker stop tomcat-cd-auto-${version}" 
  }
}

Zu beachten ist hier der Parameter concurrency der Stage-Deklaration. Die 3 besagt, dass dieser Abschnitt maximal von drei Instanzen des Workflows gleichzeitig durchlaufen werden darf. Dies ist sinnvoll, um z. B. die maximale Last auf dem System zu begrenzen. Falls keine Einschränkungen über den Parameter concurrency einer Stage definiert werden, können beliebig viele Instanzen des Workflows den Bereich gleichzeitig durchlaufen.

Benutzerbestätigungen anfordern

Abschließend wollen wir das Beispiel mit der in Listing 8 dargestellten User-Acceptance-Test-Stage testen.

stage name: 'User Acceptance Test Stage', concurrency: 1
input "Deploy to User Acceptance Test Stage?"

node('master') { 
  deployOnDockerTomcat('tomcat-cd-user', 8083)
  echo "http://localhost:8083/continuous-delivery-example-webapp"
}

Ziel dieser Stage ist es, eine Umgebung für die manuellen Fachbereichtests zur Verfügung zu stellen. Diese Umgebung soll immer nur genau einmal existieren und unter einem definierten URL erreichbar sein. Aus diesem Grunde wird die maximale Anzahl der parallel auszuführenden Workflowinstanzen in diesem Bereich mit 1 festgelegt. Jedes neue Deployment auf dieser Umgebung muss zunächst durch eine Benutzereingabe bestätigt werden. Erreicht wird dies durch den Befehl input, mit dem eine entsprechende Abfrage definiert werden kann.

Der Benutzer hat dann in der Konsolenausgabe des Jenkins Builds die Möglichkeit, mit PROCEED den Ablauf des Workflows fortzusetzen oder ihn mit ABORT an dieser Stelle zu beenden. Aber was passiert, falls durch mehrere Commits hintereinander diverse Instanzen des Workflows gestartet werden und niemand die entsprechende Abfrage bestätigt? Kein Problem, denn die Parametrisierung der Stage mit concurrency 1 verhindert, dass mehr als eine Instanz bis zur Benutzerabfrage durchkommt. Darüber hinaus sorgt die Deklaration der Stage dafür, dass immer nur die neueste Workflowinstanz auf die Beendigung der aktuell ausgeführten Instanz wartet. Ältere Instanzen werden an dieser Stelle automatisch mit dem Hinweis Canceled since #XXX got here beendet. Zur Verdeutlichung zeigt Abbildung 8 die Konsolenausgabe zu einem Build #127, der zunächst den bereits an der Stage-Grenze wartenden Build #126 beendet und dann seinerseits auf den Build #125 wartet.

Nachdem der Build #125 erfolgreich abgeschlossen wurde, wird der Build #127 fortgesetzt und wartet dann seinerseits auf eine Benutzerbestätigung. Zum Abschluss der User-Acceptance-Test-Stage wird dann noch der URL der Testumgebung mithilfe des Befehls echo in der Konsolenausgabe als Link ausgegeben.

Abb. 8: Konsolenausgabe zum Thema Staging und Benutzerbestätigung

Abb. 8: Konsolenausgabe zum Thema Staging und Benutzerbestätigung

Workflows bei der Capitol Versicherung

Als Frank unserer Arbeitsgruppe zwei Wochen später seine Evaluierungsergebnisse vorstellt, sind alle von den neuen Möglichkeiten und der Flexibilität des Workflow-Plug-ins begeistert. Die Arbeitsgruppe beschließt exemplarisch eine Deployment-Pipeline für das Projekt ReBeTol aufzusetzen. Echtes Continuous Delivery bis in Produktion trauen sich die doch eher konservativ geprägten Kollegen von der Capitol Versicherung zwar noch nicht zu, aber zumindest der Weg bis zu den Fachbereichstests soll auf diese Art und Weise automatisiert werden.

Kurz vor Fertigstellung der ersten Deployment-Pipeline dann der Schock! Jenkins 2.0 wurde veröffentlicht und als Hauptneuerung steht in den Release Notes etwas von „Built-in support for delivery pipelines“. Hat man etwa auf das falsche Pferd gesetzt? Das muss Frank sich näher ansehen. Nach einer kurzen Begutachtung des Jenkins-2.0-Docker-Images dann die Erleichterung. Das Workflow-Plug-in wurde lediglich in Pipeline-Plug-in umbenannt und sogar in die Liste der empfohlenen Basis-Plug-ins aufgenommen. Die Konfiguration hat sich nicht wesentlich geändert, und es gibt jetzt zusätzlich noch eine ansehnliche Visualisierung in Form einer Stage-View (Abb. 9). Und da die neue Version sogar vollständig abwärtskompatibel sein soll, kann unsere Arbeitsgruppe ihre erste Deployment-Pipeline beruhigt abschließen.

Nach den letzten aufregenden Wochen in unserer Arbeitsgruppe ist eines klar: Das Feuer für eine kontinuierliche Verbesserung wurde neu entfacht und wer weiß, ob nicht einer der Kollegen beim nächsten Termin in sechs Monaten mit einer weiteren Idee um die Ecke kommt, wie sich der Deployment-Prozess weiter vereinfachen lässt.

Abb. 9: Neu dazugekommen in Jenkins 2.0 ist die Visualisierung der Pipeline Stage View

Abb. 9: Neu dazugekommen in Jenkins 2.0 ist die Visualisierung der Pipeline Stage View

Groove your own Jenkins!

Wir haben mit der Job-DSL und dem Workflow-Plug-in einige Möglichkeiten kennengelernt, um Jenkins mithilfe von Groovy-Skripten fit für Continuous Delivery zu machen. Das hat unserer Arbeitsgruppe bei der Capitol Versicherung viel Spaß gemacht und sie dem Ziel einer vollautomatisierten Deployment-Pipeline ein gutes Stück näher gebracht. Wir hoffen, auch bei Ihnen Interesse am Thema Infrastrukturautomatisierung mit Jenkins und Groovy geweckt zu haben, und vielleicht setzen Sie ja sogar Ihre eigene Vision von Continuous Delivery mit Jenkins und Groovy um. Nutzen Sie doch als Inspiration das begleitende Git Repository zu diesem Artikel. Dort finden Sie den vollständigen Code und ein lauffähiges Beispiel einer Deployment-Pipeline mit dem Workflow-Plug-in. Also viel Spaß beim grooven!

Geschrieben von
Jan Stamer
Jan Stamer
Jan Stamer ist Senior-Softwareentwickler bei red6 in Hamburg, einem Spin-off der Hanse-Merkur-Versicherung. red6 entwickelt innovative Insurance-Lösungen mit zeitgemäßen Technologien mit Schwerpunkt auf Java und Node.js.
René Grohmann
René Grohmann
René Grohmann ist Leading Software Engineer bei der PPI AG Informationstechnologie in Hamburg. Er beschäftigt sich dort schwerpunktmäßig mit der Konzeption und Umsetzung von Java-Enterprise-Anwendungen für die Finanzbranche.
Kommentare

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu: