fastlane 2.108.0 → 2.109.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +76 -76
- data/deliver/lib/deliver/app_screenshot.rb +22 -1
- data/fastlane/lib/fastlane/action_collector.rb +1 -22
- data/fastlane/lib/fastlane/actions/appetize.rb +20 -3
- data/fastlane/lib/fastlane/actions/docs/build_ios_app.md +12 -9
- data/fastlane/lib/fastlane/actions/pod_lib_lint.rb +25 -16
- data/fastlane/lib/fastlane/actions/pod_push.rb +1 -1
- data/fastlane/lib/fastlane/actions/puts.rb +1 -1
- data/fastlane/lib/fastlane/actions/set_github_release.rb +1 -0
- data/fastlane/lib/fastlane/actions/testfairy.rb +11 -5
- data/fastlane/lib/fastlane/fast_file.rb +9 -6
- data/fastlane/lib/fastlane/helper/adb_helper.rb +3 -3
- data/fastlane/lib/fastlane/helper/crashlytics_helper.rb +5 -5
- data/fastlane/lib/fastlane/version.rb +1 -1
- data/fastlane/swift/Deliverfile.swift +1 -1
- data/fastlane/swift/Fastlane.swift +16 -6
- data/fastlane/swift/Gymfile.swift +1 -1
- data/fastlane/swift/Matchfile.swift +1 -1
- data/fastlane/swift/Precheckfile.swift +1 -1
- data/fastlane/swift/Scanfile.swift +1 -1
- data/fastlane/swift/Screengrabfile.swift +1 -1
- data/fastlane/swift/Snapshotfile.swift +1 -1
- data/fastlane_core/lib/fastlane_core.rb +0 -1
- data/fastlane_core/lib/fastlane_core/configuration/configuration.rb +2 -2
- data/fastlane_core/lib/fastlane_core/project.rb +9 -11
- data/match/lib/match/encryption.rb +33 -9
- data/match/lib/match/runner.rb +15 -3
- data/match/lib/match/spaceship_ensure.rb +2 -5
- data/match/lib/match/storage.rb +29 -7
- data/match/lib/match/storage/git_storage.rb +30 -48
- data/match/lib/match/storage/interface.rb +39 -1
- data/precheck/lib/precheck/rules/other_platforms_rule.rb +4 -1
- data/scan/lib/scan/error_handler.rb +8 -1
- data/sigh/lib/assets/resign.sh +39 -63
- data/snapshot/lib/snapshot/reports_generator.rb +1 -0
- data/spaceship/lib/spaceship/client.rb +174 -58
- data/spaceship/lib/spaceship/commands_generator.rb +1 -0
- data/spaceship/lib/spaceship/du/du_client.rb +18 -12
- data/spaceship/lib/spaceship/spaceauth_runner.rb +1 -1
- data/spaceship/lib/spaceship/tunes/app_submission.rb +2 -1
- data/spaceship/lib/spaceship/tunes/device_type.rb +1 -1
- data/spaceship/lib/spaceship/tunes/tunes_client.rb +5 -2
- data/spaceship/lib/spaceship/{two_step_client.rb → two_step_or_factor_client.rb} +65 -96
- data/supply/lib/supply/options.rb +17 -3
- data/supply/lib/supply/uploader.rb +12 -5
- metadata +17 -19
- data/deliver/lib/deliver/.app_screenshot.rb.swp +0 -0
- data/fastlane_core/lib/fastlane_core/tool_collector.rb +0 -304
@@ -92,6 +92,7 @@ module Snapshot
|
|
92
92
|
'iPad Pro (9.7-inch)' => 'iPad Pro (9.7-inch)',
|
93
93
|
'iPad Pro (9.7 inch)' => 'iPad Pro (9.7-inch)', # iOS 10.3.1 simulator
|
94
94
|
'iPad Pro (10.5-inch)' => 'iPad Pro (10.5-inch)',
|
95
|
+
'iPad Pro (11-inch)' => 'iPad Pro (11-inch)',
|
95
96
|
'iPad Pro (12.9-inch) (2nd generation)' => 'iPad Pro (12.9-inch) (2nd generation)',
|
96
97
|
'iPad Pro (12.9-inch)' => 'iPad Pro (12.9-inch)',
|
97
98
|
'iPad Pro (12.9 inch)' => 'iPad Pro (12.9-inch)', # iOS 10.3.1 simulator
|
@@ -4,6 +4,7 @@ require 'faraday_middleware'
|
|
4
4
|
require 'logger'
|
5
5
|
require 'tmpdir'
|
6
6
|
require 'cgi'
|
7
|
+
require 'tempfile'
|
7
8
|
|
8
9
|
require 'fastlane/version'
|
9
10
|
require_relative 'babosa_fix'
|
@@ -53,32 +54,14 @@ module Spaceship
|
|
53
54
|
GatewayTimeoutError = Spaceship::GatewayTimeoutError
|
54
55
|
InternalServerError = Spaceship::InternalServerError
|
55
56
|
|
56
|
-
# Authenticates with Apple's web services. This method has to be called once
|
57
|
-
# to generate a valid session. The session will automatically be used from then
|
58
|
-
# on.
|
59
|
-
#
|
60
|
-
# This method will automatically use the username from the Appfile (if available)
|
61
|
-
# and fetch the password from the Keychain (if available)
|
62
|
-
#
|
63
|
-
# @param user (String) (optional): The username (usually the email address)
|
64
|
-
# @param password (String) (optional): The password
|
65
|
-
#
|
66
|
-
# @raise InvalidUserCredentialsError: raised if authentication failed
|
67
|
-
#
|
68
|
-
# @return (Spaceship::Client) The client the login method was called for
|
69
|
-
def self.login(user = nil, password = nil)
|
70
|
-
instance = self.new
|
71
|
-
if instance.login(user, password)
|
72
|
-
instance
|
73
|
-
else
|
74
|
-
raise InvalidUserCredentialsError.new, "Invalid User Credentials"
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
57
|
def self.hostname
|
79
58
|
raise "You must implement self.hostname"
|
80
59
|
end
|
81
60
|
|
61
|
+
#####################################################
|
62
|
+
# @!group Teams + User
|
63
|
+
#####################################################
|
64
|
+
|
82
65
|
# @return (Array) A list of all available teams
|
83
66
|
def teams
|
84
67
|
user_details_data['associatedAccounts'].sort_by do |team|
|
@@ -198,6 +181,10 @@ module Spaceship
|
|
198
181
|
(team_information || {})['name']
|
199
182
|
end
|
200
183
|
|
184
|
+
#####################################################
|
185
|
+
# @!group Client Init
|
186
|
+
#####################################################
|
187
|
+
|
201
188
|
# Instantiates a client but with a cookie derived from another client.
|
202
189
|
#
|
203
190
|
# HACK: since the `@cookie` is not exposed, we use this hacky way of sharing the instance.
|
@@ -238,6 +225,10 @@ module Spaceship
|
|
238
225
|
end
|
239
226
|
end
|
240
227
|
|
228
|
+
#####################################################
|
229
|
+
# @!group Request Logger
|
230
|
+
#####################################################
|
231
|
+
|
241
232
|
# The logger in which all requests are logged
|
242
233
|
# /tmp/spaceship[time]_[pid].log by default
|
243
234
|
def logger
|
@@ -251,13 +242,18 @@ module Spaceship
|
|
251
242
|
end
|
252
243
|
|
253
244
|
@logger.formatter = proc do |severity, datetime, progname, msg|
|
254
|
-
|
245
|
+
severity = format('%-5.5s', severity)
|
246
|
+
"#{severity} [#{datetime.strftime('%H:%M:%S')}]: #{msg}\n"
|
255
247
|
end
|
256
248
|
end
|
257
249
|
|
258
250
|
@logger
|
259
251
|
end
|
260
252
|
|
253
|
+
#####################################################
|
254
|
+
# @!group Session Cookie
|
255
|
+
#####################################################
|
256
|
+
|
261
257
|
##
|
262
258
|
# Return the session cookie.
|
263
259
|
#
|
@@ -331,6 +327,28 @@ module Spaceship
|
|
331
327
|
# @!group Login and Team Selection
|
332
328
|
#####################################################
|
333
329
|
|
330
|
+
# Authenticates with Apple's web services. This method has to be called once
|
331
|
+
# to generate a valid session. The session will automatically be used from then
|
332
|
+
# on.
|
333
|
+
#
|
334
|
+
# This method will automatically use the username from the Appfile (if available)
|
335
|
+
# and fetch the password from the Keychain (if available)
|
336
|
+
#
|
337
|
+
# @param user (String) (optional): The username (usually the email address)
|
338
|
+
# @param password (String) (optional): The password
|
339
|
+
#
|
340
|
+
# @raise InvalidUserCredentialsError: raised if authentication failed
|
341
|
+
#
|
342
|
+
# @return (Spaceship::Client) The client the login method was called for
|
343
|
+
def self.login(user = nil, password = nil)
|
344
|
+
instance = self.new
|
345
|
+
if instance.login(user, password)
|
346
|
+
instance
|
347
|
+
else
|
348
|
+
raise InvalidUserCredentialsError.new, "Invalid User Credentials"
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
334
352
|
# Authenticates with Apple's web services. This method has to be called once
|
335
353
|
# to generate a valid session. The session will automatically be used from then
|
336
354
|
# on.
|
@@ -348,6 +366,8 @@ module Spaceship
|
|
348
366
|
if user.to_s.empty? || password.to_s.empty?
|
349
367
|
require 'credentials_manager/account_manager'
|
350
368
|
|
369
|
+
puts("Reading keychain entry, because either user or password were empty") if Spaceship::Globals.verbose?
|
370
|
+
|
351
371
|
keychain_entry = CredentialsManager::AccountManager.new(user: user, password: password)
|
352
372
|
user ||= keychain_entry.user
|
353
373
|
password = keychain_entry.password
|
@@ -360,7 +380,7 @@ module Spaceship
|
|
360
380
|
self.user = user
|
361
381
|
@password = password
|
362
382
|
begin
|
363
|
-
do_login(user, password)
|
383
|
+
do_login(user, password) # calls `send_login_request` in sub class (which then will redirect back here to `send_shared_login_request`, below)
|
364
384
|
rescue InvalidUserCredentialsError => ex
|
365
385
|
raise ex unless keychain_entry
|
366
386
|
|
@@ -374,20 +394,19 @@ module Spaceship
|
|
374
394
|
|
375
395
|
# This method is used for both the Apple Dev Portal and App Store Connect
|
376
396
|
# This will also handle 2 step verification
|
397
|
+
#
|
398
|
+
# It is called in `send_login_request` of sub classes (which the method `login`, above, transferred over to via `do_login`)
|
377
399
|
def send_shared_login_request(user, password)
|
378
|
-
# Check if we have a cached/valid session
|
379
|
-
# Fixes
|
380
|
-
# - https://github.com/fastlane/fastlane/issues/10812
|
381
|
-
# - https://github.com/fastlane/fastlane/issues/10793
|
400
|
+
# Check if we have a cached/valid session
|
382
401
|
#
|
383
|
-
#
|
384
|
-
#
|
385
|
-
# but unfortunately
|
386
|
-
#
|
387
|
-
#
|
388
|
-
# By loading existing sessions and checking if they're valid, we're sending less login requests
|
402
|
+
# Background:
|
403
|
+
# December 4th 2017 Apple introduced a rate limit - which is of course fine by itself -
|
404
|
+
# but unfortunately also rate limits successful logins. If you call multiple tools in a
|
405
|
+
# lane (e.g. call match 5 times), this would lock you out of the account for a while.
|
406
|
+
# By loading existing sessions and checking if they're valid, we're sending less login requests.
|
389
407
|
# More context on why this change was necessary https://github.com/fastlane/fastlane/pull/11108
|
390
408
|
#
|
409
|
+
# If there was a successful manual login before, we have a session on disk
|
391
410
|
if load_session_from_file
|
392
411
|
# Check if the session is still valid here
|
393
412
|
begin
|
@@ -403,12 +422,24 @@ module Spaceship
|
|
403
422
|
# which is common, as the session automatically invalidates after x hours (we don't know x)
|
404
423
|
# In this case we don't actually care about the exact exception, and why it was failing
|
405
424
|
# because either way, we'll have to do a fresh login, where we do the actual error handling
|
425
|
+
puts("Available session is not valid any more. Continuing with normal login.")
|
406
426
|
end
|
407
427
|
end
|
408
|
-
|
409
|
-
#
|
410
|
-
|
411
|
-
|
428
|
+
#
|
429
|
+
# The user can pass the session via environment variable (Mainly used in CI environments)
|
430
|
+
if load_session_from_env
|
431
|
+
# see above
|
432
|
+
begin
|
433
|
+
# see above
|
434
|
+
return true if fetch_olympus_session
|
435
|
+
rescue
|
436
|
+
puts("Session loaded from environment variable is not valid. Continuing with normal login.")
|
437
|
+
# see above
|
438
|
+
end
|
439
|
+
end
|
440
|
+
#
|
441
|
+
# After this point, we sure have no valid session any more and have to create a new one
|
442
|
+
#
|
412
443
|
|
413
444
|
data = {
|
414
445
|
accountName: user,
|
@@ -458,9 +489,9 @@ module Spaceship
|
|
458
489
|
fetch_olympus_session
|
459
490
|
return response
|
460
491
|
when 409
|
461
|
-
# 2 factor is enabled for this account, first handle that
|
492
|
+
# 2 step/factor is enabled for this account, first handle that
|
493
|
+
handle_two_step_or_factor(response)
|
462
494
|
# and then get the olympus session
|
463
|
-
handle_two_step(response)
|
464
495
|
fetch_olympus_session
|
465
496
|
return true
|
466
497
|
else
|
@@ -525,6 +556,44 @@ module Spaceship
|
|
525
556
|
raise AppleTimeoutError.new, "Could not receive latest API key from App Store Connect, this might be a server issue."
|
526
557
|
end
|
527
558
|
|
559
|
+
#####################################################
|
560
|
+
# @!group Session
|
561
|
+
#####################################################
|
562
|
+
|
563
|
+
def load_session_from_file
|
564
|
+
if File.exist?(persistent_cookie_path)
|
565
|
+
puts("Loading session from '#{persistent_cookie_path}'") if Spaceship::Globals.verbose?
|
566
|
+
@cookie.load(persistent_cookie_path)
|
567
|
+
return true
|
568
|
+
end
|
569
|
+
return false
|
570
|
+
end
|
571
|
+
|
572
|
+
def load_session_from_env
|
573
|
+
return if self.class.spaceship_session_env.to_s.length == 0
|
574
|
+
puts("Loading session from environment variable") if Spaceship::Globals.verbose?
|
575
|
+
|
576
|
+
file = Tempfile.new('cookie.yml')
|
577
|
+
file.write(self.class.spaceship_session_env.gsub("\\n", "\n"))
|
578
|
+
file.close
|
579
|
+
|
580
|
+
begin
|
581
|
+
@cookie.load(file.path)
|
582
|
+
rescue => ex
|
583
|
+
puts("Error loading session from environment")
|
584
|
+
puts("Make sure to pass the session in a valid format")
|
585
|
+
raise ex
|
586
|
+
ensure
|
587
|
+
file.unlink
|
588
|
+
end
|
589
|
+
end
|
590
|
+
|
591
|
+
# Fetch the session cookie from the environment
|
592
|
+
# (if exists)
|
593
|
+
def self.spaceship_session_env
|
594
|
+
ENV["FASTLANE_SESSION"] || ENV["SPACESHIP_SESSION"]
|
595
|
+
end
|
596
|
+
|
528
597
|
#####################################################
|
529
598
|
# @!group Helpers
|
530
599
|
#####################################################
|
@@ -533,21 +602,35 @@ module Spaceship
|
|
533
602
|
return yield
|
534
603
|
rescue \
|
535
604
|
Faraday::Error::ConnectionFailed,
|
536
|
-
Faraday::Error::TimeoutError,
|
537
|
-
Faraday::ParsingError, # <h2>Internal Server Error</h2> with content type json
|
605
|
+
Faraday::Error::TimeoutError, # New Faraday version: Faraday::TimeoutError => ex
|
538
606
|
AppleTimeoutError,
|
539
|
-
GatewayTimeoutError
|
540
|
-
InternalServerError => ex # New Faraday version: Faraday::TimeoutError => ex
|
607
|
+
GatewayTimeoutError => ex
|
541
608
|
tries -= 1
|
542
609
|
unless tries.zero?
|
543
|
-
|
610
|
+
msg = "Timeout received: '#{ex.class}', '#{ex.message}'. Retrying after 3 seconds (remaining: #{tries})..."
|
611
|
+
puts(msg) if Spaceship::Globals.verbose?
|
612
|
+
logger.warn(msg)
|
613
|
+
|
614
|
+
sleep(3) unless Object.const_defined?("SpecHelper")
|
615
|
+
retry
|
616
|
+
end
|
617
|
+
raise ex # re-raise the exception
|
618
|
+
rescue \
|
619
|
+
Faraday::ParsingError, # <h2>Internal Server Error</h2> with content type json
|
620
|
+
InternalServerError => ex
|
621
|
+
tries -= 1
|
622
|
+
unless tries.zero?
|
623
|
+
msg = "Internal Server Error received: '#{ex.class}', '#{ex.message}'. Retrying after 3 seconds (remaining: #{tries})..."
|
624
|
+
puts(msg) if Spaceship::Globals.verbose?
|
625
|
+
logger.warn(msg)
|
626
|
+
|
544
627
|
sleep(3) unless Object.const_defined?("SpecHelper")
|
545
628
|
retry
|
546
629
|
end
|
547
630
|
raise ex # re-raise the exception
|
548
631
|
rescue UnauthorizedAccessError => ex
|
549
632
|
if @loggedin && !(tries -= 1).zero?
|
550
|
-
msg = "Auth error received: '#{ex.message}'. Login in again then retrying after 3 seconds (remaining: #{tries})..."
|
633
|
+
msg = "Auth error received: '#{ex.class}', '#{ex.message}'. Login in again then retrying after 3 seconds (remaining: #{tries})..."
|
551
634
|
puts(msg) if Spaceship::Globals.verbose?
|
552
635
|
logger.warn(msg)
|
553
636
|
|
@@ -572,7 +655,7 @@ module Spaceship
|
|
572
655
|
headers['User-Agent'] = USER_AGENT
|
573
656
|
|
574
657
|
# Before encoding the parameters, log them
|
575
|
-
log_request(method, url_or_path, params)
|
658
|
+
log_request(method, url_or_path, params, headers, &block)
|
576
659
|
|
577
660
|
# form-encode the params only if there are params, and the block is not supplied.
|
578
661
|
# this is so that certain requests can be made using the block for more control
|
@@ -586,8 +669,6 @@ module Spaceship
|
|
586
669
|
send_request(method, url_or_path, params, headers, &block)
|
587
670
|
end
|
588
671
|
|
589
|
-
log_response(method, url_or_path, response)
|
590
|
-
|
591
672
|
return response
|
592
673
|
end
|
593
674
|
|
@@ -602,9 +683,12 @@ module Spaceship
|
|
602
683
|
|
603
684
|
content = expected_key ? response.body[expected_key] : response.body
|
604
685
|
end
|
686
|
+
|
687
|
+
# if content (filled with whole body or just expected_key) is missing
|
605
688
|
if content.nil?
|
606
689
|
detect_most_common_errors_and_raise_exceptions(response.body) if response.body
|
607
690
|
raise UnexpectedResponse, response.body
|
691
|
+
# else if it is a hash and `resultString` includes `NotAllowed`
|
608
692
|
elsif content.kind_of?(Hash) && (content["resultString"] || "").include?("NotAllowed")
|
609
693
|
# example content when doing a Developer Portal action with not enough permission
|
610
694
|
# => {"responseId"=>"e5013d83-c5cb-4ba0-bb62-734a8d56007f",
|
@@ -616,7 +700,7 @@ module Spaceship
|
|
616
700
|
# "userLocale"=>"en_US",
|
617
701
|
# "requestUrl"=>"https://developer.apple.com/services-account/QH65B2/account/ios/certificate/downloadCertificateContent.action",
|
618
702
|
# "httpCode"=>200}
|
619
|
-
|
703
|
+
raise_insufficient_permission_error!(additional_error_string: content["userString"])
|
620
704
|
else
|
621
705
|
store_csrf_tokens(response)
|
622
706
|
content
|
@@ -626,11 +710,11 @@ module Spaceship
|
|
626
710
|
def detect_most_common_errors_and_raise_exceptions(body)
|
627
711
|
# Check if the failure is due to missing permissions (App Store Connect)
|
628
712
|
if body["messages"] && body["messages"]["error"].include?("Forbidden")
|
629
|
-
|
713
|
+
raise_insufficient_permission_error!
|
630
714
|
elsif body["messages"] && body["messages"]["error"].include?("insufficient privileges")
|
631
715
|
# Passing a specific `caller_location` here to make sure we return the correct method
|
632
716
|
# With the default location the error would say that `parse_response` is the caller
|
633
|
-
|
717
|
+
raise_insufficient_permission_error!(caller_location: 3)
|
634
718
|
elsif body.to_s.include?("Internal Server Error - Read")
|
635
719
|
raise InternalServerError, "Received an internal server error from App Store Connect / Developer Portal, please try again later"
|
636
720
|
elsif body.to_s.include?("Gateway Timeout - In read")
|
@@ -641,7 +725,7 @@ module Spaceship
|
|
641
725
|
end
|
642
726
|
|
643
727
|
# This also gets called from subclasses
|
644
|
-
def
|
728
|
+
def raise_insufficient_permission_error!(additional_error_string: nil, caller_location: 2)
|
645
729
|
# get the method name of the request that failed
|
646
730
|
# `block in` is used very often for requests when surrounded for paging or retrying blocks
|
647
731
|
# The ! is part of some methods when they modify or delete a resource, so we don't want to show it
|
@@ -679,19 +763,48 @@ module Spaceship
|
|
679
763
|
end
|
680
764
|
end
|
681
765
|
|
682
|
-
def log_request(method, url, params)
|
766
|
+
def log_request(method, url, params, headers = nil, &block)
|
767
|
+
url ||= extract_key_from_block('url', &block)
|
768
|
+
body = extract_key_from_block('body', &block)
|
769
|
+
if body
|
770
|
+
begin
|
771
|
+
body = JSON.parse(body)
|
772
|
+
body['password'] = '***' if body.kind_of?(Hash) && body.key?("password")
|
773
|
+
rescue JSON::ParserError
|
774
|
+
# no json, no password
|
775
|
+
end
|
776
|
+
end
|
683
777
|
params_to_log = Hash(params).dup # to also work with nil
|
684
778
|
params_to_log.delete(:accountPassword) # Dev Portal
|
685
779
|
params_to_log.delete(:theAccountPW) # iTC
|
686
780
|
params_to_log = params_to_log.collect do |key, value|
|
687
781
|
"{#{key}: #{value}}"
|
688
782
|
end
|
689
|
-
logger.info(">> #{method.upcase}
|
783
|
+
logger.info(">> #{method.upcase} #{url}: #{body.to_json} #{params_to_log.join(', ')}")
|
690
784
|
end
|
691
785
|
|
692
|
-
def log_response(method, url, response)
|
786
|
+
def log_response(method, url, response, headers = nil, &block)
|
787
|
+
url ||= extract_key_from_block('url', &block)
|
693
788
|
body = response.body.kind_of?(String) ? response.body.force_encoding(Encoding::UTF_8) : response.body
|
694
|
-
logger.debug("<< #{method.upcase}
|
789
|
+
logger.debug("<< #{method.upcase} #{url}: #{response.status} #{body}")
|
790
|
+
end
|
791
|
+
|
792
|
+
def extract_key_from_block(key, &block)
|
793
|
+
if block_given?
|
794
|
+
obj = Object.new
|
795
|
+
class << obj
|
796
|
+
attr_accessor :body, :headers, :params, :url
|
797
|
+
# rubocop: disable Style/TrivialAccessors
|
798
|
+
# the block calls `url` (not `url=`) so need to define `url` method
|
799
|
+
def url(url)
|
800
|
+
@url = url
|
801
|
+
end
|
802
|
+
# rubocop: enable Style/TrivialAccessors
|
803
|
+
end
|
804
|
+
obj.headers = {}
|
805
|
+
yield(obj)
|
806
|
+
obj.instance_variable_get("@#{key}")
|
807
|
+
end
|
695
808
|
end
|
696
809
|
|
697
810
|
# Actually sends the request to the remote server
|
@@ -699,6 +812,8 @@ module Spaceship
|
|
699
812
|
def send_request(method, url_or_path, params, headers, &block)
|
700
813
|
with_retry do
|
701
814
|
response = @client.send(method, url_or_path, params, headers, &block)
|
815
|
+
log_response(method, url_or_path, response, headers, &block)
|
816
|
+
|
702
817
|
resp_hash = response.to_hash
|
703
818
|
if resp_hash[:status] == 401
|
704
819
|
msg = "Auth lost"
|
@@ -709,6 +824,7 @@ module Spaceship
|
|
709
824
|
if response.body.to_s.include?("<title>302 Found</title>")
|
710
825
|
raise AppleTimeoutError.new, "Apple 302 detected - this might be temporary server error, check https://developer.apple.com/system-status/ to see if there is a known downtime"
|
711
826
|
end
|
827
|
+
|
712
828
|
return response
|
713
829
|
end
|
714
830
|
end
|
@@ -738,4 +854,4 @@ module Spaceship
|
|
738
854
|
# rubocop:enable Metrics/ClassLength
|
739
855
|
end
|
740
856
|
|
741
|
-
require 'spaceship/
|
857
|
+
require 'spaceship/two_step_or_factor_client'
|
@@ -24,6 +24,7 @@ module Spaceship
|
|
24
24
|
program :help_formatter, :compact
|
25
25
|
|
26
26
|
global_option('-u', '--user USERNAME', 'Specify the Apple ID you want to log in with')
|
27
|
+
global_option('--verbose') { FastlaneCore::Globals.verbose = true }
|
27
28
|
|
28
29
|
command :playground do |c|
|
29
30
|
c.syntax = 'fastlane spaceship playground'
|
@@ -101,17 +101,19 @@ module Spaceship
|
|
101
101
|
def picture_type_map
|
102
102
|
# rubocop:enable Layout/ExtraSpacing
|
103
103
|
{
|
104
|
-
watch: "MZPFT.SortedN27ScreenShot",
|
105
|
-
watchSeries4: "MZPFT.SortedN131ScreenShot",
|
106
104
|
ipad: "MZPFT.SortedTabletScreenShot",
|
107
|
-
ipadPro: "MZPFT.SortedJ99ScreenShot",
|
108
105
|
ipad105: "MZPFT.SortedJ207ScreenShot",
|
106
|
+
ipadPro: "MZPFT.SortedJ99ScreenShot",
|
107
|
+
ipadPro11: "MZPFT.SortedJ317ScreenShot",
|
108
|
+
ipadPro129: "MZPFT.SortedJ320ScreenShot",
|
109
|
+
iphone35: "MZPFT.SortedScreenShot",
|
110
|
+
iphone4: "MZPFT.SortedN41ScreenShot",
|
109
111
|
iphone6: "MZPFT.SortedN61ScreenShot",
|
110
112
|
iphone6Plus: "MZPFT.SortedN56ScreenShot",
|
111
113
|
iphone58: "MZPFT.SortedD22ScreenShot",
|
112
114
|
iphone65: "MZPFT.SortedD33ScreenShot",
|
113
|
-
|
114
|
-
|
115
|
+
watch: "MZPFT.SortedN27ScreenShot",
|
116
|
+
watchSeries4: "MZPFT.SortedN131ScreenShot",
|
115
117
|
appleTV: "MZPFT.SortedATVScreenShot",
|
116
118
|
desktop: "MZPFT.SortedDesktopScreenShot"
|
117
119
|
}
|
@@ -121,13 +123,15 @@ module Spaceship
|
|
121
123
|
# rubocop:enable Layout/ExtraSpacing
|
122
124
|
{
|
123
125
|
ipad: "MZPFT.SortedTabletMessagesScreenShot",
|
124
|
-
ipadPro: "MZPFT.SortedJ99MessagesScreenShot",
|
125
126
|
ipad105: "MZPFT.SortedJ207MessagesScreenShot",
|
127
|
+
ipadPro: "MZPFT.SortedJ99MessagesScreenShot",
|
128
|
+
ipadPro11: "MZPFT.SortedJ317MessagesScreenShot",
|
129
|
+
ipadPro129: "MZPFT.SortedJ320MessagesScreenShot",
|
130
|
+
iphone4: "MZPFT.SortedN41MessagesScreenShot",
|
126
131
|
iphone6: "MZPFT.SortedN61MessagesScreenShot",
|
127
132
|
iphone6Plus: "MZPFT.SortedN56MessagesScreenShot",
|
128
133
|
iphone58: "MZPFT.SortedD22MessagesScreenShot",
|
129
|
-
iphone65: "MZPFT.SortedD33MessagesScreenShot"
|
130
|
-
iphone4: "MZPFT.SortedN41MessagesScreenShot"
|
134
|
+
iphone65: "MZPFT.SortedD33MessagesScreenShot"
|
131
135
|
}
|
132
136
|
end
|
133
137
|
|
@@ -137,15 +141,17 @@ module Spaceship
|
|
137
141
|
watch: [[312, 390]],
|
138
142
|
watchSeries4: [[368, 448]],
|
139
143
|
ipad: [[1024, 748], [1024, 768], [2048, 1496], [2048, 1536], [768, 1004], [768, 1024], [1536, 2008], [1536, 2048]],
|
140
|
-
ipadPro: [[2048, 2732], [2732, 2048]],
|
141
144
|
ipad105: [[1668, 2224], [2224, 1668]],
|
145
|
+
ipadPro: [[2048, 2732], [2732, 2048]],
|
146
|
+
ipadPro11: [[1668, 2388], [2388, 1668]],
|
147
|
+
ipadPro129: [[2048, 2732], [2732, 2048]],
|
148
|
+
iphone35: [[640, 960], [640, 920], [960, 600], [960, 640]],
|
149
|
+
iphone4: [[640, 1096], [640, 1136], [1136, 600], [1136, 640]],
|
142
150
|
iphone6: [[750, 1334], [1334, 750]],
|
143
151
|
iphone6Plus: [[1242, 2208], [2208, 1242]],
|
144
152
|
iphone58: [[1125, 2436], [2436, 1125]],
|
145
153
|
iphone65: [[1242, 2688], [2688, 1242]],
|
146
|
-
|
147
|
-
iphone35: [[640, 960], [640, 920], [960, 600], [960, 640]],
|
148
|
-
appleTV: [[1920, 1080]],
|
154
|
+
appleTV: [[1920, 1080], [3840, 2160]],
|
149
155
|
desktop: [[1280, 800], [1440, 900], [2560, 1600], [2880, 1800]]
|
150
156
|
}
|
151
157
|
end
|