How to setup a Jenkins slave running Mac OS X for iOS projects part 1

Gabriel Cartier
Samsao
Published in
6 min readApr 2, 2014

A previous blog post described how we use Jenkins as our continuous integration system. Since we do mobile development for iOS and Android, this post is complimentary as it covers how we built our iOS build machine which is in many ways different than for Android. I will still refer to some of the steps from the other blog post.

Similarly to Android, although a lot of tutorials described some ways to create an iOS build machine, none of them seemed straight forward and a lot seemed outdated. At the end, I will include a list of interesting URLs that I’ve used to create this blog post.

The first step is to obviously get yourself a Mac to use as a build machine. There are some cloud solutions available out there (MacinCLoud, MacStadium, XCloud) but here at Samsao we have our own Mac Mini build server that happens to be my development machine as well. I would strongly recommend that option since it is not so expensive and it obviously offer more flexibility.

Connect the mac slave

Once you have the machine, the first step is to connect the slave to the jenkins server. Again, we’ll make some assumptions for clarity:

  • Jenkins runs on a server with hostname ci.example.com
  • The slave runs on a server with hostname slave.example.com.
  • The jenkins user on your mac has a Home folder at /Users/jenkins/Home

First of all, create a jenkins user on your Mac. To create a user for Mac OSX, refer to this link. You DO NOT have to make it an administrator, I would even recommend not to do so. After that, allow SSH connections to the user. To setup SSH for Mac OSX on your jenkins user, refer to this link. Typically, your Jenkins master should already have a jenkins user and you should have an SSH key already generated. If not, our previous blog post for Android building covers that part. Don’t forget to add the master machine keys to your mac authorized_keys and its host to known_hosts files in your Home folder. Once that is done, the test to connect the Jenkins master to the slave via SSH should work.

Adding the dumb node to Jenkins

Now that the user is created and that the master can connect to it, we will properly add it to our jenkins configuration. First step is to go on your jenkins server configuration (i.e. ci.example.com) then Manage Jenkins and Manage Nodes. Click the New Node button and add the slave like so:

Then configure you’re slave like this:

Launch method should be set to Launch slave agent on Unix machines via SSH. Enter the desired Host. You will notice that you cannot select any credentials. That is completely normal, as you have not entered one yet. Click on Add to add one. If you remember correctly, the Jenkins server uses SSH to connect to your slave using an SSH key. Select SSH Username with private key for Kind. Set the Scope to System and enter jenkins in the Username field. Finally, you can select From the Jenkins master ~/.ssh for the Private Key field since that is where we previously put the key. Click on Add to add the credentials. Your configuration should look like the one presented on the image.

Setting up your Jenkins account

Now your master and slave are connected, you need to configure the jenkins user on your Mac to be able to build iOS projects. Easiest way is to login directly to your jenkins user, user switching can be quite useful for that. Once logged in, you have to do the following:

  • Open XCode and install the command line tools
  • Import your developer profile to XCode from another machine/user with working profile. This link shows you how to export/import your profile. There are other ways to do it, but that’s the simplest one I’ve found.
  • Also build with the proper configuration, it should ask you to access your keychain, click always allow. Although not the most secure technique, it will allow headless builds.

Once these steps are over, you should have your Mac OSX slave to be able to build XCode projects.

Customizing your jenkins configuration

The goal of all this is to have a machine continuously building your iOS projects and doing so as easily as possible. First, some plugins are needed to build iOS projects. Go to Manage Jenkins -> Manage Plugins -> Available and install these plugins:

We’re almost there…. setup a job

You should now have a working jenkins mac slave and a jenkins configuration ready to create jobs for building iOS projects. To do so, click on New Item and select Build a free-style software project. Enter a project name (remember to keep it URL friendly) and check Restrict where this project can be run. In Label Expression, enter the name of your slave, for us it was ios-slave. In Source Code Management section, select Git if you use git and enter the repository URL. If you are using GitLab, refer to the previous blog post to properly add your SSH keys and the web hook. The GitHub plugin is also pretty straight forward. If you are using CocoaPods, add a Update CocoaPods build step. You can either select the Clean “Pods” folder or not. After that, you should add an XCode build step. Click the Settings button, either select the Clean before build? option and enter Release as the configuration. After that, select the Code signing settings and select Unlock Keychain?. Enter ${HOME}/Library/Keychains/login.keychain as Keychain path and set the password. This is needed to properly sign the build. I know there are different ways to do that, again, this was the simplest solution for me. Finally, if you are using CocoaPods, you will need to configure the Advanced build settings. In Xcode Schema File specify your scheme name and in Xcode Workspace File specify the workspace name. An additional step in XCode is needed to share your schema in your repository. This link explains how to manage your schemes. The important part is that your scheme is shared, that way it will be uploaded to your repository and jenkins will then fetch it to build. The pictures below show an example of how your configuration should look like.

I realize that the post is quite long, I will make a part 2 explaining how to automatically build your IPA file and push it to a service such as Testflight.

Like usual, comments are welcome!

Here are some links that I used to create this post:
https://gist.github.com/schwa/4033966 http://nativex.com/science/continuous-build-and-deployment-for-ios-and-android-apps/ https://blog.codecentric.de/en/2012/01/continuous-integration-for-ios-projects-with-jenkins-ci/

--

--

Gabriel Cartier
Samsao
Editor for

Love technology. On a quest to build a product.