.NET MAUI/Xamarin + Azure DevOps + App Center

To create a rapidly scaling mobile solution you will need to enable continuous delivery & continuous integration. The goal is to fully automate a build that kicks off every time a change is merged in, then ship the build to testers.

There is an alternative way of implementing CI/CD as App Center has its own build pipelines.

Azure DevOps will trigger builds that initiate when changes a checked into a targeted branch. During the build process, after the iOS & Android the apps compile, they are signed with AdHoc security files. These security files are .p12 & .mobileprovisioning files for iOS & a .keystore file for Android. Finally, the signed app file is moved to a file staging area, then it ships out to App Center.

Once the app arrives in App Center you’re able to send it to test groups of users. You can enable automatic provisioning so that new iOS users can join your group automatically. App Center also offers a suite of usage & crash analytics.

Create New Repository

Navigate to Azure DevOps & click the Repos tab. Initialize a new repository and clone it to your machine. You will need to create a Personal Access Token in Azure and upload an RSA key to push & pull code.

Create New Project

Launch Visual Studio for Windows on a Windows machine or Parallels on Mac & create a new Xamarin or .NET MAUI project in the repository folder. Don’t forget to add a .gitignore file to remove some of the noise. Push your code up to your new repository and you can start building.

Create New Android Pipeline

Switch back to Azure DevOps and go to Pipelines > Create Pipeline. You will be presented with a choice of YAML or classic editor, let’s go with classic. Next you must choose a repository and a default branch so choose the one we just created. Now you must select a template. We will be creating two pipelines for Android & iOS although there are ways to combine the pipeline in YAML. Let’s start with Android. Search for the Xamarin.Android template.

Xamarin.Android pipeline template

First change your title to something meaningful like Android AdHoc. Next click the Triggers tab and select enable continuous integration. This will trigger your pipeline every time a change is merged into the branch you choose.

Triggers tab

Go back to the Tasks tab and change the job name from Agent Job 1 to something meaningful like Build, Sign & Distribute. Click the nuget tab and set the Task # to the highest available. Expand Advanced and clear text from Version of NuGet.exe to install, we want this to always be latest available.

If you’re using a brand new Azure DevOps account, you may get the following error when you run the pipeline. You will need access granted from Azure team in order to continue.

##[error]No hosted parallelism has been purchased or granted. To request a free parallelism grant, please fill out the following form https://aka.ms/azpipelines-parallelism-request

Create New Keystore

This step is only required if you want to distribute your app to the store, its not required for AdHoc testing. Back in Visual Studio, go to View > Terminal. The UI for creating a .keystore has not been added to Visual Studio 2022 at the time of writing this article. Replace the file name & alias to something more suiting and run this command.

keytool -genkey -v -keystore mykey.keystore -alias JonsSandyBeach -keyalg RSA -keysize 2048 -validity 10000

This should trigger a series of questions.

Keystore questionnaire

Once you’ve completed this the .keystore file will be added to the directory that you were using terminal in. Go back to Azure under Pipelines select Library > Secure Files and upload the keystore file.

Next, go to your pipeline > Variables tab and add your keystore password. Switch over to the Tasks tab and select the Android signing task. Select the .keystore file you uploaded reference your keystore password variable like $(KeystorePassword). Add the Alias name in my case it was JonsSandyBeach.

Ship Android to App Center

Right click the Deploy to App Center task and enable it. Head over to App Center and create a new account or sign into an existing one. Select create new project and choose Android OS & Xamarin platform. Click Settings > API Tokens > New API token to create a token with full access. Copy the token and switch over to Azure DevOps. Just below App Center service connection, click the New button. Add the App Center token and grant access to all pipelines.

The next thing you need to configure is the slug from your App Center URL. Your App Center Android projects URL might look something like this.


To get your slug you just take the strings before and after apps and slap them together.


Add your default release notes and your good to go. Save and build the pipeline. Once it’s completed you should see your app in App Center!

Now that App Center has it, you can click the build > Distribute, and send the app via email to anyone.

Create New iOS Pipeline

In Azure DevOps > Pipelines create a new Pipeline for iOS. Choose the classic editor again, and search for Xamarin.iOS template. Give the pipeline a meaningful name and select the latest Azure MacOS pipeline.

Build pipeline properties

The first thing we need to do is create an Ad Hoc .mobileprovisioning file create a .p12 file from it’s certificate. There are plenty of articles that will walk you through creating these files. It’s a bit out of scope for this posting.

Once you have the AdHoc .mobile provisioning and .p12 files then go to Azure DevOps > Pipelines > Library > Secure Files and upload them to Azure. Right click the Install Apple Certificate task and enable it. Select the .p12 file you just uploaded and set the password as a variable.

Right click the Install an Apple Provisioning Profile task, enable it, and select your .mobileprovisioning file from the drop-down.

Select the nuget task and make sure the latest Task # is selected. Clear text from version of Nuget.exe to install, we always want the latest.

Navigate to the build Xamarin.iOS task and uncheck Build for iOS simulator!

This one took me for a ride for the longest time. If you were to try to create an .ipa file on your local machine you would have to connect a physical device. This is because simulators cannot create distribution .ipa files. We must uncheck the Build for iOS simulator box in order to generate an .ipa file.

Ship iOS to App Center

Right click the Deploy to App Center task and enable it. Just like Android, iOS also requires its own project and its own API key. Go back to App Center & create a new project, OS: iOS, Platform: Xamarin. Click on Settings > App API Tokens > New API Token and create a full access token. Copy this token and head back to DevOps where you will click New under App Center connection and paste the token. Don’t forget to grant access to all pipelines.

Get the API slug the same way we did for Android and Add your release notes. Save & Build the pipeline and bam! You will have an iOS app in App Center > Distribute, once the build completes.

iOS Automatic Resigning

Of course we all know that an AdHoc provisioning profile must have the UDID’s of all the iPhones that need to test the app. It would be a pain to constantly have to add UDID’s and add them to the provisioning profile every time we get a new tester. That is why App Center enables automatic provisioning profile resigning.

Go to App Center > Distribute > Groups and create a new group for iOS testers. Click the wrench icon to enable resigning.

Group Settings

Sign in with your developer account and upload the .p12 certificate you created earlier. Great, you’re ready for iOS automation.


We can drastically improve the code integration & delivery process by using Azure DevOps with App Center. When an app is shipped directly to testers, the experience is superior & you will find bugs that you may have not seen otherwise. If you are starting fresh, then you will need Azure team to grant you access to hosted parallelism. I hope that you found this article enjoyable and learned something new.