.NET Revision Tool

Schreibt die aktuelle VCS-Revision eines Arbeitsverzeichnisses in einem anpassbaren Format während dem Build in ein .NET-Assembly oder zeigt sie nur an.

Diese Anwendung wurde durch .NET Revision Task für MSBuild ersetzt. Das ist als NuGet-Paket verfügbar und in MSBuild integriert, wodurch es robuster und mächtiger ist. Es unterstützt auch .NET-Core/Standard-Projekte.

.NET Revision Tool ist ein kleines Entwicklerwerkzeug, das Informationen zur aktuellen Git- oder SVN-Revision eines Arbeitsverzeichnisses ausgibt. Es kann diese Angaben auch direkt in deinen Anwendungsquelltext schreiben, so dass sie gleich mitkompiliert werden. Das funktioniert für .NET-Projektmappen in C# und VB.NET, die die übliche Visual-Studio-Projektstruktur verwenden.

Aktuell werden folgende VCS (version control system, Versionsverwaltungssystem) unterstützt:

  • Git
  • Subversion

Weitere können einfach im Code hinzugefügt werden.

Warum?

Jede etwas größere Anwendung hat eine Versionsnummer, die der Benutzer in einer Form von Über/Info-Dialogfenster abrufen kann. Wenn du häufig neue Versionen veröffentlichst und keine semantischen Versionsnummern (Übersetzung) wie Major.Minor.Patch verwalten möchtest (wie für .NET Revision Tool selbst), könntest du einfach die Git-/SVN-Revisions-ID oder den Commit-Zeitpunkt als Versionsnummer für dein Programm verwenden.

Durch das automatisierte Eintragen dieser Revisions-ID in den Anwendungsquelltext vermeidest du es, das einmal zu vergessen. Außerdem harmoniert die Keyword-Ersetzungsfunktion von Git/SVN selbst nicht besonders gut mit C#-/VB.NET-Quelltext, um eine lesbare Versionsangabe für das Assembly zu erzeugen. .NET Revision Tool ist für diesen Fall optimiert und auf Sonderwünsche anpassbar.

Wie wird es benutzt?

Versionsformat und Quelltext

Zunächst musst du dich für ein mögliches Versionierungsschema entscheiden. Es gibt vielfältige Möglichkeiten, die auch davon abhängig sind, welches VCS verwendet wird. Das Format der Versionsnummer wird als Zeichenfolge mit Platzhaltern angegeben. Zunächst möchte ich drei Verfahren vorstellen.

  • Für SVN-Repositorys bietet sich die fortlaufende Revisionsnummer an. Die kann als eine Komponente in der Versionsnummer verwendet werden, z. B. 1.0.{revnum} oder 4.{revnum}. Wenn die Zahl zu groß wird, kann sie mit einem Offset angepasst werden.
  • In Git-Repositorys gibt es diese stabile fortlaufende Nummer nicht immer*. Stattdessen lässt sich der Commit-Zeitpunkt in eine Versionsangabe kodieren. (Dabei sollten nur Releases aus einem Branch in einem Repository veröffentlicht werden.) Damit die Zahlen nicht zu groß werden, muss ein Basisjahr angegeben werden, bei dem die Zählung beginnt. Im Dezimalschema werden zwei Nummern verwendet: Die Zahl der Tage seit dem Basisjahr, und die Zahl der Zeitintervalle an diesem Tag (hier Viertelstunden). 1.{dmin:2015} etwa führt nach drei Jahren zu Versionsnummern wie 1.2345.67. Die erste Nummer (1) kann später erhöht werden, um das Basisjahr oder das Schema zu wechseln.
  • Das einfache Format {c:ymd.} verwendet direkt das vollständige Datum eines Commits (Jahr.Monat.Tag), z. B. 2015.01.27.

