Skip to content

Instantly share code, notes, and snippets.

@cbguder
Forked from avh4/Rakefile
Last active December 18, 2015 05:29

Revisions

  1. cbguder revised this gist Jun 7, 2013. 1 changed file with 28 additions and 15 deletions.
    43 changes: 28 additions & 15 deletions Rakefile
    Original file line number Diff line number Diff line change
    @@ -32,22 +32,35 @@ def product_name
    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)
    retries = 0

    while retries < 10 do
    retries += 1

    puts "Executing #{cmd} and checking for FAILURE"
    result = %x[#{cmd} 2>&1]

    puts "Results:"
    puts result

    if result.include?("Simulator session timed out")
    puts "Simulator timed out, retrying..."
    kill_simulator
    else
    if !result.include?("Finished")
    exit(1)
    end

    if result.include?("FAILURE")
    exit(1)
    elsif result.include?("EXCEPTION")
    exit(1)
    else
    exit(0)
    end
    end
    end

    exit(1)
    end

  2. @avh4 avh4 created this gist Mar 22, 2013.
    244 changes: 244 additions & 0 deletions Rakefile
    Original file line number Diff line number Diff line change
    @@ -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