Innovations-Nummer +49 (0)7304 / 803 0

Blog-n-Roll:
Wissen,
das rockt!

ALM

2016.01.31

Päckchen packen mit NuGet, TFS 2015 und Build vNext. Teil 4: Pakete debuggen
By admin / 31 January / ALM, Entwickler / 0 comm.

Funktionalität automatisiert für andere Anwendungen bereitstellen Anmerkung: Dies ist die für Visual Studio / TFS 2015 und Build vNext überarbeitete Version unseres Artikels auf entwickler.de. Es hat sich einiges getan: Das neue Buildsystem vereinfacht das zentrale Erstellen und Bereitstellen von NuGet-Paketen erheblich, und die NuGet-Integration in Visual Studio Team Services bietet einen Einfachen weg, eigene […]

Funktionalität automatisiert für andere Anwendungen bereitstellen Anmerkung: Dies ist die für Visual Studio / TFS 2015 und Build vNext überarbeitete Version unseres Artikels auf entwickler.de. Es hat sich einiges getan: Das neue Buildsystem vereinfacht das zentrale Erstellen und Bereitstellen von NuGet-Paketen erheblich, und die NuGet-Integration in Visual Studio Team Services bietet einen Einfachen weg, eigene Paket-Feeds in der Cloud zu hosten. Viel Spaß! Der Open Source-Paketmanager NuGet hat sich in der .NET-Welt zur Standardmethode einwickelt, um Funktionalität zwischen mehreren Projekten zu teilen oder öffentlich bereitzustellen – fast jeder Programmierer hat schon ein NuGet-Paket in sein Projekt eingebunden. Doch NuGet kann mehr: Es bietet die Möglichkeit, wichtige Teile des Entwicklungsprozesses innerhalb der eigenen Organisation weiter zu verbessern und zu automatisieren.

Blogserie


 

Lokal erstellte Pakete debuggen

Im den bisherigen Teilen dieser Artikelserie haben wir gesehen, wie NuGet-Paketes schnell und einfach konsumiert, erstellt und verteilt werden können. Wie steht es aber mit dem Debugging, wenn diese Pakete in andere Projekte eingebunden werden? Haben wir das Paket auf unserem eigenen Rechner erstellt, dann ist die Sache recht einfach, weil die aktuellen Sourcen zu dem Paket lokal vorliegen und da vermutlich genau diese Version auch in unser Paket verpackt wurde. In diesem Fall genügt es einfach, die .pdb-Datei mit ein das Projekt einzufügen. Damit diese Datei in unserem regulären Paket nicht mitverpackt wird, legen wir einfach eine zweite .nuspec-Datei an, welche das entsprechende File enthält. image Dann passen wir unseren Post Build Event an, der das Paket baut und in ein lokales Repository (hier unsere bereits bekanntes Share MyPackages) kopiert: nuget pack $(MSBuildProjectDirectory)HelloLib.Symbols.nuspec –OutputDirectory \tfs-2015-1\MyPackages  -Properties Configuration=Debug -version 9999.99.99.99 -Verbosity detailed Den bestehenden nuget pack Befehl haben wir noch etwas aufgebohrt: Anstatt in unser Projektverzeichnis kopieren wir das Paket auf das lokale Share. Wir geben anstatt der regulären .nuspec-Datei nun die Version an, welche das .pdb-File enthält – hier HelloLib.Symbols.nuspec. Weiterhin setzen wir den Parameter Verbosity auf detailed, um mehr Informationen zu erhalten, falls Probleme bei der Paketerstellung auftreten. Um zu zeigen, das dieses Paket lokal gebaut wurde, wird die Versionsnummer auf 9999.99.99.99 gesetzt – das hat weiterhin den Vorteil, das wir das Paket von unserem lokalen Share als Update installieren können. image Der lokale Build erstellt jetzt das HelloLib.Symbols Paket und kopiert es auf das lokale Share. image Jetzt können wir das Paket wie gehabt in die referenzierende Solution Hello World einbinden (entweder über Deinstallation / Installation oder eben über den Update-Reiter.) image Nur noch schnell noch einen Breakpoint setzen… image … und mit F5 die Ausführung starten. Sobald der Breakpoint erreicht wird … image … führt F11 direkt zum Sprung in den HelloLib Code.

Debugging von Paketen aus dem Team Build

