thrust 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cb3c733a86a1d3a7d7aec4521cc0c746713b8225
4
- data.tar.gz: e9b1773c0d258a7aa9409b6cb0e07fd72eda7157
3
+ metadata.gz: 1fb35577e4d2487d491cf57395111792a028a785
4
+ data.tar.gz: f0e51c4c87b0c4a13bca26cd6e6a470e35c67da6
5
5
  SHA512:
6
- metadata.gz: b498bcb659a91cbfd17fabef26e3a7b26e109a034e86475526d5255321ff049395e75675dc76212c43afbb1a9092ea33c5b6ef42445eb3476c14e863ef96d486
7
- data.tar.gz: 6579b916c3db7a727960a744147773d10e438ff97f20ec940837f33e24db7868f9529b515166379e1a2efda12ba92feec5a6dc6a2404bb66b171cf80f7571de0
6
+ metadata.gz: bd29c2f0d662de90beb61fff4184025a56fdceff88cff0a47425f5f8c2bed2bc94b31a6c7a87bce8490a7ac77846cbea9e69816c5352d59dbca1ff63103dc098
7
+ data.tar.gz: fa708a3f2a70f51bb1063487e59c6276d1811364057f35db4d627d95d7e90ddaf7439b6ba24367d2d8df49d4d7186e2d867b65d706e28c5e79843f0e16e8ff91
data/bin/thrust CHANGED
@@ -16,8 +16,8 @@ project_root = Dir.pwd
16
16
  thrust_root = File.expand_path(File.join(File.dirname(__FILE__), '..'))
17
17
 
18
18
  rakefile = File.join(project_root, 'Rakefile')
19
- File.open(rakefile, 'a') do |f|
20
- f.puts "require 'thrust/tasks'"
19
+ File.open(rakefile, 'a+') do |f|
20
+ f.puts "require 'thrust/tasks'" unless f.grep(/require 'thrust\/tasks'/).any?
21
21
  end
22
22
 
23
23
  if File.exists?('AndroidManifest.xml')
@@ -29,12 +29,8 @@ end
29
29
 
30
30
  FileUtils.cp(File.join(thrust_root, 'lib', 'config', example_file_name), File.join(project_root, 'thrust.example.yml'))
31
31
  puts ''
32
- puts " To finish installation of " + "Thrust".green + ", rename:\n\n"
33
- puts " #{project_root}/thrust.example.yml\n".blue
34
- puts " to:\n\n"
35
- puts " #{project_root}/thrust.yml\n".blue
36
- puts " and edit it for your project."
32
+ puts ' To finish installation of Thrust, rename ' + 'thrust.example.yml'.blue + ' to ' + 'thrust.yml'.blue + ' and edit it for your project.'
37
33
 
38
34
  puts ''
39
- puts " Thrust rake tasks were generated in your Rakefile."
40
- puts " Type 'rake -T' to see the list of tasks after you have created your thrust.yml configuration.".green
35
+ puts ' Thrust rake tasks were generated in your Rakefile.'
36
+ puts " Type 'rake -T' to see the list of available tasks after you have created your thrust.yml configuration."
@@ -1,4 +1,4 @@
1
- thrust_version: 0.4
1
+ thrust_version: 0.5
2
2
  project_name: My Great Project
3
3
  app_name: My Great App
4
4
 
@@ -1,10 +1,10 @@
1
- thrust_version: 0.4
1
+ thrust_version: 0.5
2
2
  project_name: My Great Project # do not use if building with an xcode workspace
3
3
  # workspace_name: My Workspace # use if building with an xcode workspace
4
4
  # path_to_xcodeproj: 'App/MyApp.xcodeproj' # use if xcodeproj is not in the same directory as this yaml file. Optional.
5
5
  app_name: My Great App
6
6
  ios_distribution_certificate: 'Name of Distribution Signing Certificate'
7
- ios_sim_binary: 'ios-sim' # or wax-sim. iOS only.
7
+ #ios_sim_path: '/path/to/ios-sim' # Optional. Use to prefer a specific ios-sim binary (e.g. within project directory) over a system-installed version (homebrew)
8
8
 
9
9
  testflight:
10
10
  api_token: 'testflight api token' # To find your App Token, follow the instructions at: http://help.testflightapp.com/customer/portal/articles/829956-what-does-the-api-token-do-
@@ -15,29 +15,38 @@ deployment_targets:
15
15
  distribution_list: Developers # This is the name of a TestFlight distribution list
