Setting up CI for your .NET MAUI Windows app in Azure DevOps

In this post I will show you how you can set up continuous integration (CI) for your .NET MAUI Windows app in Azure DevOps. If you want to check out how you can do this for Android and iOS, you can check out my other posts for them here and here. This post is heavily inspired by Gerald Versluis’s video on how to sideload or publish your MAUI Windows app.

Create your pipeline

Start off by creating a new pipeline from Azure DevOps. Select the “Starter pipeline” and name your YAML file something like windows-maui-build.yml. We’ll modify this with the steps needed to create the MSIX file for your Windows app.

Select your VM image

In your new YAML file, we need to modify this to use an image running Windows. We’ll be using the windows-latest image:

  vmImage: windows-latest

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. This can be done using the Command Line task and the dotnet workload command:

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

Build it

Now we can build the app using the .NET Core task with some arguments. We’ll use the publish command to output a MSIX file and set the target framework to net6.0-windows10.0.19041.0. Make sure that this matches the one in your csproj.

- task: DotNetCoreCLI@2
    command: 'publish'
    publishWebProjects: false
    projects: 'MyMAUIProject.sln'
    arguments: '-c $(buildConfiguration) -f:net6.0-windows10.0.19041.0'
    zipAfterPublish: false
    modifyOutputPath: false

Where do I sign?

If you want to publish the resulting MSIX file to Windows Store, you can use this without having to sign your package. However, if you plan on sideloading your app, you’ll need to sign your app. You can do this with a self-signed certificate (mostly used for testing) or a certificate issued by a trusted source. For instructions on how to create a self-signed certificate, follow this guide.

Once you have created and exported this certificate, go ahead and upload this to Secure Files in your project in Azure DevOps.

In your pipeline, add the Download Secure File task and point it at the certificate you just uploaded:

- task: DownloadSecureFile@1
    secureFile: 'mymauiwindowscert.pfx'

Copy the MSIX file over to the artifact staging directory so that we more easily can sign it from there:

- task: CopyFiles@2
    SourceFolder: '$(Agent.BuildDirectory)'
    Contents: '**/MyMauiProject*.msix'
    TargetFolder: '$(Build.ArtifactStagingDirectory)'
    flattenFolders: true

Now we’re ready to do the actual signing. We’ll run a custom script to sign the MSIX package using our certificate and the password we used to generate the certificate.

    - script: '"C:\Program Files (x86)\Windows Kits\10\App Certification Kit\SignTool" sign /fd SHA256 /f $(Agent.TempDirectory)/mymauiwindowscert.pfx /p sup3rs3cr3tp4ssw0rd $(Build.ArtifactStagingDirectory)\MyMauiProject_1.0.0.0_x64.msix'
      displayName: 'Sign MSIX Package'

And that should provide you with a signed MSIX package ready for distribution!

Here’s the final YAML file:

Final notes

As you might have noticed, the signing step is hard-coded to a specific version, so this could probably be set as a pipeline variable or be tied to some auto-incrementing of build number during CI.

Microsoft also recently published a great blog post regarding DevOps for .NET MAUI, which I recommend checking out.

Leave a Reply

Your email address will not be published. Required fields are marked *

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