Skip to content

Instantly share code, notes, and snippets.

@alloy
Created January 30, 2012 18:06
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save alloy/1705714 to your computer and use it in GitHub Desktop.
Save alloy/1705714 to your computer and use it in GitHub Desktop.
Rake tasks to create an iOS app archive and push dSYM to HockeyApp.
module Gem; end
require 'rubygems/version'
namespace :version do
module InfoPlist
extend self
def [](key)
output = `/usr/libexec/PlistBuddy -c 'Print #{key}' Bananas-Info.plist`.strip
raise "The key `#{key}' does not exist in `Bananas-Info.plist'." if output.include?('Does Not Exist')
output
end
def set(key, value, file = 'Bananas-Info.plist')
`/usr/libexec/PlistBuddy -c 'Set :#{key} "#{value}"' '#{file}'`.strip
end
def []=(key, value)
set(key, value)
end
# Short git commit hash, e.g: abc1234
def build_version
self['CFBundleVersion']
end
def build_version=(revision)
self['CFBundleVersion'] = revision
# In case this is being called from an Xcode 'script build phase', update the plist inside the build as well,
# because adding the plist to the bundle is the first thing Xcode does, there's no way to run a script before
# then.
if dir = ENV['BUILT_PRODUCTS_DIR']
puts "[!] Updating in build as well:"
# inside the app bundle
file = File.join(dir, ENV['UNLOCALIZED_RESOURCES_FOLDER_PATH'], 'Info.plist')
puts "- #{file}"
set('CFBundleVersion', revision, file)
# inside the dSYM bundle
file = File.join(dir, "#{ENV['WRAPPER_NAME']}.dSYM", 'Contents', 'Info.plist')
puts "- #{file}"
set('CFBundleVersion', revision, file)
end
end
# The human-readable version, e.g.: 1.2.3
def marketing_version
self['CFBundleShortVersionString']
end
def marketing_version=(version)
self['CFBundleShortVersionString'] = version
end
def bump_marketing_version_segment(segment_index)
segments = Gem::Version.new(marketing_version).segments
# increase segment at given index
segments[segment_index] = segments[segment_index].to_i + 1
# zero-out all segments after the given index
(segment_index+1..segments.size-1).each { |i| segments[i] = 0 }
# convert possible nils to 0 and create version string
version = segments.map(&:to_i).join('.')
puts "Setting marketing version to: #{version}"
self.marketing_version = version
sh "git commit Bananas-Info.plist -m 'Bump to #{version}'"
end
def marketing_and_build_version
"#{marketing_version} (#{build_version})"
end
end
desc "Print the current version"
task :current do
puts InfoPlist.marketing_and_build_version
end
desc "Sets build version to last git commit (happens on each build)"
task :set_build_version do
rev = `git rev-parse --short HEAD`.strip
puts "Setting build version to: #{rev}"
InfoPlist.build_version = rev
end
namespace :bump do
desc "Bump patch version (0.0.X)"
task :patch do
InfoPlist.bump_marketing_version_segment(2)
end
desc "Bump minor version (0.X.0)"
task :minor do
InfoPlist.bump_marketing_version_segment(1)
end
desc "Bump major version (X.0.0)"
task :major do
InfoPlist.bump_marketing_version_segment(0)
end
end
end
desc "Print the current version"
task :version => 'version:current'
desc "Clean Xcode builds"
task :clean do
sh "rm -rf DerivedData"
end
desc "Create a 'archive' build"
task :archive => :clean do
sh "/usr/bin/xcodebuild archive -workspace Bananas.xcworkspace -scheme Bananas"
end
HOCKEY_APP = {
'API_TOKEN' => 'secret',
'APP_ID' => 'secret'
}
ARCHIVE_BUILT_DIR = 'DerivedData/Bananas/ArchiveIntermediates/Bananas/BuildProductsPath/Release-iphoneos'
namespace :release do
desc "Clean, create 'archive', commit build and dSYM, and create a tag"
task :create => :archive do
puts "Saving build of version `#{InfoPlist.marketing_version}'"
sh "cd '#{ARCHIVE_BUILT_DIR}' && zip -r Bananas.app.zip Bananas.app && zip -r Bananas.app.dSYM.zip Bananas.app.dSYM"
release = "Releases/#{InfoPlist.marketing_version}"
sh "mkdir -p #{release}"
sh "mv #{ARCHIVE_BUILT_DIR}/*.zip #{release}"
sh "git add Bananas-Info.plist #{release}"
sh "git commit -m 'Release #{InfoPlist.marketing_version}'"
sh "git tag -a #{InfoPlist.marketing_version} -m 'Release #{InfoPlist.marketing_version}'"
end
desc "Push build/dSYM commit and tag to `origin/master' and push the dSYM file to hockeyapp.net"
task :push do
sh "git push origin master"
sh "git push --tags"
sh %{
curl \
-F "dsym=@Releases/#{InfoPlist.marketing_version}/Bananas.app.dSYM.zip" \
-H "X-HockeyAppToken: #{HOCKEY_APP['API_TOKEN']}" \
https://rink.hockeyapp.net/api/2/apps/#{HOCKEY_APP['APP_ID']}/app_versions
}.strip
puts
puts "Now please submit the build from Xcode's archive overview as normal."
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment