Archiv für den Monat: Oktober 2013

Build Patterns: Build Script Injection

Einführung

Vor einiger Zeit habe ich auf Twitter gelesen, dass Roy Osherove sich mit Build Patterns auseinander setzt und ein entsprechendes Buch („Beautiful Builds“) darüber schreiben will. Da es bei LeanPub veröffentlich wird, kann man es bereits vor der Fertigstellung kaufen und reinlesen:

Im Rahmen der Konferenz „Continuous Lifecycle 2013“ am 12.11.2013 in Karlsruhe werde ich ebenfalls einen Kurz-Vortrag zu diesem Thema halten.

Zur Vertiefung möchte ich an dieser Stelle einige Patterns mit Beispielen vorstellen. Den Anfang macht das Pattern „Build Script Injection“.

Problembeschreibung

Roy Osherove hat in seinem Blogbeitrag „Build Patterns: Script Injection“ bereits das Problem beschrieben:

Man hat einen Continuous Integration Prozess etabliert, Quellcode wird aus der Versionsverwaltung ausgecheckt, gebaut und Tests ausgeführt. Über die Zeit und Versionen haben sich jedoch die Ordnerstruktur und/oder Build-Schritte geändert:

Projektstruktur zu Zeitpunkt A
(Produktversion 1.0)

Projektstruktur zu Zeitpunkt B

(Produktversion 2.0)

Soweit so gut. Aktuelle Versionen können jederzeit gebaut werden. Doch was ist, wenn plötzlich ein Patch für Produktversion 1.0 gebaut werden muss? Die Build-Konfiguration greift dann auf Ordner zu, die es früher gar nicht gab und der Build funktioniert nicht mehr.

Lösungsansatz

Um das Problem lösen zu können, muss man den statischen Anteil der Build-Konfiguration vom dynamischen Anteil der Build-Konfiguration trennen. Den dynamischen Anteil lagert man in ein Build-Skript aus, das unter Versionskontrolle steht und versionsabhängig modifiziert werden kann.

Ausgangssituation

Zu Beginn enthält die Build-Konfiguration alle Logik über den Buildablauf und Zugriff auf die Ordner-Strukturen:

Ändert sich die Verzeichnisstruktur oder ein Build-Step, dann ist die Build-Konfiguration nicht mehr „rückwärtskompatibel“. Möchte man ältere Versionen wieder bauen, muss die gesamte Build-Konfiguration entweder angepasst oder eine Kopie pro Version angelegt werden. Das führt jedoch auf Dauer zu einer sehr großen Varianz und wird schlecht wartbar sein.

Zielsituation

Die Build-Konfiguration wird aufgesplittet und einen dynamischen und statischen Anteil:

Der statische Anteil befindet sich in der Build-Konfiguration auf dem CI-Server. Der dynamische Anteil wird in ein Build-Skript ausgelagert. Das Build-Skript enthält die gesamte Build-Logik als auch Informationen über die Verzeichnisstruktur. Zudem unterliegt das Build-Skript nun der Versionskontrolle. Dadurch dass die Build-Konfiguration auf dem CI-Server nur noch das Build-Skript aufruft, können Abläufe beliebig ausgetauscht werden, ohne dass der Build kaputt geht.

WordPress: Für kurze Zeit nicht verfügbar, um eine regelmäßige Instandhaltung durchzuführen. Prüfe in einer Minute erneut.

Heute hab ich meinen WordPress-Blog auf die neue Version 3.7.1 geupdated. Kurz nach dem Start hat sich Chrome entschieden, die Seite neu zu laden. Seitdem erscheint beim Aufruf meines Blogs die folgende Fehlermeldung:

Glücklicherweise konnte ich nach einer kurzen Google-Suche eine potentielle Lösung im Blog von Dennis Koray finden:

Man muss ich per FTP verbinden, um dann die .maintenance-Datei im Root-Verzeichnis zu löschen. Anschließend sollte das Problem gelöst sein.

Windows 8 zurücksetzen

Schneller als gedacht ist mein Windows 8 System unbrauchbar langsam geworden. Möglicherweise liegt es an den 3 Visual Studio-Installationen (2010, 2012, 2013), möglicherweise auch an anderen Programmen.

Ich habe mal die Startzeiten mit den TuneUp-Utilities analysiert, konnte aber trotzdem Deinstallation einiger Programme kaum eine Besserung feststellen.

Windows 8 hat ja eine eingebaut Unterstützung zum Zurücksetzen des gesamten Systems oder „Auffrischen“.

Hier eine kleine Anleitung zum Auffinden der System-Wiederherstellung:

Zuerst einmal geht man auf den Windows 8 Start-Bildschirm. Dort öffnet man dann die Charms-Leiste beispielsweise durch ein Wischen vom rechten Bildrand:

