Building a MAUI Android app with Azure DevOps Pipelines
Learn how to build and sign your MAUI Android app with Azure DevOps Pipelines and ouput both apk and aab files.
Setup
First off create yourself a new blank .yaml file if you don't already have one.
Triggers
You can trigger your pipeline based on changes to a branch if you like. For this example we'll trigger it manually.
Yamltrigger: none
Build stage
Now lets add our build stage and configure it to use the lastest macOS image (at the time of writing macOS-13). You can also use 'macOS-latest' but confusingly it might not be the latest version.
Yamltrigger: none
stages:
- stage: Build
displayName: Build stage
jobs:
- job: Build
displayName: Build
pool:
vmImage: 'macOS-13'
Configure MAUI
We need to install the MAUI workload first before we build so lets add a task for it.
Yamltrigger: none
stages:
- stage: Build
displayName: Build stage
jobs:
- job: Build
displayName: Build
pool:
vmImage: 'macOS-13'
steps:
- task: CmdLine@2
displayName: 'Install Latest .NET MAUI Workload'
inputs:
script: 'dotnet workload install maui'
Load our keystore
You'll need to upload your keystore to Pipelines > Library > Secure files on DevOps. Once you've done that add a task to download it. I've added a variable for the filename but you could just hardcode if you like.
Yaml- task: DownloadSecureFile@1
name: keystore
inputs:
secureFile: '$(keystoreFilename)'
Build the project
The next step is to build and sign your project. We'll use the dotnet publish command to achieve that. You'll need to include your keystore password twice and also the alias. As with the previous example I've added them both to variables. I've also set working directory as I'm using a multi-project solution, if you are using single project them you shouldn't need to.
Yaml- task: CmdLine@2
displayName: 'Build project'
inputs:
script: 'dotnet publish -f net8.0-android -c Release -p:AndroidKeyStore=true -p:AndroidSigningKeyStore=$(keystore.secureFilePath) -p:AndroidSigningKeyPass=$(keystorePassword) -p:AndroidSigningStorePass=$(keystorePassword) -p:AndroidSigningKeyAlias=$(keystoreAlias)'
workingDirectory: './Source/MyProject.Android/'
Publish build output
Finally the last thing to do is publish the apk and aab files that are output by the build. Note that the source folder will differ depending on your project name but dotnet publish always outputs to 'bin/Release/net8.0-android/publish'
Yaml- task: CopyFiles@2
displayName: 'Copy build output to staging'
inputs:
SourceFolder: '$(Agent.BuildDirectory)/s/Source/MyProject.Android/bin/Release/net8.0-android/publish'
Contents: |
**/*.apk
**/*.aab
TargetFolder: '$(ArtifactStagingDirectory)'
flattenFolders: true
- publish: $(ArtifactStagingDirectory)
artifact: drop