Uno Platform - Part 5
Creating nuget packages

I currently use Azure DevOps for my build and release pipelines.
Based on a YAML file, the projects are built, the NuGet packages packaged and eventually pushed.

Before I can start checking this step, I must first make sure that my NuGet package for the Uno Platform library is created correctly. This means that the NuGet package should support various platforms. These platforms should be the same as defined in the csproj file.

In the earlier UWP version I had to perform some tricks to create a multi-platform UWP library. This was more about the processor architecture – x86, x64, ARM and ARM64.
This meant, you first had to create a build for each architecture and then create an additional reference file.

The beauty of an Uno Platform library, is that this split and extra action is apparently no longer necessary.
Here the platform is defined as UAP, Android and/or WebAssembly.
The output of this, is generated when building the project. And if you define these versions in your nuspec file, they will be automatically recognized by the head you’re currently using in an Uno application.

What I also did find out is that in your csproj file, you have to define all the UAP versions that you want to be available. The same goes for the nuspec file.

As a result, it takes a little longer to build and your nuspec file is grown a little larger, but it is also recognized by multiple UWP versions of your application.

Don’t forget to add the Uno.Core and Uno.UI libraries to your nuspec file and remove the standard Microsoft.NETCore.UniversalWindowsPlatform library.
I then built the nuget locally and referenced it to my sample project to see if everything was still working.

Yes! Everything runs like it should.
So, mission accomplished.

This is what my nuspec first looked like

<?xml version="1.0"?>
<package >
  <metadata>
    <id>I-Synergy.Framework.UI</id>
    <version>$Version$</version>
    <authors>Ismail Hassani</authors>
    <owners>International Intelligence</owners>
    <icon>Icon_128.png</icon>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <license type="expression">MIT</license>
    <description>I-Synergy UI Framework for UWP Applications</description>
    <releaseNotes></releaseNotes>
    <copyright>Copyright 2008-2020</copyright>
    <tags>I-Synergy UI Framework Universal Windows Applications</tags>
    <projectUrl>https://github.com/I-Synergy/I-Synergy.Framework</projectUrl>
    <repository type="git" url="https://github.com/I-Synergy/I-Synergy.Framework" branch="$Branch$" commit="$CommitId$" />

    <dependencies>
      <group targetFramework="uap10.0">
        <dependency id="I-Synergy.Framework.Core" version="[$PackageVersion$]" />
        <dependency id="I-Synergy.Framework.Mvvm" version="[$PackageVersion$]" />
        <dependency id="Microsoft.Extensions.Configuration.Json" version="3.1.8" />
        <dependency id="Microsoft.Extensions.Logging" version="3.1.8" />
        <dependency id="Microsoft.NETCore.UniversalWindowsPlatform" version="6.2.10" />
        <dependency id="Microsoft.UI.Xaml" version="2.4.3" />
        <dependency id="Microsoft.Xaml.Behaviors.Uwp.Managed" version="2.0.1" />
        <dependency id="Microsoft.Toolkit.Uwp.UI.Controls" version="6.1.1" />
      </group>
    </dependencies>
  </metadata>

  <files>
    <file src="Icon_128.png" target="" />
    
    <!-- Architecture-independent reference library for use at compile-time; generated by the PowerShell script. -->
    <file src="$AssemblyFolder$\ISynergy.Framework.UI\$BuildConfiguration$\ISynergy.Framework.UI.dll" target="ref\uap10.0" />
    <file src="$AssemblyFolder$\ISynergy.Framework.UI\$BuildConfiguration$\ISynergy.Framework.UI.pri" target="ref\uap10.0" />

    <!-- XML documentation file goes together with the reference library. -->
    <!-- Resource files go together with the reference library. -->
    <file src="$AssemblyFolder$\ISynergy.Framework.UI\x86\$BuildConfiguration$\ISynergy.Framework.UI\**\*.*" target="ref\uap10.0\ISynergy.Framework.UI" />

    <!-- The architecture-specific files go in architecture-specific directories. -->
    <file src="$AssemblyFolder$\ISynergy.Framework.UI\x86\$BuildConfiguration$\ISynergy.Framework.UI.dll" target="runtimes\win10-x86\lib\uap10.0" />
    <file src="$AssemblyFolder$\ISynergy.Framework.UI\x86\$BuildConfiguration$\ISynergy.Framework.UI.pdb" target="runtimes\win10-x86\lib\uap10.0" />

    <file src="$AssemblyFolder$\ISynergy.Framework.UI\x64\$BuildConfiguration$\ISynergy.Framework.UI.dll" target="runtimes\win10-x64\lib\uap10.0" />
    <file src="$AssemblyFolder$\ISynergy.Framework.UI\x64\$BuildConfiguration$\ISynergy.Framework.UI.pdb" target="runtimes\win10-x64\lib\uap10.0" />

    <file src="$AssemblyFolder$\ISynergy.Framework.UI\ARM\$BuildConfiguration$\ISynergy.Framework.UI.dll" target="runtimes\win10-arm\lib\uap10.0" />
    <file src="$AssemblyFolder$\ISynergy.Framework.UI\ARM\$BuildConfiguration$\ISynergy.Framework.UI.pdb" target="runtimes\win10-arm\lib\uap10.0" />

    <file src="$AssemblyFolder$\ISynergy.Framework.UI\ARM64\$BuildConfiguration$\ISynergy.Framework.UI.dll" target="runtimes\win10-arm64\lib\uap10.0" />
    <file src="$AssemblyFolder$\ISynergy.Framework.UI\ARM64\$BuildConfiguration$\ISynergy.Framework.UI.pdb" target="runtimes\win10-arm64\lib\uap10.0" />
  </files>
