Azure DevOps - Maui Application Build and Release on TestFlight
Ho deciso di crivere questo articolo perchè ad oggi la documentazione che si trova online è spesso obsoleta.
In questa pagina spiegherò come costruire una pipepeline su Azure DevOps sia per la buil di un'app Maui che una release su Apple TestFlight.
Al momento utilizzo Maui con .NET 8. Tra qualche mese Microsoft sfornerà .NET9 e provvederò ad aggiornare l'articolo.
Cercherò di indicare tutti gli step anche i più scontati.
Il caso che prenderò in esame è una semplice applicazione che fa la conversione di un carattere ascii in altri formati.
Il nome dell'app è "Easy Ascii Converter"
Il nome del pacchetto è "com.gi.easyasciiconverter"
Registrazione dell'app su Apple App Store Connect
Identificatore in Apple App Store Connect
Prima di tutto è necessario creare l'identificatore in Apple App Store Connect per l'app.
Dalla pagina https://developer.apple.com/account/resources/identifiers/list aggiungi il nuovo identificatore per l'app:
- Tipo: "App IDs" -> Continue
- Tipo: "AppA -> Continue
- Description: "Easy Ascii Converter"
- Bundle: "com.gi.easyasciiconverter"
- Capabilities: non seleziono nulla perchè non ho nulla di "particolare -> Register
Provisioning profiles
Come secondo step è fondamentale creare i file di provisioning. Ne creeremo due, uno per development e uno per la distribuzione.
Dalla pagina https://developer.apple.com/account/resources/profiles/list aggiungi un nuovo profilo:
- Tipo Development -> iOS App Development -> Continue
- Seleziona dalla dropdown "App ID" l'identificatore appena creato. Nel mio caso "Easy Ascii Converter". Continue
- Seleziona il certificato. Nel mio caso "Giuseppe Iemma (iOS Development) -> Continue
- Includi i devices registrati. Solitamente includo tutti i miei devices (2 telefoni e un tablet) -> Continue
- Dai un nome al profilo. Ho dato come nome "EasyAsciiConverterDev" cosi da differenziarlo dal provisioning profile di distribuzione -> Continue
- Scarica il profilo appena creato.
Adesso possiamo creare il secondo profilo che sarà quello di distribuzione. I passi sono analoghi.
Dalla pagina https://developer.apple.com/account/resources/profiles/list aggiungi un nuovo profilo:
- Tipo Distribution -> App Store Connect-> Continue
- Seleziona dalla dropdown "App ID" l'identificatore appena creato. Nel mio caso "Easy Ascii Converter". Continue
- Seleziona il certificato. Nel mio caso "Giuseppe Iemma (iOS Distribution) -> Continue
- Dai un nome al profilo. Ho dato come nome "EasyAsciiConverterProd" cosi da differenziarlo dal provisioning profile di distribuzione -> Continue
- Scarica il profilo appena creato.
A questo punto possiamo abbandonare il browser e passare a Visual Studio 2022.
Proprietà del progetto in Visual Studio 2022
Per lo sviluppo utilizzo una workstation "Windows" quindi prima di proseguire faccio in "Pairing" con il mio Mac. Questo mi consentirà di associare i file di provisioning creati in App Connect e anche di eseguire il progetto su un emulatore o un iPhone fisico connesso al Macbook.
In "MAUIS Shared" -> "General" definire:
- Application title. Nel mio caso "Easy Ascii Converter"
- Application ID. Nel mio caso "com.gi.easyasciiconverter"
In "iOS" -> "Bundle Signing":
- Scheme: "Manual Provisioning"
- Signing Identity: iOS Development
Adesso selezioniamo la configurazione di avvio come iOS Simulators -> iPhone 15 17.2
Se tutto è andato a buon fine sul MAC dovrebbe avviarsi l'emulatore e quindi la nostra applicazione. In caso contrario guarda l'output di compilazione per capire quale sia l'eventuale problema.
Nota: se è la prima volta che avviamo il simulatore, potrebbero servire alcuni minuti per il primo caricamento.
Azure DevOps Build pipeline per MAUI
Siamo arrivati al punto in cui la solution compila e viene avviata correttamente.
Procediamo con la costruzione della build su Azure DevOps.
Operazioni preliminari
Impostazione del certificato
Sul MAC aprire Xcode. Dal menu in alto a sinistra cliccare su "Settings". Dalla lista degli "App IDs" selezionare l'account corretto poi cliccare su "Manage Certificate". Apparirà la lista dei certificati. Cliccare con entrambi i tasti sul certificato di distribuzione da ustilizzare. Apparirà un context menu "Export Certificate". Esportare il certificato .p12 e salvarlo (ricorda la password che userai perchè ti servirà negli step successivi). Io ho utilizzato una chiavetta usb perchè ho configurato le build dal pc Windows.
Il certificato va caricato in Library -> Secure files.
Il nome del file è indicato alla riga 24 del file yaml.
Importazione del file di provisioning
Il file di provisioning (se non già fatto) può essere scaricato dall' Apple Sore Connect.
Poi è da caricare così come fatto per il certificato.
Importiamo lo yaml relativo alla build
Parto dal prosupposto che il codice sorgente sia già DevOps e non su altri repository come ad esempio GitHub.
Andiamo su "Pipelines" e creiamone una nuova.
Incolla il seguente yaml.
trigger:
- main
variables:
BuildConfiguration: Release
DotNetVersion: 8.0.100
stages:
- stage: BuildiOS
jobs:
- job: BuildMAUIApp
displayName: Build MAUI App
pool:
vmImage: 'macOS-13'
demands:
- MSBuild
steps:
- task: InstallAppleCertificate@2
inputs:
certSecureFile: 'GIAppleDistribution.p12'
certPwd: '$(iOSCertPassword)'
keychain: 'temp'
- task: InstallAppleProvisioningProfile@1
inputs:
provisioningProfileLocation: 'secureFiles'
provProfileSecureFile: 'EasyAsciiConverterProd.mobileprovision'
- task: PowerShell@2
displayName: Select Xcode Version
inputs:
targetType: 'inline'
script: |
echo Mac OS version:
sw_vers -productVersion
echo Installed Xcode versions:
ls /Applications | grep 'Xcode'
echo currently selected xcode:
xcrun xcode-select --print-path
echo selecting latest xcode...
sudo xcode-select -s /Applications/Xcode_15.2.app
xcrun xcode-select --print-path
xcodebuild -version
- task: UseDotNet@2
displayName: .NET Version
inputs:
packageType: 'sdk'
version: '$(DotNetVersion)'
- task: Bash@3
displayName: Install MAUI
inputs:
targetType: 'inline'
script: |
dotnet nuget locals all --clear
dotnet workload install maui --source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet8/nuget/v3/index.json --source https://api.nuget.org/v3/index.json
dotnet workload install android ios macos maui wasm-tools --source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet8/nuget/v3/index.json --source https://api.nuget.org/v3/index.json
- task: Bash@3
displayName: Restore nuget
inputs:
targetType: 'inline'
script: |
cd src/
dotnet restore EasyAsciiConverter.sln
# https://docs.microsoft.com/en-us/dotnet/maui/ios/deployment/overview
- task: Bash@3
displayName: Build iOS App
inputs:
targetType: 'inline'
script: |
cd src
dotnet publish -f net8.0-ios -c Release
- task: CopyFiles@2
inputs:
Contents: |
**/*.app
**/*.ipa
TargetFolder: '$(Build.ArtifactStagingDirectory)'
- task: PublishBuildArtifacts@1
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'drop_ios'
publishLocation: 'Container'
Modificare:
- la riga 24 con il nome del certificato
- la riga 31 con il nome del file di provisioning
- la riga 70 con il nome della solution
Aggiungere una variabile di nome "iOSCertPassword" e valore uguale alla password inserita durante l'esportazione del certificato.
Adesso possiamo lanciare la build!
Lancio della pipeline di build per l'app MAUI
La prima volta che lanceremo la build dovremo concedere i permessi per l'accesso ai file di certificato e provisioning.
Cliccare sul tasto "View" e dare i permessi. La buid dovrebbe procedere.