Jenkins Tutorial – CI CD Pipeline erklärt mit Beispielen

Jenkins Pipeline CI CD - Coding Tutorials Steffen Lippke

Du brauchst ein Jenkins Tutorial?

Hier ist die komplette Einführung in CI / CD.

Starten wir!

Was ist Jenkins?

Der Butler in Jenkins ist ein toller Typ

Jenkins ist eine Continuous Integration / Continuous Delivery (CI /CD) Software, welche viele Arbeitsschritte bei der Entwicklung und Veröffentlichungen einer Software automatisiert. Continuous Integration bedeutet, dass alle Fortschritte von Entwicklern, welche am Tag entstehen, automatisch zu einem fertigen gebauten Produkt integriert werden. Der Code führt die Software zusammen und baut eine oder mehrere verschiedene Versionsstände. Das System ist stark automatisiert, um theoretisch mehrere Releases am Tag durchzuführen. In der Realität werden nicht alle Releases veröffentlicht, aber den Zwischenstand ist ausführbar (zum Testen).

Pipelines arbeiten mit super frischen Code (Bleading Edge), deshalb kann die Pipeline wegen Fehlern, Tests und sonstigen Bedingungen scheitern oder zu der fertigen Software durchlaufen (Erfolg).

Warum soll ich eine Pipeline verwenden?

Schnell, Schneller, Pipeline

Ein Entwickler kann jetzt noch eine Änderung an einem Produkt vornehmen und in wenigen Minuten eine fertige Software an den Kunden senden (theoretisch). Dabei handelt es sich nicht um eine unbrauchbare Code-Leiche, sondern um eine funktionierende Software.

Ein Release nach dem anderen ....
Ein Release nach dem anderen ….

Bessere Qualität durch automatisches Testen

In einem guten Softwareprojekt sind immer Unit-, Regressions- oder Integrations-Tests eingebunden. Diese testen die Software auf Herz und Nieren und die Interaktion mit anderer Software. Die Pipeline prüft verpflichten bei jedem Release, ob die Tests funktionieren. Solange keine komplexen neuen Features eingearbeitet wurden, ist die Software direkt vom Endkunden verwendbar.

Der Überblick – Zusammenführen der Einzelteile

Software Projekte können sehr schnell sehr unübersichtlich werden. 1000 von Entwickler arbeiten an einem Produkt. Eine Pipeline führt den Code zu einem Produkt zusammen. Das schafft mehr Übersicht.

IT ist Handarbeit – Reduzierung manueller Aufgaben

Die IT automatisiert nicht nur die reale Welt, sondern automatisiert sich selbst. Pipelines führen anderen Programme aus, während Pipelines selbst eine Art Programm (Meta-Programm) bzw. Skript sind. Wenn ein fauler Entwickler eine Aufgabe 10 Mal am Tag macht, dann automatisiert dieser die Aufgabe.

Multicore – Parallelisierung von Arbeiten

Die Welt der Endgeräte ist so divers, dass eine Pipeline notwendig ist. Code muss für verschiedene Endgeräte, z. B. Prozessorarten vorbereitet (kompiliert) werden. Diese Arbeit muss kein Mensch machen, sondern dafür soll eine Pipeline schuften.

Was sind Pipelines?

Pipelines sind Scripte mit Abfolgen von Automatisierungsschritten. Eine Pipeline kann so einfach oder komplex wie das Projekt sein. Die folgenden Bausteine beinhalten viele Pipelines. Für mich sind die folgenden Bausteine Pflicht:

Code zusammenstellen: Die Pipeline kopiert den Code von allen (bzw. einem) Repo in den Arbeitsordner.

Testen ist der Schlüssel
Testen ist der Schlüssel

Testen: Alle Projekte beinhalten Tests, mit der die Funktion des Codes zu einem großen Teil abgedeckt sind. Hat der Entwickler eine Abhängigkeit zu einer anderen Funktion, Repo oder Software vergessen (Interdependenz)?

Automatischer Detektiv – Statischer Sicherheitstest

Statischen Tools soll die Software auf mögliche Ausnutzungen (Exploits) testen. Diese Software ist kein Garant für Schwachstellen-freie Software, sondern ein erster voll automatisierbarer Check, um die groben Klatscher zu entdecken. Wir müssen nicht unnötig viel manuelles Pentesting durchführen, wenn die Software eine erste Fehlersuche ermöglicht.

Einfach mal bauen

Jede Pipeline soll ein nutzbares Endprodukt haben. Bisher hat die Pipeline nur die Güte des Codes analysiert. Jetzt soll die Pipeline möglichst für alle Endgeräte, CPU-Architekturen, Installationsformate oder Betriebssystem eine passende ausführbare Datei erstellen. Ein nettes Format ist Docker, weil diese eine abgestimmte Laufzeitumgebung mit sich bringt. Diese ist wichtig für den nächsten Schritt.

Direkt lauffähig machen – Installieren

Wenn wir ein fertiges Docker-Image haben, kann die Pipeline das Image mit einem Kommando installieren. Die Vorbereitung tätigst Du nur beim Aufsetzen des Docker-Hosts. Jede zukünftige Installation basiert auf dem Docker-Image, welches alles beinhaltet, damit die Software läuft.

v
Portainer ist ein Super-Werkzeug für die Installation danach

Continuous Delivery (CD) sieht vor, dass das System produktiv (nach alle Testschritten) installiert ist. Die klassische Softwareentwicklung sieht eine Testphase und Abnahme vor. Bei CD kann das Unternehmen einen Teil der Fangemeinde dafür missbrauchen 🙂 (Beta-Versionen, Insider-Preview). Das Unternehmen führt ein Rollback durch, wenn die Fans unzufrieden sind.