16
16
  notify: true # Whether to notify people on the distribution list about this deployment
17
17
  note_generation_method: autotag # If you set this value, it will auto-generate the deploy notes from the commit history. Optional.
18
- ios_target: MyGreatAppTarget # Name of the build target. Optional, defaults to app name. iOS only.
19
- ios_build_configuration: Release # iOS only
20
- ios_provisioning_search_query: 'query to find Provisioning Profile' # iOS only. Optional.
21
- versioning_method: 'none' # Optional. Leave blank to use Git commit sha's for build numbers.
18
+ ios_target: MyGreatAppTarget # Name of the build target. Optional, defaults to app name.
19
+ ios_build_configuration: Release
20
+ ios_provisioning_search_query: 'query to find Provisioning Profile' # Otherwise, it will use the first provisioning profile in ~/Library/MobileDevice/Provisioning Profiles/
21
+ versioning_method: 'none' # or 'timestamp-sha' or 'commits'. Leave blank to use Git commit SHAs for build numbers.
22
+ tag: ci # Deploys latest commit with the tag. Leave blank to deploy from master.
22
23
 
23
24
  demo:
24
25
  distribution_list: Beta Testers
25
26
  notify: true
27
+ ios_build_configuration: Demo
28
+ ios_provisioning_search_query: 'query to find Provisioning Profile'
26
29
 
27
30
  ios_spec_targets:
28
31
  specs: # This is the name of the rake task: `rake specs`
29
- target: UISpecs # name of the build target
30
- # scheme: Specs (My Great App) # use in addition to target when you want to use a scheme (necessary if you are building with an xcode workspace)
31
- type: app # Spec target type: app or bundle. Optional, defaults to app.
32
- build_configuration: Debug # name of the build configuration
32
+ target: UISpecs # Name of the build target.
33
+ scheme: Specs (My Great App) # Use if the scheme name is different from the target name. Necessary when building in an xcode workspace.
34
+ type: app # Spec target type: 'app' or 'bundle'. Optional, defaults to app.
35
+ build_configuration: Debug # Name of the build configuration.
33
36
  build_sdk: iphonesimulator7.0 # SDK used to build the target. Optional, defaults to latest iphonesimulator.
34
- runtime_sdk: 7.0 # SDK used to run the target. Not optional.
35
- # device: ipad # Device to run the specs on. Deprecated in ios-sim 3.0+, use device_type_id instead.
36
- device_type_id: com.apple.CoreSimulator.SimDeviceType.iPad-Retina, 7.0 # required if using ios-sim 3.0
37
+ device_name: iPhone 4s # Device name as suggested by `ios-sim showdevicetypes`.
38
+ os_version: 7.1 # OS version to run. Defaults to latest available version.
39
+ timeout: 90 # Optional. Destination timeout defaults to 30 seconds.
37
40
 
38
- integration:
41
+ spec_bundle: # Example of a spec bundle configuration.
42
+ scheme: My Great App # Use the name for the main app scheme.
43
+ type: bundle
44
+ build_configuration: Debug
45
+ device_name: iPhone 4s
46
+ os_version: 7.1
47
+
48
+ integration: # Example of a Mac OSX target.
39
49
  target: IntegrationSpecs
40
- # scheme: IntegrationSpecs (My Great App) # use in addition to target when you want to use a scheme (necessary if you are building with an xcode workspace)
50
+ scheme: IntegrationSpecs (My Great App) # Use if the scheme name is different from the target name. Necessary when building in an xcode workspace.
41
51
  build_configuration: Release
42
52
  build_sdk: macosx
43
- runtime_sdk: macosx
data/lib/tasks/cedar.rake CHANGED
@@ -27,7 +27,7 @@ task :clean_build => :clean
27
27
 
28
28
  @thrust.app_config.ios_spec_targets.each do |target_name, target_info|
29
29
  desc target_info.scheme ? "Run the #{target_info.scheme} scheme" : "Run the #{target_info.target} target"
30
- task target_name, :runtime_sdk do |_, args|
30
+ task target_name, :device_name, :os_version do |_, args|
31
31
  exit(1) unless Thrust::Tasks::IOSSpecs.new.run(@thrust, target_info, args)
32
32
  end
33
33
  end
@@ -10,15 +10,19 @@ namespace :testflight do
10
10
  desc "Deploy Android build to #{task_name} (use NOTIFY=false to prevent team notification)"
11
11
  task task_name do |_, _|
12
12
  Thrust::Android::DeployProvider.new.instance(@thrust, deployment_config, task_name).run
