fastlane 2.29.0 → 2.29.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/deliver/lib/assets/summary.html.erb +24 -7
- data/deliver/lib/deliver/options.rb +4 -0
- data/deliver/lib/deliver/setup.rb +11 -0
- data/deliver/lib/deliver/upload_metadata.rb +42 -0
- data/fastlane/lib/fastlane/actions/update_fastlane.rb +1 -2
- data/fastlane/lib/fastlane/documentation/actions_list.rb +22 -0
- data/fastlane/lib/fastlane/environment_printer.rb +11 -13
- data/fastlane/lib/fastlane/one_off.rb +1 -0
- data/fastlane/lib/fastlane/version.rb +1 -1
- data/fastlane_core/lib/fastlane_core/update_checker/update_checker.rb +5 -1
- data/match/lib/match/encrypt.rb +3 -1
- data/pilot/lib/pilot/tester_manager.rb +53 -14
- data/snapshot/lib/snapshot/options.rb +6 -1
- data/snapshot/lib/snapshot/runner.rb +2 -2
- data/snapshot/lib/snapshot/test_command_generator.rb +16 -6
- data/spaceship/lib/spaceship/.DS_Store +0 -0
- data/spaceship/lib/spaceship/test_flight/client.rb +4 -5
- data/spaceship/lib/spaceship/test_flight/group.rb +6 -2
- data/spaceship/lib/spaceship/test_flight/tester.rb +7 -0
- data/spaceship/lib/spaceship/tunes/app_version.rb +58 -0
- data/spaceship/lib/spaceship/tunes/member.rb +17 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4df803cb7188d41a48f3d759d9c163b6ba0727f9
|
4
|
+
data.tar.gz: b85c21bdcbf222cf50d54cc090b8c8e4e9b7fd8f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 447d8827823088b25927f9013be1b6c2013722981a599556848fc83c4b2e0b50a4879deede3f592940f603cb6aab7dde33ba84aa364bef795e67b11cee7271fb
|
7
|
+
data.tar.gz: dbd5145ed06f18ada1d6efd993ffc1821753c52c7b4e515ef865c4dcbb863d82545c79b893fdc770048cbd0f5059c24cd3fd15aab434a86dc4c4a606fb92b002
|
@@ -118,13 +118,13 @@
|
|
118
118
|
margin-right: 20px;
|
119
119
|
}
|
120
120
|
|
121
|
-
.app-
|
121
|
+
.app-minor-information {
|
122
122
|
margin-left: 15px;
|
123
123
|
margin-right: 15px;
|
124
124
|
margin-top: 22px;
|
125
125
|
}
|
126
126
|
|
127
|
-
.app-
|
127
|
+
.app-minor-information-key {
|
128
128
|
font-weight: 700;
|
129
129
|
}
|
130
130
|
</style>
|
@@ -241,20 +241,37 @@
|
|
241
241
|
|
242
242
|
<hr />
|
243
243
|
<% end # end data %>
|
244
|
+
<% if @options[:trade_representative_contact_information] %>
|
245
|
+
<div class="app-minor-information">
|
246
|
+
<div class="cat-headline">Trade Representative Contact Information</div>
|
247
|
+
<dl class="app-minor-information">
|
248
|
+
<% @options[:trade_representative_contact_information].each do |key, value| %>
|
249
|
+
<dt class="app-minor-information-key">
|
250
|
+
<%= key.to_s.capitalize.gsub("_", " ") %>
|
251
|
+
</dt>
|
252
|
+
<dd class="app-minor-information-text">
|
253
|
+
<%= (value || '').gsub("\n", "<br />") %>
|
254
|
+
</dd>
|
255
|
+
<% end %>
|
256
|
+
</dl>
|
257
|
+
</div>
|
258
|
+
<hr />
|
259
|
+
<% end %>
|
260
|
+
|
244
261
|
<% if @options[:app_review_information] %>
|
245
|
-
<div class="app-
|
262
|
+
<div class="app-minor-information">
|
246
263
|
<div class="cat-headline">Review Information</div>
|
247
|
-
<dl class="app-
|
264
|
+
<dl class="app-minor-information">
|
248
265
|
<% @options[:app_review_information].each do |key, value| %>
|
249
|
-
<dt class="app-
|
266
|
+
<dt class="app-minor-information-key">
|
250
267
|
<%= key.to_s.capitalize.gsub("_", " ") %>
|
251
268
|
</dt>
|
252
|
-
<dd class="app-
|
269
|
+
<dd class="app-minor-information-text">
|
253
270
|
<%= (value || '').gsub("\n", "<br />") %>
|
254
271
|
</dd>
|
255
272
|
<% end %>
|
256
273
|
</dl>
|
257
274
|
</div>
|
258
|
-
|
275
|
+
<% end %>
|
259
276
|
</body>
|
260
277
|
</html>
|
@@ -228,6 +228,10 @@ module Deliver
|
|
228
228
|
description: "Metadata: The english name of the secondary second sub category(e.g. `Educational`, `Puzzle`)",
|
229
229
|
optional: true,
|
230
230
|
is_string: true),
|
231
|
+
FastlaneCore::ConfigItem.new(key: :trade_representative_contact_information,
|
232
|
+
description: "Metadata: A hash containing the trade representative contact information",
|
233
|
+
optional: true,
|
234
|
+
is_string: false),
|
231
235
|
FastlaneCore::ConfigItem.new(key: :app_review_information,
|
232
236
|
description: "Metadata: A hash containing the review information",
|
233
237
|
optional: true,
|
@@ -66,6 +66,17 @@ module Deliver
|
|
66
66
|
UI.message("Writing to '#{resulting_path}'")
|
67
67
|
end
|
68
68
|
|
69
|
+
# Trade Representative Contact Information
|
70
|
+
UploadMetadata::TRADE_REPRESENTATIVE_CONTACT_INFORMATION_VALUES.each do |key, option_name|
|
71
|
+
content = v.send(key).to_s
|
72
|
+
content << "\n"
|
73
|
+
base_dir = File.join(path, UploadMetadata::TRADE_REPRESENTATIVE_CONTACT_INFORMATION_DIR)
|
74
|
+
FileUtils.mkdir_p(base_dir)
|
75
|
+
resulting_path = File.join(base_dir, "#{option_name}.txt")
|
76
|
+
File.write(resulting_path, content)
|
77
|
+
UI.message("Writing to '#{resulting_path}'")
|
78
|
+
end
|
79
|
+
|
69
80
|
# Review information
|
70
81
|
UploadMetadata::REVIEW_INFORMATION_VALUES.each do |key, option_name|
|
71
82
|
content = v.send(key).to_s
|
@@ -15,6 +15,23 @@ module Deliver
|
|
15
15
|
:primary_first_sub_category, :primary_second_sub_category,
|
16
16
|
:secondary_first_sub_category, :secondary_second_sub_category]
|
17
17
|
|
18
|
+
# Trade Representative Contact Information values
|
19
|
+
TRADE_REPRESENTATIVE_CONTACT_INFORMATION_VALUES = {
|
20
|
+
trade_representative_trade_name: :trade_name,
|
21
|
+
trade_representative_first_name: :first_name,
|
22
|
+
trade_representative_last_name: :last_name,
|
23
|
+
trade_representative_address_line_1: :adderss_line1,
|
24
|
+
trade_representative_address_line_2: :adderss_line2,
|
25
|
+
trade_representative_address_line_3: :adderss_line3,
|
26
|
+
trade_representative_city_name: :city_name,
|
27
|
+
trade_representative_state: :state,
|
28
|
+
trade_representative_country: :country,
|
29
|
+
trade_representative_postal_code: :postal_code,
|
30
|
+
trade_representative_phone_number: :phone_number,
|
31
|
+
trade_representative_email: :email_address,
|
32
|
+
trade_representative_is_displayed_on_app_store: :is_displayed_on_app_store
|
33
|
+
}
|
34
|
+
|
18
35
|
# Review information values
|
19
36
|
REVIEW_INFORMATION_VALUES = {
|
20
37
|
review_first_name: :first_name,
|
@@ -32,6 +49,9 @@ module Deliver
|
|
32
49
|
# Non localized app details values, that are editable in live state
|
33
50
|
NON_LOCALISED_LIVE_VALUES = [:privacy_url]
|
34
51
|
|
52
|
+
# Directory name it contains trade representative contact information
|
53
|
+
TRADE_REPRESENTATIVE_CONTACT_INFORMATION_DIR = "trade_representative_contact_information"
|
54
|
+
|
35
55
|
# Directory name it contains review information
|
36
56
|
REVIEW_INFORMATION_DIR = "review_information"
|
37
57
|
|
@@ -92,6 +112,7 @@ module Deliver
|
|
92
112
|
|
93
113
|
v.release_on_approval = options[:automatic_release]
|
94
114
|
|
115
|
+
set_trade_representative_contact_information(v, options)
|
95
116
|
set_review_information(v, options)
|
96
117
|
set_app_rating(v, options)
|
97
118
|
|
@@ -198,6 +219,17 @@ module Deliver
|
|
198
219
|
options[key] ||= File.read(path)
|
199
220
|
end
|
200
221
|
|
222
|
+
# Load trade representative contact information
|
223
|
+
options[:trade_representative_contact_information] ||= {}
|
224
|
+
TRADE_REPRESENTATIVE_CONTACT_INFORMATION_VALUES.values.each do |option_name|
|
225
|
+
path = File.join(options[:metadata_path], TRADE_REPRESENTATIVE_CONTACT_INFORMATION_DIR, "#{option_name}.txt")
|
226
|
+
next unless File.exist?(path)
|
227
|
+
next if options[:trade_representative_contact_information][option_name].to_s.length > 0
|
228
|
+
|
229
|
+
UI.message("Loading '#{path}'...")
|
230
|
+
options[:trade_representative_contact_information][option_name] ||= File.read(path)
|
231
|
+
end
|
232
|
+
|
201
233
|
# Load review information
|
202
234
|
options[:app_review_information] ||= {}
|
203
235
|
REVIEW_INFORMATION_VALUES.values.each do |option_name|
|
@@ -212,6 +244,16 @@ module Deliver
|
|
212
244
|
|
213
245
|
private
|
214
246
|
|
247
|
+
def set_trade_representative_contact_information(v, options)
|
248
|
+
return unless options[:trade_representative_contact_information]
|
249
|
+
info = options[:trade_representative_contact_information]
|
250
|
+
UI.user_error!("`trade_representative_contact_information` must be a hash", show_github_issues: true) unless info.kind_of?(Hash)
|
251
|
+
|
252
|
+
TRADE_REPRESENTATIVE_CONTACT_INFORMATION_VALUES.each do |key, option_name|
|
253
|
+
v.send("#{key}=", info[option_name].chomp) if info[option_name].chomp
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
215
257
|
def set_review_information(v, options)
|
216
258
|
return unless options[:app_review_information]
|
217
259
|
info = options[:app_review_information]
|
@@ -57,8 +57,7 @@ module Fastlane
|
|
57
57
|
update_needed.each do |tool_info|
|
58
58
|
tool = tool_info[0]
|
59
59
|
local_version = Gem::Version.new(highest_versions[tool].version)
|
60
|
-
|
61
|
-
latest_version = FastlaneCore::UpdateChecker.fetch_latest(update_url)
|
60
|
+
latest_version = FastlaneCore::UpdateChecker.fetch_latest(tool)
|
62
61
|
UI.message("Updating #{tool} from #{local_version} to #{latest_version} ... 🚀")
|
63
62
|
|
64
63
|
# Approximate_recommendation will create a string like "~> 0.10" from a version 0.10.0, e.g. one that is valid for versions >= 0.10 and <1.0
|
@@ -73,7 +73,29 @@ module Fastlane
|
|
73
73
|
else
|
74
74
|
puts "Couldn't find action for the given filter.".red
|
75
75
|
puts "==========================================\n".red
|
76
|
+
|
76
77
|
print_all # show all available actions instead
|
78
|
+
print_suggestions(filter)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.print_suggestions(filter)
|
83
|
+
if !filter.nil? && filter.length > 1
|
84
|
+
action_names = []
|
85
|
+
all_actions(nil) do |action_ref, action_name|
|
86
|
+
action_names << action_name
|
87
|
+
end
|
88
|
+
|
89
|
+
corrections = []
|
90
|
+
|
91
|
+
if !Gem.loaded_specs["did_you_mean"].nil? && Gem.loaded_specs["did_you_mean"].version >= Gem::Version.new('1.1.0')
|
92
|
+
spell_checker = DidYouMean::SpellChecker.new(dictionary: action_names)
|
93
|
+
corrections << spell_checker.correct(filter).compact
|
94
|
+
end
|
95
|
+
|
96
|
+
corrections << action_names.select { |name| name.include? filter }
|
97
|
+
|
98
|
+
puts "Did you mean: #{corrections.flatten.uniq.join(', ')}?".green unless corrections.flatten.empty?
|
77
99
|
end
|
78
100
|
end
|
79
101
|
|
@@ -62,17 +62,16 @@ module Fastlane
|
|
62
62
|
table << "|--------|---------|\n"
|
63
63
|
plugin_manager.available_plugins.each do |plugin|
|
64
64
|
begin
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
65
|
+
installed_version = Fastlane::ActionCollector.determine_version(plugin)
|
66
|
+
latest_version = FastlaneCore::UpdateChecker.fetch_latest(plugin)
|
67
|
+
if Gem::Version.new(installed_version) == Gem::Version.new(latest_version)
|
68
|
+
update_status = "✅ Up-To-Date"
|
69
|
+
else
|
70
|
+
update_status = "🚫 Update available"
|
71
|
+
end
|
72
|
+
rescue
|
73
|
+
update_status = "💥 Check failed"
|
72
74
|
end
|
73
|
-
rescue
|
74
|
-
update_status = "💥 Check failed"
|
75
|
-
end
|
76
75
|
table << "| #{plugin} | #{installed_version} | #{update_status} |\n"
|
77
76
|
end
|
78
77
|
|
@@ -107,9 +106,8 @@ module Fastlane
|
|
107
106
|
|
108
107
|
next unless fastlane_tools.include?(current_gem.name.to_sym)
|
109
108
|
begin
|
110
|
-
|
111
|
-
|
112
|
-
if Gem::Version.new(current_gem.version) == Gem::Version.new(latest_version)
|
109
|
+
latest_version = FastlaneCore::UpdateChecker.fetch_latest(current_gem.name)
|
110
|
+
if Gem::Version.new(current_gem.version) >= Gem::Version.new(latest_version)
|
113
111
|
update_status = "✅ Up-To-Date"
|
114
112
|
else
|
115
113
|
update_status = "🚫 Update available"
|
@@ -33,6 +33,7 @@ module Fastlane
|
|
33
33
|
UI.verbose(caller.join("\n"))
|
34
34
|
UI.user_error!("The action '#{action}' is no longer bundled with fastlane. You can install it using `fastlane add_plugin #{action}`")
|
35
35
|
else
|
36
|
+
Fastlane::ActionsList.print_suggestions(action)
|
36
37
|
UI.user_error!("Action '#{action}' not available, run `fastlane actions` to get a full list")
|
37
38
|
end
|
38
39
|
end
|
@@ -112,7 +112,11 @@ module FastlaneCore
|
|
112
112
|
end
|
113
113
|
|
114
114
|
def self.fetch_latest(gem_name)
|
115
|
-
JSON.parse(Excon.get(
|
115
|
+
JSON.parse(Excon.get(generate_fetch_url(gem_name)).body)["version"]
|
116
|
+
end
|
117
|
+
|
118
|
+
def self.generate_fetch_url(gem_name)
|
119
|
+
"https://rubygems.org/api/v1/gems/#{gem_name}.json"
|
116
120
|
end
|
117
121
|
|
118
122
|
# (optional) Returns the app identifier for the current tool
|
data/match/lib/match/encrypt.rb
CHANGED
@@ -16,7 +16,9 @@ module Match
|
|
16
16
|
|
17
17
|
unless password
|
18
18
|
if !UI.interactive?
|
19
|
-
UI.error "
|
19
|
+
UI.error "Neither the MATCH_PASSWORD environment variable nor the local keychain contained a password."
|
20
|
+
UI.error "Bailing out instead of asking for a password, since this is non-interactive mode."
|
21
|
+
UI.error "Try setting the MATCH_PASSWORD environment variable, or temporarily enable interactive mode to store a password."
|
20
22
|
else
|
21
23
|
UI.important "Enter the passphrase that should be used to encrypt/decrypt your certificates"
|
22
24
|
UI.important "This passphrase is specific per repository and will be stored in your local keychain"
|
@@ -6,19 +6,28 @@ module Pilot
|
|
6
6
|
class TesterManager < Manager
|
7
7
|
def add_tester(options)
|
8
8
|
start(options)
|
9
|
-
|
10
9
|
app = find_app(app_filter: config[:apple_id] || config[:app_identifier])
|
11
10
|
UI.user_error!("You must provide either a Apple ID for the app (with the `:apple_id` option) or app identifier (with the `:app_identifier` option)") unless app
|
12
11
|
|
13
|
-
tester =
|
14
|
-
|
12
|
+
tester = find_app_tester(email: config[:email], app: app)
|
13
|
+
tester ||= create_tester(
|
14
|
+
email: config[:email],
|
15
|
+
first_name: config[:first_name],
|
16
|
+
last_name: config[:last_name],
|
17
|
+
app: app
|
18
|
+
)
|
15
19
|
begin
|
16
20
|
groups = Spaceship::TestFlight::Group.add_tester_to_groups!(tester: tester, app: app, groups: config[:groups])
|
17
21
|
if tester.kind_of?(Spaceship::Tunes::Tester::Internal)
|
18
22
|
UI.success("Successfully added tester to app #{app.name}")
|
19
23
|
else
|
20
|
-
|
21
|
-
|
24
|
+
# tester was added to the group(s) in the above add_tester_to_groups() call, now we need to let the user know which group(s)
|
25
|
+
if config[:groups]
|
26
|
+
group_names = groups.map(&:name).join(", ")
|
27
|
+
UI.success("Successfully added tester to group(s): #{group_names} in app: #{app.name}")
|
28
|
+
else
|
29
|
+
UI.success("Successfully added tester to the default tester group in app: #{app.name}")
|
30
|
+
end
|
22
31
|
end
|
23
32
|
rescue => ex
|
24
33
|
UI.error("Could not add #{tester.email} to app: #{app.name}")
|
@@ -91,21 +100,51 @@ module Pilot
|
|
91
100
|
nil
|
92
101
|
end
|
93
102
|
|
94
|
-
def
|
95
|
-
|
96
|
-
|
103
|
+
def find_app_tester(email: nil, app: nil)
|
104
|
+
current_user = Spaceship::Members.find(Spaceship::Tunes.client.user)
|
105
|
+
if current_user.admin?
|
106
|
+
tester = Spaceship::Tunes::Tester::Internal.find(email)
|
107
|
+
tester ||= Spaceship::Tunes::Tester::External.find(email)
|
108
|
+
elsif current_user.app_manager?
|
109
|
+
unless app
|
110
|
+
UI.user_error!("Account #{current_user.email_address} is only an 'App Manager' and therefore you must also define what app this tester (#{email}) should be added to")
|
111
|
+
end
|
112
|
+
tester = Spaceship::Tunes::Tester::Internal.find_by_app(app.apple_id, email)
|
113
|
+
tester ||= Spaceship::Tunes::Tester::External.find_by_app(app.apple_id, email)
|
114
|
+
else
|
115
|
+
UI.user_error!("Account #{current_user.email} doesn't have a role that is allowed to administer app testers, current roles: #{current_user.roles}")
|
116
|
+
tester = nil
|
117
|
+
end
|
97
118
|
|
98
119
|
if tester
|
99
|
-
UI.success("
|
120
|
+
UI.success("Found existing tester #{email}")
|
121
|
+
end
|
122
|
+
|
123
|
+
return tester
|
124
|
+
end
|
125
|
+
|
126
|
+
def create_tester(email: nil, first_name: nil, last_name: nil, app: nil)
|
127
|
+
current_user = Spaceship::Members.find(Spaceship::Tunes.client.user)
|
128
|
+
if current_user.admin?
|
129
|
+
tester = Spaceship::Tunes::Tester::External.create!(email: email,
|
130
|
+
first_name: first_name,
|
131
|
+
last_name: last_name)
|
132
|
+
UI.success("Successfully added tester: #{email} to your account")
|
133
|
+
elsif current_user.app_manager?
|
134
|
+
|
135
|
+
Spaceship::TestFlight::Tester.create_app_level_tester(app_id: app.apple_id,
|
136
|
+
first_name: first_name,
|
137
|
+
last_name: last_name,
|
138
|
+
email: email)
|
139
|
+
tester = Spaceship::Tunes::Tester::External.find_by_app(app.apple_id, email)
|
140
|
+
UI.success("Successfully added tester: #{email} to app: #{app.name}")
|
100
141
|
else
|
101
|
-
|
102
|
-
first_name: config[:first_name],
|
103
|
-
last_name: config[:last_name])
|
104
|
-
UI.success("Successfully added tester: #{tester.email} to your account")
|
142
|
+
UI.user_error!("Current account doesn't have permission to create a tester")
|
105
143
|
end
|
144
|
+
|
106
145
|
return tester
|
107
146
|
rescue => ex
|
108
|
-
UI.error("Could not create tester #{
|
147
|
+
UI.error("Could not create tester #{email}")
|
109
148
|
raise ex
|
110
149
|
end
|
111
150
|
|
@@ -176,7 +176,12 @@ module Snapshot
|
|
176
176
|
FastlaneCore::ConfigItem.new(key: :test_target_name,
|
177
177
|
env_name: "SNAPSHOT_TEST_TARGET_NAME",
|
178
178
|
description: "The name of the target you want to test (if you desire to override the Target Application from Xcode)",
|
179
|
-
optional: true)
|
179
|
+
optional: true),
|
180
|
+
FastlaneCore::ConfigItem.new(key: :namespace_log_files,
|
181
|
+
env_name: "SNAPSHOT_NAMESPACE_LOG_FILES",
|
182
|
+
description: "Separate the log files per device and per language",
|
183
|
+
optional: true,
|
184
|
+
is_string: false)
|
180
185
|
]
|
181
186
|
end
|
182
187
|
end
|
@@ -171,7 +171,7 @@ module Snapshot
|
|
171
171
|
|
172
172
|
open_simulator_for_device(device_type)
|
173
173
|
|
174
|
-
command = TestCommandGenerator.generate(device_type: device_type)
|
174
|
+
command = TestCommandGenerator.generate(device_type: device_type, language: language, locale: locale)
|
175
175
|
|
176
176
|
if locale
|
177
177
|
UI.header("#{device_type} - #{language} (#{locale})")
|
@@ -208,7 +208,7 @@ module Snapshot
|
|
208
208
|
end
|
209
209
|
end)
|
210
210
|
|
211
|
-
raw_output = File.read(TestCommandGenerator.xcodebuild_log_path)
|
211
|
+
raw_output = File.read(TestCommandGenerator.xcodebuild_log_path(device_type: device_type, language: language, locale: locale))
|
212
212
|
|
213
213
|
dir_name = locale || language
|
214
214
|
|
@@ -2,7 +2,7 @@ module Snapshot
|
|
2
2
|
# Responsible for building the fully working xcodebuild command
|
3
3
|
class TestCommandGenerator
|
4
4
|
class << self
|
5
|
-
def generate(device_type: nil)
|
5
|
+
def generate(device_type: nil, language: nil, locale: nil)
|
6
6
|
parts = prefix
|
7
7
|
parts << "xcodebuild"
|
8
8
|
parts += options
|
@@ -10,7 +10,7 @@ module Snapshot
|
|
10
10
|
parts += build_settings
|
11
11
|
parts += actions
|
12
12
|
parts += suffix
|
13
|
-
parts += pipe
|
13
|
+
parts += pipe(device_type, language, locale)
|
14
14
|
|
15
15
|
parts
|
16
16
|
end
|
@@ -62,8 +62,9 @@ module Snapshot
|
|
62
62
|
[]
|
63
63
|
end
|
64
64
|
|
65
|
-
def pipe
|
66
|
-
|
65
|
+
def pipe(device_type, language, locale)
|
66
|
+
log_path = xcodebuild_log_path(device_type: device_type, language: language, locale: locale)
|
67
|
+
["| tee #{log_path.shellescape} | xcpretty #{Snapshot.config[:xcpretty_args]}"]
|
67
68
|
end
|
68
69
|
|
69
70
|
def find_device(device_name, os_version = Snapshot.config[:ios_version])
|
@@ -108,8 +109,17 @@ module Snapshot
|
|
108
109
|
return ["-destination '#{value}'"]
|
109
110
|
end
|
110
111
|
|
111
|
-
def xcodebuild_log_path
|
112
|
-
|
112
|
+
def xcodebuild_log_path(device_type: nil, language: nil, locale: nil)
|
113
|
+
name_components = [Snapshot.project.app_name, Snapshot.config[:scheme]]
|
114
|
+
|
115
|
+
if Snapshot.config[:namespace_log_files]
|
116
|
+
name_components << device_type if device_type
|
117
|
+
name_components << language if language
|
118
|
+
name_components << locale if locale
|
119
|
+
end
|
120
|
+
|
121
|
+
file_name = "#{name_components.join('-')}.log"
|
122
|
+
|
113
123
|
containing = File.expand_path(Snapshot.config[:buildlog_path])
|
114
124
|
FileUtils.mkdir_p(containing)
|
115
125
|
|
Binary file
|
@@ -111,16 +111,15 @@ module Spaceship::TestFlight
|
|
111
111
|
handle_response(response)
|
112
112
|
end
|
113
113
|
|
114
|
-
def
|
114
|
+
def create_app_level_tester(app_id: nil, first_name: nil, last_name: nil, email: nil)
|
115
115
|
assert_required_params(__method__, binding)
|
116
|
-
|
117
116
|
url = "providers/#{team_id}/apps/#{app_id}/testers"
|
118
117
|
response = request(:post) do |req|
|
119
118
|
req.url url
|
120
119
|
req.body = {
|
121
|
-
"email" =>
|
122
|
-
"firstName" =>
|
123
|
-
"lastName" =>
|
120
|
+
"email" => email,
|
121
|
+
"firstName" => first_name,
|
122
|
+
"lastName" => last_name
|
124
123
|
}.to_json
|
125
124
|
req.headers['Content-Type'] = 'application/json'
|
126
125
|
end
|
@@ -46,8 +46,12 @@ module Spaceship::TestFlight
|
|
46
46
|
# is not enough to add the tester to a group. If this isn't done the next request would fail.
|
47
47
|
# This is a bug we reported to the iTunes Connect team, as it also happens on the iTunes Connect UI on 18. April 2017
|
48
48
|
def add_tester!(tester)
|
49
|
-
# This post request
|
50
|
-
|
49
|
+
# This post request creates an account-level tester and then makes it available to the app, or just makes
|
50
|
+
# it available to the app if it already exists
|
51
|
+
tester_data = client.create_app_level_tester(app_id: self.app_id,
|
52
|
+
first_name: tester.first_name,
|
53
|
+
last_name: tester.last_name,
|
54
|
+
email: tester.email)
|
51
55
|
# This put request adds the tester to the group
|
52
56
|
client.put_tester_to_group(group_id: self.id, tester_id: tester_data['id'], app_id: self.app_id)
|
53
57
|
end
|
@@ -27,6 +27,13 @@ module Spaceship::TestFlight
|
|
27
27
|
self.all(app_id: app_id).find { |tester| tester.email == email }
|
28
28
|
end
|
29
29
|
|
30
|
+
def self.create_app_level_tester(app_id: nil, first_name: nil, last_name: nil, email: nil)
|
31
|
+
client.create_app_level_tester(app_id: app_id,
|
32
|
+
first_name: first_name,
|
33
|
+
last_name: last_name,
|
34
|
+
email: email)
|
35
|
+
end
|
36
|
+
|
30
37
|
def remove_from_app!(app_id: nil)
|
31
38
|
client.delete_tester_from_app(app_id: app_id, tester_id: self.tester_id)
|
32
39
|
end
|
@@ -71,6 +71,48 @@ module Spaceship
|
|
71
71
|
# @return (Spaceship::Tunes::TransitAppFile) the structure containing information about the geo json. Can be nil
|
72
72
|
attr_accessor :transit_app_file
|
73
73
|
|
74
|
+
####
|
75
|
+
# Trade Representative Contact Information
|
76
|
+
####
|
77
|
+
# @return (String) Trade Representative Contact Information Trade Name. This attribute isn't editable
|
78
|
+
attr_accessor :trade_representative_trade_name
|
79
|
+
|
80
|
+
# @return (String) Trade Representative Contact Information First Name
|
81
|
+
attr_accessor :trade_representative_first_name
|
82
|
+
|
83
|
+
# @return (String) Trade Representative Contact Information Last Name
|
84
|
+
attr_accessor :trade_representative_last_name
|
85
|
+
|
86
|
+
# @return (String) Trade Representative Contact Information Address Line 1
|
87
|
+
attr_accessor :trade_representative_address_line_1
|
88
|
+
|
89
|
+
# @return (String) Trade Representative Contact Information Address Line 2
|
90
|
+
attr_accessor :trade_representative_address_line_2
|
91
|
+
|
92
|
+
# @return (String) Trade Representative Contact Information Address Line 3
|
93
|
+
attr_accessor :trade_representative_address_line_3
|
94
|
+
|
95
|
+
# @return (String) Trade Representative Contact Information City Name
|
96
|
+
attr_accessor :trade_representative_city_name
|
97
|
+
|
98
|
+
# @return (String) Trade Representative Contact Information State
|
99
|
+
attr_accessor :trade_representative_state
|
100
|
+
|
101
|
+
# @return (String) Trade Representative Contact Information Country
|
102
|
+
attr_accessor :trade_representative_country
|
103
|
+
|
104
|
+
# @return (String) Trade Representative Contact Information Postal Code
|
105
|
+
attr_accessor :trade_representative_postal_code
|
106
|
+
|
107
|
+
# @return (String) Trade Representative Contact Information Phone Number
|
108
|
+
attr_accessor :trade_representative_phone_number
|
109
|
+
|
110
|
+
# @return (String) Trade Representative Contact Information Email Address
|
111
|
+
attr_accessor :trade_representative_email
|
112
|
+
|
113
|
+
# @return (Boolean) Display Trade Representative Contact Information on the Korean App Store or not
|
114
|
+
attr_accessor :trade_representative_is_displayed_on_app_store
|
115
|
+
|
74
116
|
####
|
75
117
|
# App Review Information
|
76
118
|
####
|
@@ -150,6 +192,22 @@ module Spaceship
|
|
150
192
|
# GeoJson
|
151
193
|
# 'transitAppFile.value' => :transit_app_file
|
152
194
|
|
195
|
+
# Trade Representative Contact Information
|
196
|
+
|
197
|
+
'appStoreInfo.tradeName.value' => :trade_representative_trade_name,
|
198
|
+
'appStoreInfo.firstName.value' => :trade_representative_first_name,
|
199
|
+
'appStoreInfo.lastName.value' => :trade_representative_last_name,
|
200
|
+
'appStoreInfo.addressLine1.value' => :trade_representative_address_line_1,
|
201
|
+
'appStoreInfo.addressLine2.value' => :trade_representative_address_line_2,
|
202
|
+
'appStoreInfo.addressLine3.value' => :trade_representative_address_line_3,
|
203
|
+
'appStoreInfo.cityName.value' => :trade_representative_city_name,
|
204
|
+
'appStoreInfo.state.value' => :trade_representative_state,
|
205
|
+
'appStoreInfo.country.value' => :trade_representative_country,
|
206
|
+
'appStoreInfo.postalCode.value' => :trade_representative_postal_code,
|
207
|
+
'appStoreInfo.phoneNumber.value' => :trade_representative_phone_number,
|
208
|
+
'appStoreInfo.emailAddress.value' => :trade_representative_email,
|
209
|
+
'appStoreInfo.shouldDisplayInStore.value' => :trade_representative_is_displayed_on_app_store,
|
210
|
+
|
153
211
|
# App Review Information
|
154
212
|
'appReviewInfo.firstName.value' => :review_first_name,
|
155
213
|
'appReviewInfo.lastName.value' => :review_last_name,
|
@@ -16,6 +16,15 @@ module Spaceship
|
|
16
16
|
'dsId' => :user_id
|
17
17
|
)
|
18
18
|
|
19
|
+
ROLES = {
|
20
|
+
admin: 'admin',
|
21
|
+
app_manager: 'appmanager',
|
22
|
+
sales: 'sales',
|
23
|
+
developer: 'developer',
|
24
|
+
marketing: 'marketing',
|
25
|
+
reports: 'reports'
|
26
|
+
}
|
27
|
+
|
19
28
|
def roles
|
20
29
|
parsed_roles = []
|
21
30
|
raw_data["roles"].each do |role|
|
@@ -24,6 +33,14 @@ module Spaceship
|
|
24
33
|
return parsed_roles
|
25
34
|
end
|
26
35
|
|
36
|
+
def admin?
|
37
|
+
roles.include?(ROLES[:admin])
|
38
|
+
end
|
39
|
+
|
40
|
+
def app_manager?
|
41
|
+
roles.include?(ROLES[:app_manager])
|
42
|
+
end
|
43
|
+
|
27
44
|
def preferred_currency
|
28
45
|
currency_base = raw_data["preferredCurrency"]["value"]
|
29
46
|
return {
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fastlane
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.29.
|
4
|
+
version: 2.29.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Felix Krause
|
@@ -15,7 +15,7 @@ authors:
|
|
15
15
|
autorequire:
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
|
-
date: 2017-05-
|
18
|
+
date: 2017-05-11 00:00:00.000000000 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: slack-notifier
|
@@ -1257,6 +1257,7 @@ files:
|
|
1257
1257
|
- spaceship/lib/assets/languageMapping.json
|
1258
1258
|
- spaceship/lib/assets/languageMappingReadable.json
|
1259
1259
|
- spaceship/lib/spaceship.rb
|
1260
|
+
- spaceship/lib/spaceship/.DS_Store
|
1260
1261
|
- spaceship/lib/spaceship/babosa_fix.rb
|
1261
1262
|
- spaceship/lib/spaceship/base.rb
|
1262
1263
|
- spaceship/lib/spaceship/client.rb
|
@@ -1386,7 +1387,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
1386
1387
|
version: '0'
|
1387
1388
|
requirements: []
|
1388
1389
|
rubyforge_project:
|
1389
|
-
rubygems_version: 2.5
|
1390
|
+
rubygems_version: 2.2.5
|
1390
1391
|
signing_key:
|
1391
1392
|
specification_version: 4
|
1392
1393
|
summary: The easiest way to automate beta deployments and releases for your iOS and
|