Continuous Delivery Of iOS Apps With Jenkins: Basic Setup

Adam Eri
blackmirror
Published in
3 min readMay 31, 2017

All manual operations are doomed to fail. There are several processes with iOS development, which take a lot of time and/or are error-prone:

  • generating, publishing documentation
  • adding, updating translations
  • creating App Store/TestFlight/Hockey releases
  • running UI automation and unit test
  • creating screenshots for app submission
  • uploading iTunesConnect metadata

At Bikemap, we automated all these with the help of Jenkins and fastlane. We have several different pipelines for different tasks: documentations, TestFlight builds, LingoHub translations, release builds and so forth.

Here is a little insight to our setup.

MacOS Server

You can use any Mac for this job, we have a Mac Mini in the office. You will need to install MacOS server, otherwise, the Mac will always go a power nap or sleep mode (even if you disable it).

We use nginx to serve as a proxy, easiest is to install with homebrew:

$ brew install nginx

Jenkins is running on port 8080, so we configure nginx to listen on ports 80 and 443 as a proxy.

In your /usr/local/etc/nginx/server/bulding.conf:

Do not forget to setup your DNS, so that jenkins.yourserver.com is pointed to the Mac’s IP address. Also, in the macOS Server settings, set your domain as the hostname.

Install Jenkins

Jenkins is a great choice for your CI/CD. Easy to install and configure. The easiest install is with brew, but any other method will work.

$ brew install nginx
$ brew services start jenkins

Navigate to localhost:8080 and complete the setup. To make the UI more civilised, you can install this theme. And we also use the blue ocean plugin.

Fastlane

If you are not already using the fastlane tools, you really should. While all the operations they support can be done using built-in tools and commands, fastlane makes automation dead simple.

The process of building, archiving, signing of the Bikemap app is configured in the Fastfile. Upload to ITC is done using deliver.

Pipeline

Pipelines are the new and awesome way to organise your Jenkins deployment. It uses a declarative groovy script to describe stages and steps for your processes.

The multi-branch pipeline is the perfect choice for us. As the name suggests, it allows multiple branches to be built/delivered. For instance, when one developer working on a feature branch, they can build/test/distribute their own version without interfering with the other developers.

Then when the feature is ready and merged, the develop branch can be built/tested/distributed/etc.

Our Pipelines

In our projects, the branches more or less share the same pipeline with a few exceptions.

  • Check out code
  • Install dependencies (Cocoapods)
  • SwiftLint
  • Running unit tests, UI tests
  • Generating and publishing documentation (Jazzy) — develop only
  • Signature and distribution — TestFlight — releases only
  • Notifications on Slack with the latest changes

You configure your pipeline in a Jenkinsfile in your project root. Ours looks something like this. Note the parallel steps in the testing stage and the branch conditions for the documentation.

This is a rather basic example, but you can go crazy with your solution: capturing localised screenshots, uploading iTunesConnect metadata, JIRA integration, and so on and so forth.

You can also plug in actual devices in the Mac mini and run the tests on all of them in parallel.

--

--

Adam Eri
blackmirror

A software architect building apps and games for Apple platforms and cloud based micro-service solutions.