Erstellen, Testen und Bereitstellen von Xcode-Apps

Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2019

Hier erfahren Sie, wie Sie Xcode-Projekte mit Azure Pipelines erstellen und bereitstellen.

Voraussetzungen

Erstellen der Pipeline

  1. Melden Sie sich bei Ihrer Azure DevOps-Organisation an, und wechseln Sie zu Ihrem Projekt.

  2. Gehen Sie zu Pipelines und wählen Sie dann Neue Pipeline aus oder Pipeline erstellen, wenn Sie Ihre erste Pipeline erstellen.

  3. Führen Sie die Schritte des Assistenten aus. Dabei wählen Sie zuerst GitHub als Speicherort Ihres Quellcodes aus.

  4. Möglicherweise werden Sie zu GitHub weitergeleitet, um sich anzumelden. Geben Sie in diesem Fall Ihre Anmeldeinformationen für GitHub ein.

  5. Wenn die Liste der Repositorys angezeigt wird, wählen Sie Ihr Repository aus.

  6. Sie werden möglicherweise zu GitHub weitergeleitet, um die Azure Pipelines-App zu installieren. Wählen Sie in diesem Fall „Approve & Install“ (Genehmigen und installieren) aus.

Wenn die Registerkarte Konfigurieren erscheint, wählen Sie Xcode aus.

  1. Wenn Ihre neue Pipeline angezeigt wird, sehen Sie sich den YAML-Code an, um herauszufinden, was er macht. Wenn Sie so weit sind, wählen Sie Speichern und ausführen aus.

    Schaltfläche zum Speichern und Ausführen in einer neuen YAML-Pipeline

  2. Sie werden aufgefordert, eine neue azure-pipelines.yml-Datei in Ihr Repository zu committen. Sobald Sie mit der Nachricht zufrieden sind, wählen Sie erneut Speichern und ausführen aus.

    Wenn Sie Ihre Pipeline in Aktion überwachen möchten, wählen Sie den Buildauftrag aus.

    Sie haben gerade eine Pipeline erstellt und ausgeführt, die wir automatisch für Sie erstellt haben, da Ihr Code eine gute Übereinstimmung mit der Xcode-Vorlage schien.

    Sie verfügen nun über eine funktionierende YAML-Pipeline (azure-pipelines.yml) in Ihrem Repository, die Sie anpassen können.

  3. Wenn Sie bereit sind, Änderungen an Ihrer Pipeline vorzunehmen, wählen Sie sie auf der Seite Pipelines aus, und bearbeiten Sie dann die azure-pipelines.yml-Datei.

In den folgenden Abschnitten erfahren Sie mehr über die gängigen Möglichkeiten zum Anpassen Ihrer Pipeline.

Tipp

Um wie in diesem Artikel beschrieben Änderungen an der YAML-Datei vorzunehmen, wählen Sie die Pipeline auf der Seite Pipelines aus, und wählen Sie dann Bearbeiten aus, um den Editor für die azure-pipelines.yml-Datei zu öffnen.

Buildumgebung

Sie können Azure Pipelines verwenden, um Apps mit Xcode zu erstellen, ohne eine eigene Infrastruktur einrichten zu müssen. Xcode ist auf von Microsoft gehosteten macOS-Agents in Azure Pipelines vorinstalliert. Sie können die macOS-Agents verwenden, um Ihre Builds auszuführen.

Die genauen Versionen von Xcode, die vorinstalliert sind, finden Sie unter Von Microsoft gehostete Agents.

Erstellen Sie eine Datei mit dem Namen azure-pipelines.yml im Stamm Ihres Repositorys. Fügen Sie dann den folgenden Codeschnipsel zu Ihrer azure-pipelines.yml-Datei hinzu, um den entsprechenden Agentpool auszuwählen:

# https://learn.microsoft.com/azure/devops/pipelines/ecosystems/xcode
pool:
  vmImage: 'macOS-latest'

Erstellen einer App mit Xcode