Nach dem Auswählen der Einstellungen wählt man dort „PC-Einstellungen ändern“:

In den PC-Einstellungen kann man neben dem Umstellen des Profilfotos, des Anmelde-Bildschirms usw. auch das System Wiederherstellen:

 

Über den Menüpunkt „Alles entfernen und Windows neu installieren“ wird das System auf die Werkseinstellungen zurückgesetzt:

Mein nächster Blog-Artikel wird dann mit frisch aufgesetztem System geschrieben 🙂

Domain-Umzug

Nachdem sich über Jahre hinweg immer mehrere Domains für unterschiedliche Projekte(-Ideen) angesammelt haben, wurde es endlich mal Zeit zur Konsolidierung.

So habe ich beispielsweise meine Domains bei 1&1, Host-Europe und All-Inkl. gehabt. Diese habe ich teilweise ersatzlos gestrichen oder umgezogen. Da ich mit dem Preis-/Leistungsverhältnis von 1&1 nicht mehr zufrieden war, habe ich nun alle Domains zu Host-Europe umgezogen.

KK-Antrag

Früher habe ich mal eine Domain über einen sogenannten KK-Antrag umgezogen – das war vielleicht ein Krampf!

KK steht für „Konnektivitäts-Koordination“. Damit wird in einem formalen Ablauf der Provider- bzw. Registrar-Wechsel geregelt. Neben dem Antragsteller, d.h. gegebenenfalls neuen Domaininhaber, sind an dem KK-Prozess, der alte und neue Provider und der alte Domaininhaber beteiligt. Damit sich Verzögerungen bei der Domainübertragung und dem Aktualisieren der DNS-Server nicht ergeben, sollte die Kündigung beim alten Provider und die Bestellung beim neuen Provider sich um 1-2 Wochen überlagern. Andernfalls kann es sogar vorkommen, dass die Seite eine Weile nicht mehr erreichbar ist.

Mit dieser Erfahrung im Hinterkopf habe ich den Umzug lange vor mich hergeschoben. Genau diese Nicht-Erreichbarkeit war mir damals zum Verhängnis geworden.

Approve Move

Neu ist jedoch mittlerweile die Möglichkeit, den Umzug vollelektronisch durchzuführen! 1&1 als auch Host-Europe unterstützen Approve Move.

Das geht so: Beim alten Provider beantrag mal den Domain-Wechsel und erhält einen Auth-Code für Approve Move.

Anschließend erscheint der Auth-Code auf der Domain-Info Seite:

Nach dem Wunsch, die Domain zum neuen Provider (Host-Europe) umzuziehen, erhält man eine E-Mail mit dem Link auf die Approve Move Seite:

Nach dem Klick auf den Link öffnet sich die Approve Move Seite:

Hier gibt man dann geht Code ein, den man vom alten Provider erhalten hat. Nach Bestätigung erhalt man gleich die Statusmeldung:

Backup

E-Mails

Vor einem Umzug sollte man sich aber Gedanken machen, wie man die Daten von einem Server zu einem anderen Server umziehen kann.

Da ich IMAP-Konten nutze, und E-Mails nicht mehr per POP3 abrufe, verbleiben alle E-Mails beim Provider. Daher muss man einen Weg finden, die E-Mails zu sichern um sie später wiederherstellen zu können.

Für IMAP habe ich MailStore verwendet:

MailStore ist für den privaten Gebrauch kostenlos und sichert zuverlässig die E-Mails.

Alternativ kann ich auch das kostenlose IMAPsize empfehlen:

Die UI ist etwas veraltet und einige Buttons erscheinen erst nachdem man mit der Maus drüber fährt. Dafür verrichtet es wirklich zuverlässige Dienste.

WebSpace

Die Inhalte auf meiner Webseite habe ich mit einem FTP-Programm gesichert. Dazu habe ich die Inhalte heruntergeladen und lokal abgelegt. Die mySQL-Datenbanken habe ich mithilfe von phpmyAdmin gesichert. Es gab nur ein kleines Problem mit der Größe der SQL-Sicherheit bei der Wiederherstellung. Ein einfaches Aufsplitten der SQL-Datei hat das Problem jedoch behoben.

Dienstleister

Wem das zu kompliziert ist, kann auch auf Dienstleister zurückgreifen, die den Webspace und E-Mails dann sichern und an der neuen Stelle wiederherstellen.

Host-Europe bietet beispielsweise Audriga an: https://www.audriga.com/

Verwenden von Feature-Toggle-Patterns, um der Merge-Hölle zu entgehen

Die Merge-Hölle

