thrust 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|