Um eine App mit Xcode zu erstellen, fügen Sie der azure-pipelines.yml-Datei den folgenden Codeschnipsel hinzu. Dies ist ein minimaler Schnipsel, mit dem ein iOS-Projekt mit dem Standardschema und ohne Verpackung für den Simulator erstellt wird. Ändern Sie die Werte so, dass sie Ihrer Projektkonfiguration entsprechen. Weitere Informationen zu diesen Optionen finden Sie in der Xcode-Aufgabe.

pool:
  vmImage: 'macos-latest'

steps:
- task: Xcode@5
  inputs:
    actions: 'build'
    scheme: ''
    sdk: 'iphoneos'
    configuration: 'Release'
    xcWorkspacePath: '**/*.xcodeproj/project.xcworkspace'
    xcodeVersion: 'default' # Options: 10, 11, 12, 13, 14, default, specifyPath

Hinzufügen von Codesignaturen und Bereitstellung

Eine Xcode-App muss signiert und bereitgestellt werden, damit sie auf einem Gerät ausgeführt oder im App Store veröffentlicht werden kann. Beim Signierungs- und Bereitstellungsprozess wird Zugriff auf Ihr P12-Signaturzertifikat und ein oder mehrere Bereitstellungsprofile benötigt. Die Aufgaben Install Apple Certificate und Install Apple Provisioning Profile machen diese während eines Builds für Xcode verfügbar.

Weitere Informationen finden Sie unter Signieren Ihrer mobilen App.

Carthage

Wenn Ihr Projekt Carthage mit einem privaten Carthage-Repository verwendet, können Sie die Authentifizierung einrichten, indem Sie eine Umgebungsvariable namens GITHUB_ACCESS_TOKEN mit dem Wert eines Tokens einrichten, das Zugriff auf das Repository hat. Carthage erkennt und verwendet diese Umgebungsvariable automatisch.

Fügen Sie das geheime Token nicht direkt zu Ihrer Pipeline-YAML hinzu. Erstellen Sie stattdessen eine neue Pipelinevariable mit aktivierter Sperre im Variablenbereich, um diesen Wert zu verschlüsseln. Weitere Informationen finden Sie unter Geheime Variablen.

Hier ist ein Beispiel, das eine geheime Variable namens myGitHubAccessToken für den Wert der GITHUB_ACCESS_TOKEN-Umgebungsvariable verwendet.

- script: carthage update --platform iOS
  env:
    GITHUB_ACCESS_TOKEN: $(myGitHubAccessToken)

Testen auf von Azure gehosteten Geräten

Fügen Sie die Aufgabe App Center Test hinzu, um die App in einem gehosteten Lab mit iOS- und Android-Geräten zu testen. Eine kostenlose Testversion von App Center ist erforderlich, deren kostenpflichtige Version später verwendet werden muss.

Zuerst registrieren Sie sich bei App Center.