13
-
14
- Rake::Task['autotag:create'].invoke(task_name)
15
13
  end
16
14
  else
17
15
  desc "Deploy iOS build to #{task_name} (use NOTIFY=false to prevent team notification)"
18
16
  task task_name do |_, _|
19
- Thrust::IOS::DeployProvider.new.instance(@thrust, deployment_config, task_name).run
17
+ begin
18
+ Thrust::IOS::DeployProvider.new.instance(@thrust, deployment_config, task_name).run
19
+ rescue Exception => e
20
+ puts "\n\n"
21
+ puts e.message.red
22
+ puts "\n\n"
20
23
 
21
- Rake::Task['autotag:create'].invoke(task_name)
24
+ Thrust::Git.new($stdout, Thrust::Executor.new).reset
25
+ end
22
26
  end
23
27
  end
24
28
  end
@@ -8,6 +8,6 @@ task :set_build_number, :build_number do |_, args|
8
8
  Thrust::Android::Tools.new.change_build_number(Time.now.utc.strftime('%y%m%d%H%M'), args[:build_number])
9
9
  else
10
10
  path_to_xcodeproj = @thrust.app_config.path_to_xcodeproj
11
- Thrust::IOS::AgvTool.new.change_build_number(args[:build_number], path_to_xcodeproj)
11
+ Thrust::IOS::AgvTool.new.change_build_number(args[:build_number], nil, path_to_xcodeproj)
12
12
  end
13
13
  end
@@ -1,24 +1,26 @@
1
1
  module Thrust
2
2
  module Android
3
3
  class Deploy
4
- def initialize(out, tools, git, testflight, notify, distribution_list, autogenerate_notes, deployment_target)
4
+ def initialize(out, tools, git, testflight, deployment_config, deployment_target)
5
5
  @out = out
6
6
  @tools = tools
7
7
  @git = git
8
8
  @testflight = testflight
9
- @notify = notify
10
- @distribution_list = distribution_list
9
+ @deployment_config = deployment_config
11
10
  @deployment_target = deployment_target
12
- @autogenerate_notes = autogenerate_notes
13
11
  end
14
12
 
15
13
  def run
16
14
  @git.ensure_clean
15
+ @git.checkout_tag(@deployment_config.tag) if @deployment_config.tag
16
+
17
17
  @tools.change_build_number(Time.now.utc.strftime('%y%m%d%H%M'), @git.current_commit)
18
18
  apk_path = @tools.build_signed_release
19
19
 
20
- @testflight.upload(apk_path, @notify, @distribution_list, @autogenerate_notes, @deployment_target)
20
+ autogenerate_notes = @deployment_config.note_generation_method == 'autotag'
21
+ @testflight.upload(apk_path, @deployment_config.notify, @deployment_config.distribution_list, autogenerate_notes, @deployment_target)
21
22
 
23
+ @git.create_tag(@deployment_target)
22
24
  @git.reset
23
25
  end
24
26
  end
@@ -9,8 +9,7 @@ module Thrust
9
9
  testflight_config = thrust_config.app_config.testflight
10
10
  testflight = Thrust::Testflight.new(thrust_executor, $stdout, $stdin, testflight_config.api_token, testflight_config.team_token)
11
11
 
12
- autogenerate_notes = deployment_config.note_generation_method == 'autotag'
13
- Thrust::Android::Deploy.new($stdout, tools, git, testflight, deployment_config.notify, deployment_config.distribution_list, autogenerate_notes, deployment_target)
12
+ Thrust::Android::Deploy.new($stdout, tools, git, testflight, deployment_config, deployment_target)
14
13
  end
15
14
  end
16
15
  end
@@ -7,7 +7,7 @@ module Thrust
7
7
  attr_reader :app_name,
8
8
  :deployment_targets,
9
9
  :ios_distribution_certificate,
10
- :ios_sim_binary,
10
+ :ios_sim_path,
11
11
  :ios_spec_targets,
12
12
  :project_name,
13
13
  :testflight,
@@ -19,7 +19,7 @@ module Thrust
19
19
  @app_name = attributes['app_name']
20
20
  @deployment_targets = generate_deployment_targets(attributes['deployment_targets'])
21
21
  @ios_distribution_certificate = attributes['ios_distribution_certificate']
22
- @ios_sim_binary = attributes['ios_sim_binary']
22
+ @ios_sim_path = attributes['ios_sim_path']
23
23
  @ios_spec_targets = generate_ios_spec_targets(attributes['ios_spec_targets'])
