Xcode 앱 빌드, 테스트 및 배포

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

Azure Pipelines를 사용하여 Xcode 프로젝트를 빌드하고 배포하는 방법을 알아봅니다.

필수 조건

  • GitHub 리포지토리의 Xcode 9+ 프로젝트입니다. 프로젝트가 없는 경우 앱에 대한 Xcode 프로젝트 만들기를 참조 하세요.

파이프라인 만들기

  1. Azure DevOps 조직에 로그인하고, 프로젝트로 이동합니다.

  2. 파이프라인으로 이동한 다음 새 파이프라인을 선택하거나 첫 번째 파이프라인을 만드는 경우 파이프라인 만들기를 선택합니다.

  3. 먼저 소스 코드의 위치로 GitHub 선택하여 마법사의 단계를 수행합니다.

  4. 로그인할 GitHub로 리디렉션될 수 있습니다. 그렇다면 GitHub 자격 증명을 입력합니다.

  5. 리포지토리 목록이 표시되면 리포지토리를 선택합니다.

  6. Azure Pipelines 앱을 설치하도록 GitHub로 리디렉션될 수 있습니다. 그렇다면 승인 및 설치를 선택합니다.

구성 탭이 나타나면 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 PipelinesMicrosoft 호스팅 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 리포지토리와 함께 Carthage를 사용하는 경우 리포지토리에 액세스할 수 있는 토큰 값으로 명명된 GITHUB_ACCESS_TOKEN 환경 변수를 설정하여 인증을 설정할 수 있습니다. Carthage는 이 환경 변수를 자동으로 감지하고 사용합니다.

비밀 토큰을 파이프라인 YAML에 직접 추가하지 마세요. 대신 변수 창에서 잠금을 사용하도록 설정된 새 파이프라인 변수를 만들어 이 값을 암호화합니다. 비밀 변수를 참조 하세요.

다음은 환경 변수 값 GITHUB_ACCESS_TOKEN 에 명명된 myGitHubAccessToken 비밀 변수를 사용하는 예제입니다.

- 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 배포 작업을 추가하여 테스터 또는 베타 사용자 그룹에 앱을 배포하거나 앱을 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 앱 스토어

Apple App Store 확장을 설치하고 다음 작업을 사용하여 App Store와의 상호 작용을 자동화합니다. 기본적으로 이러한 작업은 사용자가 구성하는 서비스 연결을 사용하여 Apple에 인증됩니다.

Release

App Store 릴리스 작업을 추가하여 App Store에서 기존 iOS TestFlight 베타 앱 또는 프로덕션 앱에 대한 업데이트 릴리스를 자동화합니다.

Apple 인증은 지역별 및 fastlane 세션 토큰이 빠르게 만료되며 다시 만들고 다시 구성해야 하므로 Apple 2단계 인증에서 이 작업을 사용하는 제한 사항을 참조하세요.

- 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

홍보

앱 스토어 승격 작업을 추가하여 이전에 제출한 앱의 승격을 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