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.

Leave a comment

Please note that we won't show your email to others, or use it for sending unwanted emails. We will only use it to render your Gravatar image and to validate you as a real person.