24
24
  @project_name = attributes['project_name']
25
25
  @testflight = generate_testflight_credentials(attributes['testflight'])
data/lib/thrust/config.rb CHANGED
@@ -6,7 +6,7 @@ module Thrust
6
6
  class Config
7
7
  attr_reader :project_root, :app_config, :build_dir
8
8
 
9
- THRUST_VERSION = '0.4'
9
+ THRUST_VERSION = '0.5'
10
10
  THRUST_ROOT = File.expand_path('../..', __FILE__)
11
11
 
12
12
  def self.make(relative_project_root, config_file)
@@ -6,7 +6,8 @@ module Thrust
6
6
  :ios_target,
7
7
  :note_generation_method,
8
8
  :notify,
9
- :versioning_method
9
+ :versioning_method,
10
+ :tag
10
11
 
11
12
  def initialize(attributes)
12
13
  @distribution_list = attributes['distribution_list']
@@ -16,6 +17,7 @@ module Thrust
16
17
  @note_generation_method = attributes['note_generation_method']
17
18
  @notify = attributes['notify']
18
19
  @versioning_method = attributes['versioning_method']
20
+ @tag = attributes['tag']
19
21
  end
20
22
  end
21
23
  end
@@ -24,6 +24,7 @@ module Thrust
24
24
  end
25
25
 
26
26
  def capture_output_from_system(cmd, env = {})
27
+ @out.puts "Executing #{cmd}"
27
28
  execution = @execution_helper.capture_status_and_output_from_command(cmd, env)
28
29
 
29
30
  raise(CommandFailed, '******** Build failed ********') unless execution[:success]
data/lib/thrust/git.rb CHANGED
@@ -21,8 +21,14 @@ module Thrust
21
21
  @thrust_executor.capture_output_from_system('git log --format=format:%h -1').strip
22
22
  end
23
23
 
24
+ def checkout_tag(tag)
25
+ tag_sha = latest_commit_with_tag(tag)
26
+ @thrust_executor.system_or_exit("git checkout #{tag_sha}")
27
+ end
28
+
24
29
  def reset
25
30
  @thrust_executor.system_or_exit('git reset --hard')
31
+ @thrust_executor.system_or_exit('git checkout master')
26
32
  end
27
33
 
28
34
  def checkout_file(filename)
@@ -30,7 +36,7 @@ module Thrust
30
36
  end
31
37
 
32
38
  def commit_summary_for_last_deploy(deployment_target)
33
- sha_of_latest_deployed_commit = latest_deployed_commit(deployment_target)
39
+ sha_of_latest_deployed_commit = latest_commit_with_tag(deployment_target)
34
40
  if sha_of_latest_deployed_commit
35
41
  "#{deployment_target}:".blue + " #{summary_for_commit(sha_of_latest_deployed_commit)}"
36
42
  else
@@ -40,7 +46,7 @@ module Thrust
40
46
 
41
47
  def generate_notes_for_deployment(deployment_target)
42
48
  sha_of_latest_commit = @thrust_executor.capture_output_from_system('git rev-parse HEAD').strip
43
- sha_of_latest_deployed_commit = latest_deployed_commit(deployment_target)
49
+ sha_of_latest_deployed_commit = latest_commit_with_tag(deployment_target)
44
50
 
45
51
  notes = Tempfile.new('deployment_notes')
46
52
 
@@ -58,14 +64,18 @@ module Thrust
58
64
  @thrust_executor.capture_output_from_system("git rev-list HEAD | wc -l").strip
59
65
  end
60
66
 
67
+ def create_tag(tag_name)
68
+ @thrust_executor.system_or_exit("autotag create #{tag_name}")
69
+ end
70
+
61
71
  private
62
72
 
63
73
  def summary_for_commit(sha)
64
74
  @thrust_executor.capture_output_from_system("git log --oneline -n 1 #{sha}")
65
75
  end
66
76
 
67
- def latest_deployed_commit(deployment_target)
68
- list = @thrust_executor.capture_output_from_system("autotag list #{deployment_target}")
77
+ def latest_commit_with_tag(tag_name)
78
+ list = @thrust_executor.capture_output_from_system("autotag list #{tag_name}")
69
79
  unless list.strip.empty?
70
80
  list.split("\n").last.split(" ").first
71
81
  end
@@ -6,9 +6,9 @@ module Thrust
6
6
  @git = git
7
7
  end
8
8
 
