Bei Anwendungen die nativ auf einem Betriebssystem vom Benutzer heruntergeladen und installiert werden, ist es klar, dass eine Versionierung notwendig ist, um den Nutzern anzeigen zu können, welche Software Version sie aktuell installiert haben und welche zur Verfügung steht.
Wie ist das bei einer Web-App?
Generell muss den Usern einer Web-App nicht die Version mitgeteilt werden, da sie die Anwendung nicht installieren brauchen und diese einfach wie gehabt über den Browser öffnen können.
Wem dient die Versionierung?
Letztlich dient die Version hauptsächlich den Entwicklern und Administratoren einer Anwendung welche Version tatsächlich auch veröffentlicht wurde, wenn während des Deployments eines Service aufgrund von Ausführungsproblemen ggf. auf den alten Stand zurück gerollt oder gar nicht ausgeführt wurde oder die Anwendung Fehler enthält, die behoben werden müssen.
Zusätzlich hilft es dem Product Owner (Produktmanager) bestimmte Release- (bzw. Produkt-) Stände zu planen und die neuen Features dem Endkunden zu kommunizieren.
Wobei unterstützt die Versionierung?
Die Versionierung hilft vor allem Entwicklern. Aber auch dem Product Owner oder der Marketingabteilung bei der Kommunikation von neuen Features.
Insbesondere unterstützt die Versionierung:
- Bei Kompatibilitätsproblemen mit Drittanbieter Software
- Bei fehlerhaften oder nicht ausgeführten Deployments
- Kommunikation von neuen Features
- Rollback-Möglichkeit auf eine frühere Version
- Der Testbarkeit einer bestimmten Version
Wie sollte die Versionierung stattfinden?
Die Versionsnummer sollte einem einheitlichen Schema entsprechen.
Etabliert hat sich dabei die Semantische Versionierung mit [Major].[Minor].[Patch], welche die Kompatibilität und die Art der Änderung (Bugfix / Feature) kennzeichnet.
Dabei sollte nach Möglichkeit natürlich immer die Abwärtskompatibilität gewährleistet werden.
Damit nicht bei jedem Ausrollen eines Bugfixes, die kommunizierte Release Version angepasst werden muss, macht es Sinn die ersten beiden Teile der Version, also [Major].[Minor] für die Release (bzw. Produkt) Version und das letzte Versionsfragment [.Patch] für neue Deployments zu nutzen, welche automatisiert über die Build oder Release Pipeline auf Basis der BuildNummer oder des Commits vergeben werden können.
So kann sichergestellt werden, das über das letzte Versionsfragement, Entwickler wissen, welche Änderungen (bzw. welcher Repository Commit) auf dem Zielsystem veröffentlicht wurde.
Unterscheidung nach Ausführungsumgebung
Bei der Versionierung muss zwischen den einzelnen Ausführungsumgebungen welche für die Anwendung geschaffen wurden, unterschieden werden.
Klassischerweise sind das Development (DEV), Staging (TEST) und Produktion (PROD).
Development: Auf dem DEV System werden üblicherweise über die Pipeline die neuesten Stände aller Services deployt, damit diese kontinuierlich gemeinsam ausgeführt und deren Funktionsfähigkeit rasch gewährleistet werden kann. Eine Versionierung ist hier nicht notwendig, da es klar ist, dass der neueste Stand aller Services verwendet wird.
Staging (Test): Das Test System dient vor allem, wie der Name bereits verlauten lässt, dem Testen eines neues Releases. Es enthält vollständig entwickelte Features welche von einem Tester (Testteam) getestet und von dem Product Owner oder dem Endkunden zur Abnahme bereitstehen. Für das Deployment auf Staging wurde vorzugsweise eine neue Versionsnummer inkl. den zu entwickelten Features kommuniziert. Die einzelnen Services werden zusammen mit der neuen Release Versionsnummer und einer fortlaufenden Buildnummer der einzelnen Services auf dem Zielsystem veröffentlicht:
[ReleaseNummer].[BuildNummer]
Beispiel:
UI: [1.1].[20251102735]
Web-API: [1.1].[20251202920]
Calc-Engine-Service: [1.1].[20251102735]
Produktion: Auf dem Produktionssystem stehen die neuen Releases dem Kunden zur Verfügung, welche vorher auf Staging getestet und vom Product Owner oder dem Kunden abgenommen wurden. Das Versionierungsschema erfolgt hier dem gleichen Schema (ReleaseVersion.BuildVersion] wie unter Staging.
Bereitstellen von Hotfixes
Soll nach einem Release ein Hotfix eines Services ausgespielt werden, kann dieses einzeln unter der gleichen Release Nummer mit einem Präfix des Hotfixes versehen werden. So bleibt die Release Nummer beständig und die Änderungsversion des Hotfixes ersichtlich.
Die Hotfix Version kann, wie auch bei den anderen Versionierungen, aus der Release Version und der Build Nummer der Pipeline bestehen.
Setzen der Versionsnummer
Über die Build Pipeline der Assembly in welcher die Anwendung gebaut wird, kann die Versionsnummer der Assembly gesetzt werden.
Hierzu gibt es verschiedene Möglichkeiten:
- Eintragen der Versionsnummer in der Projektdatei (.csproj)
- AssemblyInfo.cs bearbeiten
- Verwenden von Pipeline Variablen
- Verwenden von GitTools und Setzen von Tags
Auch wenn die Versionierung mit allen beschriebenen Punkten funktioniert, empfinde ich die ersten Beiden eher als unpraktikabel. Da in jedem Projekt die Versionsangaben einzeln gepflegt werden müssen
Empfehlen kann ich die Verwendung von GitTools und Tagging für die Release Version, in Kombination mit der Verwendung der eindeutigen BuildNummer der Pipeline $(Build.BuildId) für die Patch bzw. Build Version
Versionierung einer klassischen Client-/Server Web-Anwendung
Handelt es sich bei der Web-App um eine klassische Client-/Server Anwendung wie einer einfachen MVC App oder einer Angular UI mit einer .NET Web API dann kann die Versionierung einfach innerhalb der Web API erfolgen und der UI über einen Endpoint mitgeteilt werden.
Versionierung bei einer verteilten Anwendung (Architektur)
Beim Einsatz einer verteilten Architektur oder gar einer Microservice Architektur wird die Versionierung der Anwendung schon etwas schwieriger. Da jeder einzelne Service eine eigene Versionsnummer erhält und diese sich durchaus unterscheiden können.
Um auf das Pflegen von Versionsständen einzelner Services zu einem bestehenden Release verzichten zu können, macht es bei einer verteilten Anwendung Sinn, diese als gemeinsames DeploymentSet unter einer gemeinsamen Release Version zu veröffentlichen, unabhängig davon ob es Änderungen an dem Service gab oder nicht.
Dazu gehören inklusive der UI alle Assemblies des Releases.
Fazit
Die Versionierung einer Web-App ist aus organisatorischen Gründen sinnvoll und mit geringen Aufwand bewerkstelligt.
