Build Patterns
BEST PRACTICES UND PATTERNS FÜR BUILD KONFIGURATIONEN
Ralf Abramowitsch


Senior Software Development Engineer @ Vector Informatik GmbH



Dozent: Software-Entwicklung mit .NET @ DHBW Stuttgart



Kontakt


E-Mail: ralf@abramowitsch.de



Blog: http://blog.abramowitsch.de



Twitter: @minibrain81
Agenda


Einführung



Build Patterns



Build-Skelett



Ablagen-unabhängige Build-Skripte



Infrastruktur-unabhängige Build-Skripte



Kumulative Builds





Build Script Injection

Gated Commits

Zusammenfassung
Einführung
Einführung zu Patterns


Patterns wurden für architektonische Konzepte von
Christopher Alexander et al. entwickelt.



"Each pattern is a three-part rule, which expresses a relation
between..



a problem,





a certain context,
and a solution" (Alexander et al. 1977).

Patterns beschreiben Best Practices, erklären gute
Designs, so dass diese Lösungen leicht wiederverwendet
werden können.
http://en.wikipedia.org/wiki/File:A_Pattern_Language.jpg
Einführung zu Build Patterns
Beautiful Builds


Autor: Roy Osherove



Aktueller Stand: 30% fertig



https://leanpub.com/build
Build Script Injection
Build Script Injection
Problem


CI-Prozess ist etabliert und Produkte können gebaut werden



Build-Abläufe sind in der Build-Konfiguration hinterlegt



Build-Konfigurationen werden an aktuelle Anforderungen angepasst
und immer gleich nachgezogen



Alte Produktversion muss gebaut werden, zu der die neue BuildKonfiguration nicht passt  Build schlägt fehl
Build Script Injection
Projektstruktur zu Zeitpunkt A
(Produktversion 1.0)
Project 1
Bin
Source
Project 2

Projektstruktur zu Zeitpunkt B
(Produktversion 2.0)
Bin
Source
Project 1
Project 2

Bin

Setup

Source

Utils

Setup
Utils
Build Script Injection
Project 1
Bin
Source
Project 2

Bin
BuildKonfiguration

Source
Setup
Utils
Unter
Versionskontrolle
Build Script Injection
Lösung


Aufteilen der Build-Konfiguration in 2 Teile:


Ein Script, das im Umfeld der Build-Konfiguration abgelegt ist




Sehr statische und "dumme" Skripte

Ein Script, das unter SourceCode-Verwaltung steht


Script-Änderungen sind passend zur Produkt-Version



Script ist passend zu Aktionen und
zur aktuellen Struktur von Dateien (typischerweise relative Pfade)



Entwickler sollten vollen Zugriff auf diese Skripte haben
Build Script Injection
Statischer Anteil

Dynamischer Anteil
Project 1
Bin
Source

Project 2
BuildKonfiguration

Bin

Build-Skript

Source
Setup
Utils

Unter Versionskontrolle
Build-Skelette
Build Skelette
Problem


Arbeiten an einem Produkt laufen bereits auf Hochtouren



Mit Buildautomatisierung wurde noch nicht oder nur teilweise
begonnen



Je weiter das Projekt voranschreitet, um so


mehr Schritte müssen manuell vorgenommen werden und



eine Build-Automatisierung wird immer schwerer
Build Skelette
Lösung


Zu Beginn eines Projekts gleich mit der Buildautomatisierung beginnen


Leeres Entwicklungsprojekt (z.B. Visual Studio Solution) anlegen



Buildskript erstellen



Leeres Test-Projekt erstellen und in CI-Prozess einbauen



Deploy-Cycle einrichten
Build Skelette
Vorteile


Build-Prozess existiert von Anfang an



Einfach Anpassungen möglich



Schnelles Feedback
Build Skelette
Bestandteile des “Build Skeletts”



Ein Build Skript (unter Versionskontrolle) zum Kompilieren des Quellcodes



Continuous Integration Server


Buildkonfiguration “CI”:
Führt bei Code-Änderungen (Check-Ins) das Build-Skript aus



Buildkonfiguration “Deploy”:
Deploy-To-Test oder Deploy-To-Production
Ablagen-unabhängige Skripte
Ablagen-unabhängige Skripte
Problem


Build-Skripte laufen nur auf dem lokalen Rechner



Inbetriebnahme eines CI-Systems wird sehr aufwändig



Spezielle Build-Ordner



Bibliotheken müssen an bestimmte Ordner kopiert werden





Laufwerke mounten

Etc. …

Build-Skript hat spezielle Anforderungen an die Umgebung in der es ausgeführt wird
Ablagen-unabhängige Skripte
Lösung


Relative Pfade anstelle absoluter Pfade



