Sätze wie
- „Der gesamte Vorgang wird automatisch ausgelöst durch Einchecken in die Versionsverwaltung.“[1]
- „<x> is an open-source continuous integration server with...“ [2]
- „[…] Kontinuierliche Integration steigert die Effizienz durch Automatisierung […]“[3]
zeigen mir immer wieder die immense Macht der semantischen Diffusion.
Es gibt keine CI-Server – selbst Szenarien, in denen der Server am Ende eines fehlerhaften Buildlaufes das gelieferte Changeset zurückweist, stellen nicht sicher, dass die Teilergebnisse wirklich integriert werden.
Was oft als CI-Server beschrieben wird, sind Build-Server, integriert wird hier nichts. Buildserver gibt es durchaus auch in meinem Vokabular, kontinuierliche Integration aber, so wie ich sie das erste Mal 2001 bei Kent Beck beschrieben gesehen habe, ist eine Arbeitsweise, bei der alle Beteiligten sicherstellen, dass ihre letzten fertiggestellten Arbeitsergebnisse in das Gesamtprodukt integriert sind. Dorthin zu kommen, gibt es viele Wege, aber keiner davon ist durch einen Server zu automatisieren.
Auf abstraktem Niveau ist das Vorgehen immer wieder das Gleiche:
- An den eigenen Arbeitsergebnissen arbeiten
- Sicherstellen, dass die aktuelle Version des Produktes funktioniert
- Meine eigenen Arbeitsergebnisse integrieren
- Sicherstellen, dass die jetzt aktuelle Version des Produktes funktioniert
- wenn sie nicht funktioniert, wieder einen funktionierenden Stand herstellen
- Wenn dies ebenfalls nicht funktioniert, dann das ganze Team zusammenrufen, um wieder einen funktionierenden Stand herzustellen
- Die eigenen Arbeitsergebnisse modifizieren, bis berechtigter Grund zu der Annahme besteht, dass eine Integration jetzt erfolgreich sein kann
- Das Ganze so lange wiederholen, bis die eigenen Arbeitsergebnisse komplett in das Gesamtprodukt integriert sind, bevor neue Halbfertigteile produziert werden
In der Praxis gibt es sehr viele valide Ausprägungen dieses Vorgehens, die unter anderem auch die Nutzung von Buildservern umfassen können. Sie alle aber scheinen zunächst einen erheblichen Nachteil zu haben, der meiner Meinung nach Ursache dafür ist, dass so oft keine permanente Integration stattfindet, sondern statt dessen das fehlen der Integrationsarbeit hinter dem Feigenblatt des „Integrations-Servers“ versteckt wird.
Dieser Nachteil ist, dass in dieser Welt nicht mehrere „Änderungen“ zur gleichen Zeit integriert werden können. Und da die Integration nach diesem Modell ja erst abgeschlossen ist, wenn das System nachweislich funktioniert, steht und fällt die Umsetzbarkeit dieses Vorgehens mit der Zeit, die benötigt wird, um das Funktionieren des Gesamtsystems nachzuweisen.
An dieser Stelle sind zwei grundsätzlich unterschiedliche Herangehensweisen üblich. Eine Lösung für die Herausforderung kann sein, die Zeit zu minimieren, die benötigt wird, um das Funktionieren des Gesamtsystems nachzuweisen. Das ist der „harte” Weg, der zunächst deutlich schwieriger scheint und es erforderlich macht, sich mit allen Problemen auseinanderzusetzen, sobald sie auftauchen.
Eine andere – scheinbare – Lösung, dieser Herausforderung zu begegnen, ist die Entkopplung der Integration von der Weiterführung der Arbeiten. Hier haben dann automatisierte Integrationstests und die sogenannten „CI-Server” ihren großen Auftritt.
Das Vorgehen hier ist also:
- An den eigenen Arbeitsergebnissen arbeiten
- Die eigenen Arbeitsergebnisse zur Verifikation an den Integrationsserver abgeben (möglicherweise von mehreren Teams zur Zeit)
- An neuen eigenen Arbeitsergebnissen arbeiten
hier haben wir je nach Anzahl der Entwickler mehr oder weniger nicht-integrierten Code
- Falls (später) ein Fehler vom Server gemeldet wird, versuchen diesen zu beseitigen
Das ist natürlich viel einfacher, es gibt keine Schleifen, die man drehen muss, keine Synchronisation mit anderen Integrationswilligen, keine Wartezeiten während der Integration.
Das große Problem bei diesem Vorgehen ist nur, dass nicht verifizierte Teilfertigprodukte entstehen – um so mehr, je häufiger die Entwickler ihre Teilergebnisse an den Server überantworten.
Es gibt zwar schon geraume Zeit Ansätze dieses Thema auch technisch zu adressieren – z. B. mit gerrit und darauf aufsetzenden Workflows – aber hier dienen die Werkzeuge erfreulicherweise der Unterstützung der Menschen, und es wird nicht unterstellt, dass sie die Integration durchführen.
Eigentlich lässt sich ganz leicht feststellen, ob es in einer Umgebung eine permanente Integration gibt oder nicht – immer dann, wenn es fehlerhafte Builds gibt, scheint die Integration weder permanent noch kontinuierlich zu sein.
Schließlich ist in der „roten“ Zeit mindestens der für den Fehler verantwortliche Teil eben gerade nicht integriert. Und wenn die Build-Zeit lang genug ist, dann ist in der Zeit Neues entstanden, was ebenfalls nicht integriert ist. Und während die Fehler behoben werden steigt die Menge nicht integrierter Teilprodukte, wenn die anderen Projektmitglieder weiter arbeiten.
All dies passiert nicht, wenn tatsächlich nach dem oben beschriebenen Muster permanent integriert wird!
Wer also permanente Integration (continuous integration) will, muss sich meiner Ansicht nach auf Prozessebene damit auseinandersetzen und wir alle sollte Build-Server auch Build-Server nennen und den Begriff CI-Server meiden, solange diese keine wirkliche Integration betreiben können.
Bis zum nächsten Mal
Michael Mahlberg
Quellen aus der Einleitung:
Und gerade noch im Netz gefunden:
Bereits vor 2006 hat Jim Shore seine Einstellung zu Continuous Integration veröffentlich, und hatte insbesondere seine eigene Meinung zu CruiseControl (einem speziellen Build-Server)