thrust 0.5.2 → 0.6.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 +2 -9
- data/lib/config/{ios_example.yml → thrust_example.yml} +26 -19
- data/lib/tasks/autotag.rake +2 -2
- data/lib/tasks/cedar.rake +8 -11
- data/lib/tasks/testflight.rake +5 -14
- data/lib/tasks/version.rake +3 -7
- data/lib/thrust.rb +11 -13
- data/lib/thrust/agv_tool.rb +14 -0
- data/lib/thrust/app_config.rb +24 -10
- data/lib/thrust/cedar_results_parser.rb +7 -0
- data/lib/thrust/config_loader.rb +48 -0
- data/lib/thrust/deploy.rb +53 -0
- data/lib/thrust/deploy_provider.rb +17 -0
- data/lib/thrust/deployment_target.rb +6 -6
- data/lib/thrust/execution_helper.rb +1 -1
- data/lib/thrust/executor.rb +2 -1
- data/lib/thrust/ios_spec_launcher.rb +36 -0
- data/lib/thrust/osx_spec_launcher.rb +15 -0
- data/lib/thrust/scheme_parser.rb +35 -0
- data/lib/thrust/{ios_spec_target.rb → spec_target.rb} +1 -3
- data/lib/thrust/tasks.rb +1 -1
- data/lib/thrust/tasks/autotag/list.rb +2 -2
- data/lib/thrust/tasks/clean.rb +5 -5
- data/lib/thrust/tasks/focused_specs.rb +14 -4
- data/lib/thrust/tasks/nof.rb +8 -3
- data/lib/thrust/tasks/spec_runner.rb +75 -0
- data/lib/thrust/xcode_tools.rb +159 -0
- data/lib/thrust/xcode_tools_provider.rb +11 -0
- metadata +36 -23
- data/lib/config/android_example.yml +0 -17
- data/lib/thrust/android/deploy.rb +0 -38
- data/lib/thrust/android/deploy_provider.rb +0 -16
- data/lib/thrust/android/tools.rb +0 -43
- data/lib/thrust/config.rb +0 -43
- data/lib/thrust/ios/agv_tool.rb +0 -16
- data/lib/thrust/ios/cedar.rb +0 -27
- data/lib/thrust/ios/deploy.rb +0 -55
- data/lib/thrust/ios/deploy_provider.rb +0 -19
- data/lib/thrust/ios/x_code_tools.rb +0 -154
- data/lib/thrust/ios/x_code_tools_provider.rb +0 -13
- data/lib/thrust/tasks/ios_specs.rb +0 -43
@@ -1,9 +1,9 @@
|
|
1
1
|
module Thrust
|
2
2
|
class DeploymentTarget
|
3
3
|
attr_reader :distribution_list,
|
4
|
-
:
|
5
|
-
:
|
6
|
-
:
|
4
|
+
:build_configuration,
|
5
|
+
:provisioning_search_query,
|
6
|
+
:target,
|
7
7
|
:note_generation_method,
|
8
8
|
:notify,
|
9
9
|
:versioning_method,
|
@@ -11,9 +11,9 @@ module Thrust
|
|
11
11
|
|
12
12
|
def initialize(attributes)
|
13
13
|
@distribution_list = attributes['distribution_list']
|
14
|
-
@
|
15
|
-
@
|
16
|
-
@
|
14
|
+
@build_configuration = attributes['build_configuration']
|
15
|
+
@provisioning_search_query = attributes['provisioning_search_query']
|
16
|
+
@target = attributes['target']
|
17
17
|
@note_generation_method = attributes['note_generation_method']
|
18
18
|
@notify = attributes['notify']
|
19
19
|
@versioning_method = attributes['versioning_method']
|
data/lib/thrust/executor.rb
CHANGED
@@ -36,10 +36,11 @@ module Thrust
|
|
36
36
|
@out.puts "Executing #{cmd} and checking for FAILURE"
|
37
37
|
execution = @execution_helper.capture_status_and_output_from_command("#{cmd} 2>&1", env)
|
38
38
|
result = execution[:output]
|
39
|
+
|
39
40
|
@out.puts "Results:"
|
40
41
|
@out.puts result
|
41
42
|
|
42
|
-
|
43
|
+
Thrust::CedarResultsParser.parse_results_for_success(result)
|
43
44
|
end
|
44
45
|
end
|
45
46
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'tmpdir'
|
2
|
+
|
3
|
+
module Thrust
|
4
|
+
class IOSSpecLauncher
|
5
|
+
def initialize(out = $stdout, thrust_executor = Thrust::Executor.new)
|
6
|
+
@thrust_executor = thrust_executor
|
7
|
+
@out = out
|
8
|
+
end
|
9
|
+
|
10
|
+
def run(executable_name, build_configuration, build_sdk, os_version, device_name, timeout, build_directory, simulator_binary, environment_variables)
|
11
|
+
device_type_id = "com.apple.CoreSimulator.SimDeviceType.#{device_name}, #{os_version}"
|
12
|
+
app_executable = File.join(build_directory, "#{build_configuration}-#{build_sdk}", "#{executable_name}.app")
|
13
|
+
simulator_binary ||= 'ios-sim'
|
14
|
+
output_file = "tmp/thrust_specs_output"
|
15
|
+
|
16
|
+
arguments = ["--devicetypeid \"#{device_type_id}\"",
|
17
|
+
"--timeout #{timeout || '30'}",
|
18
|
+
"--stdout #{output_file}",
|
19
|
+
"--setenv CFFIXED_USER_HOME=\"#{Dir.tmpdir}\"",]
|
20
|
+
|
21
|
+
environment_variables.each do |key, value|
|
22
|
+
arguments << "--setenv #{key}=\"#{value}\""
|
23
|
+
end
|
24
|
+
|
25
|
+
@thrust_executor.system_or_exit("#{simulator_binary} launch #{app_executable} #{arguments.compact.join(' ')}")
|
26
|
+
|
27
|
+
results = File.read(output_file)
|
28
|
+
FileUtils.rm_r('tmp')
|
29
|
+
|
30
|
+
@out.puts 'Results:'
|
31
|
+
@out.puts results
|
32
|
+
|
33
|
+
Thrust::CedarResultsParser.parse_results_for_success(results)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Thrust
|
2
|
+
class OSXSpecLauncher
|
3
|
+
def initialize(out = $stdout, thrust_executor = Thrust::Executor.new)
|
4
|
+
@thrust_executor = thrust_executor
|
5
|
+
@out = out
|
6
|
+
end
|
7
|
+
|
8
|
+
def run(executable_name, build_configuration, build_directory, environment_variables)
|
9
|
+
build_path = File.join(build_directory, build_configuration)
|
10
|
+
app_executable = File.join(build_path, executable_name)
|
11
|
+
env = {'DYLD_FRAMEWORK_PATH' => "\"#{build_path}\""}.merge(environment_variables)
|
12
|
+
@thrust_executor.check_command_for_failure("\"#{app_executable}\"", env)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'nori'
|
2
|
+
|
3
|
+
module Thrust
|
4
|
+
class SchemeParser
|
5
|
+
def parse_environment_variables(scheme, xcodeproj_path = nil)
|
6
|
+
config = load_scheme(scheme, xcodeproj_path)
|
7
|
+
|
8
|
+
env = {}
|
9
|
+
|
10
|
+
if config['Scheme']['LaunchAction']['EnvironmentVariables']
|
11
|
+
environment_variables = config['Scheme']['LaunchAction']['EnvironmentVariables']['EnvironmentVariable']
|
12
|
+
environment_variables = [environment_variables] unless environment_variables.is_a?(Array)
|
13
|
+
|
14
|
+
environment_variables.each do |environment_variable|
|
15
|
+
if environment_variable['@isEnabled'] == 'YES'
|
16
|
+
env[environment_variable['@key']] = environment_variable['@value']
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
env
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def load_scheme(scheme, xcodeproj_path)
|
27
|
+
scheme_path = "**/#{scheme}.xcscheme"
|
28
|
+
scheme_path = "#{xcodeproj_path}/#{scheme_path}" if xcodeproj_path
|
29
|
+
|
30
|
+
scheme_file = Dir.glob(scheme_path).first
|
31
|
+
parser = Nori.new(parser: :rexml)
|
32
|
+
parser.parse(File.read(scheme_file))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -1,12 +1,11 @@
|
|
1
1
|
module Thrust
|
2
|
-
class
|
2
|
+
class SpecTarget
|
3
3
|
attr_reader :build_configuration,
|
4
4
|
:build_sdk,
|
5
5
|
:device,
|
6
6
|
:device_name,
|
7
7
|
:os_version,
|
8
8
|
:scheme,
|
9
|
-
:target,
|
10
9
|
:type,
|
11
10
|
:timeout
|
12
11
|
|
@@ -17,7 +16,6 @@ module Thrust
|
|
17
16
|
@device_name = attributes['device_name']
|
18
17
|
@os_version = attributes['os_version']
|
19
18
|
@scheme = attributes['scheme']
|
20
|
-
@target = attributes['target']
|
21
19
|
@type = attributes['type'] || 'app'
|
22
20
|
@timeout = attributes['timeout']
|
23
21
|
end
|
data/lib/thrust/tasks.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
load File.expand_path('../../tasks/cedar.rake', __FILE__)
|
1
|
+
load File.expand_path('../../tasks/cedar.rake', __FILE__)
|
2
2
|
load File.expand_path('../../tasks/autotag.rake', __FILE__)
|
3
3
|
load File.expand_path('../../tasks/testflight.rake', __FILE__)
|
4
4
|
load File.expand_path('../../tasks/version.rake', __FILE__)
|
@@ -6,8 +6,8 @@ module Thrust
|
|
6
6
|
@git = git
|
7
7
|
end
|
8
8
|
|
9
|
-
def run(
|
10
|
-
|
9
|
+
def run(app_config)
|
10
|
+
app_config.deployment_targets.each do |deployment_target, _|
|
11
11
|
puts @git.commit_summary_for_last_deploy(deployment_target)
|
12
12
|
end
|
13
13
|
end
|
data/lib/thrust/tasks/clean.rb
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
module Thrust
|
2
2
|
module Tasks
|
3
3
|
class Clean
|
4
|
-
def initialize(out = $stdout, xcode_tools_provider = Thrust::
|
4
|
+
def initialize(out = $stdout, xcode_tools_provider = Thrust::XcodeToolsProvider.new)
|
5
5
|
@xcode_tools_provider = xcode_tools_provider
|
6
6
|
@out = out
|
7
7
|
end
|
8
8
|
|
9
|
-
def run(
|
9
|
+
def run(app_config)
|
10
10
|
tools_options = {
|
11
|
-
project_name:
|
12
|
-
workspace_name:
|
11
|
+
project_name: app_config.project_name,
|
12
|
+
workspace_name: app_config.workspace_name
|
13
13
|
}
|
14
14
|
|
15
|
-
xcode_tools = @xcode_tools_provider.instance(@out, nil,
|
15
|
+
xcode_tools = @xcode_tools_provider.instance(@out, nil, app_config.build_directory, tools_options)
|
16
16
|
xcode_tools.clean_build
|
17
17
|
end
|
18
18
|
end
|
@@ -3,14 +3,24 @@ module Thrust
|
|
3
3
|
class FocusedSpecs
|
4
4
|
FOCUSED_METHODS = %w[fit(@ fcontext(@ fdescribe(@]
|
5
5
|
|
6
|
-
def initialize(executor = Thrust::Executor.new)
|
6
|
+
def initialize(out = $stdout, executor = Thrust::Executor.new)
|
7
|
+
@out = out
|
7
8
|
@executor = executor
|
8
9
|
end
|
9
10
|
|
10
|
-
def run(
|
11
|
+
def run(app_config)
|
12
|
+
if app_config.spec_directories.empty?
|
13
|
+
@out.puts 'Unable to find focused specs without `spec_directories` defined in thrust.yml.'.red
|
14
|
+
exit 1
|
15
|
+
end
|
16
|
+
|
11
17
|
pattern = FOCUSED_METHODS.join("\\|")
|
12
|
-
directories =
|
13
|
-
@executor.
|
18
|
+
directories = app_config.spec_directories.map{ |sd| "\"#{sd}\"" }.join(' ')
|
19
|
+
output = @executor.capture_output_from_system %Q[grep -l -r -e "\\(#{pattern}\\)" #{directories} | grep -v 'Frameworks' || true]
|
20
|
+
|
21
|
+
@out.puts output
|
22
|
+
|
23
|
+
output.split("\n")
|
14
24
|
end
|
15
25
|
end
|
16
26
|
end
|
data/lib/thrust/tasks/nof.rb
CHANGED
@@ -3,17 +3,22 @@ module Thrust
|
|
3
3
|
class Nof
|
4
4
|
FOCUSED_METHODS = %w[fit(@ fcontext(@ fdescribe(@]
|
5
5
|
|
6
|
-
def initialize(executor = Thrust::Executor.new)
|
6
|
+
def initialize(executor = Thrust::Executor.new, focused_specs = Thrust::Tasks::FocusedSpecs.new)
|
7
7
|
@executor = executor
|
8
|
+
@focused_specs = focused_specs
|
8
9
|
end
|
9
10
|
|
10
|
-
def run
|
11
|
+
def run(app_config)
|
11
12
|
substitutions = FOCUSED_METHODS.map do |method|
|
12
13
|
unfocused_method = method.sub(/^f/, '')
|
13
14
|
"-e 's/#{method}/#{unfocused_method}/g;'"
|
14
15
|
end
|
15
16
|
|
16
|
-
|
17
|
+
focused_spec_files = @focused_specs.run(app_config)
|
18
|
+
unless focused_spec_files.empty?
|
19
|
+
quoted_spec_files = focused_spec_files.map { |file| "\"#{file}\"" }.join(' ')
|
20
|
+
@executor.system_or_exit %Q[sed -i '' #{substitutions.join(' ')} #{quoted_spec_files}]
|
21
|
+
end
|
17
22
|
end
|
18
23
|
end
|
19
24
|
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'nori'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module Thrust
|
5
|
+
module Tasks
|
6
|
+
class SpecRunner
|
7
|
+
def initialize(out = $stdout,
|
8
|
+
xcode_tools_provider = Thrust::XcodeToolsProvider.new,
|
9
|
+
ios_spec_launcher = Thrust::IOSSpecLauncher.new,
|
10
|
+
osx_spec_launcher = Thrust::OSXSpecLauncher.new,
|
11
|
+
scheme_parser = Thrust::SchemeParser.new)
|
12
|
+
@xcode_tools_provider = xcode_tools_provider
|
13
|
+
@ios_spec_launcher = ios_spec_launcher
|
14
|
+
@osx_spec_launcher = osx_spec_launcher
|
15
|
+
@scheme_parser = scheme_parser
|
16
|
+
@out = out
|
17
|
+
end
|
18
|
+
|
19
|
+
def run(app_config, target_info, args)
|
20
|
+
build_configuration = target_info.build_configuration
|
21
|
+
type = target_info.type
|
22
|
+
scheme = target_info.scheme
|
23
|
+
build_sdk = target_info.build_sdk
|
24
|
+
os_version = args[:os_version] || target_info.os_version
|
25
|
+
device_name = args[:device_name] || target_info.device_name
|
26
|
+
|
27
|
+
if device_name
|
28
|
+
substitution_map = {'bundle' => '-', 'app' => ' '}
|
29
|
+
destination_map = {'bundle' => ' ', 'app' => '-'}
|
30
|
+
device_name.gsub!(substitution_map[type], destination_map[type])
|
31
|
+
end
|
32
|
+
|
33
|
+
xcode_tools = @xcode_tools_provider.instance(@out,
|
34
|
+
build_configuration,
|
35
|
+
app_config.build_directory,
|
36
|
+
project_name: app_config.project_name,
|
37
|
+
workspace_name: app_config.workspace_name)
|
38
|
+
|
39
|
+
if type == 'app'
|
40
|
+
xcode_tools.build_scheme(scheme, build_sdk)
|
41
|
+
|
42
|
+
executable_name = xcode_tools.find_executable_name(scheme)
|
43
|
+
environment_variables = @scheme_parser.parse_environment_variables(scheme, app_config.path_to_xcodeproj)
|
44
|
+
environment_variables['CEDAR_RANDOM_SEED'] = ENV['CEDAR_RANDOM_SEED'] if ENV['CEDAR_RANDOM_SEED']
|
45
|
+
|
46
|
+
if build_sdk.include?('macosx')
|
47
|
+
@osx_spec_launcher.run(executable_name,
|
48
|
+
build_configuration,
|
49
|
+
app_config.build_directory,
|
50
|
+
environment_variables)
|
51
|
+
else
|
52
|
+
xcode_tools.kill_simulator
|
53
|
+
|
54
|
+
@ios_spec_launcher.run(executable_name,
|
55
|
+
build_configuration,
|
56
|
+
build_sdk,
|
57
|
+
os_version,
|
58
|
+
device_name,
|
59
|
+
target_info.timeout,
|
60
|
+
app_config.build_directory,
|
61
|
+
app_config.ios_sim_path,
|
62
|
+
environment_variables)
|
63
|
+
end
|
64
|
+
else
|
65
|
+
xcode_tools.test(scheme,
|
66
|
+
build_configuration,
|
67
|
+
os_version,
|
68
|
+
device_name,
|
69
|
+
target_info.timeout,
|
70
|
+
app_config.build_directory)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
module Thrust
|
2
|
+
class XcodeTools
|
3
|
+
ProvisioningProfileNotFound = Class.new(StandardError)
|
4
|
+
ProvisioningProfileNotEmbedded = Class.new(StandardError)
|
5
|
+
|
6
|
+
def initialize(thrust_executor, out, build_configuration, build_directory, options = {})
|
7
|
+
@thrust_executor = thrust_executor
|
8
|
+
@out = out
|
9
|
+
@git = Thrust::Git.new(@out, @thrust_executor)
|
10
|
+
@build_configuration = build_configuration
|
11
|
+
@build_directory = build_directory
|
12
|
+
@project_name = options[:project_name]
|
13
|
+
@workspace_name = options[:workspace_name]
|
14
|
+
raise "project_name OR workspace_name required" unless @project_name.nil? ^ @workspace_name.nil?
|
15
|
+
end
|
16
|
+
|
17
|
+
def cleanly_create_ipa(target, app_name, signing_identity, provision_search_query = nil)
|
18
|
+
kill_simulator
|
19
|
+
build_target(target, 'iphoneos', true)
|
20
|
+
ipa_name = create_ipa(app_name, signing_identity, provision_search_query)
|
21
|
+
verify_provision(app_name, provision_search_query)
|
22
|
+
|
23
|
+
return ipa_name
|
24
|
+
end
|
25
|
+
|
26
|
+
def build_configuration_directory
|
27
|
+
"#{@build_directory}/#{@build_configuration}-iphoneos"
|
28
|
+
end
|
29
|
+
|
30
|
+
def clean_build
|
31
|
+
@out.puts 'Cleaning...'
|
32
|
+
FileUtils.rm_rf(@build_directory)
|
33
|
+
end
|
34
|
+
|
35
|
+
def build_scheme(scheme, build_sdk, clean = false)
|
36
|
+
@out.puts 'Building...'
|
37
|
+
build("-scheme \"#{scheme}\"", build_sdk, clean)
|
38
|
+
end
|
39
|
+
|
40
|
+
def build_target(target, build_sdk, clean = false)
|
41
|
+
@out.puts 'Building...'
|
42
|
+
build("-target \"#{target}\"", build_sdk, clean)
|
43
|
+
end
|
44
|
+
|
45
|
+
def test(scheme, build_configuration, os_version, device_name, timeout, build_dir)
|
46
|
+
destination = "OS=#{os_version},name=#{device_name}"
|
47
|
+
timeout ||= "30"
|
48
|
+
|
49
|
+
cmd = [
|
50
|
+
"xcodebuild",
|
51
|
+
"test",
|
52
|
+
"-scheme '#{scheme}'",
|
53
|
+
"-configuration '#{build_configuration}'",
|
54
|
+
"-destination '#{destination}'",
|
55
|
+
"-destination-timeout '#{timeout}'",
|
56
|
+
"SYMROOT='#{build_dir}'"
|
57
|
+
].join(' ')
|
58
|
+
|
59
|
+
@thrust_executor.check_command_for_failure(cmd)
|
60
|
+
end
|
61
|
+
|
62
|
+
def kill_simulator
|
63
|
+
@out.puts('Killing simulator...')
|
64
|
+
@thrust_executor.system %q[killall -m -KILL "gdb"]
|
65
|
+
@thrust_executor.system %q[killall -m -KILL "otest"]
|
66
|
+
@thrust_executor.system %q[killall -m -KILL "iOS Simulator"]
|
67
|
+
end
|
68
|
+
|
69
|
+
def find_executable_name(scheme)
|
70
|
+
build_settings = @thrust_executor.capture_output_from_system("xcodebuild -scheme \"#{scheme}\" -showBuildSettings")
|
71
|
+
matches = build_settings.match(/EXECUTABLE_NAME = (.*)$/)
|
72
|
+
matches.captures.first
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def provision_path(provision_search_query)
|
78
|
+
provision_search_path = File.expand_path("~/Library/MobileDevice/Provisioning Profiles")
|
79
|
+
command = %Q(find '#{provision_search_path}' -print0 | xargs -0 grep -lr '#{provision_search_query}' --null | xargs -0 ls -t)
|
80
|
+
provisioning_profile = @thrust_executor.capture_output_from_system(command).split("\n").first
|
81
|
+
if !provisioning_profile
|
82
|
+
raise(ProvisioningProfileNotFound, "\nCouldn't find provisioning profiles matching #{provision_search_query}.\n\nThe command used was:\n\n#{command}")
|
83
|
+
end
|
84
|
+
provisioning_profile
|
85
|
+
end
|
86
|
+
|
87
|
+
def build(scheme_or_target_flag, build_sdk, clean)
|
88
|
+
sdk_flag = build_sdk ? "-sdk #{build_sdk}" : nil
|
89
|
+
configuration_build_dir = File.join(@build_directory, "#{@build_configuration}-#{build_sdk}")
|
90
|
+
configuration_build_dir_option = build_sdk.include?('macosx') ? nil : "CONFIGURATION_BUILD_DIR=\"#{configuration_build_dir}\""
|
91
|
+
|
92
|
+
command = [
|
93
|
+
'set -o pipefail &&',
|
94
|
+
'xcodebuild',
|
95
|
+
project_or_workspace_flag,
|
96
|
+
scheme_or_target_flag,
|
97
|
+
"-configuration #{@build_configuration}",
|
98
|
+
sdk_flag,
|
99
|
+
clean ? 'clean build' : nil,
|
100
|
+
"SYMROOT=\"#{@build_directory}\"",
|
101
|
+
configuration_build_dir_option,
|
102
|
+
'2>&1',
|
103
|
+
"| grep -v 'backing file'"
|
104
|
+
].compact.join(' ')
|
105
|
+
output_file = output_file("#{@build_configuration}-build")
|
106
|
+
begin
|
107
|
+
@thrust_executor.system_or_exit(command, output_file)
|
108
|
+
rescue Thrust::Executor::CommandFailed => e
|
109
|
+
@out.write File.read(output_file)
|
110
|
+
raise e
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def create_ipa(app_name, signing_identity, provision_search_query)
|
115
|
+
@out.puts 'Packaging...'
|
116
|
+
app_filepath = "#{build_configuration_directory}/#{app_name}.app"
|
117
|
+
ipa_filepath = "#{build_configuration_directory}/#{app_name}.ipa"
|
118
|
+
package_command = [
|
119
|
+
"xcrun",
|
120
|
+
"-sdk iphoneos",
|
121
|
+
"-v PackageApplication",
|
122
|
+
"'#{app_filepath}'",
|
123
|
+
"-o '#{ipa_filepath}'",
|
124
|
+
"--embed '#{provision_path(provision_search_query)}'"
|
125
|
+
].join(' ')
|
126
|
+
@thrust_executor.system_or_exit(package_command)
|
127
|
+
|
128
|
+
@thrust_executor.system_or_exit("cd '#{build_configuration_directory}' && unzip '#{app_name}.ipa'")
|
129
|
+
@thrust_executor.system_or_exit("/usr/bin/codesign --verify --force --preserve-metadata=identifier,entitlements --sign '#{signing_identity}' '#{build_configuration_directory}/Payload/#{app_name}.app'")
|
130
|
+
@thrust_executor.system_or_exit("cd '#{build_configuration_directory}' && zip -qr '#{app_name}.ipa' 'Payload'")
|
131
|
+
|
132
|
+
ipa_filepath
|
133
|
+
end
|
134
|
+
|
135
|
+
def verify_provision(app_name, provision_search_query)
|
136
|
+
@out.puts 'Verifying provisioning profile...'
|
137
|
+
embedded_filename = "#{build_configuration_directory}/#{app_name}.app/embedded.mobileprovision"
|
138
|
+
correct_provision_filename = provision_path(provision_search_query)
|
139
|
+
|
140
|
+
if !FileUtils.cmp(embedded_filename, correct_provision_filename)
|
141
|
+
raise(ProvisioningProfileNotEmbedded, "Wrong mobile provision embedded by xcrun. Check your xcode provisioning profile settings.")
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def output_file(target)
|
146
|
+
output_dir = if ENV['IS_CI_BOX']
|
147
|
+
ENV['CC_BUILD_ARTIFACTS']
|
148
|
+
else
|
149
|
+
File.exists?(@build_directory) ? @build_directory : FileUtils.mkdir_p(@build_directory)
|
150
|
+
end
|
151
|
+
|
152
|
+
File.join(output_dir, "#{target}.output").tap { |file| @out.puts "Output: #{file}" }
|
153
|
+
end
|
154
|
+
|
155
|
+
def project_or_workspace_flag
|
156
|
+
@workspace_name ? "-workspace #{@workspace_name}.xcworkspace" : "-project #{@project_name}.xcodeproj"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|