Bei der professionellen Software-Entwicklung ist eine Versionsverwaltung nicht mehr wegzudenken. Fast alle Versionskontroll-Systeme unterstützen Branches, in denen man beispielsweise die Entwicklung von Features vornimmt, um den Code im Hauptzweig (trunk) nicht zu beeinflussen und unabhängig das Feature entwickeln zu können:

Hier ist ein Beispiel dafür, wie ich bisher die Produkt- / Projektentwicklung kannte: Nachdem eine Produkt-Version released wurde, werden Feature-Branches angelegt, um die Features unabhängig vom Entwicklungs-Branch zu entwickeln. Das hat sehr viele Vorteile: Beispielsweise könnte sich das Produktmanagement entscheiden, ein Feature erst in einer späteren Version zu integrieren, falls sich die Entwicklung verzögern sollte. Zudem kann die Entwicklung eines Features unabhängig von der Entwicklung anderer Features stattfinden.

Wer so arbeitet, kennt auch den Begriff der „Merge-Hölle“. Diese tritt nämlich dann auf, wenn die Entwicklungs-Branches für unterschiedliche Features und der trunk im Code zu weit auseinander laufen oder Code in der gleichen Datei mehrfach umgebaut wurde. Dann nämlich funktioniert der Merge nicht mehr so einfach:

Wenn es sich dabei nur um eine Code-Datei handelt, ist das zwar ärgerlich, aber noch akzeptabel. Die Merge-Hölle ergibt sich, wenn sehr viele Dateien in unterschiedlichen Entwicklungszweigen verändert wurden und vielleicht sogar noch neue Dateien mit gleichem Namen angelegt wurden. Dann funktioniert in der Regel der Merge nicht mehr und man verbringt Stunden und Tage damit, die Konflikte aufzulösen und hofft, dass danach noch alles so funktioniert, wie es man gedacht war.

Weiterhin kann es passieren, dass Probleme, die in einem Branch gefixt wurden, durch den Merge wieder verloren gehen.

Das Feature Toggle Pattern

Hier kann das Feature-Toggle-Pattern Abhilfe schaffen:

Anstelle der Verwendung unterschiedlicher Entwicklungs-Branches findet sie Entwicklung immer auf dem gleichen Branch (trunk) statt. Martin Fowler hat in seinem Artikel „Feature Toggle“ (http://martinfowler.com/bliki/FeatureToggle.html) detailliert beschrieben, wie das Feature-Toggle Pattern funktioniert.

Damit ist es möglich, auch noch „experimentellen“, noch nicht fertigen Code in Produktivsystemen zu releasen. Man muss quasi nur sicherstellen, dass der unfertige Code nie ausgeführt wird. Dadurch arbeitet jeder immer auf dem aktuellen Entwicklungszweig und kann Änderungen an der Codebasis registrieren und darauf reagieren.

Doch wie setzt man das Feature Toggle Pattern in der Praxis um?

Wichtig ist, dass die Stelle, an der das Feature aktiviert bzw. deaktiviert wird, später einfach zu finden und zu entfernen ist, wenn das Feature „produktiv“ geschaltet wird. Wenn ein Schalter nicht entfernt wird, bürdet man sich unnötigerweise „technische Schulden“ auf. Am einfachsten geht das beispielsweise mit einer (abstrakten) Klasse, die eine Property „IsEnabled“ zur Verfügung stellt und von der alle Feature Schalter erben:

internal
abstract
class
FeatureSwitch

{


public
abstract
bool
IsEnabled { get; set; }

}

 

Von dieser Klasse FeatureSwitch leitet man nun einfach einen Schalter für das eigene Feature („MyFeature“) ab:

internal
class
MyFeatureSwitch : FeatureSwitch

{


private
bool
_isEnabled = true;

 


public
override
bool
IsEnabled

{


get { return
_isEnabled; }


set { _isEnabled = value; }

}

}

Hier wird das Feature by-default eingeschaltet (_inEnabled = true). Genauso einfach kann das Feature auch wieder deaktiviert werden.

Im Code verwendet man den Schalter dann so:

MyFeatureSwitch myFeature = new
MyFeatureSwitch();

 

if (myFeature.IsEnabled)

{


// implement feature code here …

}

else

{

 

}

 

Man instanziiert einfach an einer beliebigen Stelle, an der das Feature verwendet wird, den FeatureSwitch. Dort prüft man dann über die Eigenschaft „IsEnabled“, ob das Feature „scharf geschaltet“ ist und implementiert den Code so, als wenn das Feature produktiv verwendet wird.

Alternativ zur abstrakten Basisklasse „FeatureSwitch“ könnte man auch einen ConfigSwitch verwenden wie ich es beispielsweise im Blog von Federik Normen gesehen habe: http://weblogs.asp.net/fredriknormen/archive/2013/09/28/merge-hell-and-feature-toggle.aspx