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 +4 -4
- data/bin/thrust +5 -9
- data/lib/config/android_example.yml +1 -1
- data/lib/config/ios_example.yml +25 -16
- data/lib/tasks/cedar.rake +1 -1
- data/lib/tasks/testflight.rake +8 -4
- data/lib/tasks/version.rake +1 -1
- data/lib/thrust/android/deploy.rb +7 -5
- data/lib/thrust/android/deploy_provider.rb +1 -2
- data/lib/thrust/app_config.rb +2 -2
- data/lib/thrust/config.rb +1 -1
- data/lib/thrust/deployment_target.rb +3 -1
- data/lib/thrust/executor.rb +1 -0
- data/lib/thrust/git.rb +14 -4
- data/lib/thrust/ios/agv_tool.rb +2 -2
- data/lib/thrust/ios/cedar.rb +6 -19
- data/lib/thrust/ios/deploy.rb +9 -4
- data/lib/thrust/ios/x_code_tools.rb +29 -20
- data/lib/thrust/ios_spec_target.rb +7 -5
- data/lib/thrust/tasks/ios_specs.rb +9 -5
- data/lib/thrust/testflight.rb +21 -10
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1fb35577e4d2487d491cf57395111792a028a785
|
4
|
+
data.tar.gz: f0e51c4c87b0c4a13bca26cd6e6a470e35c67da6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|
40
|
-
puts " Type 'rake -T' to see the list of tasks after you have created your thrust.yml configuration."
|
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."
|
data/lib/config/ios_example.yml
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
thrust_version: 0.
|
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
|
-
|
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.
|
19
|
-
ios_build_configuration: Release
|
20
|
-
ios_provisioning_search_query: 'query to find Provisioning Profile' #
|
21
|
-
versioning_method: 'none' #
|
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 #
|
30
|
-
|
31
|
-
type: app # Spec target type: app or bundle. Optional, defaults to app.
|
32
|
-
build_configuration: Debug #
|
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
|
-
|
35
|
-
|
36
|
-
|
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
|
-
|
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
|
-
|
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, :
|
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
|
data/lib/tasks/testflight.rake
CHANGED
@@ -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
|
-
|
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
|
-
|
24
|
+
Thrust::Git.new($stdout, Thrust::Executor.new).reset
|
25
|
+
end
|
22
26
|
end
|
23
27
|
end
|
24
28
|
end
|
data/lib/tasks/version.rake
CHANGED
@@ -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,
|
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
|
-
@
|
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
|
-
|
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
|
-
|
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
|
data/lib/thrust/app_config.rb
CHANGED
@@ -7,7 +7,7 @@ module Thrust
|
|
7
7
|
attr_reader :app_name,
|
8
8
|
:deployment_targets,
|
9
9
|
:ios_distribution_certificate,
|
10
|
-
:
|
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
|
-
@
|
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,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
|
data/lib/thrust/executor.rb
CHANGED
@@ -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 =
|
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 =
|
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
|
68
|
-
list = @thrust_executor.capture_output_from_system("autotag list #{
|
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
|
data/lib/thrust/ios/agv_tool.rb
CHANGED
@@ -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
|
data/lib/thrust/ios/cedar.rb
CHANGED
@@ -8,31 +8,18 @@ module Thrust
|
|
8
8
|
@out = out
|
9
9
|
end
|
10
10
|
|
11
|
-
def run(build_configuration, target,
|
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
|
-
|
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
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
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
|
data/lib/thrust/ios/deploy.rb
CHANGED
@@ -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
|
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(
|
39
|
+
run_xcode(build_sdk, scheme_or_target, architecture)
|
40
40
|
end
|
41
41
|
|
42
|
-
def test(scheme, build_configuration,
|
43
|
-
destination = "OS=#{
|
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
|
-
"
|
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 -
|
70
|
-
|
71
|
-
|
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
|
-
|
77
|
-
|
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
|
-
"'#{
|
82
|
-
"-o '#{
|
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(
|
87
|
-
|
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(
|
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
|
-
"
|
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}
|
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
|
-
:
|
7
|
-
:
|
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
|
-
@
|
17
|
-
@
|
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
|
-
|
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,
|
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,
|
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
|
data/lib/thrust/testflight.rb
CHANGED
@@ -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
|
-
@
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
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
|
+
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:
|
30
|
+
date: 2014-11-20 00:00:00.000000000 Z
|
30
31
|
dependencies:
|
31
32
|
- !ruby/object:Gem::Dependency
|
32
33
|
name: colorize
|