fastlane 2.29.0 → 2.29.1
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/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
|