Automating iPhone releases with Rake

View all recent articles by Luke Redpath

03 March 2009 Automating iPhone releases with Rake

So far for me the release process for Squeemote has been fairly manual. After checking the final release several times using a development build, then an ad-hoc build, the time would come to create a distribution build. I’ve done this several times now and each time I’ve gone through the same tedious steps so I thought it’s time I wrote myself a Rake task to automate the process somewhat.

If you’re a Ruby/Rails developer you will no doubt have Rake installed. Otherwise, with Ruby installed (which you should have as it ships with Leopard) then you can install the latest version of Rake using the command gem install rake. If you’re not familiar with Rake, to use this task, create a file named Rakefile in the root of your project and add the code below. To run it, simply execute rake release from a Terminal.

The Rake task is still in it’s infancy but I will continue to update the gist as I make further improvements. It performs the following steps:

  1. Bumps the build number using agvtool (see this article on using agvtool)
  2. Builds the release using my main target and by default the Development distribution
  3. Creates a folder in my saved releases folder and copies the built package (and the dsym file) to the release folder.
  4. Compresses the package into a zip file ready for uploading to Apple.
RELEASE_OUTPUT_PATH = File.expand_path(
  "~/Projects/releases/Squeemote")
TARGET_NAME = "Squeemote"
CONFIGURATION = ENV['CONFIGURATION'] || "Distribution"
SDK_VERSION = ENV['SDK'] || 'iphoneos2.2'
 
task :release do
  puts "* Bumping build version."
    `agvtool bump -all`
    
  puts "* Building #{CONFIGURATION} release."
    `xcodebuild -target #{TARGET_NAME} \
      -configuration #{CONFIGURATION} -sdk #{SDK_VERSION}`
    build_path = File.join('build', "#{CONFIGURATION}-iphoneos")
    
  puts "* Creating #{CONFIGURATION} package"
    output_path = File.join(RELEASE_OUTPUT_PATH, 
    `agvtool mvers -terse1`.strip + "-#{CONFIGURATION.downcase}")
    `rm -Rf #{output_path}` if File.exist?(output_path)
    `mkdir #{output_path} && \
     mv #{File.join(build_path, '*')} #{output_path}`
    
  puts "* Compressing."
    `cd #{output_path} && zip -ry \
      #{TARGET_NAME}.zip #{TARGET_NAME}.app`
  
  puts "* Done."
end

Feel free to modify this to your needs; I encourage you to fork the gist and make your changes available for everybody else.

Overriding default behaviour

The configuration and SDK can be overridden using environment variables so its possible to use this task to build ad-hoc releases too. The main feature currently missing is checking whether or not the build was successful or not before continuing, something I’ll fix shortly. It also doesn’t set the agvtool “marketing version” (e.g. 1.2), which I generally do manually on my repository master branch when starting work on the next version of my app.

If anybody else has any nice tips for automating their iPhone development workflow, I’d like to hear them.