Hotwire Tech Blog

Scribes from Hotwire Engineering


If you are already using Jenkins for continuous integration you can easily adopt for iOS as well. You can use all the features of creating jobs like build, unit tests, smoke, and regression as well as creating pipelines. This blog helps you to get started with setting up iOS CI and also running tests in parallel on multiple computers.


Discard Old Builds

Discard Old Builds controls how long we would like to keep the build records such as console output, artifacts, reports. This can be achieved by one of two criteria

  • Days to keep builds – Jenkins will delete info if it reaches the specified number of days.
  • Max number of builds to keep – Jenkins will save records until the specified number of builds. Once this number is reached, oldest records will be removed.

Any build can be marked as ‘Keep this log forever’, to exclude certain important builds from being discarded automatically.


Permission to copy artifacts

Comma separated list of projects that can copy artifacts of this project. The advantage of copying artifacts is we can run all the downstream jobs from the same set of source code.


Parameterized build

This allows to parameterizing a build with input available to the build job. The advantage of making the build parameterized is we can change the configuration dynamically for various automation. For example, the same job can be built from different branches on different environments. Parameters can be Test Parameter, String Parameter, Choice Parameter and are identified by their names.

The Choice parameter is a simple string parameter which gives us the option to select simple from a list. This is used during a build, either as an environment variable or through variable substitution in some other parts of the configuration.

String parameter is a simple text parameter, where we can enter a string value, which can be used during a build, either as an environment variable or through variable substitution in some other parts of the configuration.

Text parameter allows to specifying a small text that could be parsed to build executors (shell, maven, ant, etc.) at build time. The main difference between Text and String parameters is that the Text parameter supports multi-line, while the String one doesn’t.

Restrict where this project can be run

Sometimes a project can be successfully built on a particular slave. This option forces Jenkins to always build this project on a specific computer. When there are a group of machines that the job can be built on, a label is specified as the node, which will cause Jenkins to build the project on any of the machines with that label. This is to get the faster results of automated testing on Jenkins. If unchecked, builds can run on any available node.



Execute Shell

Runs a ‘sh’ shell script which can be configurable for building the project. This script runs with the workspace as the current directory. Usually, prefer not to put a long shell script in here. Instead, consider adding the shell script in SCM and call that shell script from Jenkins (via bash -ex, so that the changes can be tracked. In addition to this if we have multiple jobs using the same shell script, only one file needs to be changed if needed. It is always better to clean up files from previous builds.

xctool -derivedDataPath=path -destination destinationSpecifier GCC_PREPROCESSOR_DEFINITIONS=’${inherited} param1=value1′ -scheme=schemename clean build

  • -derivedDataPath  Overrides the folder that should be used for derived data when performing a build action on a scheme in a workspace.
  • destinationSpecifier is the type of device or simulator. Defaults to a destination that is compatible with selected scheme.
  • -GCC_PREPROCESSOR_DEFINITIONS is a preprocessor macro when using xctool to build an app using a bunch of different configurations.
  • -scheme schemename Build the scheme specified by schemename. Required if building a workspace.
  • -sdk [<sdkfullpath> | <sdkname>] Build a Xcode project or workspace against the specified SDK, using build tools appropriate for that SDK. The argument may be an absolute path to an SDK or the canonical name of an SDK.

  • -workspace workspacename Build the workspace specified by workspacename



Archive the artifacts

Archives the build artifacts so that they can be downloaded later. Jenkins keeps artifacts for a build as long as a build log itself is kept, If we need but if you don’t need old artifacts and would rather save disk space, you can do so.

Note that the Maven job type automatically archives any produced Maven artifacts. Any artifacts configured here will be archived on top of that. Automatic artifact archiving can be disabled under the advanced Maven options.

Email Notifications

Jenkins comes with some notification plug-ins that can be added for all the jobs. This can be completely customized so that some important information from the build can be added. Email and hipchat notifications are configured here.

Trigger parameterized builds on other projects

This allows to trigger builds on other projects, with parameters that are predefined, or supplied by the finished build. All parameters will be passed to the downstream jobs, even if the downstream job is not parameterized, or if no property of that name is defined.



Copy artifacts from another project

  • Project nameName of source (upstream) project for copying of artifacts. If it is a Maven project, artifacts from all of its modules will be copied. Job name will be specified here to copy.
  • Which buildUpstream build that triggers this job can be selected to get the recent changes. The build number of the selected build will be in the environment for later build steps to reference.
  • Artifacts to copyRelative paths to artifacts to copy or can be blank to copy all artifacts.
  • Artifacts not to copySpecify paths or patterns of artifacts to exclude, even if specified in “Artifacts to copy”. Can be blank.
  • Target directoryDirectory to place copied artifacts. I can be blank to use the workspace.
  • Unzip the artifacts


Build configuration

  • Root POM If workspace has the top-level pom.xml in somewhere other than the 1st module’s root directory, specify the path (relative to the module root) here, such as parent/pom.xml. If left empty, defaults to pom.xml
  • Goals and options Specifies the goals to execute, such as “clean install” or “deploy”. This field can also accept any other command line options to Maven, such as “-e” or “-DskipTests=true”.


Next steps for CI – Xcode server & bots.

Xcode Server is a service provided by OS X Server. Set up Bots that run on the server.

Advantages of Xcode Server:

  • Bots are easy to set up.
  • Bots are tightly integrated with Xcode.
  • Bots can be created, modified, and monitored from the Log Navigator, and only the bot for the particular project and branch will show.
  • Faster test execution time.
  • Easier to keep up with new iOS releases.
  • Reduced dependency on third party tools
  • No need to write additional code to get screenshots
  • Able to access code from failed test when viewing the bot in Xcode.

Watch out for separate blog focusing on best practices on Xcode server and bots.