Jenkins CI with Xamarin.iOS, Xamarin Test Cloud and TestFlight – Part 1

You know how (technical) bloggers sometimes say that their blog is their personal memory dump? Sometimes you go searching for the solution to an issue and find the answer on your own blog! I bet this blog post is going to be one of those posts 🙂

Previously I wrote about issues when installing Java on Yosemite during a Jenkins install. I was installing Jenkins because I’m setting up a CI environment for our Xamarin.iOS app. The purpose of this CI environment is to build our Xamarin.iOS app, run the Xamarin.UITests on our Xamarin Test Cloud instance and upload the build to TestFlight for our internal QA and developers to play with.

I bought a nice Mac Mini for this purpose with OS X Yosemite installed. I started out with the Using Jenkins with Xamarin guide on the Xamarin website. This guide mentions a number of prerequisites, but I will try to be as complete as possible in describing the steps to get a Jenkins CI running with Xamarin.iOS, Xamarin Test Cloud and TestFlight.

Setting up User Accounts

First you need a dedicated user account with email address to access the different services you will be using. E.g. a user buildmaster with email buildmaster@yourdomain.com. This user needs to:

  • Be set up with an apple id and be added in the Member Center of your Apple Developer Portal.
    Apple Member Center

    Apple Member Center

  • Be added to your Xamarin.iOS subscription. You can get a free build server license from Xamarin so you don’t need to sacrifice an existing user. Just contact sales@xamarin.com and they will set you up.
  • Be added to your Xamarin Test Cloud instance. More on this later…
  • Be added to your source control users, in our case Bitbucket.
  • Be added to yourTestFlight instance as a Team Developer as only a Team Developer can upload builds.
    Add TestFlight user

    Add TestFlight user

 Installing the Tools

Now that the user accounts have been set up, you can start installing the software. Before we install Jenkins itself, we first have to install some prerequisites.

  • Install Xcode. Xcode is available in the Mac App Store and that’s why you need the apple id setup in the previous steps. If you try to build the Xamarin.iOS solution in a later stage and you haven’t opened Xcode before, you will get an error message in your build log complaining about accepting the license agreement. To prevent this you can do two things:
    1. Open Xcode once and agree to the license agreement.
    2. In Terminal run this command:
      sudo xcodebuild -license
  • Install the Xamarin Platform. This includes the Xamarin.iOS and Xamarin.Android SDKs and Xamarin Studio. If you already have a Xamarin account (which I assume for this post) you can download it here. If you don’t have an account yet you can download the trial or starter edition here.
  • Now you can install Jenkins using the Xamarin guide, but beware of the Java Runtime Environment error!

Certificates, Provisioning Profiles and the Keychain

When building iOS apps you need to have your signing certificate and provisioning profiles installed. If you don’t have a signing certificate yet, you need to request it and there’s enough to say about that to fill a complete post in itself! If you already have them, e.g. on a developer workstation you can export them from the developer workstation and import them again on the build machine.

Jenkins will also need access to the keychain while building and signing the Xamarin.iOS app. There’s a few ways to do this:

  • As we are running Jenkins under a user account and not as a daemon we can simply run a build from Xamarin Studio (once we have our code checked out from the repository of course). You will then get a pop-up asking to allow access to the keychain, similar to this where you have to answer Always Allow. From this moment on, the buildmaster user will have access to the keychain.
  • If this is not the case you could create a dedicated keychain, or unlock the keychain before the build step, like this:
    security unlock-keychain -p 's3kr1tp4ssw0rd' ~/Library/Keychains/login.keychain

Time to set up Jenkins….or not?

Now that we’ve handled all these requirements and prerequisites it’s finally time to set up Jenkins and create some jobs that do the actual Continuous Integration work: Build, Test and Deploy our app! However, I’ve noticed that this post is becoming quite long so I’m going to call this Part 1 and in Part 2 we will setup the Jenkins jobs. Stay tuned!