public
Last active

Jenkins, Xcode, Github, Testflight/Hockey on a Mac Mini

  • Download Gist
gistfile1.md
Markdown
  • Buy a mac mini
  • Install 10.8
  • Create a user account for Jenkins
  • Install xcode
  • Turn on screen sharing
  • Turn off energy save sleeping
  • Login as your jenkins user
  • Use ssh-keygen to create a key for github
  • Create a github account for your build machine
  • Add the key to your build machine github account
  • Run xcode, install xcode command line tools
  • From terminal accept xcode's license agreement (xcodebuild --license)
  • From another build machine export your .developerprofile from xcode and import it into your build box (or you can do this the old fashioned way - but xcode export and import seems to just magically work)
  • Use git to clone your project
  • Locally (i.e. not while ssh-ed in) use xcodebuild (with right settings, e.g. release config) to make sure it builds clean on the command line.
  • The keychain should prompt for access to your signing certificate you WANT to make sure you always allow access to this certificate (otherwise jenkins CANNOT build headlessly)
  • Install homebrew
  • Install jenkins via homebrew
  • Follow directions to add homebrew to your launchd
  • Remove the line in the launchd plist that limits jenkins to localhost
  • Use launctl to run jenkins
  • ADDED: Accept "Are you sure you're mad enough to install Java" dialog.
  • ADDED: Relaunch jenkins (chances are the dialog prompt prevent it from launching): ("launctl unload/load")
  • ADDED: You can now unplug the display and keyboard from the Mac Mini and just ssh and/or screen share with it.
  • Visit the jenkins homepage http://buildmachine:8080
  • Remove useless jenkins default plugins (unless you want to build java crap)
  • Add jenkins plugins for xcode, git, github and testflight
  • Create a new jenkins job that builds via xcode
  • Turn on xcode ipa generation
  • Add your github clone URL to the job, fill in the polling field (I've set up jenkins to poll github every 10 minutes)
  • ADDED: Add your testflight API keys to jenkins, create a testflight distribution list and add that to jenkins too.
  • I created two jobs - one that polled github every 10 minutes and one that builds each day. Only the daily build generates testflight builds.

What now?

This list doesn't cover tagging, branching, versioning, e-mail setup, etc, etc. But it should get you up and running.

Troubleshooting:

My three biggest problems were:

  • Jenkins by default runs on localhost (lo), I needed it to run on en0. This is controlled via a switch passed to jenkin's launchd plist.
  • Xcodebuild couldn't sign the binary and no keychain dialog was appearing on the mini. I had to manually allow access to the keychain certiciate. See here for more: https://wiki.jenkins-ci.org/display/JENKINS/Xcode+Plugin#XcodePlugin-Userinteractionisnotallowed
  • I forgot to turn off sleeping on the Mac Mini and the next daily build didn't happen.

Update

The TestFlight plugin just up-ed and stopped uploading builds to TestFlight. Not sure what went wrong - maybe TestFlight API is unreliable. Who knows? I've switched the team and the build box over to Hockey and installed the (via similar) Hockey Jenkins plugin and things just work fine. Up to our ~30th daily build now.

Seems like there's a bug in the Xcode plugin when creating ipa's (i.e. it won't make them). To resolve this, you have to make sure that the Marketing version and Technical version fields are not left blank. I set both of mine to ${BUILD_NUMBER}. Once you do that, ipa generation works again.

I've blogged more detailed instructions here http://orangejuiceliberationfront.com/setting-up-jenkins-for-github-and-xcode-with-nightlies/ In particular, they mention how to build from Github w/o polling, and contain example scripts that use xcodebuild to build stuff.

Thanks for sharing, just a short notice: With Xcode 5

From terminal accept xcode's license agreement (xcodebuild --license)

should be sudo xcodebuild -license (needs root privileges)

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.