Skip to content

Instantly share code, notes, and snippets.

@kvnsmth
Created November 26, 2012 18:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kvnsmth/4149753 to your computer and use it in GitHub Desktop.
Save kvnsmth/4149753 to your computer and use it in GitHub Desktop.
Example Rakefile for distributing through TestFlight
PROJECT_NAME = "Awesome" # the name of your xcode project
APP_NAME = "Awesome" # whatever your app name is
@configuration = "Release" # xcode project configuration to use
@app_suffix = "-Staging"
SDK_VERSION = "5.1"
SDK_DIR = "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator#{SDK_VERSION}.sdk"
BUILD_DIR = File.join(File.dirname(__FILE__), "build")
TESTFLIGHT_API_TOKEN = "TESTFLIGHT_API_TOKEN"
TESTFLIGHT_TEAM_TOKEN = "TESTFLIGHT_TEAM_TOKEN"
@testflight_distribution_list = "TestFlight Distribution List Name"
def product_name
"#{APP_NAME}#{@app_suffix}"
end
def system_or_exit(cmd, stdout = nil)
puts "Executing #{cmd}"
cmd += " >#{stdout}" if stdout
system(cmd) or raise "******** Build failed ********"
end
def with_env_vars(env_vars)
old_values = {}
env_vars.each do |key,new_value|
old_values[key] = ENV[key]
ENV[key] = new_value
end
yield
env_vars.each_key do |key|
ENV[key] = old_values[key]
end
end
def output_file(target)
Dir.mkdir(BUILD_DIR) unless File.exists?(BUILD_DIR)
output_dir = BUILD_DIR
output_file = File.join(output_dir, "#{target}.output")
puts "Output: #{output_file}"
output_file
end
# use tasks to setup different configurations
# staging and production are examples below
desc "Staging configuration"
task :staging do
@configuration = "Release"
@app_suffix = "-Staging"
@developer_name = "" # whatever your codesigning identity is
@provisiong_profile = "./Support/App_Staging.mobileprovision" # modify as necessary
end
desc "Production configuration"
task :production do
@configuration = "Distribution"
@app_suffix = ""
@developer_name = "" # whatever your codesigning identity is
@provisiong_profile = "./Support/App_Ad_Hoc.mobileprovision" # modify as necessary
end
desc "Trim whitespace"
task :trim_whitespace do
system_or_exit %Q[git status --short | awk '$1 !~ /.*[DR]/ {print $2}' | grep -E '.*\\.m?[cmhn]$' | xargs sed -i '' -e 's/ / /g;s/ *$//g;']
end
desc "Clean simulator directories"
task :clean_simulator do
system("rm -Rf ~/Library/Application\ Support/iPhone\ Simulator/#{SDK_VERSION}/Applications/*")
end
desc "Clean all targets"
task :clean do
system_or_exit "xcodebuild -project #{PROJECT_NAME}.xcodeproj -alltargets -configuration #{@configuration} clean SYMROOT=#{BUILD_DIR}", output_file("clean")
FileUtils.rm_rf BUILD_DIR
end
desc "Build application"
task :build_app do
system_or_exit(%Q[xcodebuild -project #{PROJECT_NAME}.xcodeproj -target #{APP_NAME} -configuration #{@configuration} build SYMROOT=#{BUILD_DIR}], output_file("app"))
end
desc "Bump version number"
task :bump_version do
system_or_exit(%Q[agvtool bump -all])
system_or_exit(%Q[git add Support/#{PROJECT_NAME}-Info.plist #{PROJECT_NAME}.xcodeproj/project.pbxproj])
system_or_exit(%Q[git commit -m 'bump version'])
end
desc "Package application"
task :package_app => :build_app do
system_or_exit(%Q[/usr/bin/xcrun -sdk iphoneos PackageApplication -v "#{BUILD_DIR}/#{@configuration}-iphoneos/#{product_name}.app" -o "#{BUILD_DIR}/#{product_name}.ipa" --sign "#{@developer_name}" --embed "#{@provisiong_profile}"])
system_or_exit(%Q[cd #{BUILD_DIR}/#{@configuration}-iphoneos; zip -r ../#{product_name}.app.dSYM.zip #{product_name}.app.dSYM])
end
namespace :testflight do
desc "Deploy to TestFlight"
task :deploy => [:clean, :require_clean_index, :bump_version, :tag_git, :package_app] do
print "Deploy Notes: "
message = STDIN.gets
message += "\n" + `git log HEAD^..HEAD`
message_file = "deploy_notes.txt"
File.open(message_file, 'w') {|f| f.write(message) }
system_or_exit(%Q[curl http://testflightapp.com/api/builds.json \
-F file=@#{BUILD_DIR}/#{product_name}.ipa \
-F dsym=@#{BUILD_DIR}/#{product_name}.app.dSYM.zip \
-F api_token='#{TESTFLIGHT_API_TOKEN}' \
-F team_token='#{TESTFLIGHT_TEAM_TOKEN}' \
-F notes=@#{message_file} \
-F notify=True \
-F distribution_lists='#{@testflight_distribution_list}'])
File.delete(message_file)
system_or_exit("git push; git push --tags")
end
end
desc "Build all targets"
task :build_all do
kill_simulator
system_or_exit "xcodebuild -project #{PROJECT_NAME}.xcodeproj -alltargets -configuration #{@configuration} build TEST_AFTER_BUILD=NO SYMROOT=#{BUILD_DIR}", output_file("build_all")
end
desc "adds a release tag to git"
task :tag_git do
release_tag = "#{@configuration.downcase}-#{agv_version}"
system_or_exit("git tag #{release_tag}")
end
desc "ensures that there's nothing in the git index before creating a release"
task :require_clean_index do
diff = `git diff-index --cached HEAD`
if diff.length > 0
raise "\nYou have uncommitted changes in your git index. You can't deploy with uncommitted changes."
end
end
def agv_version
output = `agvtool what-version`
output.match(/(\d+)/)[1]
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment