Worklog SeeingSharp 2: Nugetpakete erstellen und veröffentlichen

Bei Seeing# ist es langsam so weit, dass ich die ersten Nuget-Pakete hochladen möchte. Früher im alten Seeing#-Projekt habe ich dazu noch eine separate VisualStudio-Erweiterung verwendet. Im neuen .csproj-Format ist nun die Möglichkeit eingeführt worden, dass man standardmäßig direkt aus dem CSharp-Projekt heraus auch die Nuget-Pakete erstellen kann. Genau dieses Features wollte ich hier auch direkt ausprobieren. Insgesamt hat das auch recht gut funktioniert, mit Ausnahme der Projekte für die Universal Windows Platform (UWP), doch näheres dazu unten im Artikel.

Umstellung Projektformat

Der erste Schritt zum Ziel hat noch nicht viel mit der Erstellung von Nuget-Paketen selbst zu tun, und zwar musste ich zunächst mal auf das neue .csproj-Format umstellen. Der erste Schritt war in meinem Fall die Migration der veralteten packages.config-Datei. Der Inhalt dieser Datei landet nun als PackageReference direkt in der .csproj-Datei, weitere Informationen unter [1]. Dieser Schritt ist recht gut durch VisualStudio unterstützt, und kann man nach einem Rechtsklick auf die packages.config Datei direkt „Migrate packages.config to PackageReference“ aufrufen – fertig. In meinem Fall hat das auch durchweg problemlos funktioniert.

Der zweite Schritt ist allerdings schon etwas komplizierter. Hier geht es darum, das .csproj-Format selbst zu migrieren. Unter [2] sind ein paar Wege beschrieben, wie man migrieren kann – einen vollwertigen Automatismus scheint es leider (noch) nicht zu geben (zumindest hätte ich keinen gefunden). Ich selbst habe den ersten im verlinkten Artikel genannten Weg gewählt: „start over“ bzw. eine völlig neue .csproj-Datei erstellen. Als Vorlage habe ich mir separat ein vergleichbares Projekt erstellt und die Inhalte rauskopiert. Da im neuen Format jede Datei innerhalb des Projektordners automatisch als Bestandteil des Projekts angesehen wird, war das auch ein nicht mal so aufwandstreibender Weg, wie man auf den ersten Blick vermuten mag. Ein paar Sachen gab es für mich dann aber doch, die ich händisch nachpflegen musste:

  • Eingebettete Ressourcen müssen separat in der .csproj-Datei angegeben werden. Hier reicht es aber auch, im VisualStudio die jeweiligen Dateien auszuwählen und den Parameter Build Action auf EmbeddedResource zu stellen
  • Gleiches gilt für andere „besondere“ Dateien wie Xaml-Dateien in WPF, Resourcen in WPF, etc.
  • Datei-Links müssen ebenfalls entweder neu eingefügt oder direkt in der .csproj-Datei angegeben werden

Insgesamt hilft bei diesem Vorhaben die stark vereinfachte .csproj-Datei. Das größte Problem für mich ist aber, dass Projekte für die Universal Windows Platform (UWP) noch nicht mit dem neuen .csproj-Format funktionieren – diese Projekte (bei mir 2) müssen erst mal im alten Format bleiben.

Pflege Paket-Eigenschaften

Paket-Eigenschaften können direkt in den Einstellungen zum jeweiligen Projekt konfiguriert werden (Siehe Abbildung 1). Achtung: Hierbei wird auch die frühere AssemblyInfo.cs-Datei automatisch erzeugt. Möchte man das nicht, kann man über das <GenerateAssemblyInfo> Element in der .csproj-Datei verhindern (siehe [3]). Insgesamt finde ich die neue Lösung sehr schlank und elegant.

Abbildung 1: Eigenschaften für das Nuget-Paket einstellen

Ein Problem hatte ich aber hier zunächst: Beim früheren Format habe ich eine gemeinsame SolutionInfo.cs-Datei erzeugt und diese in jedes Projekt verlinkt. Inhalt waren gemeinsame Eigenschaften aller Projekte wie etwa Version oder Author – diese habe ich dann entsprechend in der normalen AssemblyInfo.cs-Datei entfernt. Im neuen Format gibt es hier aber auch einen einfach Weg über eine gemeinsame Directory.Build.props-Datei. Diese Datei liegt bei mir direkt im Solution-Verzeichnis und definiert gemeinsame Einstellung für alle .csproj-Dateien in der Solution. Der Inhalt ist im Fall von SeeingSharp2 der folgende:

<Project>
  <PropertyGroup>
    <Authors>Roland König</Authors>
    <Company>Roland König</Company>
    <Description>Seeing# is a 3D/2D rendering library for C# powered by Direct3D. It is meant for desktop applications (Win.Forms, Wpf) or Windows Store Apps</Description>
    <Copyright>©2019 by Roland König</Copyright>
    <PackageProjectUrl>https://github.com/RolandKoenig/SeeingSharp2</PackageProjectUrl>
    <RepositoryUrl>https://github.com/RolandKoenig/SeeingSharp2</RepositoryUrl>
    <RepositoryType>Git</RepositoryType>
    <PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
    <Version>0.5.1</Version>
    <PackageVersion>0.5.1-alpha</PackageVersion>
    <Product>SeeingSharp 2</Product>
    <PackageLicenseFile>LICENSE.md</PackageLicenseFile>
  </PropertyGroup>
</Project>

Damit habe ich wieder eine zentrale Stelle, an der ich alle Eigenschaften für die erzeugten Nuget-Pakete pflegen kann. Einzige für die beiden UWP-Projekte muss ich einen separaten Weg gehen.

Erstellung der Nuget-Pakete

Die Nuget-Pakete können nun recht einfach über den Kontextmenü-Eintrag „publish“ des jeweiligen Projekts händisch erstellt werden. Ich selbst habe hier jedes Projekt so eingestellt, dass diese einen gemeinsamen publish-Ordner direkt im Verzeichnis der Solution verwenden. Nachdem ich das so in jedem der dafür relevanten VisualStudio-Projekte eingestellt habe, habe ich mir noch einen PowerShell-Script erzeugt, welcher auf einmal für alle Projekt die Nuget-Pakete erzeugt. Hier der Inhalt des PowerShell-Scripts:

Remove-Item -path ./publish/*

dotnet pack -c Release -o ./publish ./SeeingSharp
dotnet pack -c Release -o ./publish ./SeeingSharp.WinForms
dotnet pack -c Release -o ./publish ./SeeingSharp.WinFormsCore
dotnet pack -c Release -o ./publish ./SeeingSharp.Wpf
dotnet pack -c Release -o ./publish ./SeeingSharp.WpfCore

Fazit

In Summe sind die Pakete außer für die UWP-Unterstützung allesamt auf Nuget.org online – zunächst als prerelease. Das UWP im neuen .csproj-Format noch nicht unterstützt wird finde ich etwas ärgerlich, vermute aber, dass sich das spätestens mit WinUI 3.0 ändern wird. Für mich hat UWP aber insgesamt auch geringer Priorität, da ich dieses Framework in der Praxis überhaupt nicht mehr verwende.

[Verweise]
[1] – https://docs.microsoft.com/de-de/nuget/consume-packages/migrate-packages-config-to-package-reference
[2] – https://natemcmaster.com/blog/2017/03/09/vs2015-to-vs2017-upgrade/
[3] – https://docs.microsoft.com/de-de/dotnet/core/tools/csproj

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.