Continuous integration for iPhone projects in TeamCity

Jonah Williams ·

Carbon Five has been using TeamCity as our continuous integration server for most of our recent projects, including our iPhone work. Out continuous integration environment monitors the git repository used by each project, runs the project’s tests each time a change is pushed to the repository, and can automatically produce an ad-hoc build of an app each time the tests pass.

Configuring the TeamCity build agent
In order to build an iPhone project I need a build runner running on an OS X machine with Xcode installed so I added a remote build agent on a mac mini. Each of the build configurations below then requires that compatible build agents be running on OS X.

Running unit tests with GTM
I have been using GTM to run iPhone unit tests as part of the build process for a “Unit Tests” build target (see Alon’s post on our iPhone Unit Testing Toolkit). Running these tests with a TeamCity build agent just requires a command line build runner which calls the `xcodebuild` command and specifies the project, built target, and configuration to build.

Command executable: /Developer/usr/bin/xcodebuild
Command parameters: -project example_project.xcodeproj -target “Unit Tests” -configuration “Debug” -sdk iphonesimulator4.0

Ad-hoc builds
Ad-hoc builds run with a similar command:

Command executable: /Developer/usr/bin/xcodebuild
Command parameters: -project example_project.xcodeproj -target “ExampleProject” -configuration “Distribution” -sdk iphoneos4.0
Once the ad-hoc build has been created I want to save the resulting app and its debug symbols so I add these as build artifacts under the TeamCity build configuration’s General Settings:

Artifact paths:
/Users/teamcity/xcode_builds/Distribution-iphoneos/ =>
/Users/teamcity/xcode_builds/Distribution-iphoneos/ =>

Now my ad-hoc builds are produced automatically, always up to date with my working code changes, and available as an easy download from my TeamCity server. TeamCity will also save the artifacts for each build so I can easily retrieve the dSYM for a particular ad-hoc build to symbolicate a crashlog for that build on any developer’s machine.

Future improvements
If necessary I can run tests on actual iPhone hardware by changing the sdk (`-sdk iphoneos4.0`) but I am not yet sure how I could specify which one of multiple devices would run the tests. It would be nice to eventually be able to choose between multiple devices so I can deliberately run some tests on a device with a specific OS version or feature set.
With my current configuration TeamCity can only report a pass/fail status for iPhone tests. I need to consider modifying the GTM test runner script or switching to GHUnit or Cedar to get per-test results and then be able to build up a history of individual test failures.
I also need to add a build configuration which uses agvtool to automatically increment the project’s build number as part of every ad-hoc build.