An Easy Way to Make an iOS Build for TestFlight Using Jenkins

I hope you enjoyed Part I and Part II of this series. In this part, I will explain in detail how to publish builds remotely and how to direct send builds to beta users from TestFlight.

Continuous Deployment

Up until now, we have been setting up a popular continuous integration server called Jenkins and syncing it with GitHub, so it can run tests every time new code is pushed, creating an .iPA file for the project. To send the latest build to all the beta testers, or internal testers, can be a repetitive and time consuming task, especially when working on Agile based projects, where each day of work is counted and clients want to see actual work rather than daily status updates.

At such time, Jenkins will let down such pressure for making a build and sending it to the client.

  • How it is possible to send build at particular time?
  • How it is possible to send build when git push is execute?

Jenkins was made to provide a solution to these questions with a build trigger.

[See Also:Building and Configuring Open vSwitch on OpenWrt for Cloud Networking]

Build Triggers

If you want your job to run only when you tell it to, then you can skip the “Build Triggers” section. Otherwise, here is information on how to set up jobs to run on a schedule, to run after pushes to your SCM, to run after another job successfully runs, or just to check for updates to pull every minute. Start by setting up the job to check the SCM every 5 minutes for changes. Select “Poll SCM” and use the schedule “H/5 * * * *.” You can define any schedule according to your needs using cron syntax .

This field follows the syntax of cron. Specifically, each line consists of 5 fields separated by a tab or whitespace, as shown below.


  • MINUTE: Minutes within the hour (0-59)
  • HOUR: Hour of the Day (0-23)
  • DOM: Day of Month (1-31)
  • MONTH: Month of Year(1-12)
  • DOW: Day of the Week (0-7) where 0 and 7 denotes to Sunday.

Zymr - build triggers

Now, create a solution to automatically push that code to our app server, eliminating the need for manual deploy.

To deploy a build automatically to the iTunes server, some sort of shell script needs to run. To set it, go to Job Configuration. In the “Build” section, tap on “Add Build Step”  and add “Execute Shell.” Then add script in command area as shown below.

Zymr - execute shell

Shell Script for Continuous Deployment

The script allows continuous deployment on the iTunes store for beta testing.

Note for the script below:

<USER_NAME> = iTunes User Name

<PASSWORD>  = Password

<YOUR_APP_ID> = Application ID (Get app ID from iTunesconnect)


set -ex

basename =”/usr/bin/basename”



MD5=$(md5 -q $IPA_FILE)

BYTESIZE=$(stat -f “%z” $IPA_FILE)




# Remove previous temp

test -d ${TEMPDIR} && rm -rf ${TEMPDIR}

mkdir ${TEMPDIR}

mkdir ${TEMPDIR}/mybundle.itmsp

cat <<EOM > ${TEMPDIR}/mybundle.itmsp/metadata.xml

<?xml version=”1.0″ encoding=”UTF-8″?>

<package version=”software4.7″ xmlns=””>

<software_assets apple_id=”<YOUR_APP_ID>”>

<asset type=”bundle”>










cp ${IPA_FILE} $TEMPDIR/mybundle.itmsp


/Applications/ -m upload -f
${TEMPDIR} -u ${USERNAME} -p ${PASSWORD} -v detailed

This shell script exports the .iPA from {WORKSPACE}/build, creates a metadata.xml file, and creates an .itmsp file to upload on iTunes Store using Application Loader, which internally uses iTMSTransporter. ‘myBundle.itmsp’ is a combination of metadata.xml and .ipa file.

This script successfully uploads the .iPA directly to the Testflight of the iTunes Store. Yet the build still needs to be sent manually to beta testers from iTunesconnect. We still want to find a way to make that process happen automatically for convenience. The solution is a slight change in the last line of the script, and it will magically send the build to beta testers automatically.

Replace -v detailed with –upload

Apply and save.



/iTMSTransporter -m upload -f ${TEMPDIR} -u

${USERNAME} -p ${PASSWORD} –upload

This will automate the build distribution for beta testers without human interruption. Now let us spread this magic with remote access of Jenkins, so that expert developers can also do this when an application needs to be sent with beta users.

[See Also: How to Use RestKit in Swift for iOS Development]

Remote access of Jenkins

Until now, Jenkins could only be accessed through a localhost. What if we want access from a different machine?

While we install Jenkins with brew, it has created a .plist file. iOS developers know what the content and value of a .plist file are. The default value of –httpListenAddress is, meaning that Jenkins can run as localhost. Though it is in the same domain, this dashboard is not accessible. Simply apply instead of It means that the –httpListenAddress is not only bound with the localhost.

From a different machine in same domain, this dashboard can be accessed by executing X.X.X.X/8080. This plist file is available at path: /Users/sagar.g/Library/LaunchAgents/homebrew.mxcl.jenkins.plist

Zymr - plist file


Definitely CI empowers developers to automate the build development and distribution process. Finally, with a single click, developers can remotely access Jenkins and send builds with the latest source to beta users from TestFlight via iTunes. Now you also become a magician, thanks to Jenkins providing plugins allowing us to do so. We hope you enjoyed this series.

Everything you need to know about outsourcing technology development

Access a special Introduction Package with everything you want to know about outsourcing your technology development. How should you evaluate a partner? What components of your solution that are suitable to be handed off to a partner? These answers and more below.

Introduction Package

Source: zymr

Zymr blogger, Zymr, Inc.


Leave a Reply