# App Center test v1
# Test app packages with Visual Studio App Center.
- task: AppCenterTest@1
  inputs:
    appFile: # string. Alias: app. Required. Binary application file path. 
    artifactsDirectory: '$(Build.ArtifactStagingDirectory)/AppCenterTest' # string. Alias: artifactsDir. Required. Artifacts directory. Default: $(Build.ArtifactStagingDirectory)/AppCenterTest.
  # Prepare Tests
    #prepareTests: true # boolean. Alias: enablePrepare. Prepare tests. Default: true.
    frameworkOption: 'appium' # 'appium' | 'espresso' | 'calabash' | 'uitest' | 'xcuitest'. Alias: framework. Required when enablePrepare = true. Test framework. Default: appium.
    #appiumBuildDirectory: # string. Alias: appiumBuildDir. Required when enablePrepare = true && framework = appium. Build directory. 
    #espressoBuildDirectory: # string. Alias: espressoBuildDir. Optional. Use when enablePrepare = true && framework = espresso. Build directory. 
    #espressoTestApkFile: # string. Alias: espressoTestApkPath. Optional. Use when enablePrepare = true && framework = espresso. Test APK path. 
    #calabashProjectDirectory: # string. Alias: calabashProjectDir. Required when enablePrepare = true && framework = calabash. Project directory. 
    #calabashConfigFile: # string. Optional. Use when enablePrepare = true && framework = calabash. Cucumber config file. 
    #calabashProfile: # string. Optional. Use when enablePrepare = true && framework = calabash. Profile to run. 
    #calabashSkipConfigCheck: false # boolean. Optional. Use when enablePrepare = true && framework = calabash. Skip Configuration Check. Default: false.
    #uiTestBuildDirectory: # string. Alias: uitestBuildDir. Required when enablePrepare = true && framework = uitest. Build directory. 
    #uitestStorePath: # string. Optional. Use when enablePrepare = true && framework = uitest. Store file. 
    #uiTestStorePassword: # string. Alias: uitestStorePass. Optional. Use when enablePrepare = true && framework = uitest. Store password. 
    #uitestKeyAlias: # string. Optional. Use when enablePrepare = true && framework = uitest. Key alias. 
    #uiTestKeyPassword: # string. Alias: uitestKeyPass. Optional. Use when enablePrepare = true && framework = uitest. Key password. 
    #uiTestToolsDirectory: # string. Alias: uitestToolsDir. Optional. Use when enablePrepare = true && framework = uitest. Test tools directory. 
    #signInfo: # string. Optional. Use when framework = calabash || framework = uitest. Signing information. 
    #xcUITestBuildDirectory: # string. Alias: xcuitestBuildDir. Optional. Use when enablePrepare = true && framework = xcuitest. Build directory. 
    #xcUITestIpaFile: # string. Alias: xcuitestTestIpaPath. Optional. Use when enablePrepare = true && framework = xcuitest. Test IPA path. 
    #prepareOptions: # string. Alias: prepareOpts. Optional. Use when enablePrepare = true. Additional options. 
  # Run Tests
    #runTests: true # boolean. Alias: enableRun. Run tests. Default: true.
    credentialsOption: 'serviceEndpoint' # 'serviceEndpoint' | 'inputs'. Alias: credsType. Required when enableRun = true. Authentication method. Default: serviceEndpoint.
    #serverEndpoint: # string. Required when enableRun = true && credsType = serviceEndpoint. App Center service connection. 
    #username: # string. Required when enableRun = true && credsType = inputs. App Center username. 
    #password: # string. Required when enableRun = true && credsType = inputs. App Center password. 
    appSlug: # string. Required when enableRun = true. App slug. 
    devices: # string. Required when enableRun = true. Devices. 
    #series: 'master' # string. Optional. Use when enableRun = true. Test series. Default: master.
    #dsymDirectory: # string. Alias: dsymDir. Optional. Use when enableRun = true. dSYM directory. 
    localeOption: 'en_US' # 'da_DK' | 'nl_NL' | 'en_GB' | 'en_US' | 'fr_FR' | 'de_DE' | 'ja_JP' | 'ru_RU' | 'es_MX' | 'es_ES' | 'user'. Alias: locale. Required when enableRun = true. System language. Default: en_US.
    #userDefinedLocale: # string. Optional. Use when enableRun = true && locale = user. Other locale. 
    #loginOptions: # string. Alias: loginOpts. Optional. Use when enableRun = true && credsType = inputs. Additional options for login. 
    #runOptions: # string. Alias: runOpts. Optional. Use when enableRun = true. Additional options for run. 
    #skipWaitingForResults: false # boolean. Alias: async. Optional. Use when enableRun = true. Do not wait for test result. Default: false.
  # Advanced
    #cliFile: # string. Alias: cliLocationOverride. App Center CLI location. 
    #showDebugOutput: false # boolean. Alias: debug. Enable debug output. Default: false.

Beibehalten von Artefakten mit dem Builddatensatz

Fügen Sie die Aufgaben Copy Files und Publish Build Artifacts hinzu, um Ihr IPA mit dem Builddatensatz zu speichern oder zu testen und in nachfolgenden Pipelines bereitzustellen. Weitere Informationen finden Sie unter Artefakte.

- task: CopyFiles@2
  inputs:
    contents: '**/*.ipa'
    targetFolder: '$(build.artifactStagingDirectory)'
- task: PublishBuildArtifacts@1
  inputs:
    PathtoPublish: '$(Build.ArtifactStagingDirectory)'
    ArtifactName: 'drop'
    publishLocation: 'Container'

Bereitstellen

App Center

