fastlane 2.34.0 → 2.35.0
Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2a703ca979d3b3cd10a0396a0cc9a826bfa43d67
|
4
|
+
data.tar.gz: 5909052758266430d88fc2a1970b8399848039da
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 17c241d3e80cf683d5ff1a5426cea3870cd1f58bb4574d8d3a823499e0a472ea079fbd80d37d0bb604b56f0ca150aeb47afc48b96f1e67f6bb047dcf7c2683e8
|
7
|
+
data.tar.gz: 1f8ee5eccdccfd78b1270c1a604037faac1b474d94b84bc6e3d0c24b0a3402ec3e322c9586119f8d3a6cb2ddea5a6e0fed395e02a325709d5e871cb8226c7461
|
@@ -28,6 +28,7 @@ module Fastlane
|
|
28
28
|
|
29
29
|
input_format: '--input-format',
|
30
30
|
scheme: '--scheme',
|
31
|
+
configuration: '--configuration',
|
31
32
|
workspace: '--workspace',
|
32
33
|
binary_file: '--binary-file',
|
33
34
|
binary_basename: '--binary-basename',
|
@@ -52,7 +53,20 @@ module Fastlane
|
|
52
53
|
File.file?('.slather.yml')
|
53
54
|
end
|
54
55
|
|
56
|
+
def self.slather_version
|
57
|
+
require 'slather'
|
58
|
+
Slather::VERSION
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.configuration_available?
|
62
|
+
Gem::Version.new('2.4.1') <= Gem::Version.new(slather_version)
|
63
|
+
end
|
64
|
+
|
55
65
|
def self.validate_params!(params)
|
66
|
+
if params[:configuration]
|
67
|
+
UI.user_error!('configuration option is available since version 2.4.1') unless configuration_available?
|
68
|
+
end
|
69
|
+
|
56
70
|
if params[:proj] || has_config_file
|
57
71
|
true
|
58
72
|
else
|
@@ -121,6 +135,10 @@ Slather is available at https://github.com/SlatherOrg/slather
|
|
121
135
|
env_name: "FL_SLATHER_SCHEME", # The name of the environment variable
|
122
136
|
description: "Scheme to use when calling slather",
|
123
137
|
optional: true),
|
138
|
+
FastlaneCore::ConfigItem.new(key: :configuration,
|
139
|
+
env_name: "FL_SLATHER_CONFIGURATION", # The name of the environment variable
|
140
|
+
description: "Configuration to use when calling slather (since slather-2.4.1)",
|
141
|
+
optional: true),
|
124
142
|
FastlaneCore::ConfigItem.new(key: :input_format,
|
125
143
|
env_name: "FL_SLATHER_INPUT_FORMAT", # The name of the environment variable
|
126
144
|
description: "The input format that slather should look for",
|
@@ -137,6 +137,50 @@ module Spaceship
|
|
137
137
|
end
|
138
138
|
end
|
139
139
|
|
140
|
+
# Fetch the general information of the user, is used by various methods across spaceship
|
141
|
+
# Sample return value
|
142
|
+
# => {"associatedAccounts"=>
|
143
|
+
# [{"contentProvider"=>{"contentProviderId"=>11142800, "name"=>"Felix Krause", "contentProviderTypes"=>["Purple Software"]}, "roles"=>["Developer"], "lastLogin"=>1468784113000}],
|
144
|
+
# "sessionToken"=>{"dsId"=>"8501011116", "contentProviderId"=>18111111, "expirationDate"=>nil, "ipAddress"=>nil},
|
145
|
+
# "permittedActivities"=>
|
146
|
+
# {"EDIT"=>
|
147
|
+
# ["UserManagementSelf",
|
148
|
+
# "GameCenterTestData",
|
149
|
+
# "AppAddonCreation"],
|
150
|
+
# "REPORT"=>
|
151
|
+
# ["UserManagementSelf",
|
152
|
+
# "AppAddonCreation"],
|
153
|
+
# "VIEW"=>
|
154
|
+
# ["TestFlightAppExternalTesterManagement",
|
155
|
+
# ...
|
156
|
+
# "HelpGeneral",
|
157
|
+
# "HelpApplicationLoader"]},
|
158
|
+
# "preferredCurrencyCode"=>"EUR",
|
159
|
+
# "preferredCountryCode"=>nil,
|
160
|
+
# "countryOfOrigin"=>"AT",
|
161
|
+
# "isLocaleNameReversed"=>false,
|
162
|
+
# "feldsparToken"=>nil,
|
163
|
+
# "feldsparChannelName"=>nil,
|
164
|
+
# "hasPendingFeldsparBindingRequest"=>false,
|
165
|
+
# "isLegalUser"=>false,
|
166
|
+
# "userId"=>"1771111155",
|
167
|
+
# "firstname"=>"Detlef",
|
168
|
+
# "lastname"=>"Mueller",
|
169
|
+
# "isEmailInvalid"=>false,
|
170
|
+
# "hasContractInfo"=>false,
|
171
|
+
# "canEditITCUsersAndRoles"=>false,
|
172
|
+
# "canViewITCUsersAndRoles"=>true,
|
173
|
+
# "canEditIAPUsersAndRoles"=>false,
|
174
|
+
# "transporterEnabled"=>false,
|
175
|
+
# "contentProviderFeatures"=>["APP_SILOING", "PROMO_CODE_REDESIGN", ...],
|
176
|
+
# "contentProviderType"=>"Purple Software",
|
177
|
+
# "displayName"=>"Detlef",
|
178
|
+
# "contentProviderId"=>"18742800",
|
179
|
+
# "userFeatures"=>[],
|
180
|
+
# "visibility"=>true,
|
181
|
+
# "DYCVisibility"=>false,
|
182
|
+
# "contentProvider"=>"Felix Krause",
|
183
|
+
# "userName"=>"detlef@krausefx.com"}
|
140
184
|
def user_details_data
|
141
185
|
return @_cached_user_details if @_cached_user_details
|
142
186
|
r = request(:get, '/WebObjects/iTunesConnect.woa/ra/user/detail')
|
@@ -186,6 +230,13 @@ module Spaceship
|
|
186
230
|
@current_team_id = team_id
|
187
231
|
end
|
188
232
|
|
233
|
+
# @return (Hash) Fetches all information of the currently used team
|
234
|
+
def team_information
|
235
|
+
teams.find do |t|
|
236
|
+
t['teamId'] == team_id
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
189
240
|
# Instantiates a client but with a cookie derived from another client.
|
190
241
|
#
|
191
242
|
# HACK: since the `@cookie` is not exposed, we use this hacky way of sharing the instance.
|
@@ -350,7 +401,7 @@ module Spaceship
|
|
350
401
|
if keychain_entry.invalid_credentials
|
351
402
|
login(user)
|
352
403
|
else
|
353
|
-
|
404
|
+
raise ex
|
354
405
|
end
|
355
406
|
end
|
356
407
|
end
|
@@ -392,10 +443,11 @@ module Spaceship
|
|
392
443
|
end
|
393
444
|
|
394
445
|
response = request(:post) do |req|
|
395
|
-
req.url "https://idmsa.apple.com/appleauth/auth/signin
|
446
|
+
req.url "https://idmsa.apple.com/appleauth/auth/signin"
|
396
447
|
req.body = data.to_json
|
397
448
|
req.headers['Content-Type'] = 'application/json'
|
398
449
|
req.headers['X-Requested-With'] = 'XMLHttpRequest'
|
450
|
+
req.headers['X-Apple-Widget-Key'] = self.itc_service_key
|
399
451
|
req.headers['Accept'] = 'application/json, text/javascript'
|
400
452
|
req.headers["Cookie"] = modified_cookie if modified_cookie
|
401
453
|
end
|
@@ -403,23 +455,22 @@ module Spaceship
|
|
403
455
|
raise InvalidUserCredentialsError.new, "Invalid username and password combination. Used '#{user}' as the username."
|
404
456
|
end
|
405
457
|
|
406
|
-
#
|
407
|
-
request(:get, "https://itunesconnect.apple.com/WebObjects/iTunesConnect.woa/wa")
|
408
|
-
|
409
|
-
# Get the `itctx` from the new (22nd May 2017) API endpoint "olympus"
|
410
|
-
request(:get, "https://olympus.itunes.apple.com/v1/session")
|
458
|
+
# Now we know if the login is successful or if we need to do 2 factor
|
411
459
|
|
412
460
|
case response.status
|
413
461
|
when 403
|
414
462
|
raise InvalidUserCredentialsError.new, "Invalid username and password combination. Used '#{user}' as the username."
|
415
463
|
when 200
|
464
|
+
fetch_olympus_session
|
416
465
|
return response
|
466
|
+
when 409
|
467
|
+
# 2 factor is enabled for this account, first handle that
|
468
|
+
# and then get the olympus session
|
469
|
+
handle_two_step(response)
|
470
|
+
fetch_olympus_session
|
471
|
+
return true
|
417
472
|
else
|
418
|
-
|
419
|
-
if location && URI.parse(location).path == "/auth" # redirect to 2 step auth page
|
420
|
-
handle_two_step(response)
|
421
|
-
return true
|
422
|
-
elsif (response.body || "").include?('invalid="true"')
|
473
|
+
if (response.body || "").include?('invalid="true"')
|
423
474
|
# User Credentials are wrong
|
424
475
|
raise InvalidUserCredentialsError.new, "Invalid username and password combination. Used '#{user}' as the username."
|
425
476
|
elsif (response['Set-Cookie'] || "").include?("itctx")
|
@@ -431,6 +482,11 @@ module Spaceship
|
|
431
482
|
end
|
432
483
|
end
|
433
484
|
|
485
|
+
# Get the `itctx` from the new (22nd May 2017) API endpoint "olympus"
|
486
|
+
def fetch_olympus_session
|
487
|
+
request(:get, "https://olympus.itunes.apple.com/v1/session")
|
488
|
+
end
|
489
|
+
|
434
490
|
def itc_service_key
|
435
491
|
return @service_key if @service_key
|
436
492
|
|
@@ -438,16 +494,10 @@ module Spaceship
|
|
438
494
|
itc_service_key_path = "/tmp/spaceship_itc_service_key.txt"
|
439
495
|
return File.read(itc_service_key_path) if File.exist?(itc_service_key_path)
|
440
496
|
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
#
|
446
|
-
# https://github.com/fastlane/fastlane/issues/4610
|
447
|
-
headers = { 'Accept-Encoding' => 'identity' }
|
448
|
-
# We need a service key from a JS file to properly auth
|
449
|
-
js = request(:get, "https://itunesconnect.apple.com/itc/static-resources/controllers/login_cntrl.js", nil, headers)
|
450
|
-
@service_key = js.body.match(/itcServiceKey = '(.*)'/)[1]
|
497
|
+
response = request(:get, "https://olympus.itunes.apple.com/v1/app/config?hostname=itunesconnect.apple.com")
|
498
|
+
@service_key = response.body["authServiceKey"].to_s
|
499
|
+
|
500
|
+
raise "Service key is empty" if @service_key.length == 0
|
451
501
|
|
452
502
|
# Cache the key locally
|
453
503
|
File.write(itc_service_key_path, @service_key)
|
@@ -43,59 +43,6 @@ module Spaceship
|
|
43
43
|
"https://itunesconnect.apple.com/WebObjects/iTunesConnect.woa/"
|
44
44
|
end
|
45
45
|
|
46
|
-
# @return (Array) A list of all available teams
|
47
|
-
def teams
|
48
|
-
user_details_data['associatedAccounts'].sort_by do |team|
|
49
|
-
[
|
50
|
-
team['contentProvider']['name'],
|
51
|
-
team['contentProvider']['contentProviderId']
|
52
|
-
]
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
# @return (String) The currently selected Team ID
|
57
|
-
def team_id
|
58
|
-
return @current_team_id if @current_team_id
|
59
|
-
|
60
|
-
if teams.count > 1
|
61
|
-
puts "The current user is in #{teams.count} teams. Pass a team ID or call `select_team` to choose a team. Using the first one for now."
|
62
|
-
end
|
63
|
-
@current_team_id ||= teams[0]['contentProvider']['contentProviderId']
|
64
|
-
end
|
65
|
-
|
66
|
-
# Set a new team ID which will be used from now on
|
67
|
-
def team_id=(team_id)
|
68
|
-
# First, we verify the team actually exists, because otherwise iTC would return the
|
69
|
-
# following confusing error message
|
70
|
-
#
|
71
|
-
# invalid content provider id
|
72
|
-
#
|
73
|
-
available_teams = teams.collect do |team|
|
74
|
-
(team["contentProvider"] || {})["contentProviderId"]
|
75
|
-
end
|
76
|
-
|
77
|
-
result = available_teams.find do |available_team_id|
|
78
|
-
team_id.to_s == available_team_id.to_s
|
79
|
-
end
|
80
|
-
|
81
|
-
unless result
|
82
|
-
raise ITunesConnectError.new, "Could not set team ID to '#{team_id}', only found the following available teams: #{available_teams.join(', ')}"
|
83
|
-
end
|
84
|
-
|
85
|
-
response = request(:post) do |req|
|
86
|
-
req.url "ra/v1/session/webSession"
|
87
|
-
req.body = {
|
88
|
-
contentProviderId: team_id,
|
89
|
-
dsId: user_detail_data.ds_id # https://github.com/fastlane/fastlane/issues/6711
|
90
|
-
}.to_json
|
91
|
-
req.headers['Content-Type'] = 'application/json'
|
92
|
-
end
|
93
|
-
|
94
|
-
handle_itc_response(response.body)
|
95
|
-
|
96
|
-
@current_team_id = team_id
|
97
|
-
end
|
98
|
-
|
99
46
|
# Shows a team selection for the user in the terminal. This should not be
|
100
47
|
# called on CI systems
|
101
48
|
def select_team
|
@@ -149,13 +96,6 @@ module Spaceship
|
|
149
96
|
end
|
150
97
|
end
|
151
98
|
|
152
|
-
# @return (Hash) Fetches all information of the currently used team
|
153
|
-
def team_information
|
154
|
-
teams.find do |t|
|
155
|
-
t['teamId'] == team_id
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
99
|
def send_login_request(user, password)
|
160
100
|
clear_user_cached_data
|
161
101
|
send_shared_login_request(user, password)
|
@@ -679,56 +619,6 @@ module Spaceship
|
|
679
619
|
Spaceship::Tunes::AppVersionRef.factory(data)
|
680
620
|
end
|
681
621
|
|
682
|
-
# Fetch the general information of the user, is used by various methods across spaceship
|
683
|
-
# Sample return value
|
684
|
-
# => {"associatedAccounts"=>
|
685
|
-
# [{"contentProvider"=>{"contentProviderId"=>11142800, "name"=>"Felix Krause", "contentProviderTypes"=>["Purple Software"]}, "roles"=>["Developer"], "lastLogin"=>1468784113000}],
|
686
|
-
# "sessionToken"=>{"dsId"=>"8501011116", "contentProviderId"=>18111111, "expirationDate"=>nil, "ipAddress"=>nil},
|
687
|
-
# "permittedActivities"=>
|
688
|
-
# {"EDIT"=>
|
689
|
-
# ["UserManagementSelf",
|
690
|
-
# "GameCenterTestData",
|
691
|
-
# "AppAddonCreation"],
|
692
|
-
# "REPORT"=>
|
693
|
-
# ["UserManagementSelf",
|
694
|
-
# "AppAddonCreation"],
|
695
|
-
# "VIEW"=>
|
696
|
-
# ["TestFlightAppExternalTesterManagement",
|
697
|
-
# ...
|
698
|
-
# "HelpGeneral",
|
699
|
-
# "HelpApplicationLoader"]},
|
700
|
-
# "preferredCurrencyCode"=>"EUR",
|
701
|
-
# "preferredCountryCode"=>nil,
|
702
|
-
# "countryOfOrigin"=>"AT",
|
703
|
-
# "isLocaleNameReversed"=>false,
|
704
|
-
# "feldsparToken"=>nil,
|
705
|
-
# "feldsparChannelName"=>nil,
|
706
|
-
# "hasPendingFeldsparBindingRequest"=>false,
|
707
|
-
# "isLegalUser"=>false,
|
708
|
-
# "userId"=>"1771111155",
|
709
|
-
# "firstname"=>"Detlef",
|
710
|
-
# "lastname"=>"Mueller",
|
711
|
-
# "isEmailInvalid"=>false,
|
712
|
-
# "hasContractInfo"=>false,
|
713
|
-
# "canEditITCUsersAndRoles"=>false,
|
714
|
-
# "canViewITCUsersAndRoles"=>true,
|
715
|
-
# "canEditIAPUsersAndRoles"=>false,
|
716
|
-
# "transporterEnabled"=>false,
|
717
|
-
# "contentProviderFeatures"=>["APP_SILOING", "PROMO_CODE_REDESIGN", ...],
|
718
|
-
# "contentProviderType"=>"Purple Software",
|
719
|
-
# "displayName"=>"Detlef",
|
720
|
-
# "contentProviderId"=>"18742800",
|
721
|
-
# "userFeatures"=>[],
|
722
|
-
# "visibility"=>true,
|
723
|
-
# "DYCVisibility"=>false,
|
724
|
-
# "contentProvider"=>"Felix Krause",
|
725
|
-
# "userName"=>"detlef@krausefx.com"}
|
726
|
-
def user_details_data
|
727
|
-
return @_cached_user_details if @_cached_user_details
|
728
|
-
r = request(:get, '/WebObjects/iTunesConnect.woa/ra/user/detail')
|
729
|
-
@_cached_user_details = parse_response(r, 'data')
|
730
|
-
end
|
731
|
-
|
732
622
|
# Fetches the User Detail information from ITC. This gets called often and almost never changes
|
733
623
|
# so we cache it
|
734
624
|
# @return [UserDetail] the response
|
@@ -6,9 +6,7 @@ module Spaceship
|
|
6
6
|
|
7
7
|
r = request(:get) do |req|
|
8
8
|
req.url "https://idmsa.apple.com/appleauth/auth"
|
9
|
-
req
|
10
|
-
req.headers["X-Apple-Id-Session-Id"] = @x_apple_id_session_id
|
11
|
-
req.headers["Accept"] = "application/json"
|
9
|
+
update_request_headers(req)
|
12
10
|
end
|
13
11
|
|
14
12
|
if r.body.kind_of?(Hash) && r.body["trustedDevices"].kind_of?(Array)
|
@@ -66,11 +64,10 @@ module Spaceship
|
|
66
64
|
# Send securityCode back to server to get a valid session
|
67
65
|
r = request(:post) do |req|
|
68
66
|
req.url "https://idmsa.apple.com/appleauth/auth/verify/trusteddevice/securitycode"
|
69
|
-
req.headers["Accept"] = "application/json"
|
70
67
|
req.headers['Content-Type'] = 'application/json'
|
71
|
-
req.headers["scnt"] = @scnt
|
72
|
-
req.headers["X-Apple-Id-Session-Id"] = @x_apple_id_session_id
|
73
68
|
req.body = { "securityCode" => { "code" => code.to_s } }.to_json
|
69
|
+
|
70
|
+
update_request_headers(req)
|
74
71
|
end
|
75
72
|
|
76
73
|
# we use `Spaceship::TunesClient.new.handle_itc_response`
|
@@ -121,9 +118,7 @@ module Spaceship
|
|
121
118
|
# Request Token
|
122
119
|
r = request(:put) do |req|
|
123
120
|
req.url "https://idmsa.apple.com/appleauth/auth/verify/device/#{device_id}/securitycode"
|
124
|
-
req
|
125
|
-
req.headers["scnt"] = @scnt
|
126
|
-
req.headers["X-Apple-Id-Session-Id"] = @x_apple_id_session_id
|
121
|
+
update_request_headers(req)
|
127
122
|
end
|
128
123
|
|
129
124
|
# we use `Spaceship::TunesClient.new.handle_itc_response`
|
@@ -137,11 +132,10 @@ module Spaceship
|
|
137
132
|
# Send token back to server to get a valid session
|
138
133
|
r = request(:post) do |req|
|
139
134
|
req.url "https://idmsa.apple.com/appleauth/auth/verify/device/#{device_id}/securitycode"
|
140
|
-
req.headers["Accept"] = "application/json"
|
141
|
-
req.headers["scnt"] = @scnt
|
142
|
-
req.headers["X-Apple-Id-Session-Id"] = @x_apple_id_session_id
|
143
135
|
req.body = { "code" => code.to_s }.to_json
|
144
136
|
req.headers['Content-Type'] = 'application/json'
|
137
|
+
|
138
|
+
update_request_headers(req)
|
145
139
|
end
|
146
140
|
|
147
141
|
begin
|
@@ -193,8 +187,8 @@ module Spaceship
|
|
193
187
|
|
194
188
|
request(:get) do |req|
|
195
189
|
req.url "https://idmsa.apple.com/appleauth/auth/2sv/trust"
|
196
|
-
|
197
|
-
req
|
190
|
+
|
191
|
+
update_request_headers(req)
|
198
192
|
end
|
199
193
|
# This request will fail if the user isn't added to a team on iTC
|
200
194
|
# However we don't really care, this request will still return the
|
@@ -202,5 +196,14 @@ module Spaceship
|
|
202
196
|
|
203
197
|
self.store_cookie
|
204
198
|
end
|
199
|
+
|
200
|
+
# Responsible for setting all required header attributes for the requests
|
201
|
+
# to succeed
|
202
|
+
def update_request_headers(req)
|
203
|
+
req.headers["X-Apple-Id-Session-Id"] = @x_apple_id_session_id
|
204
|
+
req.headers["X-Apple-Widget-Key"] = self.itc_service_key
|
205
|
+
req.headers["Accept"] = "application/json"
|
206
|
+
req.headers["scnt"] = @scnt
|
207
|
+
end
|
205
208
|
end
|
206
209
|
end
|