Wird das Package allerdings von einem Kollegen oder mit einem TFS Build erstellt, funktioniert der oben beschriebene Weg nicht mehr. Hier haben wir ja als Nutzer des Packages die Sourcen des Packages nicht zwingend in der richtigen Version an der gleichen Stelle auf unserem Entwicklungs-Rechner. Wir kommen zwar gegebenenfalls über unser spezielles Debugging-Package an die .pdb-Datei, aber die Code-Dateien fehlen uns auf jeden Fall. Deshalb muss hier eine andere Lösung gefunden werden. Die ist glücklicherweise aber – Sie ahnen es – sehr einfach. Wir brauchen zunächst einen weiteren Netzwerk-Share auf den die Entwickler und der TFS Team Build Zugriff haben. Dann geben wir in unserer Build Definition im Step Index Sources & Publish Symbols diesen Pfad unter Path to Publish Symbols an. image Bei einem Build werden jetzt automatisch die Symboldateien auf dem angegeben Share veröffentlicht. Nun müssen wir in Visual Studio noch einige wichtige Einstellungen vornehmen. image Enable Just My Code wird deaktiviert, denn wir wollen ja auch “fremden Code” debuggen, und die Unterstützung für den Symbolserver wird mit Enable Source Server Support aktiviert. Schließlich zeigen wir Visual Studio noch, wo das Share mit den Symbol-Files zu finden ist: image Jetzt können wir auch auf einem fremden Rechner fröhlich eingebundene Pakete debuggen. Wie gehabt setzen wir einen Breakpoint … image … und springen mit F11 in die Funktion aus der Bibilothek HelloLib. image Das klappt auch prima, aber wir erhalten eine Sicherheitswarnung – denn jetzt versucht Visual Studio, die nicht vorhanden Sourcen, die wir offensichtlich aber sehen wollen, aus dem TFS zur Ansicht abzurufen und startet dazu das TFS-Kommandozeilen-Tool tf.exe view. Weil fremder Code potentiell immer ein Risiko darstellt, müssen wir das bestätigen, was wir aber gerne tun. Für die Zukunft können wir gleich auswählen, ob wir weiterhin solche Warnungen sehen wollen oder generell unser Vertrauen aussprechen. image Nach erfolgter Zustimmung lädt Visual Studio die Datei in den konfigurierten Ordner für den Symbol-Cache herunter und wir können wunderbar unseren Code aus dem Package debuggen, ohne dass wir uns selbst darum kümmern müssen, wie wir die passende Version der Source-.Dateien heruntergeladen bekommen. Schließlich passt ja nicht unbedingt die neueste Version aus der Versionsverwaltung genau zu unserem Paket. Der Symbol-Server kennt aber die Version in unserem Package und kann die passende Version der Code-Dateien vom TFS herunterladen. image Das Debugging kann kann nun im eingebundenen Paket HelloLib weitergehen. image Woher der Debugger sich die Informationen lädt kann man übrigens auch sehr schön im Fenster Modules (Debug / Windows / Modules) sehen. Übrigens: Mehr Infos zum Thema Source- und Symbol-Server finden sich in einem interessanten Artikel auf Ed Blankenships Blog.

Die Zwei-Repository-Lösung

Wenn ein Package neu entwickelt wird oder wenn Anpassungen (z.B. ein Bugfix) gemacht wurden, dann möchte man das neue Package natürlich erst lokal einmal testen und dazu sollte es nicht notwendig sein, die Änderungen einzuchecken und zu warten, bis der Team Build durchgelaufen ist. Wie das geht, wurde weiter oben demonstriert. In der Praxis ist es sinnvoll, zwei Repositories zu verwenden – eines für die lokal gebauten Pakete zu Debugging-Zwecken und ein öffentliches, zentrales Repository. Wie wir Repositories anlegen haben wir ja schon gesehen- im vorliegenden Fall sind sowohl das lokale, Share-basierte Repository als auch der zentrale Server als Package Sources eingetragen. image Wichtig:  Wir können über die Pfeile die Reihenfolge der Repositories beeinflussen. Diese Reihenfolge gibt gleichzeitig vor, in welcher Reihenfolge NuGet die Repositories nach einem bestimmten Package durchsucht. Es wird dann das erste Package mit den angegebenen Suchparametern (ID, Version) verwendet. Das können wir nun nutzen, um im lokalen Repository Pakete abzulegen und die dort vorhandenen mit einer höheren Priorität zu verwenden als die Pakete aus dem zentralen Repository. Dabei gehen wir so vor:
  1. Wir haben die Consumer-Solution geöffnet. Diese benutzt bereits unser Package aus dem zentralen Repository in der Version 26.1.31.6. Das lokale Repository ist leer.
  2. Wir analysieren einen Bug und stellen fest, dass dieser in unserem Package liegen muss. Wir öffnen nun in einer zweiten Visual Studio Instanz die Package Solution und passen den Code entsprechend an.
  3. Ein lokaler Build in Visual Studio erzeugt nun das Package. Mit der zuvor beschriebenen Versionierungs-Methodik ergibt sich ein Package mit der Version 999.99.99.99. Wir kopieren das Symbol-Package in unser lokales Repository. Dieser Vorgang haben wir ja bereits durch unseren Post Build Event automatisiert.
  4. Durch ein einfaches Update wird das Package in der Consumer-Solution nun auf diese Version aktualisiert und wir können unsere Anpassungen einfach testen und debuggen.
  5. Nachdem wir die Änderungen geprüft und eingecheckt haben, starten wir einen TFS-Build. Erzeugt nun ein Package mit der nächst höheren Version, welches wir in unser zentrales Repository kopieren.
Um diese Version nun in unsere Consumer Solution einzubinden, steht ab der Version NuGet 2.8 eine Downgrade-Option zur Verfügung, d.h. wir können das Paket aus dem lokalen Repository löschen und die aktuelle Version aus dem zentralen Repository einbinden.

Fazit

Selbermachen lohnt sich: NuGet bietet nicht nur einen bequemen Weg, fremden Code in eigene Projekte einzubinden. Mit etwas MS-Build-Magie wird es zum idealen Werkzeug, um Code einfach, versionssicher und mit allem Debugging-Komfort zu verteilen – ob „nur“ in der eigenen Organisation oder für die ganze Welt. Viel Spaß dabei!
Nach oben