In this blog post I will show how to set up a Continuous Integration server for iOS applications. It will run our Unit Tests and confirm that builds aren’t corrupted.
We will use:
- TeamCity as our CI server – it provides really good (and official!) support for iOS projects, integration with AppCode and easy to use interface.
- xctool as a replacement for Apple’s xcodebuild – it eases a lot of pains connected with building an application.
- git as our VCS – you can easily follow this post even if you use a different VCS, but from now on I will assume that you use git
- Download TeamCity for Mac OS X from https://www.jetbrains.com/teamcity/download/
- Unpack the downloaded package with
tar xfz <name of package>.tar.gz
- Run TeamCity server with one default agent with script
sh <TeamCity home>/bin/runAll.sh start
- Open http://localhost:8111/ in your browser.
- Select Proceed on the welcome page:
- Select one of the available databases.1 Select Proceed when you are ready.
- Wait for TeamCity to finish the initialization.
- Read and accept the license agreement and then select Continue:
- Create your administrator account for TeamCity:
Now your basic setup is ready. You can fill in the remaining data, but it is not necessary to continue.
Why build script?
We will use a custom build script instead of built-in TeamCity tools. Although those tools are much easier to use, a custom script has few deciding advantages:
- much more flexible – we are not restricted to running XCTests and builds. We can add Acceptance Tests and UI tests later on.
- agnostic of your CI server – if you ever decide to use different technology than TeamCity you will be able to reuse it.
- goes with the source files – you can run it on your local machine2 and changes to it doesn’t require you to go through the web page.
My build script
- Copy the script below to the main folder of your project and replace
TEST_SCHEME_NAMEwith your application data. Don’t forget to remove my footnotes from the build script :).
- Add executable permissions to your script with
chmod +x SCRIPT_NAME.
# Clean repository, DerivedData folder and simulator git reset --hard3 git clean -fd4 rm -rf ~/Library/Developer/Xcode/DerivedData/APPLICATION_NAME*5 xcrun simctl erase all6 # Unit tests xctool \ -scheme TEST_SCHEME_NAME \7 -workspace APPLICATION_NAME.xcworkspace \8 -destination "platform=iOS Simulator,name=iPhone 6,OS=8.3" \9 -sdk iphonesimulator \ -reporter junit:test-results/TEST-UnitTests.xml \10 -reporter pretty \11 clean test
Adding a project to TeamCity
Now that we have everything installed and the build script is committed into our project we can finally configure our first task in TeamCity.
- Open http://localhost:8111/ in your browser and log in to your previously created account.
- Select Create Project:
If you already created any project you need to select Administration/Projects/Create project.
- Fill in Name and Project ID12 fields and select Create:
- The next thing we need to do is to create a build configuration. Select Create build configuration:
- Fill in Name and Build configuration ID12 fields and select Create:
- Next step is to configure the VCS for your project:
- a) Select
- as type of your
- b) Type in the name for your
- c) Type in your
- d) Type in the URL for your repository.
- e) Change
- to the name of the branch you want to test (but leave refs/heads/).
- f) Select the appropriate
- . The easiest ones to configure are
- (if your project is public) or
- (if it is private).
- g) You can test if the configuration is correct now.
- h) When you are ready, select
- Next we need to add steps to our configuration. From the left menu select Build Steps:
- And then Add build step:
- From the list of available build steps select Command Line:
- In the Custom script section, type in
sh SCRIPT_NAMEto run your script every build and select Save:
- Now we have Continuous Integration up and running but we can’t see the results of the tests. Select Build Features13 from the left menu:
- And then Add build feature:
- From the popup menu select XML report processing (you may need to scroll – it is at the bottom of the list):
- And from the Report type select Ant JUnit:
- In Monitoring rules we type
test-results/*.xml, to tell the parser to take all results from the test-results folder. After that select Save:
- Test if everything is working with Run command in the right upper corner of the page:
- Make our server notify us by email about build results
- Change the authentication method to use deploy key instead of our credentials
- Set up production database
- Add Acceptance Tests step
- Make our server automatically start after reset
- Separate Agent and HTTP server
- Set up automatic sending builds to our testers and/or clients
We will add them in future posts.
- For evaluation you can select Internal, but TeamCity‘s advice is to change it as soon you want to move to production. ↩
- TeamCity can do that for you also through integration with AppCode ↩
- Reset git repository before build. This step is not mandatory. ↩
- Clean git repository before build. This step is not mandatory. ↩
- Remove DerivedData folder for your application. This step is not mandatory. ↩
- Erase the simulator before running tests. This step is not mandatory and can be dangerous if you have more than one agent, but it solved few problems with builds. ↩
- Default scheme is named after your project and it contains test target. ↩
- Skip this part if you don’t use workspaces. ↩
- You can specify here on which simulator you want to test your application. You can remove this line if you want to use the default one. ↩
- Redirect test results in jUnit format to folder test-results. We will use them later to display test results in CI. ↩
- Display test results to console. Useful for debugging. ↩
- ID can contain only alpha-numeric characters and underscores, is restricted to 80 characters, starts with a Latin letter and must be unique across all other similar IDs. ↩
- Build Features are commands that are executed after the build is finished. ↩