Fügen Sie die Aufgabe App Center Distribute hinzu, um eine App an eine Gruppe von Tester*innen oder Betabenutzer*innen zu verteilen, oder stufen Sie die App auf Intune oder den Apple App Store höher. Ein kostenloses App Center-Konto wird benötigt (es ist keine Zahlung erforderlich).

# App Center distribute v3
# Distribute app builds to testers and users via Visual Studio App Center.
- task: AppCenterDistribute@3
  inputs:
    serverEndpoint: # string. Required. App Center service connection. 
    appSlug: # string. Required. App slug. 
    appFile: # string. Alias: app. Required. Binary file path. 
    #buildVersion: # string. Build version. 
    releaseNotesOption: 'input' # 'input' | 'file'. Alias: releaseNotesSelection. Required. Create release notes. Default: input.
    releaseNotesInput: # string. Required when releaseNotesSelection = input. Release notes. 
    #releaseNotesFile: # string. Required when releaseNotesSelection = file. Release notes file. 
    #isMandatory: false # boolean. Require users to update to this release. Default: false.
    destinationType: 'groups' # 'groups' | 'store'. Required. Release destination. Default: groups.
    #distributionGroupId: # string. Alias: destinationGroupIds. Optional. Use when destinationType = groups. Destination IDs. 
    #destinationStoreId: # string. Required when destinationType = store. Destination ID. 
    #isSilent: # boolean. Optional. Use when destinationType = groups. Do not notify testers. Release will still be available to install. 
  # Symbols
    #symbolsOption: 'Apple' # 'Apple' | 'Android' | 'UWP'. Alias: symbolsType. Symbols type. Default: Apple.
    #symbolsPath: # string. Optional. Use when symbolsType == AndroidNative || symbolsType = Windows. Symbols path. 
    #appxsymPath: # string. Optional. Use when symbolsType = UWP. Symbols path (*.appxsym). 
    #symbolsDsymFiles: # string. Alias: dsymPath. Optional. Use when symbolsType = Apple. dSYM path. 
    #symbolsMappingTxtFile: # string. Alias: mappingTxtPath. Optional. Use when symbolsType = Android. Mapping file. 
    #nativeLibrariesPath: # string. Optional. Use when symbolsType == Android. Native Library File Path. 
    #symbolsIncludeParentDirectory: # boolean. Alias: packParentFolder. Optional. Use when symbolsType = Apple. Include all items in parent folder.

Apple App Store

Installieren Sie die Apple App Store-Erweiterung, und verwenden Sie die folgenden Aufgaben, um die Interaktion mit dem App Store zu automatisieren. Standardmäßig authentifizieren sich diese Aufgaben bei Apple mit einer Dienstverbindung, die Sie konfigurieren.

Freigabe

Fügen Sie die Aufgabe App Store Release hinzu, um die Veröffentlichung von Updates für vorhandene iOS TestFlight-Beta-Apps oder Produktions-Apps im App Store zu automatisieren.

Lesen Sie die Einschränkungen der Verwendung dieser Aufgabe mit der Zwei-Faktor-Authentifizierung von Apple, da die Apple-Authentifizierung regionsspezifisch ist und die Fastlane-Sitzungstoken schnell ablaufen und neu erstellt und neu konfiguriert werden müssen.

- task: AppStoreRelease@1
  displayName: 'Publish to the App Store TestFlight track'
  inputs:
    serviceEndpoint: 'My Apple App Store service connection' # This service connection must be added by you
    appIdentifier: com.yourorganization.testapplication.etc
    ipaPath: '$(build.artifactstagingdirectory)/**/*.ipa'
    shouldSkipWaitingForProcessing: true
    shouldSkipSubmission: true

Höherstufen

Fügen Sie die Aufgabe App Store Promote hinzu, um die Höherstufung einer zuvor übermittelten App von iTunes Connect zum App Store zu automatisieren.

- task: AppStorePromote@1
  displayName: 'Submit to the App Store for review'
  inputs:
    serviceEndpoint: 'My Apple App Store service connection' # This service connection must be added by you
    appIdentifier: com.yourorganization.testapplication.etc
    shouldAutoRelease: false