In meinem letzten Blogpost habe ich diverse Optimierungsmöglichkeiten für Webentwickler angesprochen. Ein wiederkehrender Punkt war das Automatisieren diverser Prozesse. Nun möchte ich auf die Gründe einer Automatisierung und verschiedener Automatisierungsmöglichkeiten (eingeteilt in die Bereiche Setup, Development und Deployment) eingehen.

Warum Automatisieren?

Einer der größten Feinde eines Programmierers (mit wenigen performancebedingten Ausnahmen) ist Redundanz. Mit Redundanz muss nicht immer nur das wiederkehrende Vorkommen informationsgleichwertiger Daten und Strukturen (besonders bekannt aus dem Bereich der Datenbanken, aber auch Wiederholung von Markups) sein, sondern kann sich auch im Wiederholen von gleichen oder ähnlichen Prozessen verstecken. Diese Abneigung gegenüber der Redundanz ist nicht nur eines der vielen Spleens für die wir Programmierer bekannt sind, sondern hat auch rational erklärbare Gründe:

Unnötiger Zeitaufwand

Über die Jahre entwickelt ein Programmierer diverse Abläufe, die er bei jedem neuen Projekt wiederholt. Sei es der simple Start mit einer minimalen HTML-Struktur, das Minifien von Bildern oder das Konvertieren von Less-Dateien in vom Browser lesbaren Cascading Stylesheets. Dies sind Prozesse die von einer kleinen Landingpage bis zur komplexen Webapplikation stets wiederkehren. Auch das Aufsetzen eines Projekts (bei einem Kollegen, am Zweitgerät oder am Server) bringt wiederkehrende Tätigkeiten (Plugins downloaden, Ordnerstruktur vorbereiten) mit sich.

Heißt es zwar, „Die Definition von Wahnsinn ist, immer wieder das Gleiche zu tun und andere Ergebnisse zu erwarten“, liegt in der Entwicklung oft jedoch der Wahnsinn allein darin, immer wieder das Gleiche zu tun, und dabei zusätzlich noch Gefahr zu laufen, einmal tatsächlich ein anderes (unerwünschtes) Ergebnis zu erhalten.

Automatisierung kann diese wichtigen wiederkehrenden Aufgaben übernehmen und so viele Prozesse beschleunigen und vereinheitlichen.

Schlechte Wartbarkeit

Eine beliebte Fehlerquelle sind repetitive Prozesse aufgrund von redundanten Strukturen. Sei es eine Navigation, deren Markup in allen Unterseiten gleich ist oder mehrere Funktionen, die das gleiche machen, das Warten von mehreren gleichen Codezeilen oder Daten – all das ist nicht nur unnötig zeitaufwendig, sondern birgt auch einen Fehler, der nur darauf wartet, gemacht zu werden. Automatisierung kann hier eingreifen und z.B. durch selbstständiges Aktualisieren aller Seiten einem Fehler zuvorkommen.

Automatisierung im Setup

Wie bereits angesprochen, gibt es beim Setup wiederkehrende Prozesse. Mit Setup ist hier nicht nur das einmalige Erstellen eines Ordners mit dem Namen des Projektes („Initial Setup“) gemeint, Setup kann selbst bei einem einzelnen Projekt öfter nötig sein („Recurrent Setup“). Sei das beim Zweitrechner oder bei den Kollegen die auch daran arbeiten.

Initial Setup

Dieser Schritt sollte bestenfalls wirklich nur einmal nötig sein, doch auch hier gibt es ein Tool, das mittels Automatisierung den Prozess beschleunigen kann: Yeoman.io. Bei Yeoman handelt es sich um ein Komandozeilentool, das mittels sogenannter Generatoren ein neues Projekt vorbereitet. Man hat die Wahl zwischen vorgefertigten Generatoren für verschiedene Anwendungen (Webapp, Chrome Extension, Angular App), aber kann auch aus einer Vielzahl von Generatoren aus der Open Source Community wählen. Ist auch hier nichts zu finden, hat man immer noch die Möglichkeit, seinen eigenen Generator zu schreiben. Diese Generatoren erstellen eine Ordnerstruktur, fügen die nötigen Dateien ein (HTML, JavaScript, CSS) und konfigurieren Tools wie Bower und Grunt.

