{"id":978,"date":"2013-10-31T06:21:00","date_gmt":"2013-10-31T06:21:00","guid":{"rendered":"http:\/\/abramowitsch.de\/blog\/?p=978"},"modified":"2013-10-31T06:21:48","modified_gmt":"2013-10-31T06:21:48","slug":"build-patterns-build-script-injection","status":"publish","type":"post","link":"https:\/\/abramowitsch.de\/blog\/?p=978","title":{"rendered":"Build Patterns: Build Script Injection"},"content":{"rendered":"<h2>Einf\u00fchrung<br \/><\/h2>\n<p>Vor einiger Zeit habe ich auf Twitter gelesen, dass <a href=\"http:\/\/osherove.com\/\">Roy Osherove<\/a> sich mit <a href=\"http:\/\/osherove.com\/blog\/2012\/12\/30\/build-patterns-script-injection.html\">Build Patterns<\/a> auseinander setzt und ein entsprechendes Buch (<a href=\"https:\/\/leanpub.com\/build\">&#8222;Beautiful Builds&#8220;<\/a>) dar\u00fcber schreiben will. Da es bei <a href=\"http:\/\/www.leanpub.com\">LeanPub<\/a> ver\u00f6ffentlich wird, kann man es bereits vor der Fertigstellung kaufen und reinlesen:<\/p>\n<p>Im Rahmen der Konferenz &#8222;<a href=\"http:\/\/www.continuouslifecycle.de\/\">Continuous Lifecycle 2013<\/a>&#8220; am 12.11.2013 in Karlsruhe werde ich ebenfalls einen Kurz-Vortrag zu diesem Thema halten.<\/p>\n<p>Zur Vertiefung m\u00f6chte ich an dieser Stelle einige Patterns mit Beispielen vorstellen. Den Anfang macht das Pattern &#8222;Build Script Injection&#8220;.<\/p>\n<h2>Problembeschreibung <br \/><\/h2>\n<p>Roy Osherove hat in seinem Blogbeitrag <a href=\"http:\/\/osherove.com\/blog\/2012\/12\/30\/build-patterns-script-injection.html\">&#8222;Build Patterns: Script Injection&#8220;<\/a> bereits das Problem beschrieben:<\/p>\n<p>Man hat einen <a href=\"http:\/\/de.wikipedia.org\/wiki\/Kontinuierliche_Integration\">Continuous Integration<\/a> Prozess etabliert, Quellcode wird aus der Versionsverwaltung ausgecheckt, gebaut und Tests ausgef\u00fchrt. \u00dcber die Zeit und Versionen haben sich jedoch die Ordnerstruktur und\/oder Build-Schritte ge\u00e4ndert:<\/p>\n<div>\n<table style=\"border-collapse: collapse\" border=\"0\">\n<colgroup>\n<col style=\"width: 392px\">\n<col style=\"width: 392px\"><\/colgroup>\n<tbody valign=\"top\">\n<tr>\n<td style=\"padding-left: 9px; padding-right: 9px\">\n<p><strong>Projektstruktur zu Zeitpunkt A<br \/>(Produktversion 1.0)<br \/><\/strong><\/p>\n<p><img decoding=\"async\" alt=\"\" src=\"http:\/\/abramowitsch.de\/blog\/wp-content\/uploads\/2013\/10\/101613_0729_BuildPatter1.png\"><\/p>\n<\/td>\n<td style=\"padding-left: 9px; padding-right: 9px\">\n<p><strong>Projektstruktur zu Zeitpunkt B<br \/><\/strong><\/p>\n<p><strong>(Produktversion 2.0)<br \/><\/strong><\/p>\n<p><img decoding=\"async\" alt=\"\" src=\"http:\/\/abramowitsch.de\/blog\/wp-content\/uploads\/2013\/10\/101613_0729_BuildPatter2.png\"><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>Soweit so gut. Aktuelle Versionen k\u00f6nnen jederzeit gebaut werden. Doch was ist, wenn pl\u00f6tzlich ein Patch f\u00fcr Produktversion 1.0 gebaut werden muss? Die Build-Konfiguration greift dann auf Ordner zu, die es fr\u00fcher gar nicht gab und der Build funktioniert nicht mehr.<\/p>\n<h2>L\u00f6sungsansatz<br \/><\/h2>\n<p>Um das Problem l\u00f6sen zu k\u00f6nnen, 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\u00e4ngig modifiziert werden kann.<\/p>\n<h3>Ausgangssituation<br \/><\/h3>\n<p>Zu Beginn enth\u00e4lt die Build-Konfiguration alle Logik \u00fcber den Buildablauf und Zugriff auf die Ordner-Strukturen:<\/p>\n<p><img decoding=\"async\" alt=\"\" src=\"http:\/\/abramowitsch.de\/blog\/wp-content\/uploads\/2013\/10\/101613_0729_BuildPatter3.png\"><\/p>\n<p>\u00c4ndert sich die Verzeichnisstruktur oder ein Build-Step, dann ist die Build-Konfiguration nicht mehr &#8222;r\u00fcckw\u00e4rtskompatibel&#8220;. M\u00f6chte man \u00e4ltere Versionen wieder bauen, muss die gesamte Build-Konfiguration entweder angepasst oder eine Kopie pro Version angelegt werden. Das f\u00fchrt jedoch auf Dauer zu einer sehr gro\u00dfen Varianz und wird schlecht wartbar sein.<\/p>\n<h3>Zielsituation<br \/><\/h3>\n<p>Die Build-Konfiguration wird aufgesplittet und einen dynamischen und statischen Anteil:<\/p>\n<p><img decoding=\"async\" alt=\"\" src=\"http:\/\/abramowitsch.de\/blog\/wp-content\/uploads\/2013\/10\/101613_0729_BuildPatter4.png\"><\/p>\n<p>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\u00e4lt die gesamte Build-Logik als auch Informationen \u00fcber 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\u00f6nnen Abl\u00e4ufe beliebig ausgetauscht werden, ohne dass der Build kaputt geht.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Einf\u00fchrung Vor einiger Zeit habe ich auf Twitter gelesen, dass Roy Osherove sich mit Build Patterns auseinander setzt und ein entsprechendes Buch (&#8222;Beautiful Builds&#8220;) dar\u00fcber schreiben will. Da es bei LeanPub ver\u00f6ffentlich wird, kann man es bereits vor der Fertigstellung kaufen und reinlesen: Im Rahmen der Konferenz &#8222;Continuous Lifecycle 2013&#8220; am 12.11.2013 in Karlsruhe werde [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[116],"tags":[121,118,120,119],"class_list":["post-978","post","type-post","status-publish","format-standard","hentry","category-build-patterns","tag-build","tag-build-injection","tag-build-konfiguration","tag-build-script"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p3Ug90-fM","_links":{"self":[{"href":"https:\/\/abramowitsch.de\/blog\/index.php?rest_route=\/wp\/v2\/posts\/978","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/abramowitsch.de\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/abramowitsch.de\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/abramowitsch.de\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/abramowitsch.de\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=978"}],"version-history":[{"count":3,"href":"https:\/\/abramowitsch.de\/blog\/index.php?rest_route=\/wp\/v2\/posts\/978\/revisions"}],"predecessor-version":[{"id":1002,"href":"https:\/\/abramowitsch.de\/blog\/index.php?rest_route=\/wp\/v2\/posts\/978\/revisions\/1002"}],"wp:attachment":[{"href":"https:\/\/abramowitsch.de\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=978"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/abramowitsch.de\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=978"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/abramowitsch.de\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=978"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}