*) Betrachtet man nur einen einzigen Branch für Releases, z. B. den master-Branch, und integriert alle Änderungen aus einem anderen Branch in diesen hinein (nicht umgekehrt!), dann kann man auch die Commits in diesem Branch durchnummerieren. Diese Zahl wird von .NET Revision Tool immer im Platzhalter {revnum} bereitgestellt. Sie sollte aber nur unter diesen Bedingungen verwendet werden! Weitere Informationen werden im Artikel Maintaining a consistent linear history for git log --first-parent beschrieben (dazu passender Workflow).

Diese Schemata erzeugen normale nummerische Versionsnummern. Die können für die Attribute Assembly­Version und Assembly­File­Version verwendet werden. (Bei StackOverflow werden die Unterschiede der einzelnen Versionsattribute genau erklärt.) .NET Revision Tool trägt die Versionsnummer nur in die Attribute ein, die auch im Quelltext vorkommen, und fügt keine Attribute hinzu!

Um weitere Angaben wie bspw. den Commit-Hash in der Version aufzunehmen, wird das Assembly­Informational­Version-Attribut benötigt, denn nur das kann beliebigen Freitext aufnehmen. In den Windows-Dateieigenschaften erscheint die Angabe separat unter „Produktversion“. Hier gilt die Konvention, dass dieses Format mit einer einfachen Versionsnummer beginnen sollte, auf die ein anderes Zeichen als Ziffern oder Punkt folgt. Dadurch lässt sich die lange Versionsangabe automatisch gekürzt auch für die einfachen Attribute nutzen (abschaltbar). Beispiel: 1.{dmin:2015}_{chash:6} (Zeitbasierte Versionsnummer, gefolgt von 6-stelligem Hash)

Wenn du nur ein kurzes Format nutzt, kannst du es entweder beim Aufruf von .NET Revision Tool mit dem Parameter /format angeben oder im Quelltext beim Assembly­Informational­Version-Attribut festlegen. Hier steht der Platzhalter-String dann direkt im Quelltext und geht nicht irgendwo im Buildprozess unter. Ein langes Format muss immer in diesem Attribut angegeben werden, da es zur Ersetzung immer von dort gelesen wird. Öffne dazu die Datei AssemblyInfo.cs oder .vb im Ordner „Properties“ bzw. „My Project“. Such nach dem Assembly­Informational­Version-Attribut oder füg es hinzu, falls es noch nicht da ist. Hier ein paar Beispiele:

// Einfache Versionsattribute, Inhalt egal
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

// Freitext-Attribut enthält den Format-String, hier SVN
[assembly: AssemblyInformationalVersion("1.0.{revnum} {c:ymd-}")]

// Alternativ Git-Zeitcode und Commit-Hash (im Screenshot)
[assembly: AssemblyInformationalVersion("1.{dmin:2015}_{chash:6}{!}")]

Das wird dann von .NET Revision Tool für den Compiler z. B. durch Folgendes ersetzt:

// SVN
[assembly: AssemblyVersion("1.0.627")]
[assembly: AssemblyFileVersion("1.0.627")]
[assembly: AssemblyInformationalVersion("1.0.627 2015-01-27")]

// Git
[assembly: AssemblyVersion("1.39.50")]
[assembly: AssemblyFileVersion("1.39.50")]
[assembly: AssemblyInformationalVersion("1.39.50_a34fd2")]

Buildvorgang

Lad dann das Programm herunter und kopier es in das Verzeichnis deiner Visual-Studio-Projektmappe. Ich stecke solche kleinen Helferlein gerne in ein Unterverzeichnis „_scripts\bin“ (siehe Screenshot unten), gemeinsam mit dem PowerShell-Build-Framework (das dieses Programm bereits beinhaltet). Du solltest die Programmdatei ins Repository aufnehmen, um es portabel zu halten. Falls erforderlich stellt ein Eintrag wie der folgende in der .gitignore-Datei sicher, dass die Datei nicht ignoriert wird:

!_scripts/bin/

