Build and Test Xcode Projects

Last Update: 3/6/2017

Team Services | TFS 2017 | TFS 2015 | Previous versions: XAML Build, Release

Notice: Apple's WWDR certificate expired on Feb 14th and as a result you may experience signing failures if you have not updated the cert and removed the old one. Follow the steps outlined by Apple under What should I do if Xcode doesn’t recognize my distribution certificate? to resolve the problem. Note that this also affects development certs despite the title.

The prerequisites in this case are simple: Your Mac needs to have Node.js, Xcode, and xcpretty (for testing) installed. Simply open the OSX Terminal app and follow these setup instructions. On startup the agent will automatically register itself with VSTS / TFS when you start up the agent for the first time.

The Xcode Build task used here supports features to simplify configuration of code signing. See Simple, Secure CI App Signing for details.

Troubleshooting Tip: You should either setup the cross-platform agent as a launch agent (./svc.sh install agent) or run it as an interactive process (node agent/vsoagent.js) when building an Xcode project that involves code signing like iOS.

Project Setup

For the purposes of this tutorial we will assume you are trying to build an iOS app but the concepts described here essentially translate to other Xcode builds.

There is really only one step required for configuring an Xcode project for a CI environment that is not done by default when you create an Xcode project. Xcode has the concept of schemes and you'll need to set one of these as "Shared" and add it to source control so it can be used during your CI builds. Follow these steps:

  1. In Xcode, open your project and go to Product Scheme Manage Schemes...

  2. Check Shared next to the Scheme you want to use during CI. Remember the name of the scheme you shared as we will reference it later.

  3. Now add the new files and folders in your .xcodeproj folder (specifically the xcsharedata folder to source control).

Shared Scheme

Create the definition

  1. Open your team project in your web browser.

    • On-premises http://{your_server}:8080/tfs/DefaultCollection/{your_team_project}
    • Visual Studio Team Services https://{your_account}.visualstudio.com/DefaultCollection/{your_team_project}
  2. Create a build definition.

    New build definition

  3. Click Empty to start with an empty definition.

Set Build Variables

Next, click on the Variables tab and add in the Configuration and SDK variables.

  • Configuration: Debug or Release
  • SDK: iphoneos

    Xcode Variables

Add Steps

On the Build tab, add some steps.

Build: Xcode Build Build: Xcode

Settings:

  • Actions: build
  • Configuration: Xcode can have any number of configurations but "Debug" and "Release" are there by default. We'll use $(Configuration) which gets this value from a Variable.
  • SDK: Run xcodebuild -showsdks to see the valid list of SDKs. Ex: "iphoneos", "iphonesimulator". We'll use $(SDK) so it is set as a variable.
  • Workspace Path: This can be left to the default value unless you want to explicitly override it.
  • Scheme: Set this to the name of the Scheme you shared in your project
  • Create App Pacakge: Checked. This will automatically generate an app package (ipa) for your project once the build has completed.

There are a few other options worth noting:

  • The Signing & Provisioning category provides a number of options for making signing less complicated. See Simple, Secure CI App Signing for details.
  • Advanced / Use xcpretty will format xcodebuild output with xcpretty xcpretty. We'll cover this more when we add in a test.
  • Advanced / Xcode Developer Path allows you to specify the path of a different version of Xcode than is installed by default. Ex: /Applications/Xcode6.4.app/Contents/Developer
Build: Publish Build Artifacts Build: Publish Build Artifacts

Settings:


  • Copy Root: The default location is output/$(SDK)/$(Configuration)/$(Configuration)-$(SDK)/build.dsym
  • Contents: *.ipa
  • Artifact Name: ipa
  • Artifact Type: Server

Save and click "Queue Build..." to test it out!

Xcode Task

Troubleshooting Tip: If you encounter a "User interaction not allowed" error when running the agent as a launch agent, you will either need check the "Unlock default keychain" option or switch to referencing signing certificates using a file. See Simple, Secure CI App Signing for details.

Add In Tests

If you've created unit or UI tests in your Xcode project, you can run these and publish the results to VSTS using xcpretty. Note you will need to have xcpretty installed on the OSX machine the cross-platform build agent is on as this is not part of Xcode itself.

On the Build tab, add some steps.

Build: Xcode Build Build: Xcode

Move this to the top of your build definition (before build) and use the following settings:

  • Actions test
  • Configuration $(Configuration)
  • SDK: $(Test_SDK)
  • Workspace Path: The same value as your build.
  • Scheme: The same value as your build.
  • Create App Pacakge: Unchecked.
  • Advanced > Use xcpretty: Checked.
  • Advanced > Xcode Developer Path: The same value as your build.

Troubleshooting Tip: The "Release" configuration is not testable by default. You'll either need to use "Debug" or enable testability in for the configuration in Xcode. Also, be sure to pay attention to capitalization as "Debug" will work but "debug" may not.

Next, click on the Variables tab and add Test_SDK as a variable set to iphonesimulator

Save and click "Queue Build..." to test it out!

Troubleshooting Tip: If you run into issues with your tests hanging and/or not being able to start the iOS Simulator at times you can opt to add a Command Line task for the "killall" tool with "iOS\ Simulator" as an argument (killall iOS\ Simulator). This will force shut down the simulator in the event it is hung. Exercise care when running the command if you have multiple agents running for the same user and that you do not accidently kill other processes.

Q&A

What other kinds of apps can I build?

Build your app

What other kinds of build steps are available?

Specify your build steps

How do we protect our codebase from build breaks?

How do I modify other parts of my build definition?

I selected parallel multi-configuration, but only one build is running at a time.

If you're using Team Services, you might need more concurrent pipelines. See Concurrent build and release pipelines in Visual Studio Team Services.

How do I see what has changed in my build definition?

View the change history of your build definition

Do I need an agent?

You need at least one agent to run your build or release. Get an agent.

I can't select a default agent queue and I can't queue my build or release. How do I fix this?

See queues.

I use Team Foundation Server on-premises and I don't see some of these features. Why not?

Some of these features are available only on Visual Studio Team Services and not yet available on-premises. Some features are available on-premises if you have upgraded to the latest version of TFS.