Optionale Schritte (aus meiner Sicht)

Code Style: Soll die Klammer unter oder hinter der if-Anweisung sein? Brauchen wir ein let oder int bei Variablen? Diese Regeln kannst Du nur subjektiv beantworten. Wichtig ist nur, dass die Entwickler sich auf ein Schema einigen. Der Code Style Checker überprüft die Änderungen.

Verzweigungen: Je nach Build oder Ergebnis muss die Pipeline Verzweigungen durchlaufen. Pipelines können unendlich komplex sein. Behalte die Option im Kopf auf verschiedene Pipelines zu bauen.

Menschliche Tests: Software, welche im Anschluss direkt Endkunden unter die Nase bekommen, sollte wenigstens 1 Mensch prüfen. Menschliche Tester können Aspekte z. B. grafische Nutzeroberflächen prüfen, welche automatische Tests nur schwierig abbilden. Die Tester geben die Version frei und die Pipeline läuft weiter.

Obfuscation: Viele Unternehmen möchten ihren hart erarbeiteten Code nicht weitergeben. Deshalb nutzen diese Verschleierungstechniken, die aus Clean-Code einen menschen-unfreundlichen umständlichen Code machen. Variablennamen bestehen aus zufälligen Folgen von „I“ und „L“, sodass der Code möglichst unappetitlich wirkt.

Da kommt große Freude auf
Da kommt große Freude auf

Branding: Jeder Kunde möchte eine eigene App mit ihrem eigenen Logo und den Unternehmensfarben haben. Dies kann eine Pipeline am Ende des Build-Prozesses integrieren.

Jenkins Tutorial – Das Installieren

Jenkins kannst Du am einfachsten mit Docker installieren. Wenn Du keine Ahnung von Docker hast, dann schaue Dir hier das Tutorial an. Docker ist auch die Schlüsseltechnologie, um CI / CD nach heutigen Standards umzusetzen. Jenkins selbst könntest Du alternativ nativ installieren (Java App) und Dir spezielle native Deployment Scripts überlegen.

Die Docker Compose für den Start sieht so aus:

docker-compose.yml

version: "3.9"
services:
  jenkins:
    image: jenkins/jenkins:latest
    deploy:
      restart_policy:
        condition: on-failure
        delay: 3s
        max_attempts: 5
        window: 60s
    user: root
    ports:
      - 8080:80
      - 50000:50000
    container_name: jenkins
    networks:
      - mysqlnetwork
    volumes:
      - jenkinsstorage:/var/jenkins_home
      - /run/user/1000/docker.sock:/var/run/docker.sock
      - /home/user/bin/docker:/usr/local/bin/docker


volumes:
  jenkinsstorage:
    
networks:
  mysqlnetwork:
    external: true
    name: mysqlnetwork

Führe dann das Kommando aus docker compose up

Grundlage schaffen

Die einfachste Methode ist das manuelle Anstoßen einer Pipeline. Du drückst auf den Knopf „Starten“ und die Pipeline rennt. Die elegante Lösung ist, dass bei jedem Commit (oder Merge) auf einer Git-Verzweigung (Branch) die Pipeline losrennt – mit Webhooks.

Jenkins erkläre ich anhand von dem App-Framework Ionic. Du kannst jede anderen Code / Framework verwenden.

Lege eine Ionic Projekt in einem öffentlichen Git-Repo an.

Erstelle eine Jenkins-Datei. Die Syntax Jenkins musst Du Dir schrittweise aneignen. Für jedes Repo sieht dieses anders aus, wenn Du nicht exakt gleich arbeitest. Prinzipiell kannst Du mit „sh“ viele Shell Kommandos zum Bauen, Testen oder Konfigurieren ausführen. Variablen unterstützt Jenkins auch.

pipeline {
    environment {
        registry = 's20'
        registryCredential = '977ae189-bf38-4b7c-a7c4-ccc5f6111858'
        dockerImage = ''
    }

    agent {
        docker {
            image 'busybox'
        }
    }
   

        stage('Frontend') {
            agent {
                docker {
                    image 'satantime/puppeteer-node:19-buster-slim'
                }
            }

            stages {
                stage('Install NPM Dep') {
                    steps {
                        dir('frontend-ionic') {
                            sh 'npm install -f'
                            sh 'npm install -g @angular/cli'
                            sh 'npm i -D puppeteer && node node_modules/puppeteer/install.js'
                        }
                    }
                }

                stage('Run Tests') {
                    steps {
                        dir('frontend-ionic') {
                            sh 'ng test'
                        }
                    }
                }

                stage('Modify Env') {
                    steps {
                        dir('frontend-ionic') {
                            sh 'cp src/app/config.prod.ts src/app/config.ts'
                        }
                    }
                }

                stage('Build Ionic Docker') {
                    steps {
                        dir('frontend-ionic') {
                            script {
                                dockerImage = docker.build 's20:nightly'
                            }
                        }
                    }
                }

                stage('Push Ionic Docker') {
                    steps {
                        script {
                            dir('frontend-ionic') {
                                docker.withRegistry('https://register.lan', registryCredential) {
                                    dockerImage.push()
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

Halte die Reihenfolge Stage > Steps > Scripts (Optional: > Subfolder) > Kommando / Aktion immer ein. Benenne die Stages eindeutig. Die sh Zeilen beinhalten die Kommandos, die die Aktionen ausführen. Der Agent ist die Grundlage, in der die Pipeline sich ausführt.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Die Webseite nutzt nur technisch notwendige Cookies.