9
- def change_build_number(build_number, path_to_xcodeproj)
9
+ def change_build_number(build_number, timestamp = nil, path_to_xcodeproj = nil)
10
10
  path_to_xcodeproj = path_to_xcodeproj ? File.dirname(path_to_xcodeproj) : '.'
11
- @thrust_executor.system_or_exit "cd #{path_to_xcodeproj} && agvtool new-version -all '#{build_number}'"
11
+ @thrust_executor.system_or_exit "cd #{path_to_xcodeproj} && agvtool new-version -all '#{timestamp ? timestamp + '-' : ''}#{build_number}'"
12
12
  @git.checkout_file("#{path_to_xcodeproj}/*.xcodeproj")
13
13
  end
14
14
  end
@@ -8,31 +8,18 @@ module Thrust
8
8
  @out = out
9
9
  end
10
10
 
11
- def run(build_configuration, target, runtime_sdk, build_sdk, device, device_type_id, build_dir, simulator_binary)
11
+ def run(build_configuration, target, build_sdk, os_version, device_name, timeout, build_dir, simulator_binary)
12
12
  if build_sdk == 'macosx'
13
13
  build_path = File.join(build_dir, build_configuration)
14
14
  app_dir = File.join(build_path, target)
15
15
  @thrust_executor.check_command_for_failure(app_dir.inspect, {'DYLD_FRAMEWORK_PATH' => build_path.inspect})
16
16
  else
