Azure DevOps pipeline for Maui

azure devops

In this new post, I like to show you how I created an Azure DevOps pipeline for building Maui components. I binged around to see if there was something I could use. In the end, I started to play with the YAML.

Scenario

After my last post about a component for Maiu, I wanted to create a pipeline using Azure DevOps and publish the component to NuGet.

In order to publish your component to NuGet, you have to configure a Service Connection to the NuGet website via the settings in your project in Azure DevOps.

For more details about the pipelines, I recommend reading my other posts:

Implementation

So, the component PSC.Maui.Components.Doughnuts works for all platforms and there is no customization for any platform. The component is built with NET7. So, it is pretty straightforward.

Select your VM image

In the new YAML file, we need to modify which VM image we’ll be using. Since we want one that contains NET7, we’ll use windows-2022:

pool:
  vmImage: windows-2022

As of writing, the windows-latest image has not yet been updated to use Visual Studio 2022 along with NET7, so we’ll have to explicitly set it to windows-2022.

Install NET7

The next step is to install NET7 from the pipeline. Also, I have to specify what is the package type and where I want to install it.

- task: UseDotNet@2
  displayName: 'Install .NET sdk'
  inputs:
    packageType: sdk
    version: 7.0.x
    installationPath: $(Agent.ToolsDirectory)/dotnet

Install the MAUI workload

Next, we’ll install the NET MAUI workload onto the build agent. We need this to be able to build .NET MAUI apps. NET MAUI workload is an optional workload that you can install on top of the NET SDK to provide support for building cross-platform applications with NET Multi-platform App UI (NET MAUI).

This can be done using the Command Line task and the dotnet workload command:

- task: CmdLine@2
  inputs:
    script: 'dotnet workload install maui'

Restore packages

In this component, I use SkiaSharp from a NuGet package and other packages. So, I have to restore all the packages in order to build successfully the package. Also, I use my feed in Azure DevOps.

- task: DotNetCoreCLI@2
  displayName: Restore packages
  inputs:
    command: 'restore'
    feedsToUse: 'select'
    vstsFeed: 'your-nuget-feed'

Build the component and run tests

Now, I’m going to build the project and run the tests.

- task: DotNetCoreCLI@2
  displayName: Build project
  inputs:
    command: 'build'
    projects: '**/PSC.Maui.Components.Doughnuts.csproj'
    arguments: '--configuration $(buildConfiguration)'
- task: DotNetCoreCLI@2
  displayName: Run tests
  inputs:
    command: 'test'
    projects: '**/*[Te]ests/*.csproj'
    arguments: '--configuration $(buildConfiguration) --no-build'

Prepare the package

Now, the build is ready. I want to prepare the NuGet package to push on NuGet. Be careful: there are some variables here like PackageVersion that you have to add to your Variables pipeline.

- task: DotNetCoreCLI@2
  displayName: Prepare the package
  inputs:
    command: 'pack'
    packagesToPack: '**/PSC.Maui.Components.Doughnuts.csproj'
    versioningScheme: 'byEnvVar'
    versionEnvVar: 'PackageVersion'
    arguments: '-t:pack'

Publish the package in the artifacts

Now, the next step is to publish the NuGet package in the artifacts in Azure DevOps.

- task: DotNetCoreCLI@2
  displayName: Publish the package
  inputs:
    command: 'push'
    packagesToPush: '$(Build.ArtifactStagingDirectory)/*.nupkg'
    nuGetFeedType: 'internal'
    publishVstsFeed: 'your-api-code'

Publish to NuGet.org

Finally, the last task is to push the NuGet package on Nuget.org

- task: NuGetCommand@2
  displayName: Push the package to NuGet.org
  inputs:
    command: 'push'
    packagesToPush: '$(Build.ArtifactStagingDirectory)/**/*.nupkg;!$(Build.ArtifactStagingDirectory)/**/*.symbols.nupkg'
    nuGetFeedType: 'external'
    publishFeedCredentials: 'NuGet Website'

Variables

In this pipeline, I use variables to track the version of the package.

Then, add the following variables:

  • Major: the major version of your package. In the image below is 1
  • Minor: the minor version of your package. In the image below is 0
  • PackageVersionType: this is the place where you can specify if this version is -pre release, -alfa-beta or whatever you prefer
  • Patch: here is where the magic happens. I’ll explain in a second
  • PackageVersion: creating the string for the version of this package

With this, I have an incremental, automatic Patch-version of my PackageVersion variable, with Major and Minor being updated manually by yours truly. I also have the optional PackageVersionType, in case I want to label a package explicitly as being a “preview” or anything else.

For more details and a walkthrough of those variables, read my post “NuGet package versioning with DevOps“.

The full YAML

Here is the entire YAML file for future reference.

trigger:
- main

pool:
  vmImage: windows-2022

steps:
- task: UseDotNet@2
  displayName: 'Install .NET sdk'
  inputs:
    packageType: sdk
    version: 7.0.x
    installationPath: $(Agent.ToolsDirectory)/dotnet
- task: CmdLine@2
  displayName: 'Install Maui Workload'
  inputs:
    script: 'dotnet workload install maui'
- task: DotNetCoreCLI@2
  displayName: Restore packages
  inputs:
    command: 'restore'
    feedsToUse: 'select'
    vstsFeed: 'your-nuget-feed'
- task: DotNetCoreCLI@2
  displayName: Build project
  inputs:
    command: 'build'
    projects: '**/PSC.Maui.Components.Doughnuts.csproj'
    arguments: '--configuration $(buildConfiguration)'
- task: DotNetCoreCLI@2
  displayName: Run tests
  inputs:
    command: 'test'
    projects: '**/*[Te]ests/*.csproj'
    arguments: '--configuration $(buildConfiguration) --no-build'
- task: DotNetCoreCLI@2
  displayName: Prepare the package
  inputs:
    command: 'pack'
    packagesToPack: '**/PSC.Maui.Components.Doughnuts.csproj'
    versioningScheme: 'byEnvVar'
    versionEnvVar: 'PackageVersion'
    arguments: '-t:pack'
- task: DotNetCoreCLI@2
  displayName: Publish the package
  inputs:
    command: 'push'
    packagesToPush: '$(Build.ArtifactStagingDirectory)/*.nupkg'
    nuGetFeedType: 'internal'
    publishVstsFeed: 'your-api-code'
- task: NuGetCommand@2
  displayName: Push the package to NuGet.org
  inputs:
    command: 'push'
    packagesToPush: '$(Build.ArtifactStagingDirectory)/**/*.nupkg;!$(Build.ArtifactStagingDirectory)/**/*.symbols.nupkg'
    nuGetFeedType: 'external'
    publishFeedCredentials: 'NuGet Website'

Wrap up

In conclusion, this is how to build, test and publish in the Azure DevOps pipeline for Maui component. Please feel free to use the forum to ask any questions.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.