Öffne dann die Projekteigenschaften und geh auf die Seite „Buildereignisse“ (siehe Screenshot unten). Gib die folgende Befehlszeile für das Präbuildereignis ein:

"$(SolutionDir)_scripts\bin\NetRevisionTool.exe" /patch "$(ProjectDir)"

Wenn du ein anderes Verzeichnis verwendet hast, musst du den Pfad anpassen. Dann noch die Befehlszeile für das Postbuildereignis:

"$(SolutionDir)_scripts\bin\NetRevisionTool.exe" /restore "$(ProjectDir)"

Wichtig: Das Postbuildereignis muss immer ausgeführt werden, um sicherzustellen, dass die veränderte Quelltextdatei immer richtig wiederhergestellt wird, auch wenn sich das Projekt gerade nicht erstellen lässt.

Das PowerShell-Build-Framework (psbuild) nutzt .NET Revision Tool immer im Multi-Projekt-Modus, bei dem mit einem Aufruf alle Projekte in einer Projektmappe verarbeitet werden. Das geht bei vielen (> 20) Projekten deutlich schneller, als es für jedes Projekt separat aufzurufen. psbuild und NetRevisionRool koordinieren sich in diesem Fall automatisch. Wird .NET Revision Tool nur im Rahmen von psbuild benötigt, z. B. auf einem Buildserver, kann es in den Projektkonfigurationen auch weggelassen werden.

Weitere Dokumentation

Die Programmausgabe für den Parameter /help verrät dir alle Details (nur auf englisch). Es gibt noch weitere Platzhalter, um kompakte, sortierbare Versions-IDs zu erzeugen, die Option, ein unverändertes Arbeitsverzeichnis zu erfordern und andere nützliche Dinge.

Wie tut es das, was es tut?

.NET Revision Tool wird im Präbuildereignis mit dem Parameter /patch aufgerufen. Das ist jedes Mal beim Erstellen des Projekts, bevor der Compiler loslegt. Es findet deine AssemblyInfo.cs- oder .vb-Datei und ersetzt alle Platzhalter in den Versionsattributen mit den aktuellen Revisionsdaten. Visual Studio verwendet diese Datei dann zum Kompilieren. Zum Schluss wird mit dem Parameter /restore die Datei aus der vorher angelegten Sicherungskopie wiederhergestellt, damit du (und das VCS) keine Veränderungen siehst.

Kompatibilität: .NET Ab Version 4.0 Windows 10 Windows 8 Windows 7 Windows XP Mono 64 bit

Dieses Tool basiert auf den beiden älteren Programmen GitRevisionTool und SvnRevisionTool und vereint und erweitert deren Funktionsumfang.

Bilder

Image
Tools im bin-Verzeichnis
Image
Build-Ereignisse im Projekt
Image
Versionsangabe in den Dateieigenschaften

Download

NetRevisionTool.exe64 KiBProgrammdatei, Version 2.5.1

master.zipAktueller Quelltext direkt von GitHub

Es gibt ein öffentliches Git-Repository von .NET Revision Tool bei GitHub.

Funktioniert es nicht?

Wichtig: Damit das so funktioniert, darf die AssemblyInfo-Datei während des Erstellens nicht im Visual-Studio-Editor geöffnet sein (nur bis Visual Studio 2013, ab 2015 ist das egal). Ansonsten werden die Änderungen, die .NET Revision Tool in diese Datei schreibt, vom Compiler ignoriert. Wenn du die Versionsangabe änderst und Test-Builds erstellst, musst du diese Datei also immer wieder schließen.

Für Git: .NET Revision Tool erfordert eine Installation von Git für Windows. Es sucht nach bin\git.exe in Verzeichnissen, die es im Uninstaller-Eintrag findet, oder durchsucht dein Programme-Verzeichnis. Wenn es Git nicht findet, kann es dir auch nicht helfen. Es sollte ausreichen, einfach msysGit mit den Standardeinstellungen zu installieren. GitHub hat eine nette Dokumentation darüber.

