Build: Die Phase, in der Code ausführbar wird

Sie haben gerade Ihre neuesten Änderungen gepusht. Die Pipeline nimmt sie auf, checkt den Code aus und bereitet die Umgebung vor. Was passiert als Nächstes? Der nächste Schritt ist sicherzustellen, dass dieser Code tatsächlich irgendwo laufen kann. Das ist die Build-Phase.

Viele, die neu mit Pipelines arbeiten, denken bei Build nur an Kompilierung. Wenn Sie Java schreiben, kompilieren Sie zu Bytecode. Wenn Sie Go schreiben, kompilieren Sie zu einer Binärdatei. Das ist ein Teil davon, aber Build ist weiter gefasst. Jede Art von Arbeit in der Softwareauslieferung benötigt einen Build-Schritt, selbst wenn das Ergebnis keine Binärdatei ist.

Was Build eigentlich bedeutet

Code, wie Entwickler ihn schreiben, ist normalerweise nicht bereit, auf einem Server ausgeführt zu werden. Er muss in etwas umgewandelt werden, das das Zielsystem ausführen kann. Für eine Java-Anwendung bedeutet das, Quellcode in Bytecode zu kompilieren und in eine JAR- oder WAR-Datei zu packen. Für eine Node.js-Anwendung kann Build bedeuten, einen Bundler, Minifier oder Transpiler auszuführen, damit der Code produktionsreif ist. Für eine Go-Anwendung bedeutet Build, in eine eigenständige Binärdatei zu kompilieren.

Aber Build gilt nicht nur für Anwendungscode. Auch Datenbanken benötigen einen Build-Schritt. SQL-Code, gespeicherte Prozeduren und Datenbankschemata müssen kompiliert oder validiert werden. Das Ergebnis ist keine Binärdatei. Es ist eine Reihe von Migrationsdateien, die bereit sind, in der richtigen Reihenfolge gegen eine Zieldatenbank ausgeführt zu werden. Build für Datenbanken produziert typischerweise verifizierte SQL-Befehle, die auf Syntaxfehler und Abhängigkeitsreihenfolge geprüft wurden.

So könnte eine Build-Phase in einer Pipeline-Konfiguration für zwei gängige Anwendungstypen aussehen:

build-nodejs:
  stage: build
  script:
    - npm ci
    - npm run build
  artifacts:
    paths:
      - dist/

build-go:
  stage: build
  script:
    - go build -o app .
  artifacts:
    paths:
      - app

Auch Infrastruktur durchläuft einen Build-Prozess. Terraform-Dateien, CloudFormation-Vorlagen und Ansible-Playbooks benötigen Syntaxprüfung, Validierung und manchmal Kompilierung in eine besser bereitstellbare Darstellung. Das Ergebnis eines Infrastruktur-Builds könnte eine validierte Konfigurationsdatei, eine geprüfte Vorlage oder sogar ein vorgebautes Maschinen-Image sein.

Der gemeinsame Nenner ist: Build wandelt Quellcode in etwas um, das verifiziert und dann von späteren Phasen verwendet werden kann.

Das folgende Diagramm fasst zusammen, wie Build verschiedene Arten von Quellcode in ausführbare Artefakte umwandelt:

flowchart TD A[Quellcode] --> B{Build-Phase} B --> C[Anwendung: Binary / Paket / Container-Image] B --> D[Datenbank: Verifizierte Migrationsskripte] B --> E[Infrastruktur: Validierte Konfiguration / Plan] C --> F[Artefakt mit Metadaten] D --> F E --> F F --> G[Nächste Phase: Test & Scan]

Was ein guter Build produziert

Ein Build muss ein überprüfbares Ergebnis liefern. Nachdem der Build abgeschlossen ist, müssen Sie drei Dinge wissen: war er erfolgreich, was hat er produziert, und entspricht das Ergebnis den Erwartungen.

Ein gut strukturiertes Build-Ergebnis umfasst:

  • Ein Artefakt, das einsatzbereit ist. Das kann eine Binärdatei, ein Paket, ein Container-Image oder eine Migrationsdatei sein.
  • Eine Aufzeichnung der Version und des Commits, die diesen Build ausgelöst haben.
  • Metadaten wie einen Hash oder eine Prüfsumme, damit Sie überprüfen können, dass das Artefakt während der Übertragung nicht verändert wurde.
  • Einen klaren Erfolgs- oder Fehlerstatus.

Ohne diese Informationen können Sie nicht vertrauen, was die Pipeline an die nächste Phase übergibt.

Build muss wiederholbar sein

Wenn Sie denselben Build zweimal mit demselben Code ausführen, sollten Sie dasselbe Ergebnis erhalten. Dies wird als deterministischer Build bezeichnet. Das ist wichtig, denn wenn Builds nicht wiederholbar sind, kann Ihr Team nie sicher sein, dass das Artefakt tatsächlich von dem Code stammt, von dem Sie glauben, dass er es ist.

