thrust 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/config/android_example.yml +1 -1
- data/lib/config/ios_example.yml +6 -2
- data/lib/tasks/autotag.rake +14 -0
- data/lib/tasks/cedar.rake +9 -50
- data/lib/tasks/testflight.rake +2 -17
- data/lib/tasks/version.rake +6 -5
- data/lib/thrust/android/deploy.rb +21 -17
- data/lib/thrust/android/deploy_provider.rb +13 -9
- data/lib/thrust/android/tools.rb +28 -24
- data/lib/thrust/app_config.rb +57 -0
- data/lib/thrust/config.rb +33 -29
- data/lib/thrust/deployment_target.rb +21 -0
- data/lib/thrust/execution_helper.rb +17 -0
- data/lib/thrust/executor.rb +36 -21
- data/lib/thrust/git.rb +54 -47
- data/lib/thrust/ios/agv_tool.rb +13 -10
- data/lib/thrust/ios/cedar.rb +33 -18
- data/lib/thrust/ios/deploy.rb +34 -21
- data/lib/thrust/ios/deploy_provider.rb +16 -12
- data/lib/thrust/ios/x_code_tools.rb +131 -96
- data/lib/thrust/ios/x_code_tools_provider.rb +10 -7
- data/lib/thrust/ios_spec_target.rb +23 -0
- data/lib/thrust/tasks/autotag/create.rb +15 -0
- data/lib/thrust/tasks/autotag/list.rb +17 -0
- data/lib/thrust/tasks/clean.rb +20 -0
- data/lib/thrust/tasks/focused_specs.rb +17 -0
- data/lib/thrust/tasks/ios_specs.rb +37 -0
- data/lib/thrust/tasks/nof.rb +20 -0
- data/lib/thrust/tasks/trim.rb +24 -0
- data/lib/thrust/tasks.rb +4 -3
- data/lib/thrust/testflight.rb +32 -31
- data/lib/thrust/testflight_credentials.rb +11 -0
- data/lib/thrust/user_prompt.rb +11 -9
- data/lib/thrust.rb +9 -4
- metadata +35 -20
data/lib/thrust/git.rb
CHANGED
@@ -1,67 +1,74 @@
|
|
1
1
|
require 'colorize'
|
2
|
+
require 'tempfile'
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
module Thrust
|
5
|
+
class Git
|
6
|
+
def initialize(out = $stdout, thrust_executor = Thrust::Executor.new)
|
7
|
+
@thrust_executor = thrust_executor
|
8
|
+
@out = out
|
9
|
+
end
|
8
10
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
def ensure_clean
|
12
|
+
if ENV['IGNORE_GIT']
|
13
|
+
@out.puts 'WARNING NOT CHECKING FOR CLEAN WORKING DIRECTORY'.red
|
14
|
+
else
|
15
|
+
@out.puts 'Checking for clean working tree...'
|
16
|
+
@thrust_executor.system_or_exit 'git diff-index --quiet HEAD'
|
17
|
+
end
|
15
18
|
end
|
16
|
-
end
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
-
|
20
|
+
def current_commit
|
21
|
+
@thrust_executor.capture_output_from_system('git log --format=format:%h -1').strip
|
22
|
+
end
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
-
|
24
|
+
def reset
|
25
|
+
@thrust_executor.system_or_exit('git reset --hard')
|
26
|
+
end
|
25
27
|
|
26
|
-
|
27
|
-
|
28
|
-
|
28
|
+
def checkout_file(filename)
|
29
|
+
@thrust_executor.system_or_exit("git checkout #{filename}")
|
30
|
+
end
|
29
31
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
def commit_summary_for_last_deploy(deployment_target)
|
33
|
+
sha_of_latest_deployed_commit = latest_deployed_commit(deployment_target)
|
34
|
+
if sha_of_latest_deployed_commit
|
35
|
+
"#{deployment_target}:".blue + " #{summary_for_commit(sha_of_latest_deployed_commit)}"
|
36
|
+
else
|
37
|
+
"#{deployment_target}:".blue + ' Never deployed'
|
38
|
+
end
|
36
39
|
end
|
37
|
-
end
|
38
40
|
|
39
|
-
|
40
|
-
|
41
|
-
|
41
|
+
def generate_notes_for_deployment(deployment_target)
|
42
|
+
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)
|
42
44
|
|
43
|
-
|
45
|
+
notes = Tempfile.new('deployment_notes')
|
44
46
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
47
|
+
if sha_of_latest_deployed_commit
|
48
|
+
@thrust_executor.system_or_exit("git log --oneline #{sha_of_latest_deployed_commit}...#{sha_of_latest_commit}", notes.path)
|
49
|
+
else
|
50
|
+
notes.puts(summary_for_commit(sha_of_latest_commit))
|
51
|
+
notes.close
|
52
|
+
end
|
53
|
+
|
54
|
+
notes.path
|
50
55
|
end
|
51
56
|
|
52
|
-
|
53
|
-
|
57
|
+
def commit_count
|
58
|
+
@thrust_executor.capture_output_from_system("git rev-list HEAD | wc -l").strip
|
59
|
+
end
|
54
60
|
|
55
|
-
|
61
|
+
private
|
56
62
|
|
57
|
-
|
58
|
-
|
59
|
-
|
63
|
+
def summary_for_commit(sha)
|
64
|
+
@thrust_executor.capture_output_from_system("git log --oneline -n 1 #{sha}")
|
65
|
+
end
|
60
66
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
67
|
+
def latest_deployed_commit(deployment_target)
|
68
|
+
list = @thrust_executor.capture_output_from_system("autotag list #{deployment_target}")
|
69
|
+
unless list.strip.empty?
|
70
|
+
list.split("\n").last.split(" ").first
|
71
|
+
end
|
65
72
|
end
|
66
73
|
end
|
67
74
|
end
|
data/lib/thrust/ios/agv_tool.rb
CHANGED
@@ -1,13 +1,16 @@
|
|
1
|
-
|
1
|
+
module Thrust
|
2
|
+
module IOS
|
3
|
+
class AgvTool
|
4
|
+
def initialize(thrust_executor = Thrust::Executor.new, git = Thrust::Git.new)
|
5
|
+
@thrust_executor = thrust_executor
|
6
|
+
@git = git
|
7
|
+
end
|
2
8
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
def change_build_number(build_number)
|
10
|
-
@thrust_executor.system_or_exit "agvtool new-version -all '#{build_number}'"
|
11
|
-
@git.checkout_file('*.xcodeproj')
|
9
|
+
def change_build_number(build_number, path_to_xcodeproj)
|
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}'"
|
12
|
+
@git.checkout_file("#{path_to_xcodeproj}/*.xcodeproj")
|
13
|
+
end
|
14
|
+
end
|
12
15
|
end
|
13
16
|
end
|
data/lib/thrust/ios/cedar.rb
CHANGED
@@ -1,24 +1,39 @@
|
|
1
|
-
|
1
|
+
require 'tmpdir'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
module Thrust
|
4
|
+
module IOS
|
5
|
+
class Cedar
|
6
|
+
def initialize(out = $stdout, thrust_executor = Thrust::Executor.new)
|
7
|
+
@thrust_executor = thrust_executor
|
8
|
+
@out = out
|
9
|
+
end
|
10
|
+
|
11
|
+
def run(build_configuration, target, runtime_sdk, build_sdk, device, device_type_id, build_dir, simulator_binary)
|
12
|
+
if build_sdk == 'macosx'
|
13
|
+
build_path = File.join(build_dir, build_configuration)
|
14
|
+
app_dir = File.join(build_path, target)
|
15
|
+
@thrust_executor.check_command_for_failure(app_dir.inspect, {'DYLD_FRAMEWORK_PATH' => build_path.inspect})
|
16
|
+
else
|
17
|
+
app_executable = File.join(build_dir, "#{build_configuration}-#{build_sdk}", "#{target}.app")
|
6
18
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
14
31
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
out.puts "Unknown binary for running specs: '#{simulator_binary}'"
|
21
|
-
false
|
32
|
+
else
|
33
|
+
@out.puts "Unknown binary for running specs: '#{simulator_binary}'"
|
34
|
+
false
|
35
|
+
end
|
36
|
+
end
|
22
37
|
end
|
23
38
|
end
|
24
39
|
end
|
data/lib/thrust/ios/deploy.rb
CHANGED
@@ -1,27 +1,40 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
1
|
+
module Thrust
|
2
|
+
module IOS
|
3
|
+
class Deploy
|
4
|
+
def initialize(out, x_code_tools, agv_tool, git, testflight, thrust_config, deployment_config, deployment_target)
|
5
|
+
@out = out
|
6
|
+
@x_code_tools = x_code_tools
|
7
|
+
@agv_tool = agv_tool
|
8
|
+
@git = git
|
9
|
+
@testflight = testflight
|
10
|
+
@thrust_config = thrust_config
|
11
|
+
@deployment_config = deployment_config
|
12
|
+
@deployment_target = deployment_target
|
13
|
+
end
|
14
|
+
|
15
|
+
def run
|
16
|
+
@git.ensure_clean
|
17
|
+
|
18
|
+
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)
|
21
|
+
else
|
22
|
+
@agv_tool.change_build_number(@git.current_commit, @thrust_config.app_config.path_to_xcodeproj)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
12
26
|
|
13
|
-
|
14
|
-
|
15
|
-
@agv_tool.change_build_number(@git.current_commit)
|
27
|
+
app_name = @thrust_config.app_config.app_name
|
28
|
+
target = @deployment_config.ios_target || app_name
|
16
29
|
|
17
|
-
|
18
|
-
target = @deployment_config['ios_target'] || app_name
|
19
|
-
ipa_file = @x_code_tools.cleanly_create_ipa(target, app_name, @thrust_config.app_config['ios_distribution_certificate'], @deployment_config['ios_provisioning_search_query'])
|
30
|
+
ipa_file = @x_code_tools.cleanly_create_ipa(target, app_name, @thrust_config.app_config.ios_distribution_certificate, @deployment_config.ios_provisioning_search_query)
|
20
31
|
|
21
|
-
|
32
|
+
dsym_path = "#{@x_code_tools.build_configuration_directory}/#{app_name}.app.dSYM"
|
22
33
|
|
23
|
-
|
24
|
-
|
25
|
-
|
34
|
+
autogenerate_notes = @deployment_config.note_generation_method == 'autotag'
|
35
|
+
@testflight.upload(ipa_file, @deployment_config.notify, @deployment_config.distribution_list, autogenerate_notes, @deployment_target, dsym_path)
|
36
|
+
@git.reset
|
37
|
+
end
|
38
|
+
end
|
26
39
|
end
|
27
40
|
end
|
@@ -1,15 +1,19 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
1
|
+
module Thrust
|
2
|
+
module IOS
|
3
|
+
class DeployProvider
|
4
|
+
def instance(thrust_config, deployment_config, deployment_target)
|
5
|
+
stdout = $stdout
|
6
|
+
thrust_executor = Thrust::Executor.new
|
7
|
+
build_configuration = deployment_config.ios_build_configuration
|
8
|
+
tools_options = {project_name: thrust_config.app_config.project_name, workspace_name: thrust_config.app_config.workspace_name}
|
9
|
+
x_code_tools = Thrust::IOS::XCodeToolsProvider.new.instance(stdout, build_configuration, thrust_config.build_dir, tools_options)
|
10
|
+
git = Thrust::Git.new(stdout, thrust_executor)
|
11
|
+
agv_tool = Thrust::IOS::AgvTool.new(thrust_executor, git)
|
12
|
+
testflight_config = thrust_config.app_config.testflight
|
13
|
+
testflight = Thrust::Testflight.new(thrust_executor, stdout, $stdin, testflight_config.api_token, testflight_config.team_token)
|
12
14
|
|
13
|
-
|
15
|
+
Thrust::IOS::Deploy.new(stdout, x_code_tools, agv_tool, git, testflight, thrust_config, deployment_config, deployment_target)
|
16
|
+
end
|
17
|
+
end
|
14
18
|
end
|
15
19
|
end
|
@@ -1,110 +1,145 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
@out = out
|
7
|
-
@git = Thrust::Git.new(@thrust_executor, @out)
|
8
|
-
@build_configuration = build_configuration
|
9
|
-
@build_directory = build_directory
|
10
|
-
@project_name = options[:project_name]
|
11
|
-
@workspace_name = options[:workspace_name]
|
12
|
-
raise "project_name OR workspace_name required" unless @project_name.nil? ^ @workspace_name.nil?
|
13
|
-
end
|
1
|
+
module Thrust
|
2
|
+
module IOS
|
3
|
+
class XCodeTools
|
4
|
+
ProvisioningProfileNotFound = Class.new(StandardError)
|
5
|
+
ProvisioningProfileNotEmbedded = Class.new(StandardError)
|
14
6
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
7
|
+
def initialize(thrust_executor, out, build_configuration, build_directory, options = {})
|
8
|
+
@thrust_executor = thrust_executor
|
9
|
+
@out = out
|
10
|
+
@git = Thrust::Git.new(@out, @thrust_executor)
|
11
|
+
@build_configuration = build_configuration
|
12
|
+
@build_directory = build_directory
|
13
|
+
@project_name = options[:project_name]
|
14
|
+
@workspace_name = options[:workspace_name]
|
15
|
+
raise "project_name OR workspace_name required" unless @project_name.nil? ^ @workspace_name.nil?
|
16
|
+
end
|
21
17
|
|
22
|
-
|
23
|
-
|
24
|
-
|
18
|
+
def cleanly_create_ipa(target, app_name, signing_identity, provision_search_query = nil)
|
19
|
+
clean_build
|
20
|
+
kill_simulator
|
21
|
+
build_scheme_or_target(target, 'iphoneos')
|
22
|
+
ipa_name = create_ipa(app_name, signing_identity, provision_search_query)
|
23
|
+
verify_provision(app_name, provision_search_query)
|
25
24
|
|
26
|
-
|
27
|
-
|
28
|
-
FileUtils.rm_rf(@build_directory)
|
29
|
-
end
|
25
|
+
return ipa_name
|
26
|
+
end
|
30
27
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
28
|
+
def build_configuration_directory
|
29
|
+
"#{@build_directory}/#{@build_configuration}-iphoneos"
|
30
|
+
end
|
35
31
|
|
36
|
-
|
32
|
+
def clean_build
|
33
|
+
@out.puts 'Cleaning...'
|
34
|
+
FileUtils.rm_rf(@build_directory)
|
35
|
+
end
|
37
36
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
@thrust_executor.system %q[killall -m -KILL "iPhone Simulator"]
|
43
|
-
end
|
37
|
+
def build_scheme_or_target(scheme_or_target, build_sdk, architecture=nil)
|
38
|
+
@out.puts "Building..."
|
39
|
+
run_xcode('build', build_sdk, scheme_or_target, architecture)
|
40
|
+
end
|
44
41
|
|
45
|
-
|
46
|
-
|
47
|
-
command = %Q(grep -rl "#{provision_search_query}" "#{provision_search_path}")
|
48
|
-
paths = `#{command}`.split("\n")
|
49
|
-
paths.first or raise(ProvisioningProfileNotFound, "\nCouldn't find provisioning profiles matching #{provision_search_query}.\n\nThe command used was:\n\n#{command}")
|
50
|
-
end
|
42
|
+
def test(scheme, build_configuration, runtime_sdk, build_dir)
|
43
|
+
destination = "OS=#{runtime_sdk},name=iPhone Retina (3.5-inch)"
|
51
44
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
"--sign '#{signing_identity}'",
|
62
|
-
"--embed '#{provision_path(provision_search_query)}'"
|
63
|
-
].join(' ')
|
64
|
-
@thrust_executor.system_or_exit(cmd)
|
65
|
-
ipa_filename
|
66
|
-
end
|
45
|
+
cmd = [
|
46
|
+
"xcodebuild",
|
47
|
+
"test",
|
48
|
+
"-scheme #{scheme}",
|
49
|
+
"-configuration #{build_configuration}",
|
50
|
+
"-destination '#{destination}'",
|
51
|
+
"ARCHS=i386",
|
52
|
+
"SYMROOT='#{build_dir}'"
|
53
|
+
].join(' ')
|
67
54
|
|
68
|
-
|
69
|
-
|
70
|
-
target_flag = @workspace_name ? "-scheme \"#{scheme_or_target}\"" : "-target \"#{scheme_or_target}\""
|
71
|
-
sdk_flag = sdk ? "-sdk #{sdk}" : nil
|
72
|
-
configuration_build_dir = File.join(@build_directory, "#{@build_configuration}-#{sdk}")
|
73
|
-
|
74
|
-
command = [
|
75
|
-
'set -o pipefail &&',
|
76
|
-
'xcodebuild',
|
77
|
-
project_or_workspace_flag,
|
78
|
-
architecture_flag,
|
79
|
-
target_flag,
|
80
|
-
"-configuration #{@build_configuration}",
|
81
|
-
sdk_flag,
|
82
|
-
"#{build_command}",
|
83
|
-
"SYMROOT=#{@build_directory.inspect}",
|
84
|
-
"CONFIGURATION_BUILD_DIR=#{configuration_build_dir.inspect}",
|
85
|
-
'2>&1',
|
86
|
-
"| grep -v 'backing file'"
|
87
|
-
].compact.join(' ')
|
88
|
-
output_file = output_file("#{@build_configuration}-#{build_command}")
|
89
|
-
begin
|
90
|
-
@thrust_executor.system_or_exit(command, output_file)
|
91
|
-
rescue Thrust::Executor::CommandFailed => e
|
92
|
-
@out.write File.read(output_file)
|
93
|
-
raise e
|
94
|
-
end
|
95
|
-
end
|
55
|
+
@thrust_executor.check_command_for_failure(cmd)
|
56
|
+
end
|
96
57
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
58
|
+
def kill_simulator
|
59
|
+
@out.puts('Killing simulator...')
|
60
|
+
@thrust_executor.system %q[killall -m -KILL "gdb"]
|
61
|
+
@thrust_executor.system %q[killall -m -KILL "otest"]
|
62
|
+
@thrust_executor.system %q[killall -m -KILL "iPhone Simulator"]
|
63
|
+
end
|
103
64
|
|
104
|
-
|
105
|
-
|
65
|
+
private
|
66
|
+
|
67
|
+
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}")
|
72
|
+
end
|
73
|
+
|
74
|
+
def create_ipa(app_name, signing_identity, provision_search_query)
|
75
|
+
@out.puts 'Packaging...'
|
76
|
+
ipa_filename = "#{build_configuration_directory}/#{app_name}.ipa"
|
77
|
+
cmd = [
|
78
|
+
"xcrun",
|
79
|
+
"-sdk iphoneos",
|
80
|
+
"-v PackageApplication",
|
81
|
+
"'#{build_configuration_directory}/#{app_name}.app'",
|
82
|
+
"-o '#{ipa_filename}'",
|
83
|
+
"--sign '#{signing_identity}'",
|
84
|
+
"--embed '#{provision_path(provision_search_query)}'"
|
85
|
+
].join(' ')
|
86
|
+
@thrust_executor.system_or_exit(cmd)
|
87
|
+
ipa_filename
|
88
|
+
end
|
89
|
+
|
90
|
+
def verify_provision(app_name, provision_search_query)
|
91
|
+
@out.puts 'Verifying provisioning profile...'
|
92
|
+
embedded_filename = "#{build_configuration_directory}/#{app_name}.app/embedded.mobileprovision"
|
93
|
+
correct_provision_filename = provision_path(provision_search_query)
|
94
|
+
|
95
|
+
if !FileUtils.cmp(embedded_filename, correct_provision_filename)
|
96
|
+
raise(ProvisioningProfileNotEmbedded, "Wrong mobile provision embedded by xcrun. Check your xcode provisioning profile settings.")
|
97
|
+
end
|
98
|
+
end
|
106
99
|
|
107
|
-
|
108
|
-
|
100
|
+
def run_xcode(build_command, sdk = nil, scheme_or_target = nil, architecture = nil)
|
101
|
+
architecture_flag = architecture ? "-arch #{architecture}" : nil
|
102
|
+
target_flag = @workspace_name ? "-scheme \"#{scheme_or_target}\"" : "-target \"#{scheme_or_target}\""
|
103
|
+
sdk_flag = sdk ? "-sdk #{sdk}" : nil
|
104
|
+
configuration_build_dir = File.join(@build_directory, "#{@build_configuration}-#{sdk}").inspect
|
105
|
+
configuration_build_dir_option = sdk != 'macosx' ? "CONFIGURATION_BUILD_DIR=#{configuration_build_dir}" : nil
|
106
|
+
|
107
|
+
command = [
|
108
|
+
'set -o pipefail &&',
|
109
|
+
'xcodebuild',
|
110
|
+
project_or_workspace_flag,
|
111
|
+
architecture_flag,
|
112
|
+
target_flag,
|
113
|
+
"-configuration #{@build_configuration}",
|
114
|
+
sdk_flag,
|
115
|
+
"#{build_command}",
|
116
|
+
"SYMROOT=#{@build_directory.inspect}",
|
117
|
+
configuration_build_dir_option,
|
118
|
+
'2>&1',
|
119
|
+
"| grep -v 'backing file'"
|
120
|
+
].compact.join(' ')
|
121
|
+
output_file = output_file("#{@build_configuration}-#{build_command}")
|
122
|
+
begin
|
123
|
+
@thrust_executor.system_or_exit(command, output_file)
|
124
|
+
rescue Thrust::Executor::CommandFailed => e
|
125
|
+
@out.write File.read(output_file)
|
126
|
+
raise e
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def output_file(target)
|
131
|
+
output_dir = if ENV['IS_CI_BOX']
|
132
|
+
ENV['CC_BUILD_ARTIFACTS']
|
133
|
+
else
|
134
|
+
File.exists?(@build_directory) ? @build_directory : FileUtils.mkdir_p(@build_directory)
|
135
|
+
end
|
136
|
+
|
137
|
+
File.join(output_dir, "#{target}.output").tap { |file| @out.puts "Output: #{file}" }
|
138
|
+
end
|
139
|
+
|
140
|
+
def project_or_workspace_flag
|
141
|
+
@workspace_name ? "-workspace #{@workspace_name}.xcworkspace" : "-project #{@project_name}.xcodeproj"
|
142
|
+
end
|
143
|
+
end
|
109
144
|
end
|
110
145
|
end
|
@@ -1,10 +1,13 @@
|
|
1
|
-
|
1
|
+
module Thrust
|
2
|
+
module IOS
|
3
|
+
class XCodeToolsProvider
|
4
|
+
def initialize(thrust_executor = Thrust::Executor.new)
|
5
|
+
@thrust_executor = thrust_executor
|
6
|
+
end
|
2
7
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
def instance(out, build_configuration, build_directory, options)
|
8
|
-
Thrust::IOS::XCodeTools.new(@thrust_executor, out, build_configuration, build_directory, options)
|
8
|
+
def instance(out, build_configuration, build_directory, options)
|
9
|
+
Thrust::IOS::XCodeTools.new(@thrust_executor, out, build_configuration, build_directory, options)
|
10
|
+
end
|
11
|
+
end
|
9
12
|
end
|
10
13
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Thrust
|
2
|
+
class IOSSpecTarget
|
3
|
+
attr_reader :build_configuration,
|
4
|
+
:build_sdk,
|
5
|
+
:device,
|
6
|
+
:device_type_id,
|
7
|
+
:runtime_sdk,
|
8
|
+
:scheme,
|
9
|
+
:target,
|
10
|
+
:type
|
11
|
+
|
12
|
+
def initialize(attributes)
|
13
|
+
@build_configuration = attributes['build_configuration']
|
14
|
+
@build_sdk = attributes['build_sdk'] || 'iphonesimulator'
|
15
|
+
@device = attributes['device'] || 'iphone'
|
16
|
+
@device_type_id = attributes['device_type_id']
|
17
|
+
@runtime_sdk = attributes['runtime_sdk']
|
18
|
+
@scheme = attributes['scheme']
|
19
|
+
@target = attributes['target']
|
20
|
+
@type = attributes['type'] || 'app'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Thrust
|
2
|
+
module Tasks
|
3
|
+
module Autotag
|
4
|
+
class Create
|
5
|
+
def initialize(executor = Thrust::Executor.new)
|
6
|
+
@executor = executor
|
7
|
+
end
|
8
|
+
|
9
|
+
def run(stage)
|
10
|
+
@executor.capture_output_from_system("autotag create #{stage}")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Thrust
|
2
|
+
module Tasks
|
3
|
+
module Autotag
|
4
|
+
class List
|
5
|
+
def initialize(git = Thrust::Git.new)
|
6
|
+
@git = git
|
7
|
+
end
|
8
|
+
|
9
|
+
def run(thrust)
|
10
|
+
thrust.app_config.deployment_targets.each do |deployment_target, _|
|
11
|
+
puts @git.commit_summary_for_last_deploy(deployment_target)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Thrust
|
2
|
+
module Tasks
|
3
|
+
class Clean
|
4
|
+
def initialize(out = $stdout, xcode_tools_provider = Thrust::IOS::XCodeToolsProvider.new)
|
5
|
+
@xcode_tools_provider = xcode_tools_provider
|
6
|
+
@out = out
|
7
|
+
end
|
8
|
+
|
9
|
+
def run(thrust)
|
10
|
+
tools_options = {
|
11
|
+
project_name: thrust.app_config.project_name,
|
12
|
+
workspace_name: thrust.app_config.workspace_name
|
13
|
+
}
|
14
|
+
|
15
|
+
xcode_tools = @xcode_tools_provider.instance(@out, nil, thrust.build_dir, tools_options)
|
16
|
+
xcode_tools.clean_build
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|