Build-Skript steht unter Versionskontrolle (Repository)



Bibliotheken, Tools usw. im (separaten) Repository
Infrastruktur-unabhängige Skripte
Infrastruktur-unabhängige Skripte
Problem


Build-Skripte müssen an vielen Stellen angepasst werden, nur weil
sich eine Stelle ändert


Beispiele





Name der Maschine, auf die deployed wird, ändert sich
Neben Release-Targets sollen nun auch Debug-Targets gebaut werden

Verletzung des „Single-Source“-Prinzips


Name der Build-Konfiguration erscheint mehrfach im Skript
Infrastruktur-unabhängige Skripte
Lösung


Skript Variablen




Beispiel: Name der Build-Konfiguration

Skript Konfigurationsdatei


Sammlung mehrerer Skript Variablen



Vorteil: Alle Variablen an zentraler Stelle



Umgebungsvariablen



Skript Parameter
Infrastruktur-unabhängige Skripte
Mögliche Seiteneffekte



Erschweren des Debuggens von Skript-Problemen


Umgebungsvariablen müssen gut dokumentiert sein



Lokaler Build könnte fehlschlagen, wenn nicht alle Voraussetzungen

(Variablen, …) gesetzt sind
Kumulative Builds
Kumulative Builds
Problem


Builds dauern sehr lange, bis sie vollständig durchgelaufen sind



Build-Konfiguration enthält zu viele Schritte


Alle Schritte sind wichtig und können nicht übersprungen werden
Kumulative Builds
Lösung


Build-Konfigurationen sind oft ähnlich



Erstellen einer Pipeline


Wiederverwenden der Build-Artefakte
Kumulative Builds
Ausgangssituation: Continuous Integration Build
Source Code
auschecken

Debug Targets
bauen

Ausführen von
Kurz-Tests auf
Debug-Target
Kumulative Builds
Ausgangssituation: Nightly Build
Source Code
auschecken

Debug Targets
bauen

Ausführen aller
Tests auf
Debug-Target

Release Targets
bauen

Ausführen aller
Tests auf
Release-Target

Erzeugen von
CodeDoku, Installern,
…

Deployment auf
Test-Umgebung
Kumulative Builds
Ausgangssituation: Release Build
Source Code
auschecken

Debug Targets
bauen

Ausführen aller
Tests auf
Debug-Target

Release Targets
bauen

Ausführen aller
Tests auf
Release-Target

Deployment auf
ProductionUmgebung
Kumulative Builds
Zielsituation: Continuous Integration Build
Source Code
auschecken

Debug Targets
bauen

Ausführen von
Kurz-Tests auf
Debug-Target
Kumulative Builds
Zielsituation: Nightly Build
Source Code
auschecken

Debug Targets
bauen

Ausführen von
Kurz-Tests auf
Debug-Target

Build-Artefakte
aus dem CIBuild hoen

Release Targets
bauen

Ausführen aller
Tests auf
Release-Target

Erzeugen von
Installern

Deployment auf
Test-Umgebung
Kumulative Builds
Zielsituation: Release Build
Debug Targets
bauen

Ausführen von
Kurz-Tests auf
Debug-Target

Holen der BuildArtefakte aus
CI-Build

Release Targets
bauen

Ausführen aller
Tests auf
Release-Target

Holen der BuildArtefakte aus
Nightly-Build

Deployment auf
ProductionUmgebung

Source Code
auschecken

Erzeugen von
CodeDoku, Installern,
…
Gated Commits
Gated Commits
Problem


Entwickler wissen nicht, was passiert, wenn sie ihren Code
committen


Bricht der Code den aktuellen Build?



Funktionieren nach dem Commit noch alle Tests?



„Blindes“ Committen
Gated Commits
Problem

Code schreiben

Einchecken

Build

Fehlersuche

Build
ok?

Ja
Bugfix
vorhanden
Nein

Team blockiert

Nein

Ja
Gated Commits
Code schreiben

„Gated Commit“
anfordern

Entwickler Code
Snapshot wird an
Server übertragen

Snapshot wird mit
Master Source
Version gemerged

Build-Konfiguration
wird ausgeführt

Nein

Benachrichtigung
des Entwicklers

Aufräumen &
Bereitstellen von
Logfiles etc.

Build ok?

Ja

Code wird in Master
Branch committed
Zusammenfassung


Build Patterns und Best Practices optimieren den Build Prozess


Erhöhte Wartbarkeit



Kürzere Ausführungszeiten & schnelleres Feedback



Erhöhte Qualität im Entwicklungsprozess
Vielen Dank für Ihre Aufmerksamkeit

Build Patterns - Patterns und Best Practices für den Build Prozess