</package>

And this is the updated version

<?xml version="1.0"?>
<package >
  <metadata>
    <id>I-Synergy.Framework.UI</id>
    <version>$Version$</version>
    <authors>Ismail Hassani</authors>
    <owners>International Intelligence</owners>
    <icon>Icon_128.png</icon>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <license type="expression">MIT</license>
    <description>I-Synergy UI Framework for UWP Applications</description>
    <releaseNotes></releaseNotes>
    <copyright>Copyright 2008-2020</copyright>
    <tags>I-Synergy UI Framework Universal Windows Applications</tags>
    <projectUrl>https://github.com/I-Synergy/I-Synergy.Framework</projectUrl>
    <repository type="git" url="https://github.com/I-Synergy/I-Synergy.Framework" branch="$Branch$" commit="$CommitId$" />

    <dependencies>
      <group targetFramework="netstandard2.0">
        <dependency id="I-Synergy.Framework.Core" version="[$PackageVersion$]" />
        <dependency id="I-Synergy.Framework.Mvvm" version="[$PackageVersion$]" />
        <dependency id="Microsoft.Extensions.Configuration.Json" version="3.1.8" />
        <dependency id="Microsoft.Extensions.Logging" version="3.1.8" />
        <dependency id="Uno.Core" version="2.0.0" />
        <dependency id="Uno.UI" version="3.0.17" />
        <dependency id="Uno.Microsoft.Toolkit.Uwp.UI.Controls" version="6.1.0-build.191.gc988bdd4ff" />
        <dependency id="Uno.Microsoft.Xaml.Behaviors.Uwp.Managed" version="2.0.2-uno.79" />
      </group>
      <group targetFramework="uap10.0.17763">
        <dependency id="I-Synergy.Framework.Core" version="[$PackageVersion$]" />
        <dependency id="I-Synergy.Framework.Mvvm" version="[$PackageVersion$]" />
        <dependency id="Microsoft.Extensions.Configuration.Json" version="3.1.8" />
        <dependency id="Microsoft.Extensions.Logging" version="3.1.8" />
        <dependency id="Uno.Core" version="2.0.0" />
        <dependency id="Uno.UI" version="3.0.17" />
        <dependency id="Uno.Microsoft.Toolkit.Uwp.UI.Controls" version="6.1.0-build.191.gc988bdd4ff" />
        <dependency id="Uno.Microsoft.Xaml.Behaviors.Uwp.Managed" version="2.0.2-uno.79" />
      </group>
      <group targetFramework="uap10.0.18362">
        <dependency id="I-Synergy.Framework.Core" version="[$PackageVersion$]" />
        <dependency id="I-Synergy.Framework.Mvvm" version="[$PackageVersion$]" />
        <dependency id="Microsoft.Extensions.Configuration.Json" version="3.1.8" />
        <dependency id="Microsoft.Extensions.Logging" version="3.1.8" />
        <dependency id="Uno.Core" version="2.0.0" />
        <dependency id="Uno.UI" version="3.0.17" />
        <dependency id="Uno.Microsoft.Toolkit.Uwp.UI.Controls" version="6.1.0-build.191.gc988bdd4ff" />
        <dependency id="Uno.Microsoft.Xaml.Behaviors.Uwp.Managed" version="2.0.2-uno.79" />
      </group>
      <group targetFramework="monoandroid90">
        <dependency id="I-Synergy.Framework.Core" version="[$PackageVersion$]" />
        <dependency id="I-Synergy.Framework.Mvvm" version="[$PackageVersion$]" />
        <dependency id="Microsoft.Extensions.Configuration.Json" version="3.1.8" />
        <dependency id="Microsoft.Extensions.Logging" version="3.1.8" />
        <dependency id="Uno.Core" version="2.0.0" />
        <dependency id="Uno.UI" version="3.0.17" />
        <dependency id="Uno.Microsoft.Toolkit.Uwp.UI.Controls" version="6.1.0-build.191.gc988bdd4ff" />
        <dependency id="Uno.Microsoft.Xaml.Behaviors.Uwp.Managed" version="2.0.2-uno.79" />
      </group>
      <group targetFramework="monoandroid10.0">
        <dependency id="I-Synergy.Framework.Core" version="[$PackageVersion$]" />
        <dependency id="I-Synergy.Framework.Mvvm" version="[$PackageVersion$]" />
        <dependency id="Microsoft.Extensions.Configuration.Json" version="3.1.8" />
        <dependency id="Microsoft.Extensions.Logging" version="3.1.8" />
        <dependency id="Uno.Core" version="2.0.0" />
        <dependency id="Uno.UI" version="3.0.17" />
        <dependency id="Uno.Microsoft.Toolkit.Uwp.UI.Controls" version="6.1.0-build.191.gc988bdd4ff" />
        <dependency id="Uno.Microsoft.Xaml.Behaviors.Uwp.Managed" version="2.0.2-uno.79" />
      </group>
    </dependencies>
  </metadata>

  <files>
    <file src="Icon_128.png" target="" />

    <!--Android 9-->
    <file src="$AssemblyFolder$\ISynergy.Framework.UI\$BuildConfiguration$\monoandroid90\**" target="lib\monoandroid90" />
    <!--Android 10-->
    <file src="$AssemblyFolder$\ISynergy.Framework.UI\$BuildConfiguration$\monoandroid10.0\**" target="lib\monoandroid10.0" />
    <!--UAP 10.0.17763-->
    <file src="$AssemblyFolder$\ISynergy.Framework.UI\$BuildConfiguration$\uap10.0.17763\**" target="lib\uap10.0.17763" />
    <!--UAP 10.0.18362-->
    <file src="$AssemblyFolder$\ISynergy.Framework.UI\$BuildConfiguration$\uap10.0.18362\**" target="lib\uap10.0.18362" />
    <!--Net Standard 2.0-->
    <file src="$AssemblyFolder$\ISynergy.Framework.UI\$BuildConfiguration$\netstandard2.0\**" target="lib\netstandard2.0" />
  </files>
