建置、測試及部署 Xcode 應用程式

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

瞭解如何使用 Azure Pipelines 建置及部署 Xcode 專案。

必要條件

建立管線

  1. 登入您的 Azure DevOps 組織並前往您的專案。

  2. 移至 [管線],然後在建立第一個管線時選取 [ 新增管線 ] 或 [建立管線 ]。

  3. 執行精靈的步驟,首先選取 [GitHub] 作為您的原始程式碼位置。

  4. 系統可能會將您重新導向至 GitHub 以進行登入。 若是如此,請輸入 GitHub 認證。

  5. 當您看到存放庫清單時,請選取您的存放庫。

  6. 系統可能會將您重新導向至 GitHub,以安裝 Azure Pipelines 應用程式。 如果發生此情況,請選取 [核准並安裝]

當 [設定] 索引標籤出現時,請選取 [Xcode]。

  1. 在新的管線出現時,請查看 YAML 以了解其用途。 當您準備好時,請選取 [儲存並執行]

    在新的 YAML 管線中儲存並執行按鈕

  2. 系統會提示您將新的 azure-pipelines.yml 檔案認可至存放庫。 滿意訊息之後,請選取 [ 儲存],然後再次執行

    如果您想要監看管線的運作情形,請選取建置作業。

    您剛建立並執行我們為您自動建立的管線,因為您的程式代碼似乎與 Xcode 範本相符

    您現在已在存放庫中有一個可運作的 YAML 管線 (azure-pipelines.yml),可供您自定義!

  3. 當您準備好變更管線時,請在 [管線] 頁面中選取它,然後編輯azure-pipelines.yml檔案。

請參閱下列各節,以瞭解自定義管線的一些較常見方式。

提示

若要變更本主題中所述的 YAML 檔案,請在 [管線] 頁面中選取管線,然後選取 [編輯] 以開啟檔案的azure-pipelines.yml編輯器。

建置環境

您可以使用 Azure Pipelines 搭配 Xcode 建置應用程式,而不需要設定您自己的任何基礎結構。 Xcode 會預安裝在 Azure Pipelines 中 Microsoft 裝載的 macOS 代理程式 上。 您可以使用 macOS 代理程式來執行組建。

如需預安裝之 Xcode 的確切版本,請參閱 Microsoft 裝載的代理程式。

在存放庫根目錄中建立名為 azure-pipelines.yml 的檔案。 然後,將下列代碼段新增至您的 azure-pipelines.yml 檔案,以選取適當的代理程式集區:

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

使用 Xcode 建置應用程式

若要使用 Xcode 建置應用程式,請將下列代碼段新增至您的 azure-pipelines.yml 檔案。 這是使用其預設配置建置 iOS 專案的最小代碼段,適用於模擬器,而不需封裝。 變更值以符合您的項目組態。 如需這些選項的詳細資訊, 請參閱 Xcode 工作。

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

簽署和布建

必須簽署並布建 Xcode 應用程式,才能在裝置上執行,或發佈至 App Store。 簽署和布建程式需要存取您的 P12 簽署憑證和一或多個布建配置檔。 安裝Apple 憑證安裝Apple 布建配置檔工作可在建置期間提供給 Xcode 使用。

請參閱 簽署行動應用程式 以深入瞭解。

迦太基

如果您的專案使用 Carthage 搭配私人 Carthage 存放庫,您可以藉由設定名為 GITHUB_ACCESS_TOKEN 且具有存放庫存取權之令牌值的環境變數來設定驗證。 Carthage 會自動偵測並使用這個環境變數。

請勿將秘密令牌直接新增至管線 YAML。 相反地,請建立新的管線變數,並在 [變數] 窗格上啟用其鎖定,以加密此值。 請參閱 秘密變數

以下是使用名為 myGitHubAccessToken 的秘密變數作為環境變數值的 GITHUB_ACCESS_TOKEN 範例。

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

在 Azure 裝載的裝置上進行測試

新增 App Center 測試工作,以在 iOS 和 Android 裝置的託管實驗室中測試應用程式。 需要 App Center 免費試用,之後必須轉換為付費。

請先向 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.

使用組建記錄保留成品

新增 [複製檔案] 和 [發佈組建成品] 工作,以使用組建記錄或測試您的 IPA,並將其部署在後續管線中。 請參閱 成品

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

部署

App Center

新增 App Center 散發工作,將應用程式散發給測試人員或 Beta 使用者群組,或將應用程式升階至 Intune 或 Apple App Store。 需要免費的 App Center 帳戶(不需要付款)。

# 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

安裝 Apple App Store 擴充功能,並使用下列工作來自動化與 App Store 的互動。 根據預設,這些工作會使用 您設定的服務連線 向Apple進行驗證。

版本

新增 App Store 發行工作,將更新發行自動化至 App Store 中現有的 iOS TestFlight Beta 應用程式或生產應用程式。

請參閱 搭配Apple雙因素驗證使用此工作的限制 ,因為Apple驗證是區域特定且fastlane會話令牌會快速過期,且必須重新建立和重新設定。

- 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

促銷

新增 App Store 升級工作,將先前提交的應用程式從 iTunes 連線 自動升級至 App Store。

- 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