Nicht-deterministische Builds passieren meist aus zwei Gründen. Erstens hängt der Build von externen Bibliotheken ab, deren Versionen nicht festgeschrieben sind. Eines Tages aktualisiert sich die Bibliothek, und plötzlich produziert Ihr Build ein anderes Artefakt, obwohl sich Ihr Code nicht geändert hat. Zweitens läuft der Build in einer inkonsistenten Umgebung. Vielleicht hat ein Build-Agent eine andere Tool-Version als ein anderer, oder es sind zwischengespeicherte Dateien von einem vorherigen Build übrig geblieben.

Frieren Sie Ihre Abhängigkeiten ein. Fixieren Sie Ihre Tool-Versionen. Verwenden Sie saubere Build-Umgebungen. Diese Praktiken machen Ihren Build zuverlässig und Ihr Team selbstbewusst.

Build ist das erste Tor

Build ist der erste Punkt in der Pipeline, an dem eine Entscheidung getroffen wird: darf diese Änderung fortfahren oder nicht? Wenn der Build fehlschlägt, sollte die Pipeline anhalten. Es hat keinen Sinn, Tests auszuführen oder bereitzustellen, wenn das Artefakt selbst defekt ist.

Das bedeutet, Build muss schnell sein. Entwickler brauchen Feedback in Minuten, nicht in Stunden. Wenn ein Build zu lange dauert, hören die Leute auf, darauf zu warten. Sie wenden sich der nächsten Aufgabe zu, und wenn der Build schließlich fehlschlägt, haben sie bereits den Kontext gewechselt. Die Feedback-Schleife ist unterbrochen.

Halten Sie Ihren Build schlank. Tun Sie nur das Nötigste, um ein gültiges Artefakt zu produzieren. Überlassen Sie tiefere Prüfungen späteren Phasen. Ein Build, der in unter fünf Minuten läuft, gibt Entwicklern das schnelle Signal, das sie brauchen, um Probleme zu beheben, während der Code noch frisch in ihren Köpfen ist.

Build für verschiedene Arten von Arbeit

Schauen wir uns an, wie Build für jeden Hauptbereich funktioniert.

Anwendungen. Für kompilierte Sprachen bedeutet Build Kompilierung und Paketierung. Für interpretierte Sprachen kann Build Abhängigkeitsauflösung, Asset-Kompilierung und Bündelung bedeuten. Containerisierte Anwendungen fügen einen zusätzlichen Schritt hinzu: Das Erstellen des Container-Images selbst wird Teil der Build-Phase.

Datenbanken. Build für Datenbanken bedeutet Validierung der SQL-Syntax, Überprüfung, ob Migrationsdateien korrekt geordnet sind, und manchmal einen Probelauf gegen eine Kopie des Schemas. Das Ergebnis ist eine Reihe von verifizierten Migrationsskripten, die bereit zur Ausführung sind.

Infrastruktur. Build für Infrastruktur bedeutet Validierung von Konfigurationsdateien, Prüfung auf Syntaxfehler und manchmal die Erstellung eines Plans, der zeigt, was sich ändern wird. Für Tools wie Terraform könnte die Build-Phase die Ausführung von terraform plan umfassen, um eine Vorschau der Änderungen zu erstellen.

Jede Art von Arbeit hat ihre eigenen Build-Anforderungen, aber die Prinzipien sind dieselben: Quellcode in ein verifiziertes, wiederholbares Artefakt umwandeln, das an die nächste Phase übergeben werden kann.

Eine kurze Build-Checkliste

Bevor Sie Ihre Build-Phase als abgeschlossen betrachten, überprüfen Sie diese Punkte:

  • Build produziert ein verifizierbares Artefakt (Binary, Image, Migrationsdatei, Konfiguration)
  • Build ist deterministisch: gleicher Code, gleiches Ergebnis, jedes Mal
  • Build läuft in unter fünf Minuten
  • Build schlägt schnell fehl und gibt klare Fehlermeldungen
  • Build-Ergebnis enthält Metadaten zu Version, Commit und Prüfsumme
  • Externe Abhängigkeiten sind auf bestimmte Versionen festgelegt
  • Build-Umgebung ist sauber und konsistent über alle Läufe hinweg

Was als Nächstes kommt

Sobald der Build abgeschlossen ist und das Artefakt bereit ist, bewegt sich die Pipeline zur nächsten Phase: Überprüfung, ob dieses Artefakt tatsächlich funktioniert und sicher bereitgestellt werden kann. Das ist die Test- und Scan-Phase. Aber bevor Sie dorthin gelangen, stellen Sie sicher, dass Ihr Build solide ist. Eine schwache Build-Phase erzeugt Probleme, mit denen sich jede spätere Phase herumschlagen muss.

Build ist nicht nur Kompilierung. Es ist die erste echte Prüfung, dass Ihr Code bereit ist, etwas Nützliches zu werden. Machen Sie es richtig, und der Rest der Pipeline hat eine solide Grundlage, auf der er aufbauen kann.