</package>

Next step

My next step will be checking in the changes I made and queue a new build on these changes to see if everything builds ok.

Build Error!

Ok, I got the following error when the build server tries to build de UI framework.

##[error]C:\Users\VssAdministrator\.nuget\packages\msbuild.sdk.extras\2.0.54\Build\Workarounds.targets(27,5): Error : If you are building projects that require targets from full MSBuild or MSBuildFrameworkToolsPath, you need to use desktop msbuild ('msbuild.exe') instead of 'dotnet build' or 'dotnet msbuild'

As the error suggests, I can’t use dotnet build for this project type.
Instead I have to use the regular MSBuild command.

I have to change this line in my YAML pipeline

- task: DotNetCoreCLI@2
  displayName: 'Dotnet build: I-Synergy.Framework.UI'
  inputs:
    command: build
    projects: 'src\ISynergy.Framework.UI\ISynergy.Framework.UI.csproj'
    arguments: '-c $(BuildConfiguration) -p:Version=$(build.buildNumber)'
    feedsToUse: config
    nugetConfigPath: nuget.config</pre>

to this

- task: MSBuild@1
  displayName: 'Framework UI - Nuget Restore'
  inputs:
    solution: 'src\ISynergy.Framework.UI\ISynergy.Framework.UI.csproj'
    platform: AnyCpu
    configuration: '$(BuildConfiguration)'
    msbuildArguments: '/t:restore'
      
 - task: MSBuild@1
   displayName: 'Framework UI - Build'
   inputs:
     solution: 'src\ISynergy.Framework.UI\ISynergy.Framework.UI.csproj'
     platform: AnyCpu
     configuration: '$(BuildConfiguration)'
     msbuildArguments: '/p:VersionAssembly=$(build.buildNumber)'</pre>

After rebuilding, everything runs fine and I can create a pull request to merge my code to the master branch.

See you all next time ;)