|
|
@@ -0,0 +1,244 @@ |
|
|
PROJECT_NAME = "AwesomeThing" |
|
|
APP_NAME = "AwesomeThing" |
|
|
@configuration = "Debug" |
|
|
@app_suffix = "-Dev" |
|
|
@staging_developer_name = "iPhone Developer: <<FILL ME IN>>" |
|
|
@staging_provisioning_profile = "Support/AwesomeThing.mobileprovision" |
|
|
@production_developer_name = "iPhone Distribution" |
|
|
@production_provisioning_profile = "Support/AwesomeThing.mobileprovision" |
|
|
@appstore_developer_name = "iPhone Distribution" |
|
|
@appstore_provisioning_profile = "Support/AwesomeThing.mobileprovision" |
|
|
|
|
|
TESTFLIGHT_API_TOKEN = "<<FILL ME IN>>" |
|
|
TESTFLIGHT_TEAM_TOKEN = "<<FILL ME IN>>" |
|
|
@testflight_distribution_list = "Dev" |
|
|
|
|
|
SPECS_TARGET_NAME = "DomainSpecs" |
|
|
UI_SPECS_TARGET_NAME = "UISpecs" |
|
|
|
|
|
OCUNIT_LOGIC_SPECS_TARGET_NAME = "OCUnitAppLogicTests" |
|
|
OCUNIT_APPLICATION_SPECS_TARGET_NAME = "OCUnitAppTests" |
|
|
|
|
|
SDK_VERSION = "6.0" |
|
|
SDK_DIR = "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator#{SDK_VERSION}.sdk" |
|
|
BUILD_DIR = File.join(File.dirname(__FILE__), "build") |
|
|
|
|
|
def build_dir(effective_platform_name) |
|
|
File.join(BUILD_DIR, @configuration + effective_platform_name) |
|
|
end |
|
|
|
|
|
def product_name |
|
|
"#{APP_NAME}#{@app_suffix}" |
|
|
end |
|
|
|
|
|
def grep_cmd_for_failure(cmd) |
|
|
puts "Executing #{cmd} and checking for FAILURE" |
|
|
%x[#{cmd} > #{Dir.tmpdir}/cmd.out 2>&1] |
|
|
status = $? |
|
|
result = File.read("#{Dir.tmpdir}/cmd.out") |
|
|
puts "Results:" |
|
|
puts result |
|
|
if !result.include?("Finished") |
|
|
exit(1) |
|
|
end |
|
|
if result.include?("FAILURE") |
|
|
exit(1) |
|
|
elsif result.include?("EXCEPTION") |
|
|
exit(1) |
|
|
else |
|
|
exit(0) |
|
|
end |
|
|
exit(1) |
|
|
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) |
|
|
output_dir = if ENV['IS_CI_BOX'] |
|
|
ENV['CC_BUILD_ARTIFACTS'] |
|
|
else |
|
|
Dir.mkdir(BUILD_DIR) unless File.exists?(BUILD_DIR) |
|
|
BUILD_DIR |
|
|
end |
|
|
|
|
|
output_file = File.join(output_dir, "#{target}.output") |
|
|
puts "Output: #{output_file}" |
|
|
output_file |
|
|
end |
|
|
|
|
|
def kill_simulator |
|
|
system %Q[killall -m -KILL "gdb"] |
|
|
system %Q[killall -m -KILL "otest"] |
|
|
system %Q[killall -m -KILL "iPhone Simulator"] |
|
|
end |
|
|
|
|
|
task :default => [:trim_whitespace, :uispecs] |
|
|
desc "CI build" |
|
|
task :cruise => [:clean, :clean_simulator, :build_app, :uispecs] |
|
|
|
|
|
desc "Staging configuration" |
|
|
task :staging do |
|
|
@configuration = "Staging" |
|
|
@app_suffix = "-Staging" |
|
|
@developer_name = @staging_developer_name |
|
|
@provisioning_profile = @staging_provisioning_profile |
|
|
end |
|
|
|
|
|
desc "Production configuration" |
|
|
task :production do |
|
|
@configuration = "Distribution" |
|
|
@app_suffix = "" |
|
|
@developer_name = @production_developer_name |
|
|
@provisioning_profile = @production_provisioning_profile |
|
|
end |
|
|
|
|
|
desc "App Store configuration" |
|
|
task :app_store do |
|
|
@configuration = "Distribution" |
|
|
@app_suffix = "" |
|
|
@developer_name = @appstore_developer_name |
|
|
@provisioning_profile = @appstore_provisioning_profile |
|
|
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/5.1/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("git add UISpecs/UISpecs-Info.plist App/#{APP_NAME}-Info.plist #{APP_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 "#{@provisioning_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 specs" |
|
|
task :build_specs do |
|
|
puts "SYMROOT: #{ENV['SYMROOT']}" |
|
|
system_or_exit(%Q[xcodebuild -project #{PROJECT_NAME}.xcodeproj -target #{SPECS_TARGET_NAME} -configuration #{@configuration} build SYMROOT=#{BUILD_DIR}], output_file("specs")) |
|
|
end |
|
|
|
|
|
desc "Build UI specs" |
|
|
task :build_uispecs do |
|
|
kill_simulator |
|
|
system_or_exit "xcodebuild -project #{PROJECT_NAME}.xcodeproj -target #{UI_SPECS_TARGET_NAME} -configuration #{@configuration} -sdk iphonesimulator build", output_file("uispecs") |
|
|
end |
|
|
|
|
|
desc "Build Integration specs" |
|
|
task :build_integration_specs do |
|
|
kill_simulator |
|
|
system_or_exit "xcodebuild -project #{PROJECT_NAME}.xcodeproj -target IntegrationTests -sdk macosx10.8 SYMROOT=#{BUILD_DIR}", output_file("integrationspecs") |
|
|
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 "Run specs" |
|
|
task :specs => :build_specs do |
|
|
build_dir = build_dir("") |
|
|
with_env_vars("DYLD_FRAMEWORK_PATH" => build_dir) do |
|
|
system_or_exit("cd #{build_dir}; ./#{SPECS_TARGET_NAME}") |
|
|
end |
|
|
end |
|
|
|
|
|
desc "Run integration specs" |
|
|
task :integration_specs => :build_integration_specs do |
|
|
with_env_vars("DYLD_FRAMEWORK_PATH" => "#{BUILD_DIR}/Release") do |
|
|
system_or_exit "#{BUILD_DIR}/Release/IntegrationTests" |
|
|
end |
|
|
end |
|
|
|
|
|
require 'tmpdir' |
|
|
desc "Run UI specs in the simulator using ios-sim" |
|
|
task :uispecs => :build_uispecs do |
|
|
grep_cmd_for_failure(%Q[#{File.join("bin", "ios-sim")} launch #{File.join(build_dir("-iphonesimulator"), "#{UI_SPECS_TARGET_NAME}.app")} --setenv CFFIXED_USER_HOME=#{Dir.tmpdir} --setenv CEDAR_HEADLESS_SPECS=1 --setenv CEDAR_REPORTER_CLASS=CDRDefaultReporter --retina]) |
|
|
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 |
|
|
|
|
|
task :current_version do |
|
|
puts agv_version |
|
|
end |
|
|
|
|
|
def agv_version |
|
|
output = `agvtool what-version`.split("\n")[1] |
|
|
output.match(/(\d+)/)[1] |
|
|
end |