17
- app_executable = File.join(build_dir, "#{build_configuration}-#{build_sdk}", "#{target}.app")
18
-
19
- if simulator_binary =~ /waxim%/
20
- @thrust_executor.check_command_for_failure(%Q[#{simulator_binary} -s #{runtime_sdk} -f #{device} -e CFFIXED_USER_HOME=#{Dir.tmpdir} -e CEDAR_HEADLESS_SPECS=1 -e CEDAR_REPORTER_CLASS=CDRDefaultReporter #{app_executable}])
21
- elsif simulator_binary =~ /ios-sim$/
22
- if (device_type_id.nil?)
23
- if device == "ipad"
24
- @thrust_executor.check_command_for_failure(%Q[#{simulator_binary} launch #{app_executable} --sdk #{runtime_sdk} --family #{device} --setenv CFFIXED_USER_HOME=#{Dir.tmpdir} --setenv CEDAR_HEADLESS_SPECS=1 --setenv CEDAR_REPORTER_CLASS=CDRDefaultReporter])
25
- else
26
- @thrust_executor.check_command_for_failure(%Q[#{simulator_binary} launch #{app_executable} --sdk #{runtime_sdk} --family #{device} --retina --tall --setenv CFFIXED_USER_HOME=#{Dir.tmpdir} --setenv CEDAR_HEADLESS_SPECS=1 --setenv CEDAR_REPORTER_CLASS=CDRDefaultReporter])
27
- end
28
- else
29
- @thrust_executor.check_command_for_failure(%Q[#{simulator_binary} launch #{app_executable} --devicetypeid '#{device_type_id}' --setenv CFFIXED_USER_HOME=#{Dir.tmpdir} --setenv CEDAR_HEADLESS_SPECS=1 --setenv CEDAR_REPORTER_CLASS=CDRDefaultReporter])
30
- end
17
+ device_type_id = "com.apple.CoreSimulator.SimDeviceType.#{device_name}, #{os_version}"
31
18
 
32
- else
33
- @out.puts "Unknown binary for running specs: '#{simulator_binary}'"
34
- false
35
- end
19
+ app_executable = File.join(build_dir, "#{build_configuration}-#{build_sdk}", "#{target}.app")
20
+ simulator_binary ||= 'ios-sim'
21
+ timeout ||= '30'
22
+ @thrust_executor.check_command_for_failure(%Q[#{simulator_binary} launch #{app_executable} --devicetypeid '#{device_type_id}' --timeout #{timeout} --setenv CFFIXED_USER_HOME=#{Dir.tmpdir} --setenv CEDAR_REPORTER_CLASS=CDRDefaultReporter])
36
23
  end
37
24
  end
38
25
  end
@@ -14,25 +14,30 @@ module Thrust
14
14
 
15
15
  def run
16
16
  @git.ensure_clean
17
+ @git.checkout_tag(@deployment_config.tag) if @deployment_config.tag
17
18
 
18
19
  if @deployment_config.versioning_method != 'none'
19
- if (@deployment_config.versioning_method == 'commits')
20
- @agv_tool.change_build_number(@git.commit_count, @thrust_config.app_config.path_to_xcodeproj)
20
+ if @deployment_config.versioning_method == 'commits'
21
+ @agv_tool.change_build_number(@git.commit_count, nil, @thrust_config.app_config.path_to_xcodeproj)
22
+ elsif @deployment_config.versioning_method == 'timestamp-sha'
23
+ @agv_tool.change_build_number(@git.current_commit, Time.now.utc.strftime('%y%m%d%H%M'), @thrust_config.app_config.path_to_xcodeproj)
21
24
  else
22
- @agv_tool.change_build_number(@git.current_commit, @thrust_config.app_config.path_to_xcodeproj)
25
+ @agv_tool.change_build_number(@git.current_commit, nil, @thrust_config.app_config.path_to_xcodeproj)
23
26
  end
24
27
  end
25
28
 
26
-
27
29
  app_name = @thrust_config.app_config.app_name
28
30
  target = @deployment_config.ios_target || app_name
29
31
 
30
32
  ipa_file = @x_code_tools.cleanly_create_ipa(target, app_name, @thrust_config.app_config.ios_distribution_certificate, @deployment_config.ios_provisioning_search_query)
31
33
 
32
34
  dsym_path = "#{@x_code_tools.build_configuration_directory}/#{app_name}.app.dSYM"
35
+ dsym_path = nil unless File.exist?(dsym_path)
33
36
 
34
37
  autogenerate_notes = @deployment_config.note_generation_method == 'autotag'
35
38
  @testflight.upload(ipa_file, @deployment_config.notify, @deployment_config.distribution_list, autogenerate_notes, @deployment_target, dsym_path)
39
+
40
+ @git.create_tag(@deployment_target)
36
41
  @git.reset
37
42
  end
38
43
  end
@@ -36,19 +36,20 @@ module Thrust
36
36
 
37
37
  def build_scheme_or_target(scheme_or_target, build_sdk, architecture=nil)
38
38
  @out.puts "Building..."
39
- run_xcode('build', build_sdk, scheme_or_target, architecture)
39
+ run_xcode(build_sdk, scheme_or_target, architecture)
40
40
  end
41
41
 
42
- def test(scheme, build_configuration, runtime_sdk, build_dir)
43
- destination = "OS=#{runtime_sdk},name=iPhone Retina (3.5-inch)"
42
+ def test(scheme, build_configuration, os_version, device_name, timeout, build_dir)
43
+ destination = "OS=#{os_version},name=#{device_name}"
44
+ timeout ||= "30"
44
45
 
45
46
  cmd = [
46
47
  "xcodebuild",
47
48
  "test",
48
- "-scheme #{scheme}",
49
- "-configuration #{build_configuration}",
49
+ "-scheme '#{scheme}'",
50
+ "-configuration '#{build_configuration}'",
50
51
  "-destination '#{destination}'",
51
- "ARCHS=i386",
52
+ "-destination-timeout '#{timeout}'",
52
53
  "SYMROOT='#{build_dir}'"
53
54
  ].join(' ')
54
55
 
@@ -65,26 +66,34 @@ module Thrust
65
66
  private
66
67
 
67
68
  def provision_path(provision_search_query)
68
- provision_search_path = File.expand_path("~/Library/MobileDevice/Provisioning Profiles/")
69
- command = %Q(grep -rl "#{provision_search_query}" "#{provision_search_path}")
70
- paths = `#{command}`.split("\n")
71
- paths.first or raise(ProvisioningProfileNotFound, "\nCouldn't find provisioning profiles matching #{provision_search_query}.\n\nThe command used was:\n\n#{command}")
69
+ provision_search_path = File.expand_path("~/Library/MobileDevice/Provisioning Profiles")
70
+ command = %Q(find '#{provision_search_path}' -print0 | xargs -0 grep -lr '#{provision_search_query}' --null | xargs -0 ls -t)
71
+ provisioning_profile = `#{command}`.split("\n").first
72
+ if !provisioning_profile
73
+ raise(ProvisioningProfileNotFound, "\nCouldn't find provisioning profiles matching #{provision_search_query}.\n\nThe command used was:\n\n#{command}")
74
+ end
75
+ provisioning_profile
72
76
  end
73
77
 
74
78
  def create_ipa(app_name, signing_identity, provision_search_query)
75
79
  @out.puts 'Packaging...'
76
- ipa_filename = "#{build_configuration_directory}/#{app_name}.ipa"
77
- cmd = [
80
+ app_filepath = "#{build_configuration_directory}/#{app_name}.app"
81
+ ipa_filepath = "#{build_configuration_directory}/#{app_name}.ipa"
82
+ package_command = [
78
83
  "xcrun",
79
84
  "-sdk iphoneos",
80
85
  "-v PackageApplication",
81
- "'#{build_configuration_directory}/#{app_name}.app'",
82
- "-o '#{ipa_filename}'",
83
- "--sign '#{signing_identity}'",
86
+ "'#{app_filepath}'",
87
+ "-o '#{ipa_filepath}'",
84
88
  "--embed '#{provision_path(provision_search_query)}'"
85
89
  ].join(' ')
86
- @thrust_executor.system_or_exit(cmd)
87
- ipa_filename
90
+ @thrust_executor.system_or_exit(package_command)
91
+
92
+ @thrust_executor.system_or_exit("cd '#{build_configuration_directory}' && unzip '#{app_name}.ipa'")
93
+ @thrust_executor.system_or_exit("/usr/bin/codesign --verify --force --preserve-metadata=identifier,entitlements --sign '#{signing_identity}' '#{build_configuration_directory}/Payload/#{app_name}.app'")
94
+ @thrust_executor.system_or_exit("cd '#{build_configuration_directory}' && zip -qr '#{app_name}.ipa' 'Payload'")
95
+
96
+ ipa_filepath
88
97
  end
89
98
 
90
99
  def verify_provision(app_name, provision_search_query)
@@ -97,7 +106,7 @@ module Thrust
97
106
  end
98
107
  end
99
108
 
100
- def run_xcode(build_command, sdk = nil, scheme_or_target = nil, architecture = nil)
109
+ def run_xcode(sdk = nil, scheme_or_target = nil, architecture = nil)
101
110
  architecture_flag = architecture ? "-arch #{architecture}" : nil
102
111
  target_flag = @workspace_name ? "-scheme \"#{scheme_or_target}\"" : "-target \"#{scheme_or_target}\""
103
112
  sdk_flag = sdk ? "-sdk #{sdk}" : nil
@@ -112,13 +121,13 @@ module Thrust
112
121
  target_flag,
113
122
  "-configuration #{@build_configuration}",
114
123
  sdk_flag,
115
- "#{build_command}",
124
+ "clean build",
116
125
  "SYMROOT=#{@build_directory.inspect}",
117
126
  configuration_build_dir_option,
118
127
  '2>&1',
119
128
  "| grep -v 'backing file'"
120
129
  ].compact.join(' ')
121
- output_file = output_file("#{@build_configuration}-#{build_command}")
130
+ output_file = output_file("#{@build_configuration}-build")
122
131
  begin
123
132
  @thrust_executor.system_or_exit(command, output_file)
124
133
  rescue Thrust::Executor::CommandFailed => e
@@ -3,21 +3,23 @@ module Thrust
3
3
  attr_reader :build_configuration,
4
4
  :build_sdk,
5
5
  :device,
6
- :device_type_id,
7
- :runtime_sdk,
6
+ :device_name,
7
+ :os_version,
8
8
  :scheme,
9
9
  :target,
10
- :type
10
+ :type,
11
+ :timeout
11
12
 
12
13
  def initialize(attributes)
13
14
  @build_configuration = attributes['build_configuration']
14
15
  @build_sdk = attributes['build_sdk'] || 'iphonesimulator'
15
16
  @device = attributes['device'] || 'iphone'
16
- @device_type_id = attributes['device_type_id']
17
- @runtime_sdk = attributes['runtime_sdk']
17
+ @device_name = attributes['device_name']
18
+ @os_version = attributes['os_version']
18
19
  @scheme = attributes['scheme']
19
20
  @target = attributes['target']
20
21
  @type = attributes['type'] || 'app'
22
+ @timeout = attributes['timeout']
21
23
  end
22
24
  end
23
25
  end
@@ -15,21 +15,25 @@ module Thrust
15
15
  target = target_info.target
16
16
  scheme = target_info.scheme
17
17
  build_sdk = target_info.build_sdk
18
- runtime_sdk = args[:runtime_sdk] || target_info.runtime_sdk
18
+ os_version = args[:os_version] || target_info.os_version
19
+ device_name = args[:device_name] || target_info.device_name
20
+
21
+ substitution_map = {'bundle' => '-', 'app' => ' '}
22
+ destination_map = {'bundle' => ' ', 'app' => '-'}
23
+ device_name.gsub!(substitution_map[type], destination_map[type])
19
24
 
20
25
  tools_options = {
21
26
  project_name: thrust.app_config.project_name,
22
27
  workspace_name: thrust.app_config.workspace_name
23
28
  }
24
-
25
29
  xcode_tools = @xcode_tools_provider.instance(@out, build_configuration, thrust.build_dir, tools_options)
26
- xcode_tools.build_scheme_or_target(scheme || target, build_sdk)
27
30
 
28
31
  if type == 'app'
32
+ xcode_tools.build_scheme_or_target(scheme || target, build_sdk)
29
33
  xcode_tools.kill_simulator
30
- @cedar.run(build_configuration, target, runtime_sdk, build_sdk, target_info.device, target_info.device_type_id, thrust.build_dir, thrust.app_config.ios_sim_binary)
34
+ @cedar.run(build_configuration, target, build_sdk, os_version, device_name, target_info.timeout, thrust.build_dir, thrust.app_config.ios_sim_path)
31
35
  else
32
- xcode_tools.test(target || scheme, build_configuration, runtime_sdk, thrust.build_dir)
36
+ xcode_tools.test(target || scheme, build_configuration, os_version, device_name, target_info.timeout, thrust.build_dir)
33
37
  end
34
38
  end
35
39
  end
@@ -1,5 +1,7 @@
1
1
  module Thrust
2
2
  class Testflight
3
+ UploadFailed = Class.new(StandardError)
4
+
3
5
  def initialize(thrust_executor, out, input, api_token, team_token)
4
6
  @thrust_executor = thrust_executor
5
7
  @out = out
@@ -23,16 +25,25 @@ module Thrust
23
25
  message_file_path = Thrust::UserPrompt.get_user_input('Deploy Notes: ', @out, @in)
24
26
  end
25
27
 
26
- @thrust_executor.system_or_exit [
27
- 'curl http://testflightapp.com/api/builds.json',
28
- "-F file=@#{package_file}",
29
- ("-F dsym=@#{zipped_dsym_path}" if dsym_path),
30
- "-F api_token='#{(ENV['TESTFLIGHT_API_TOKEN'] || @api_token)}'",
31
- "-F team_token='#{@team_token}'",
32
- "-F notes=@#{message_file_path}",
33
- "-F notify=#{(ENV['NOTIFY'] || notify).to_s.downcase.capitalize}",
34
- ("-F distribution_lists='#{distribution_list}'" if distribution_list)
35
- ].compact.join(' ')
28
+ @out.puts 'Uploading to TestFlight...'.green
29
+
30
+ testflight_response = @thrust_executor.capture_output_from_system(['curl -sw "thrust_testflight_status_code:%{http_code}" http://testflightapp.com/api/builds.json',
31
+ "-F file=@#{package_file}",
32
+ ("-F dsym=@#{zipped_dsym_path}" if dsym_path),
33
+ "-F api_token='#{(ENV['TESTFLIGHT_API_TOKEN'] || @api_token)}'",
34
+ "-F team_token='#{@team_token}'",
35
+ "-F notes=@#{message_file_path}",
36
+ "-F notify=#{(ENV['NOTIFY'] || notify).to_s.downcase.capitalize}",
37
+ ("-F distribution_lists='#{distribution_list}'" if distribution_list)
38
+ ].compact.join(' '))
39
+
40
+ status_code = testflight_response.match(/thrust_testflight_status_code:(\d+)/).captures.first
41
+ if status_code.to_i >= 400
42
+ error_message = testflight_response.gsub(/thrust_testflight_status_code:(\d+)/, '')
43
+ raise(UploadFailed, "******** Upload Failed: #{error_message} ********")
44
+ else
45
+ @out.puts 'Finished uploading to TestFlight'.green
46
+ end
36
47
  end
37
48
  end
38
49
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thrust
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Levine
@@ -20,13 +20,14 @@ authors:
20
20
  - Molly Trombley-McCann
21
21
  - Philip Kuryloski
22
22
  - Rachel Bobbins
23
+ - Raphael Weiner
23
24
  - Sheel Choksi
24
25
  - Tyler Schultz
25
26
  - Wiley Kestner
26
27
  autorequire:
27
28
  bindir: bin
28
29
  cert_chain: []
29
- date: 2013-07-24 00:00:00.000000000 Z
30
+ date: 2014-11-20 00:00:00.000000000 Z
30
31
  dependencies:
31
32
  - !ruby/object:Gem::Dependency
32
33
  name: colorize