Initial Setup

Recurrent Setup

Der größte Punkt beim Recurrent Setup ist das Verwalten von Dependencies (JavaScript Plugins, Frameworks). Mit Bower.io kann man diese definieren und installieren, dadurch kann man diese auch aus der Versionierung entfernen. Weiters lädt Bower eventuelle Dependencies und kümmert sich um die Versionskompatibilität.

Automatisierung im Development

Gerade beim Entwickeln gibt es viele Schritte, die sich automatisieren lassen. Als Tools haben sich hier zwei zum Standard entwickelt: http://gruntjs.com/ und das jüngere http://gulpjs.com/. Ich werde mich hier auf Grunt beschränken, prinzipiell sind beide von der Funktionalität aber gleichwertig.

Grunt

Automatisiertes Kompilieren und Komprimieren

Ob das Kompilieren von Less zu CSS, das Verketten, Minifien und Uglyfien von JavaScript oder das Verbinden einzelner Templateteile (Body mit Header, Footer) – mit Grunt muss man sich um all das nicht mehr selber kümmern. Die Redundanz von multiplen auf allen Seiten wiederholten Templateteilen kann man so umgehen, indem man sie in einer zentralen Datei speichert und mittels Grunt in anderen Templates einbindet. Auch kann man Bilder wie PNGs komprimieren lassen.

Automatisiertes Builden / Reloaden

Mit dem „Watch“-Task von Grunt lässt sich so einiges vereinfachen. Werden vorher definierte Dateien oder Ordner geändert, kann man sofort einen oder mehrere Tasks zum Kompilieren ausführen. Kombiniert mit dem „Livereload“ kann man so Änderungen quasi sofort in allen offenen Browserfenstern beobachten.

Automatisiertes Testen

Dank automatisiertem Unit Testing kann man vor einem Deployment sicher gehen, dass auch alle Tests glattlaufen und nichts übersehen worden ist.

Automatisierung im Deployment

Auch beim letzten Schritt lässt sich Automation verwenden. Den Standard setzt hier Capistrano (ursprünglich für Ruby on Rails entwickelt, daher in Ruby), nach dessen Schema auch für andere Sprachen alternative oder systemspezifische Adaptionen umgesetzt wurden. So bietet Capifony eine Version extra für Symfony, während Shipit eine Configuration in JavaScript anstelle von Ruby bietet. Doch egal welche Sprache, alle führen im Großen und Ganzen dieselben Tätigkeiten durch:

Deployment auf dem Server

Die Tools verbinden sich mit dem Server und kopieren die Projektdateien, meist über ein angegebenes GIT-Repository, ob direkt über ssh oder über einen Service wie Codeship, der noch ein letztes Mal alle Tests durchläuft und das Produkt überprüft.

Versionierung

Ein neuer Deploy wird versioniert und in einem eigenen Ordner gespeichert. Man kann natürlich auch Dateien, die sich zwischen den Deploys nicht ändern sollen (Shared Files wie ein Uploadfolder oder Config Files), definieren. Der Rest wird über einen „sym-link“ als „current“ verbunden. So kann man quasi ohne Wartezeit einen neuen Deploy livestellen, da nur der Current-Folder neu verbunden werden muss. Auch kann man jederzeit zu einem älteren Deploy zurückgehen.

Fazit

Manchmal sind es die kleinen Dinge, die das Gesamte so viel einfacher machen. Die Kombination dieser kleinen Automatisierungshelfer kann gemeinsam nicht nur Prozesse vereinfachen oder vereinheitlichen, sondern trägt auch zur Qualität bei und hilft, Fehler zu vermeiden.