Für Subversion: .NET Revision Tool erfordert ein installiertes SVN-Programm. Das wird an verschiedenen Stellen automatisch gesucht, darunter die Installationsverzeichnisse des Apache SVN-Clients sowie TortoiseSVN (mit aktivierter CLI-Option).

.NET Revision Tool kann nur C#- und VB.NET-Projektdateien verarbeiten. Für andere Projekttypen wird es nur die Revisionsinformationen ausgeben (dafür aber so formatiert, wie du es willst). Du brauchst vielleicht ein eigenes CMD-Skript, um Dateien zu verändern. Setz die Formatangabe auf etwas wie SET revid={chash:8}, leite die Ausgabe in eine temporäre Batchdatei um (die muss außerhalb des Arbeitsverzeichnisses liegen, oder die Arbeitskopie wird immer als verändert gekennzeichnet!), ruf diese Datei auf und bearbeite deine Dateien unter Verwendung der Umgebungsvariable %revid% mit sed oder einem anderen Tool. Du solltest diese Datei ggf. entsprechend sichern und wiederherstellen.

Dies ist selbst eine .NET-Anwendung. Sie ist für das .NET-Framework 4.0 erstellt, du solltest also keine Probleme unter Windows 7 (mit automatischen Updates) oder neuer haben. Wenn du Visual Studio 2010 oder neuer verwendest, hast du das .NET-Framework sowieso bereits installiert.

Änderungen

2018Feb3
Version 2.6.3
  • Fixed #20: ConsoleHelper Unicode detection throws an exception; Some code cleanup
2017Apr6
Version 2.6.2
  • Updated environment variables for GitLab CI runner v9.0
2017Jan4
Version 2.6.1
  • Finding git.exe from SmartGit local installations
2016Dez2
Version 2.6
  • Finding git.exe from SourceTree and Tower local installations
  • Added {mname} placeholder resolving to the machine name
  • Added /echo option to display the resolved informational version string
2016Aug10
Version 2.5.2
  • Detect GitLab CI runner and try to determine branch name from environment variables if necessary
2016Jun14
Version 2.5.1
  • Fixed console redirection detection for "nul"
2016Mai16
Version 2.5
  • Added /removetagv option to make version number tag names useful
  • Added copyright year resolving, opt-out with /nocopyright option
2015Dez21
Version 2.4
  • Added Git tag support
2015Dez1
Version 2.3.3
  • Optimised detection of Git for Windows 2.x
2015Jul28
Version 2.3.2
  • Added global exception handler
  • Retrying to write file on IOException (observed if VS2015 is still open with the project)
2015Apr21
Version 2.3.1
  • Fix: All Git directories are considered modified
2015Apr14
Version 2.3
  • Revision number generation for Git repositories using --first-parent
  • Removed unused shared code to reduce executable file size
2015Apr2
Version 2.2
  • /revonly can be used with a revision format that produces an integer number
2015Mrz11
Version 2.1
  • New revision data fields (author time/name/mail, committer name/mail, repo URL, branch)
  • Truncated version number check
  • New hours time scheme
  • Added /root and /rejectmix parameters
2015Feb9
Version 2.0.1
  • Fixes for relative paths and SVN
2015Feb8
Version 2.0
  • First release based on GitRevisionTool and SvnRevisionTool 1.8

Lizenz und Nutzungsbedingungen

Diese Software wird unter den Bedingungen der GNU-GPL-Lizenz Version 3 veröffentlicht. Die genauen Lizenzbedingungen befinden sich im Download oder auf der GNU-Website.

Statistische Daten

  • Erstellt am 2015-02-08, aktualisiert am 2018-02-03.
  • Ca. 2 160 Codezeilen, geschätzte Ent­wick­lungs­kos­ten: 2 200 - 8 600 €