Grunt und SVN-Hooks

Nachdem sich Continuous Integration und agile Entwicklung durchgesetzt haben, ist praktisch ständig ein Release. Da will natürlich niemand mehr den ganzen Prozess händisch erledigen. In diesem Artikel soll es somit um die Automatisierung verschiedener Aufgaben mit Hilfe von SVN-Hooks und Grunt gehen.


Bevor wir loslegen, erkläre ich noch kurz die Begriffe, die wir hier verwenden werden.

Grunt ist ein sogenannter Task-Runner, der mit JavaScript konfiguriert wird. Natürlich gibt es andere (GulpBroccoli), die alle nach ähnlichen Prinzipien arbeiten.

SVN (Subversion) ist eine Versionskontrolle, die vor 10 Jahren cool war 😉 Natürlich gibt es auch hier andere (Git, Mercurial), die ebenfalls das Konzept der Hooks unterstützen.

Ein Hook ist ein kleines Programm, dass sich an einem bestimmten Punkt im normalen Ablauf einhängt.


Ablauf eines SVN Commits

  • Hook start-commit
  • SVN sammelt die Daten die committed werden sollen
  • Hook pre-commit
  • SVN erstellt eine neue Revision und schickt die Daten an den Server
  • Hook post-commit

Aus obigem Ablauf folgt, dass wir in start-commit und pre-commit den ganzen Prozess noch abbrechen können, bevor irgendetwas passiert ist.

In start-commit ist es außerdem möglich noch Dateien zu erstellen oder zu ändern, die noch mit in den Commit einfließen. Diesen Umstand werden wir im Folgenden nutzen.


Vorbereitung

Wir legen also in den SVN-Einstellungen des Projektes einen Hook für start-commit an. Da wir einen Task-Runner verwenden wollen, ist das Skript sehr einfach:

Das war’s schon. Die Datei speichern wir als start-hook-grunt.bat und machen sie SVN bekannt. Hooks werden automatisch in der Working Copy ausgeführt.

Was wir dort benötigen ist ein Gruntfile.js in dem wir die gewünschten Tasks definieren.


Gruntfile

Zu den häufigsten Aufgaben in der Webentwicklung zählen Kombination und Kompression der CSS- und JavaScript-Dateien. Grunt bietet dazu entsprechende Pakete. Im Gruntfile müssen sie konfiguriert und als Task registriert werden.

Das „Drumrum“

Hier sehen wir zunächst was jedes Gruntfile benötigt – quasi das Skelett.

JavaScript-Dateien komprimieren

Um die JavaScript-Dateien des Projektes zu komprimieren benötigen wir folgenden Abschnitt:

Anschließend haben wir im Unterverzeichnis js/min Kopien der JavaScript-Dateien in ihrer komprimierten Version. Diese werden automatisch in den Commit übernommen und somit auch auf dem Server ausgespielt.

Dateien zusammen führen

Es ist in dem meisten Fällen ratsam, die Dateien nicht nur zu verkleinern, sondern auch in einer einzigen Datei zu vereinen. Dazu definieren wir einen weiteren Task.

Danach haben wir unseren gesamten JavaScript-Code in einer Datei namens header.js. Diese binden wir auf den Produktiv-Servern des Projekts als einzige ein. Der Benutzer profitiert von schnelleren Ladezeiten und wir müssen uns nicht darum kümmern.

Stylesheet komprimieren

Das gleiche wie bei JavaScript können wir auch für Stylesheets erledigen lassen.

Selbes Spiel wie beim JavaScript, auf den Produktiv-Servern werden nur die verkleinerten Varianten ausgespielt.

Den Browsercache des Anwenders informieren

Da wir immer den gleichen Namen für unsere Skripte verwenden, wird der Browser diese cachen. Das wollen wir allerdings nur so lange, bis wir eine Änderung vornehmen. Auch hier kann uns Grunt helfen.

Hier können wir gut erkennen, dass Gruntfile.js nicht nur so aussieht wie JavaScript, sondern tatsächlich auch so interpretiert wird. Was hier passiert ist, dass eine Datei namens config_version.php im Projektverzeichnis erstellt/überschrieben wird. Sie enthält dann beispielsweise:

Diese definiert eine Konstante mit dem aktuellen Zeitstempel und kann dann zum Beispiel so verwendet werden:


Vollständiges Gruntfile