Continuous integration for iPhone apps

For the “développement mobile de la cote d’azur” meetup (french riviera mobile development meetup for you non french speakers), I did a presentation about continuous integration for mobile apps. I figured i’d share this information in a post as well.

This is meant as an overview of continuous integration to help you make the decision as to whether you want to adopt continuous integration, what approach you might want to take. This is not a step by step guide.

What is continuous integration?

Here are a few things that constitute continuous integration in my eyes:

  • store your source code in version control system (git, GitHub, GitLab, BitBucket or another)
  • Frequently integrate your code (don’t go work on a feature for three week before merging that code back in master)
  • Automatically build you application and verify this build
  • Have unit test, integration test and UI test and run them automatically at each build to verify the build
  • Automatically release build to your beta platform of choice and to the store

Why adopt continuous integration?

  • Know that the application is always ready. Once you have those test in place and they run at each build you should feel more confident about releasing it.
  • More trust within the team. With those regular build you know that what was committed has a certain level of quality, an impartial referee can call out what is broken.
  • Increase app quality. Catching bug sooner, more often will translate into a higher quality app for your user, and most likely better reviews.
  • Know what has been deployed to production. Since your server is now doing the release, you know exactly what was release, not some adhoc version that the developer put together before release because what was in git was not building.

What are the downsides of continuous integration?

  • It has a setup cost, setting up the build automation, creating automated tests.
  • You’ll want to adopt a few best practices (code reviews, git flow, unit test and its variants)
  • At first it will slow down the team while the team figures out how to best adopt those practices

Yes, like everything there is a cost to continuous integration, but honestly you will recover that cost very quickly. You should see fewer regression, fewer bugs that go into production, a faster overall release cycle.

How do you go about adopting continuous integration?

First like I mentioned, you’ll want to adopt a few best practices.

  • Branch management system. I like gitflow, i’m sure there are others, pick one that works for you.
  • Pull request and build on pull request: unless you’ve adopted pair programing, you should do pull request, someone should do a code review on that pull request and the pull request should be built by your continuous integration platform and tests should pass before the pull request is allowed to be merged.
  • Makes sure you know how to build your app. For a client of mine, I asked: how do I build the app? The answer: just hit build in Xcode. Well, it was not that easy, the developer forgot about a bunch of dependencies, private cocoa pods. So make sure you can take a clean box, follow a few steps and build your app.

A few platform options for continuous integration

Here are a few common feature across those solutions so I don’t have to repeat them:

  • integration with GitHub, gitlab, bitbucket or other git server
  • different steps/configuration of your build based on the branch, tag that was pushed to git
  • ability to build pull requests
  • Delivery of app to store, beta services
  • Build environment variable if you want to keep a few keys out of your source code

Buddybuild

Buddybuild is probably the easiest to setup. Within a couple of minutes you’ll have your application being build whenever you push code to git. It’s also the one that is easiest to use, you really don’t need to be a developer to use it. I feel that a project manager could dive in there too.

With Buddybuild you can get your code off of any git server pretty much, you get continuous build and deployment all with an easy setup. The buddybuild team has tried to automate as much as possible.

First nice feature is the automatic build number, it essentially assigns a number to every build and saves it into the app so you can know what build is what automatically.

Second nice feature I’d like to mention is that buddy build allows to deploy your app to device right away via an entreprise certificate or by managing your devices on your apple account. This makes getting your app to your team super easy.

The downside of this ease of use is a limited number of options.

Buddybuild also has a few non continuous integration functionality like crash report, and users feedback which can be useful.

For those who want more power, you can even run a shell script before and/or after the build. Allowing you to run a few more commands.

Bitrise.io

Bitrise.io is also setup in a few minutes, but the setup does have a few extra steps. This gives you a little more control over the setup.

Bitrise pretty much allows you to do all that buddy build does (except crash report and user feedback) and more, and with more power.

Where bitrise really shines is that you can build workflows which are combination of steps. You can then select when you want that workflow to run (pull request, push of code to a branch, tag added). The workflow can have as many steps as desired and you can pick those steps from a library of over a hundred steps. If you don’t find what you need you can even create your own steps. A step is really just a shell script with a set of input variable and a set of output, so that gives you plenty of room to grow. You are also free to install gems if you need to.

You can even combine workflows to start to factor your build out.

A couple of feature that can make your life easier:

  • configuration is saved as a YAML file, so you can view it, edit and most importantly version it in your source control
  • Bitrise offer a command line and docker images so that you can run the exact same build on your machine locally. Very handy to debug a build that fails.

The price of this flexibility is a little less ease of use. Bitrise is definitely geared toward developers and team that want to build a somewhat complex build system.

Jenkins

Jenkins is usually what people think about when they here about continuous integration. It’s been here for a while and can do just about anything. There is a wide community behind it, so you’ll find plenty of answers online about your questions, but you won’t have support team answer your specific questions.

On the setup side, first you’ll need a machine to make Jenkins run (or a virtual machine), then you’ll need to install and configure Jenkins to run all the time on that machine and configure it in a way that lets it start the simulator (to run your tests). This can take a certain amount of time. I would plan on about 2 days of work right there.

As I said Jenkins can build just about anything including iPhone apps. You’ll have to download the right plugin, configure your access to your favorite git repository manually. No pretty UI to make it super fast for you here. But you’ll get all the options you want for free.

There are others, again pick one that works for you.

Conclusion

The first continuous integration system I set in place was a Jenkins box running on an iMac on my desk. It was great, but I spent a lot of time setting that box up and a lot of time maintaining it. But at the end it did everything we needed it to do and eventually was integrated with other Jenkins box which were building the android app, the web site and web services. And this is where I recommend Jenkins, when you need to build a lot of different things and that you have someone on your team who will maintain that infrastructure.

If you only have an iPhone app, an android app then buddybuild should be your first stop. If you want to do some complex things then check out bitrise.

Edit:

Folks over at https://nevercode.io reached out and said I should check them out. So i’m adding them here as another alternative.