Compilar, testar e implantar aplicativos Xcode

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

Saiba como compilar e implantar projetos Xcode com o Azure Pipelines.

Pré-requisitos

Criar o pipeline

  1. Entre na organização do Azure DevOps e acesse seu projeto.

  2. Vá para Pipelines e selecione Novo pipeline ou Criar pipeline se estiver criando seu primeiro pipeline.

  3. Percorra as etapas do assistente selecionando primeiro o GitHub como o local do código-fonte.

  4. Você pode ser redirecionado para o GitHub para então entrar. Nesse caso, insira suas credenciais do GitHub.

  5. Quando a lista de repositórios for exibida, selecione o repositório.

  6. Você poderá ser redirecionado ao GitHub para instalar o aplicativo do Azure Pipelines. Se sim, selecione Aprovar e instalar.

Quando a guia Configurar for exibida, selecione Xcode.

  1. Quando o novo pipeline for exibido, observe o YAML para ver o que ele faz. Ao final, selecione Salvar e executar.

    Botão Salvar e executar em um novo pipeline YAML

  2. Será solicitado que você confirme um novo arquivo azure-pipelines.yml em seu repositório. Uma vez que a mensagem estiver satisfatória para você, selecione Salvar e executar novamente.

    Para inspecionar seu pipeline em ação, selecione o trabalho de compilação.

    Você acabou de criar e executar um pipeline que criamos automaticamente para você pois seu código parecia ser uma boa combinação para o modelo Xcode.

    Agora você tem um pipeline YAML em funcionamento (azure-pipelines.yml) no seu repositório e pronto para você personalizar!

  3. Quando quiser fazer alterações no pipeline, selecione-o na página Pipelines e edite o arquivo azure-pipelines.yml.

Confira as seções abaixo para aprender algumas das formas mais comuns de personalizar seu pipeline.

Dica

Para fazer alterações no arquivo YAML, conforme descrito neste tópico, selecione o pipeline na página Pipelines e escolha Editar para abrir um editor para o arquivo azure-pipelines.yml.

Ambiente de build

Você pode usar o Azure Pipelines para criar seus aplicativos com o Xcode sem precisar configurar qualquer infraestrutura própria. O Xcode é pré-instalado em agentes do macOS hospedados pela Microsoft no Azure Pipelines. Você pode usar os agentes do macOS para executar suas compilações.

Para obter as versões exatas do Xcode pré-instaladas, confira Agentes hospedados pela Microsoft.

Crie um arquivo chamado azure-pipelines.yml na raiz do repositório. Então adicione o seguinte snippet ao arquivo azure-pipelines.yml para selecionar o pool de agentes apropriado:

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

Criar um aplicativo com Xcode

Para criar um aplicativo com Xcode, adicione o snippet a seguir ao arquivo azure-pipelines.yml. Esse é um snippet mínimo para construir um projeto iOS usando seu esquema padrão para o Simulador e sem empacotamento. Altere valores para que eles combinem com a configuração do projeto. Confira a tarefa Xcode para obter mais informações sobre essas opções.

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

Assinatura e provisionamento

Um aplicativo Xcode deve ser assinado e provisionado para ser executado em um dispositivo ou ser publicado na App Store. O processo de assinatura e provisionamento precisa de acesso ao certificado de assinatura P12 e a um ou mais perfis de provisionamento. As tarefas Instalar o Apple Certificate e Instalar o Perfil de Provisionamento da Apple as disponibilizam para o Xcode durante uma compilação.

Confira Inscrever seu aplicativo móvel para saber mais.

Carthage

Se o seu projeto usa Carthage com um repositório Carthage privado, você pode configurar a autenticação definindo uma variável de ambiente nomeada GITHUB_ACCESS_TOKEN com o valor de um token que tem acesso ao repositório. O Carthage detectará e usará automaticamente essa variável de ambiente.

Não adicione o token secreto diretamente ao YAML do pipeline. Em vez disso, crie uma variável de pipeline com seu bloqueio habilitado no painel de Variáveis para criptografar esse valor. Confira variáveis secretas.

Veja aqui um exemplo que usa uma variável secreta chamada myGitHubAccessToken para o valor da variável de ambiente GITHUB_ACCESS_TOKEN.

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

Teste em dispositivos hospedados no Azure

Adicione a tarefa Teste do App Center para testar o aplicativo em um laboratório hospedado de dispositivos iOS e Android. É necessária uma avaliação gratuita do App Center, que posteriormente deve ser convertida em paga.

Inscrever-se com o App Center primeiro.

# 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.

Reter artefatos com o registro de compilação

Adicione as tarefas Copiar Arquivos e Publicar Artefatos de Compilação para armazenar seu IPA com o registro de compilação ou teste e implantá-lo em pipelines subsequentes. Confira Artefatos.

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

Implantar

App Center

Adicione a tarefa Distribuição do App Center para distribuir um aplicativo para um grupo de testadores ou usuários beta, ou promova o aplicativo para Intune ou a Apple App Store. É necessário ter uma conta gratuita do App Center (nenhum pagamento é necessário).

# 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

Instale a extensão da Apple App Store e use as tarefas a seguir para automatizar a interação com a App Store. Por padrão, essas tarefas são autenticadas na Apple usando uma conexão de serviço configurada.

Versão

Adicione a tarefa Versão da App Store para automatizar a versão das atualizações para aplicativos beta do iOS testFlight ou aplicativos de produção existentes na App Store.

Confira as limitações de uso dessa tarefa com a autenticação de dois fatores da Apple, já que essa autenticação é específica da região e os tokens de sessão fastlane expiram rapidamente e devem ser recriados e reconfigurados.

- 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

Promover

Adicione a tarefa Promover App Store para automatizar a promoção de um aplicativo enviado anteriormente do iTunes Connect para a 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