How To NuGet: Teil 2 – Automatisiertes Erstellen von NuGet-Paketen in .NET-Projekten
Jeder .NET-Entwickler kennt es: Man entwickelt an eigenen Frameworks und will sie dann in das Projekt einbinden. Nur wie? Der NuGet Package Manager vereinfacht die Verwaltung (Download, Installation, Deinstallation, Upgrade, Konfiguration) von Extensions. Warum also nicht die eigenen Frameworks automatisiert auf einen internen NuGet-Server laden und somit das Einbinden vereinfachen? Wie ihr euch einen internen NuGet-Server aufsetzen könnt, könnt ihr in meinem vorherigen Blog-Post nachlesen.
Und so funktioniert’s:
Erstellen eines NuGet-Paketes
Manuell erstellen
Zum Erstellen eines NuGet-Paketes muss die nuget.exe heruntergeladen und (nach dem Bauen im Visual Studio) im Verzeichnis, in dem die .csproj-File liegt, mit folgendem Befehl in der Konsole ausgeführt werden:
nuget pack Projektname.csproj
Automatisch beim Build erstellen
Das automatische Erstellen beim Build funktioniert über die Post-Build Argumente eines Projektes. Um dies zu erreichen, sind folgende Schritte notwendig:
- Die nuget.exe in das Projekt einbinden, sodass es im SolutionDir liegt
- Im Visual Studio Rechtsklick auf die Solution
- Dort auf „Add > Existing Item“ klicken
- Die nuget.exe auswählen und einbinden
- Rechtsklick auf das Projekt, welches als NuGet-Paket gebaut werden soll und auf Properties klicken
- In den Tab „Build Events“ wechseln
- Folgendes in die „Pre-build event command line“ eintragen:
if not exist "$(ProjectDir)bin\Release" Mkdir "$(ProjectDir)bin\Release"
Dies hat damit zu tun, dass beim Erstellen des NuGet-Paketes aus der .csproj der Pfad geholt wird, in dem die .dll-Datei liegt. In diesem Fall gehe ich davon aus, dass das Projekt im „Release“ Modus gebaut wurde.
- Die „Post-build event command line“ folgendermaßen abändern:
Copy /Y $(TargetDir)* $(ProjectDir)bin\Release $(SolutionDir)nuget.exe pack $(ProjectDir)Solutionname.csproj -OutputDirectory $(TargetDir)
Debuggen ermöglichen
Um zu ermöglichen, dass in NuGet-Paketen hinein debuggt werden kann, muss die .pdb-Datei mit ins Projekt geladen werden.
Hierfür sind folgende Schritte nötig:
1. Überprüfen der internen Struktur der .nupkg -Datei
- Manuell oder durch den Build eine .nupkg-Datei (NuGet Package) erzeugen
- Dieses Paket mithilfe des NuGet Package Explorers öffnen
- Hier findet man den Pfad der späteren Dateien im Bereich „Package contents“, welcher später noch benötigt wird.
Im folgenden Beispiel ist der Pfad „lib\net35-Client\“
2. Erstellen und Bearbeiten der .nuspec-Datei
Bei einer .nuspec-Datei handelt es sich um eine Spezifikationsdatei für das spätere Erstellen des NuGet-Paketes.
Um eine .nuspec-Datei zu erstellen sind folgende Schritte nötig:
- Die nuget.exe hierfür einmalig in das Verzeichnis legen, in dem die .csproj-File liegt (der folgende Befehl arbeitet immer nur für die im selben Verzeichnis liegenden Projekte)
- In der Konsole innerhalb dieses Pfades folgenden Befehl eingeben:
nuget spec
Die entstandene .nuspec-Datei nun mit einem Editor öffnen und folgendermaßen abändern:
- Die folgenden Tags entfernen oder anpassen:
- <licenseUrl>
- <projectUrl>
- <iconUrl>
- <releaseNotes>
- <tags>
- Folgende Struktur hinzufügen:
Beispiel einer .nuspec-Datei:
< ?xml version="1.0"?>
$id$
$version$
$title$
$author$
$author$
false
$description$
Copyright 2016
3. Erneut Erstellen der .nupkg- Datei
Nachdem diese Schritte durchlaufen sind, kann wie oben beschrieben das NuGet-Paket entweder manuell oder während des Builds erzeugt werden. Es wird automatisch die .pdb-Datei mit eingebaut, wodurch das Debuggen innerhalb der Bibliothek nach dem Einbinden des Paketes in ein Projekt ermöglicht wird.
Die .nuspec-Datei muss in das Projekt eingebunden sein, dass auch beim Bauen auf dem TFS-Server die Konfiguration vorhanden ist.
Deployen eines NuGet-Paketes
Für diesen Zweck wurde ein interner NuGet-Server eingerichtet. Wie ihr das macht, könnt ihr hier nachlesen.
Achtung: Bitte darauf achten, dass das Konfigurationsprofil „Release“ ausgewählt ist, da ansonsten der lokale Dateipfad bei Exceptions in Log-Dateien gespeichert wird.
Manuell deployen
Zum Deployen eines NuGet-Paketes muss die nuget.exe heruntergeladen und mit folgendem Befehl in der Konsole ausgeführt werden:
nuget.exe push Pfad-der-nupkg-Datei -s Server-Adresse api-Key
Automatisch beim Build deployen
Hierfür wird vorausgesetzt, dass die Schritte aus „Automatisch beim Build erstellen“ bereits umgesetzt wurden.
- Die „Post-build event command line“ folgendermaßen anpassen:
Copy /Y $(TargetDir)* $(ProjectDir)bin\Release del $(TargetDir)*.nupkg $(SolutionDir)nuget.exe pack $(ProjectDir)Solutionname.csproj -OutputDirectory $(TargetDir) $(SolutionDir)nuget.exe push $(TargetDir)*.nupkg -s Server-Adresse api-Key
• Die Solutionname.csproj muss eine Konfiguration für „Release“ beinhalten:
Release …
Einbinden eines NuGet-Paketes
Um das Paket in ein Projekt einzubinden, sind folgende Schritte durchzuführen:
- In Visual Studio unter „Tools“ auf „NuGet Package Manager > Package Manager Settings“ klicken
- Zum Tab „Package Sources“ wechseln
- Über das „+“ eine neue Source hinzufügen und diese dann folgendermaßen einstellen:
- Einen beliebigen Namen für die Source angeben
- Bei Source auf den „…“-Button klicken und zum Ort navigieren, an dem die Pakete abgelegt wurden
- Durch einen Klick auf „update“ den Prozess abschließen
Die Pakete können nun im NuGet Package Manager wie ein gewöhnliches NuGet-Paket eingebunden werden. Hierfür muss man im NuGet Package Manger lediglich noch die Source auswählen, in der sich das gesuchte Paket befindet.
Wichtige Hinweise
- Beim Erstellen eines NuGet-Paketes muss auch bei kleinen Änderungen die Versionsnummer hochgezählt werden. Hierbei reicht es beispielsweise von Version 1.0.0.0 auf Version 1.0.0.1 zu erhöhen. Hierdurch ist es für alle ersichtlich, wenn ein Paket abgeändert wurde. Außerdem ist es möglich, bei Problemen auf eine ältere Version zurück zu wechseln.
- Zu beachten ist, dass innerhalb der AssemblyInfo.cs des Projekts die AssemblyDescription einen Text enthalten muss.
- Problematisch könnte es werden, wenn alle Varianten eines NuGet-Paketes aus einem TFS-Projekt gelöscht werden und ein NuGet-Paket mit demselben Namen und derselben Versionsnummer (wie bereits zuvor vorhanden) hinzugefügt werden soll (siehe Nuget Package updates & Package.config remove issue (TF400024)).
Ich habe keine Möglichkeit gefunden diesen Fehler zu beheben, außer das Projekt unabgeändert neu aus dem TFS auszuchecken. (Hierbei sollte sämtlicher Fortschritt am Projekt, welcher noch nicht eingecheckt war, gesichert werden. Z.B. durch ein Shelveset).
Quellen
[1] https://docs.nuget.org/create/creating-and-publishing-a-package[2] http://blog.codeinside.eu/2013/06/21/gegen-die-mega-sln-nuget-packages-vs-projekt-referenzen/
[3] https://codingfreaks.de/archive/