Edit

Share via


Build, test, and deploy Xcode apps

Azure DevOps Services | Azure DevOps Server | Azure DevOps Server 2022 | Azure DevOps Server 2020

This article shows you how to build and deploy Xcode projects with YAML pipelines in Azure Pipelines.

Prerequisites

  • An Azure DevOps organization and project where you have permission to create pipelines and deploy apps.
  • An Xcode 9+ project and app in a GitHub repository. For more information, see Creating an Xcode Project for an App.

Create the pipeline

Important

During GitHub procedures, you might be prompted to create a GitHub service connection or be redirected to GitHub to sign in, install Azure Pipelines, or authorize Azure Pipelines. Follow the onscreen instructions to complete the process. For more information, see Access to GitHub repositories.

  1. In your Azure DevOps project, select Pipelines > New pipeline, or Create pipeline if this pipeline is the first in the project.
  2. Select GitHub as the location of your source code.
  3. On the Select a repository screen, select the repository for your Xcode project.
  4. On the Configure your pipeline screen, select Xcode.

Azure Pipelines provides a starter pipeline based on the Xcode template. Review the code in azure-pipelines.yml.

Build environment

Xcode is preinstalled on the Microsoft-hosted macOS agents in Azure Pipelines, so you don't have to set up any infrastructure. For the exact versions of Xcode that are preinstalled, see Microsoft-hosted agents software.

The pool node at the top of your azure-pipelines.yml file selects the appropriate agent pool.

pool:
  vmImage: 'macOS-latest'

Xcode build task

The Xcode task builds, tests, or archives an Xcode workspace on macOS, and it can optionally package an app. The Xcode step in the starter azure-pipelines.yml file builds the iOS project by using its default scheme, for the Simulator, and without packaging. You can change values and add parameters to match your project configuration.

Development build:

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

Production build for App Store:

For production releases, specify an explicit Xcode version, your app's scheme, and the Release configuration:

steps:
- task: Xcode@5
  inputs:
    actions: 'build'
    scheme: 'YourAppScheme'
    sdk: 'iphoneos'
    configuration: 'Release'
    xcWorkspacePath: '**/*.xcodeproj/project.xcworkspace'
    xcodeVersion: '14'
    packageApp: true
    exportPath: '$(build.artifactStagingDirectory)'
    exportOptions: 'automatic'

Key differences for production:

  • xcodeVersion: Specify a fixed version (e.g., '14') instead of 'default' for consistent, reproducible builds.
  • scheme: Replace the empty string with your app's actual scheme name.
  • sdk: Use 'iphoneos' for device builds; use 'iphonesimulator' for simulator builds.
  • configuration: Use 'Release' for production; use 'Debug' for development.
  • packageApp: Set to true to generate an .ipa file for distribution.
  • exportPath: Directs the package output to the build staging directory for artifact publishing.

Save and run the pipeline

When you finish reviewing the code in azure-pipelines.yml, select Save and run.

Screenshot of the Save and run button in a new YAML pipeline.

Optionally, edit the Commit message and provide a description. Then select Save and run again to commit the azure-pipelines.yml file to your repository and start a build.

The build run page shows build details and progress. If you want to watch your pipeline in action, select Job on the lower part of the page.

You now have a working YAML pipeline, azure-pipelines.yml, in your repository that's ready to customize.

Customize your pipeline

To make changes to your pipeline, select Edit on the pipeline page. The following sections describe some common ways to customize your Xcode pipeline based on your specific needs:

  • Signing and provisioning: Required to deploy to physical devices or the App Store.
  • Dependency management: Configure authentication for private repositories.
  • Artifact management: Store build outputs for testing and deployment.
  • Distribution: Automate release to TestFlight or the App Store.

Add signing and provisioning tasks

To run your Xcode app on a physical device or publish it to the App Store, you need to sign and provision the app. This process involves using a P12 signing certificate (a security credential that verifies your app's identity) and provisioning profiles (which authorize your app for specific devices or distribution). For more information, see Sign your mobile app.

To make the certificate and profile available to Xcode during a build, add the Install Apple Certificate and Install Apple Provisioning Profile tasks to your pipeline.

Manage dependencies

Your Xcode project might use dependency managers to handle third-party libraries and frameworks. The following sections describe how to configure authentication for private repositories with different dependency managers.

Swift Package Manager

Swift Package Manager (SPM) is Apple's native dependency manager and is integrated directly into Xcode. For projects that use SPM with private packages, you need to configure Git authentication.

If your private Swift packages are hosted on GitHub, set up authentication by using an environment variable named GITHUB_ACCESS_TOKEN with a value of a personal access token that has access to the repository.

Don't add the secret token directly to your pipeline YAML, as this action exposes it in your source code. For more information, see Set secret variables.

The following pipeline code uses a secret variable named myGitHubAccessToken for authentication when resolving Swift Package dependencies:

- task: Xcode@5
  inputs:
    actions: 'build'
    scheme: ''
    sdk: 'iphoneos'
    configuration: 'Release'
    xcWorkspacePath: '**/*.xcodeproj/project.xcworkspace'
  env:
    GITHUB_ACCESS_TOKEN: $(myGitHubAccessToken)

For private packages hosted on Azure Repos or other Git providers, configure the appropriate Git credentials before the build step.

CocoaPods

If your project uses CocoaPods, use the CocoaPods task to install dependencies.

- task: CocoaPods@0
  inputs:
    workingDirectory: '$(System.DefaultWorkingDirectory)'
    forceRepo: false

Carthage

If your project uses Carthage (a dependency manager for iOS/macOS projects) with a private Carthage repository, set up authentication by using an environment variable named GITHUB_ACCESS_TOKEN with a value of a token that has access to the repository. Carthage automatically detects and uses this environment variable.

Don't add the secret token directly to your pipeline YAML, as this action exposes it in your source code. For more information, see Set secret variables.

The following pipeline code uses a secret variable named myGitHubAccessToken for the value of the GITHUB_ACCESS_TOKEN environment variable.

- script: carthage update --platform iOS
  displayName: 'Update Carthage dependencies'
  env:
    GITHUB_ACCESS_TOKEN: $(myGitHubAccessToken)

Test on Azure-hosted devices

Visual Studio App Center was retired on March 31, 2025. Learn about recommended alternatives.

Keep artifacts with the build record

To store your iOS AppStore Package (IPA) file with the build record or test and deploy it in subsequent pipelines, add the Copy Files and Publish Pipeline Artifacts tasks to your pipeline.

- task: CopyFiles@2
  inputs:
    contents: '**/*.ipa'
    targetFolder: '$(build.artifactStagingDirectory)'
- task: PublishPipelineArtifact@1
  inputs:
    targetPath: '$(build.artifactStagingDirectory)'
    artifact: 'drop'

Deploy to Apple App Store or TestFlight

To distribute an app to testers or beta users, use Apple's TestFlight or deploy directly to the App Store. See the section below for Apple App Store deployment.

For beta testing and user feedback, consider using:

Install the Apple App Store extension and deploy to Apple App Store

To automate interaction with the Apple App Store, install the Apple App Store extension, and then use the following tasks in your pipeline. By default, these tasks authenticate to Apple by using a service connection that you must configure.

To automate the release of updates to existing iOS TestFlight beta apps or production apps in the App Store, add the App Store Release task.

There are limitations when using this task with Apple two-factor authentication. Apple authentication is region-specific, and fastlane session tokens (temporary credentials used to authenticate with Apple) expire quickly and must be recreated and reconfigured periodically.

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

To automate the promotion of a previously submitted app from iTunes Connect to the App Store, add the App Store Promote task.

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