fastlane 2.164.0 → 2.169.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +80 -80
  3. data/cert/lib/cert/.options.rb.swp +0 -0
  4. data/cert/lib/cert/.runner.rb.swp +0 -0
  5. data/cert/lib/cert/options.rb +3 -3
  6. data/cert/lib/cert/runner.rb +2 -2
  7. data/deliver/lib/deliver/app_screenshot.rb +6 -2
  8. data/deliver/lib/deliver/loader.rb +136 -18
  9. data/deliver/lib/deliver/upload_metadata.rb +4 -10
  10. data/deliver/lib/deliver/upload_screenshots.rb +1 -64
  11. data/fastlane/lib/fastlane/actions/.download_dsyms.rb.swp +0 -0
  12. data/fastlane/lib/fastlane/actions/actions_helper.rb +1 -1
  13. data/fastlane/lib/fastlane/actions/add_git_tag.rb +9 -2
  14. data/fastlane/lib/fastlane/actions/appledoc.rb +1 -1
  15. data/fastlane/lib/fastlane/actions/docs/capture_ios_screenshots.md +4 -0
  16. data/fastlane/lib/fastlane/actions/docs/frame_screenshots.md +1 -1
  17. data/fastlane/lib/fastlane/actions/slather.rb +2 -2
  18. data/fastlane/lib/fastlane/actions/spm.rb +6 -0
  19. data/fastlane/lib/fastlane/actions/update_fastlane.rb +29 -8
  20. data/fastlane/lib/fastlane/actions/upload_to_app_store.rb +3 -3
  21. data/fastlane/lib/fastlane/actions/xcode_install.rb +8 -5
  22. data/fastlane/lib/fastlane/cli_tools_distributor.rb +2 -2
  23. data/fastlane/lib/fastlane/features.rb +1 -1
  24. data/fastlane/lib/fastlane/plugins/template/.rubocop.yml +1 -0
  25. data/fastlane/lib/fastlane/swift_fastlane_function.rb +1 -1
  26. data/fastlane/lib/fastlane/version.rb +1 -1
  27. data/fastlane/swift/Deliverfile.swift +1 -1
  28. data/fastlane/swift/DeliverfileProtocol.swift +1 -1
  29. data/fastlane/swift/Fastfile.swift +1 -1
  30. data/fastlane/swift/Fastlane.swift +56 -26
  31. data/fastlane/swift/Gymfile.swift +1 -1
  32. data/fastlane/swift/GymfileProtocol.swift +5 -1
  33. data/fastlane/swift/LaneFileProtocol.swift +2 -2
  34. data/fastlane/swift/MainProcess.swift +2 -0
  35. data/fastlane/swift/Matchfile.swift +1 -1
  36. data/fastlane/swift/MatchfileProtocol.swift +4 -4
  37. data/fastlane/swift/Precheckfile.swift +1 -1
  38. data/fastlane/swift/PrecheckfileProtocol.swift +1 -1
  39. data/fastlane/swift/Runner.swift +1 -1
  40. data/fastlane/swift/Scanfile.swift +1 -1
  41. data/fastlane/swift/ScanfileProtocol.swift +9 -1
  42. data/fastlane/swift/Screengrabfile.swift +1 -1
  43. data/fastlane/swift/ScreengrabfileProtocol.swift +1 -1
  44. data/fastlane/swift/Snapshotfile.swift +1 -1
  45. data/fastlane/swift/SnapshotfileProtocol.swift +1 -1
  46. data/fastlane/swift/SocketClient.swift +1 -1
  47. data/fastlane_core/lib/fastlane_core/cert_checker.rb +12 -7
  48. data/fastlane_core/lib/fastlane_core/helper.rb +10 -2
  49. data/fastlane_core/lib/fastlane_core/itunes_transporter.rb +3 -3
  50. data/fastlane_core/lib/fastlane_core/provisioning_profile.rb +3 -1
  51. data/fastlane_core/lib/fastlane_core/ui/disable_colors.rb +8 -0
  52. data/gym/lib/gym/code_signing_mapping.rb +1 -1
  53. data/gym/lib/gym/generators/build_command_generator.rb +1 -0
  54. data/gym/lib/gym/options.rb +7 -1
  55. data/match/lib/match/.options.rb.swp +0 -0
  56. data/match/lib/match/module.rb +1 -1
  57. data/match/lib/match/nuke.rb +9 -5
  58. data/match/lib/match/options.rb +2 -2
  59. data/pilot/lib/pilot/build_manager.rb +9 -3
  60. data/scan/lib/scan/detect_values.rb +3 -1
  61. data/scan/lib/scan/module.rb +4 -0
  62. data/scan/lib/scan/options.rb +16 -1
  63. data/scan/lib/scan/runner.rb +2 -2
  64. data/scan/lib/scan/test_command_generator.rb +1 -0
  65. data/{match/lib/match/.commands_generator.rb.swp → sigh/lib/sigh/.options.rb.swp} +0 -0
  66. data/sigh/lib/sigh/runner.rb +2 -2
  67. data/snapshot/lib/assets/SnapshotHelper.swift +5 -1
  68. data/snapshot/lib/snapshot/test_command_generator.rb +1 -1
  69. data/snapshot/lib/snapshot/test_command_generator_base.rb +3 -1
  70. data/snapshot/lib/snapshot/test_command_generator_xcode_8.rb +1 -1
  71. data/spaceship/lib/spaceship/client.rb +14 -0
  72. data/spaceship/lib/spaceship/connect_api.rb +2 -0
  73. data/spaceship/lib/spaceship/connect_api/client.rb +7 -4
  74. data/spaceship/lib/spaceship/connect_api/models/age_rating_declaration.rb +3 -2
  75. data/spaceship/lib/spaceship/connect_api/models/app.rb +139 -54
  76. data/spaceship/lib/spaceship/connect_api/models/app_info.rb +16 -10
  77. data/spaceship/lib/spaceship/connect_api/models/app_info_localization.rb +8 -4
  78. data/spaceship/lib/spaceship/connect_api/models/app_preview.rb +15 -11
  79. data/spaceship/lib/spaceship/connect_api/models/app_preview_set.rb +13 -9
  80. data/spaceship/lib/spaceship/connect_api/models/app_screenshot.rb +9 -7
  81. data/spaceship/lib/spaceship/connect_api/models/app_screenshot_set.rb +15 -11
  82. data/spaceship/lib/spaceship/connect_api/models/app_store_review_attachment.rb +7 -5
  83. data/spaceship/lib/spaceship/connect_api/models/app_store_review_detail.rb +6 -4
  84. data/spaceship/lib/spaceship/connect_api/models/app_store_version.rb +55 -36
  85. data/spaceship/lib/spaceship/connect_api/models/app_store_version_localization.rb +21 -14
  86. data/spaceship/lib/spaceship/connect_api/models/app_store_version_submission.rb +3 -2
  87. data/spaceship/lib/spaceship/connect_api/models/beta_app_review_submission.rb +3 -2
  88. data/spaceship/lib/spaceship/connect_api/models/beta_feedback.rb +6 -4
  89. data/spaceship/lib/spaceship/connect_api/models/beta_group.rb +12 -2
  90. data/spaceship/lib/spaceship/connect_api/models/beta_tester.rb +12 -8
  91. data/spaceship/lib/spaceship/connect_api/models/build.rb +24 -16
  92. data/spaceship/lib/spaceship/connect_api/models/build_delivery.rb +3 -2
  93. data/spaceship/lib/spaceship/connect_api/models/bundle_id.rb +9 -6
  94. data/spaceship/lib/spaceship/connect_api/models/bundle_id_capability.rb +6 -4
  95. data/spaceship/lib/spaceship/connect_api/models/certificate.rb +12 -8
  96. data/spaceship/lib/spaceship/connect_api/models/custom_app_organization.rb +43 -0
  97. data/spaceship/lib/spaceship/connect_api/models/custom_app_user.rb +41 -0
  98. data/spaceship/lib/spaceship/connect_api/models/device.rb +6 -4
  99. data/spaceship/lib/spaceship/connect_api/models/idfa_declaration.rb +6 -4
  100. data/spaceship/lib/spaceship/connect_api/models/profile.rb +12 -8
  101. data/spaceship/lib/spaceship/connect_api/models/reset_ratings_request.rb +3 -2
  102. data/spaceship/lib/spaceship/connect_api/models/sandbox_tester.rb +9 -6
  103. data/spaceship/lib/spaceship/connect_api/models/territory.rb +3 -2
  104. data/spaceship/lib/spaceship/connect_api/models/user.rb +6 -4
  105. data/spaceship/lib/spaceship/connect_api/models/user_invitation.rb +9 -6
  106. data/spaceship/lib/spaceship/connect_api/spaceship.rb +7 -4
  107. data/spaceship/lib/spaceship/connect_api/testflight/testflight.rb +12 -0
  108. data/spaceship/lib/spaceship/connect_api/tunes/tunes.rb +71 -0
  109. data/spaceship/lib/spaceship/errors.rb +19 -0
  110. data/spaceship/lib/spaceship/tunes/iap_detail.rb +1 -1
  111. data/spaceship/lib/spaceship/tunes/tunes_client.rb +2 -2
  112. data/spaceship/lib/spaceship/two_step_or_factor_client.rb +18 -6
  113. data/supply/lib/supply.rb +1 -1
  114. data/supply/lib/supply/options.rb +1 -1
  115. data/supply/lib/supply/uploader.rb +3 -2
  116. metadata +26 -22
  117. data/match/lib/match/.importer.rb.swp +0 -0
@@ -419,6 +419,15 @@ module Scan
419
419
  description: "Use only if you're a pro, use the other options instead",
420
420
  is_string: false,
421
421
  optional: true),
422
+ FastlaneCore::ConfigItem.new(key: :catalyst_platform,
423
+ env_name: "SCAN_CATALYST_PLATFORM",
424
+ description: "Platform to build when using a Catalyst enabled app. Valid values are: ios, macos",
425
+ type: String,
426
+ optional: true,
427
+ verify_block: proc do |value|
428
+ av = %w(ios macos)
429
+ UI.user_error!("Unsupported export_method '#{value}', must be: #{av}") unless av.include?(value)
430
+ end),
422
431
  FastlaneCore::ConfigItem.new(key: :custom_report_file_name,
423
432
  env_name: "SCAN_CUSTOM_REPORT_FILE_NAME",
424
433
  description: "Sets custom full report file name when generating a single report",
@@ -436,7 +445,13 @@ module Scan
436
445
  env_name: "SCAN_CLONED_SOURCE_PACKAGES_PATH",
437
446
  description: "Sets a custom path for Swift Package Manager dependencies",
438
447
  type: String,
439
- optional: true)
448
+ optional: true),
449
+ FastlaneCore::ConfigItem.new(key: :use_system_scm,
450
+ env_name: "SCAN_USE_SYSTEM_SCM",
451
+ description: "Lets xcodebuild use system's scm configuration",
452
+ optional: true,
453
+ type: Boolean,
454
+ default_value: false)
440
455
 
441
456
  ]
442
457
  end
@@ -83,6 +83,8 @@ module Scan
83
83
  end
84
84
 
85
85
  def handle_results(tests_exit_status)
86
+ return if Scan.config[:disable_xcpretty]
87
+
86
88
  result = TestResultParser.new.parse_result(test_results)
87
89
  SlackPoster.new.run(result)
88
90
 
@@ -144,8 +146,6 @@ module Scan
144
146
  end
145
147
 
146
148
  def test_results
147
- return if Scan.config[:disable_xcpretty]
148
-
149
149
  temp_junit_report = Scan.cache[:temp_junit_report]
150
150
  return File.read(temp_junit_report) if temp_junit_report && File.file?(temp_junit_report)
151
151
 
@@ -32,6 +32,7 @@ module Scan
32
32
 
33
33
  options = []
34
34
  options += project_path_array unless config[:xctestrun]
35
+ options << "-scmProvider system" if config[:use_system_scm]
35
36
  options << "-sdk '#{config[:sdk]}'" if config[:sdk]
36
37
  options << destination # generated in `detect_values`
37
38
  options << "-toolchain '#{config[:toolchain]}'" if config[:toolchain]
@@ -303,7 +303,7 @@ module Sigh
303
303
  end
304
304
 
305
305
  if Sigh.config[:cert_owner_name]
306
- next unless c.owner_name.strip == Sigh.config[:cert_owner_name].strip
306
+ next unless c.display_name.strip == Sigh.config[:cert_owner_name].strip
307
307
  end
308
308
 
309
309
  true
@@ -327,7 +327,7 @@ module Sigh
327
327
  UI.important("Found more than one code signing identity. Choosing the first one. Check out `fastlane sigh --help` to see all available options.")
328
328
  UI.important("Available Code Signing Identities for current filters:")
329
329
  certificates.each do |c|
330
- str = ["\t- Name:", c.owner_name, "- ID:", c.id + " - Expires", c.expires.strftime("%d/%m/%Y")].join(" ")
330
+ str = ["\t- Name:", c.display_name, "- ID:", c.id + " - Expires", c.expires.strftime("%d/%m/%Y")].join(" ")
331
331
  UI.message(str.green)
332
332
  end
333
333
  end
@@ -180,7 +180,11 @@ open class Snapshot: NSObject {
180
180
  simulator = regex.stringByReplacingMatches(in: simulator, range: range, withTemplate: "")
181
181
 
182
182
  let path = screenshotsDir.appendingPathComponent("\(simulator)-\(name).png")
183
- try image.pngData()?.write(to: path, options: .atomic)
183
+ #if swift(<5.0)
184
+ UIImagePNGRepresentation(image)?.write(to: path, options: .atomic)
185
+ #else
186
+ try image.pngData()?.write(to: path, options: .atomic)
187
+ #endif
184
188
  } catch let error {
185
189
  NSLog("Problem writing screenshot: \(name) to \(screenshotsDir)/\(simulator)-\(name).png")
186
190
  NSLog(error.localizedDescription)
@@ -13,7 +13,7 @@ module Snapshot
13
13
  parts << "xcodebuild"
14
14
  parts += options(language, locale)
15
15
  parts += destination(devices)
16
- parts += build_settings
16
+ parts += build_settings(language, locale)
17
17
  parts += actions
18
18
  parts += suffix
19
19
  parts += pipe(log_path: log_path)
@@ -40,11 +40,13 @@ module Snapshot
40
40
  return options
41
41
  end
42
42
 
43
- def build_settings
43
+ def build_settings(language, locale)
44
44
  config = Snapshot.config
45
45
 
46
46
  build_settings = []
47
47
  build_settings << "FASTLANE_SNAPSHOT=YES"
48
+ build_settings << "FASTLANE_LANGUAGE=#{language}" if language
49
+ build_settings << "FASTLANE_LOCALE=#{locale}" if locale
48
50
  build_settings << "TEST_TARGET_NAME=#{config[:test_target_name].shellescape}" if config[:test_target_name]
49
51
 
50
52
  return build_settings
@@ -14,7 +14,7 @@ module Snapshot
14
14
  parts << "xcodebuild"
15
15
  parts += options(language, locale)
16
16
  parts += destination(device_type)
17
- parts += build_settings
17
+ parts += build_settings(language, locale)
18
18
  parts += actions
19
19
  parts += suffix
20
20
  parts += pipe(device_type, language, locale)
@@ -57,6 +57,7 @@ module Spaceship
57
57
  InternalServerError = Spaceship::InternalServerError
58
58
  BadGatewayError = Spaceship::BadGatewayError
59
59
  AccessForbiddenError = Spaceship::AccessForbiddenError
60
+ TooManyRequestsError = Spaceship::TooManyRequestsError
60
61
 
61
62
  def self.hostname
62
63
  raise "You must implement self.hostname"
@@ -645,6 +646,17 @@ module Spaceship
645
646
  retry
646
647
  end
647
648
  raise ex # re-raise the exception
649
+ rescue TooManyRequestsError => ex
650
+ tries -= 1
651
+ unless tries.zero?
652
+ msg = "Timeout received: '#{ex.class}', '#{ex.message}'. Retrying after #{ex.retry_after} seconds (remaining: #{tries})..."
653
+ puts(msg) if Spaceship::Globals.verbose?
654
+ logger.warn(msg)
655
+
656
+ sleep(ex.retry_after) unless Object.const_defined?("SpecHelper")
657
+ retry
658
+ end
659
+ raise ex # re-raise the exception
648
660
  rescue \
649
661
  Faraday::ParsingError, # <h2>Internal Server Error</h2> with content type json
650
662
  InternalServerError => ex
@@ -873,6 +885,8 @@ module Spaceship
873
885
  msg = "Access forbidden"
874
886
  logger.warn(msg)
875
887
  raise AccessForbiddenError.new, msg
888
+ elsif resp_hash[:status] == 429
889
+ raise TooManyRequestsError, resp_hash
876
890
  end
877
891
 
878
892
  return response
@@ -31,6 +31,8 @@ require 'spaceship/connect_api/models/beta_tester_metric'
31
31
  require 'spaceship/connect_api/models/build'
32
32
  require 'spaceship/connect_api/models/build_delivery'
33
33
  require 'spaceship/connect_api/models/build_beta_detail'
34
+ require 'spaceship/connect_api/models/custom_app_organization'
35
+ require 'spaceship/connect_api/models/custom_app_user'
34
36
  require 'spaceship/connect_api/models/pre_release_version'
35
37
 
36
38
  require 'spaceship/connect_api/models/age_rating_declaration'
@@ -13,20 +13,23 @@ module Spaceship
13
13
 
14
14
  # Initializes client with Apple's App Store Connect JWT auth key.
15
15
  #
16
- # This method will automatically use the key id, issuer id, and filepath from environment
16
+ # This method will automatically use the arguments from environment
17
17
  # variables if not given.
18
18
  #
19
- # All three parameters are needed to authenticate.
19
+ # The key_id, issuer_id and either filepath or key are needed to authenticate.
20
20
  #
21
21
  # @param key_id (String) (optional): The key id
22
22
  # @param issuer_id (String) (optional): The issuer id
23
23
  # @param filepath (String) (optional): The filepath
24
+ # @param key (String) (optional): The key
25
+ # @param duration (Integer) (optional): How long this session should last
26
+ # @param in_house (Boolean) (optional): Whether this session is an Enterprise one
24
27
  #
25
28
  # @raise InvalidUserCredentialsError: raised if authentication failed
26
29
  #
27
30
  # @return (Spaceship::ConnectAPI::Client) The client the login method was called for
28
- def self.auth(key_id: nil, issuer_id: nil, filepath: nil)
29
- token = Spaceship::ConnectAPI::Token.create(key_id: key_id, issuer_id: issuer_id, filepath: filepath)
31
+ def self.auth(key_id: nil, issuer_id: nil, filepath: nil, key: nil, duration: nil, in_house: nil)
32
+ token = Spaceship::ConnectAPI::Token.create(key_id: key_id, issuer_id: issuer_id, filepath: filepath, key: key, duration: duration, in_house: in_house)
30
33
  return ConnectAPI::Client.new(token: token)
31
34
  end
32
35
 
@@ -105,9 +105,10 @@ module Spaceship
105
105
  # API
106
106
  #
107
107
 
108
- def update(attributes: nil)
108
+ def update(client: nil, attributes: nil)
109
+ client ||= Spaceship::ConnectAPI
109
110
  attributes = reverse_attr_mapping(attributes)
110
- Spaceship::ConnectAPI.patch_age_rating_declaration(age_rating_declaration_id: id, attributes: attributes)
111
+ client.patch_age_rating_declaration(age_rating_declaration_id: id, attributes: attributes)
111
112
  end
112
113
  end
113
114
  end
@@ -18,11 +18,26 @@ module Spaceship
18
18
  attr_accessor :app_store_versions
19
19
  attr_accessor :prices
20
20
 
21
+ # Only available with Apple ID auth
22
+ attr_accessor :distribution_type
23
+ attr_accessor :educationDiscountType
24
+
21
25
  module ContentRightsDeclaration
22
26
  USES_THIRD_PARTY_CONTENT = "USES_THIRD_PARTY_CONTENT"
23
27
  DOES_NOT_USE_THIRD_PARTY_CONTENT = "DOES_NOT_USE_THIRD_PARTY_CONTENT"
24
28
  end
25
29
 
30
+ module DistributionType
31
+ APP_STORE = "APP_STORE"
32
+ CUSTOM = "CUSTOM"
33
+ end
34
+
35
+ module EducationDiscountType
36
+ DISCOUNTED = "DISCOUNTED"
37
+ NOT_APPLICABLE = "NOT_APPLICABLE"
38
+ NOT_DISCOUNTED = "NOT_DISCOUNTED"
39
+ end
40
+
26
41
  self.attr_mapping({
27
42
  "name" => "name",
28
43
  "bundleId" => "bundle_id",
@@ -32,6 +47,8 @@ module Spaceship
32
47
  "removed" => "removed",
33
48
  "isAAG" => "is_aag",
34
49
  "availableInNewTerritories" => "available_in_new_territories",
50
+ "distributionType" => "distribution_type",
51
+ "educationDiscountType" => "education_discount_type",
35
52
 
36
53
  "contentRightsDeclaration" => "content_rights_declaration",
37
54
 
@@ -52,19 +69,22 @@ module Spaceship
52
69
  # Apps
53
70
  #
54
71
 
55
- def self.all(filter: {}, includes: ESSENTIAL_INCLUDES, limit: nil, sort: nil)
56
- resps = Spaceship::ConnectAPI.get_apps(filter: filter, includes: includes, limit: limit, sort: sort).all_pages
72
+ def self.all(client: nil, filter: {}, includes: ESSENTIAL_INCLUDES, limit: nil, sort: nil)
73
+ client ||= Spaceship::ConnectAPI
74
+ resps = client.get_apps(filter: filter, includes: includes, limit: limit, sort: sort).all_pages
57
75
  return resps.flat_map(&:to_models)
58
76
  end
59
77
 
60
- def self.find(bundle_id)
61
- return all(filter: { bundleId: bundle_id }).find do |app|
78
+ def self.find(bundle_id, client: nil)
79
+ client ||= Spaceship::ConnectAPI
80
+ return all(client: client, filter: { bundleId: bundle_id }).find do |app|
62
81
  app.bundle_id == bundle_id
63
82
  end
64
83
  end
65
84
 
66
- def self.create(name: nil, version_string: nil, sku: nil, primary_locale: nil, bundle_id: nil, platforms: nil, company_name: nil)
67
- Spaceship::ConnectAPI.post_app(
85
+ def self.create(client: nil, name: nil, version_string: nil, sku: nil, primary_locale: nil, bundle_id: nil, platforms: nil, company_name: nil)
86
+ client ||= Spaceship::ConnectAPI
87
+ client.post_app(
68
88
  name: name,
69
89
  version_string: version_string,
70
90
  sku: sku,
@@ -75,35 +95,40 @@ module Spaceship
75
95
  )
76
96
  end
77
97
 
78
- def self.get(app_id: nil, includes: "appStoreVersions")
79
- return Spaceship::ConnectAPI.get_app(app_id: app_id, includes: includes).first
98
+ def self.get(client: nil, app_id: nil, includes: "appStoreVersions")
99
+ client ||= Spaceship::ConnectAPI
100
+ return client.get_app(app_id: app_id, includes: includes).first
80
101
  end
81
102
 
82
- def update(attributes: nil, app_price_tier_id: nil, territory_ids: nil)
103
+ def update(client: nil, attributes: nil, app_price_tier_id: nil, territory_ids: nil)
104
+ client ||= Spaceship::ConnectAPI
83
105
  attributes = reverse_attr_mapping(attributes)
84
- return Spaceship::ConnectAPI.patch_app(app_id: id, attributes: attributes, app_price_tier_id: app_price_tier_id, territory_ids: territory_ids)
106
+ return client.patch_app(app_id: id, attributes: attributes, app_price_tier_id: app_price_tier_id, territory_ids: territory_ids)
85
107
  end
86
108
 
87
109
  #
88
110
  # App Info
89
111
  #
90
112
 
91
- def fetch_live_app_info(includes: Spaceship::ConnectAPI::AppInfo::ESSENTIAL_INCLUDES)
113
+ def fetch_live_app_info(client: nil, includes: Spaceship::ConnectAPI::AppInfo::ESSENTIAL_INCLUDES)
114
+ client ||= Spaceship::ConnectAPI
92
115
  states = [
93
116
  Spaceship::ConnectAPI::AppInfo::AppStoreState::READY_FOR_SALE,
94
117
  Spaceship::ConnectAPI::AppInfo::AppStoreState::PENDING_APPLE_RELEASE,
95
118
  Spaceship::ConnectAPI::AppInfo::AppStoreState::PENDING_DEVELOPER_RELEASE,
96
119
  Spaceship::ConnectAPI::AppInfo::AppStoreState::PROCESSING_FOR_APP_STORE,
97
- Spaceship::ConnectAPI::AppInfo::AppStoreState::IN_REVIEW
120
+ Spaceship::ConnectAPI::AppInfo::AppStoreState::IN_REVIEW,
121
+ Spaceship::ConnectAPI::AppInfo::AppStoreState::DEVELOPER_REMOVED_FROM_SALE
98
122
  ]
99
123
 
100
- resp = Spaceship::ConnectAPI.get_app_infos(app_id: id, includes: includes)
124
+ resp = client.get_app_infos(app_id: id, includes: includes)
101
125
  return resp.to_models.select do |model|
102
126
  states.include?(model.app_store_state)
103
127
  end.first
104
128
  end
105
129
 
106
- def fetch_edit_app_info(includes: Spaceship::ConnectAPI::AppInfo::ESSENTIAL_INCLUDES)
130
+ def fetch_edit_app_info(client: nil, includes: Spaceship::ConnectAPI::AppInfo::ESSENTIAL_INCLUDES)
131
+ client ||= Spaceship::ConnectAPI
107
132
  states = [
108
133
  Spaceship::ConnectAPI::AppInfo::AppStoreState::PREPARE_FOR_SUBMISSION,
109
134
  Spaceship::ConnectAPI::AppInfo::AppStoreState::DEVELOPER_REJECTED,
@@ -113,7 +138,7 @@ module Spaceship
113
138
  Spaceship::ConnectAPI::AppInfo::AppStoreState::INVALID_BINARY
114
139
  ]
115
140
 
116
- resp = Spaceship::ConnectAPI.get_app_infos(app_id: id, includes: includes)
141
+ resp = client.get_app_infos(app_id: id, includes: includes)
117
142
  return resp.to_models.select do |model|
118
143
  states.include?(model.app_store_state)
119
144
  end.first
@@ -123,9 +148,10 @@ module Spaceship
123
148
  # Available Territories
124
149
  #
125
150
 
126
- def fetch_available_territories(filter: {}, includes: nil, limit: nil, sort: nil)
151
+ def fetch_available_territories(client: nil, filter: {}, includes: nil, limit: nil, sort: nil)
152
+ client ||= Spaceship::ConnectAPI
127
153
  filter ||= {}
128
- resps = Spaceship::ConnectAPI.get_available_territories(app_id: id, filter: filter, includes: includes, limit: limit, sort: sort).all_pages
154
+ resps = client.get_available_territories(app_id: id, filter: filter, includes: includes, limit: limit, sort: sort).all_pages
129
155
  return resps.flat_map(&:to_models)
130
156
  end
131
157
 
@@ -133,8 +159,9 @@ module Spaceship
133
159
  # App Pricing
134
160
  #
135
161
 
136
- def fetch_app_prices(filter: {}, includes: "priceTier", limit: nil, sort: nil)
137
- resp = Spaceship::ConnectAPI.get_app_prices(app_id: id, filter: filter, includes: includes, limit: limit, sort: sort)
162
+ def fetch_app_prices(client: nil, filter: {}, includes: "priceTier", limit: nil, sort: nil)
163
+ client ||= Spaceship::ConnectAPI
164
+ resp = client.get_app_prices(app_id: id, filter: filter, includes: includes, limit: limit, sort: sort)
138
165
  return resp.to_models
139
166
  end
140
167
 
@@ -142,7 +169,8 @@ module Spaceship
142
169
  # App Store Versions
143
170
  #
144
171
 
145
- def reject_version_if_possible!(platform: nil)
172
+ def reject_version_if_possible!(client: nil, platform: nil)
173
+ client ||= Spaceship::ConnectAPI
146
174
  platform ||= Spaceship::ConnectAPI::Platform::IOS
147
175
  filter = {
148
176
  appStoreState: [
@@ -155,7 +183,7 @@ module Spaceship
155
183
  }
156
184
 
157
185
  # Get the latest version
158
- version = get_app_store_versions(filter: filter, includes: "appStoreVersionSubmission")
186
+ version = get_app_store_versions(client: client, filter: filter, includes: "appStoreVersionSubmission")
159
187
  .sort_by { |v| Gem::Version.new(v.version_string) }
160
188
  .last
161
189
 
@@ -167,46 +195,53 @@ module Spaceship
167
195
  # This will either create a new version or change the version number
168
196
  # from an existing version
169
197
  # @return (Bool) Was something changed?
170
- def ensure_version!(version_string, platform: nil)
198
+ def ensure_version!(version_string, platform: nil, client: nil)
199
+ client ||= Spaceship::ConnectAPI
171
200
  app_store_version = get_edit_app_store_version(platform: platform)
172
201
 
173
202
  if app_store_version
174
203
  if version_string != app_store_version.version_string
175
204
  attributes = { versionString: version_string }
176
- app_store_version.update(attributes: attributes)
205
+ app_store_version.update(client: client, attributes: attributes)
177
206
  return true
178
207
  end
179
208
  return false
180
209
  else
181
210
  attributes = { versionString: version_string, platform: platform }
182
- Spaceship::ConnectAPI.post_app_store_version(app_id: id, attributes: attributes)
211
+ client.post_app_store_version(app_id: id, attributes: attributes)
183
212
 
184
213
  return true
185
214
  end
186
215
  end
187
216
 
188
- def get_latest_app_store_version(platform: nil, includes: nil)
217
+ def get_latest_app_store_version(client: nil, platform: nil, includes: nil)
218
+ client ||= Spaceship::ConnectAPI
189
219
  platform ||= Spaceship::ConnectAPI::Platform::IOS
190
220
  filter = {
191
221
  platform: platform
192
222
  }
193
223
 
194
224
  # Get the latest version
195
- return get_app_store_versions(filter: filter, includes: includes)
225
+ return get_app_store_versions(client: client, filter: filter, includes: includes)
196
226
  .sort_by { |v| Date.parse(v.created_date) }
197
227
  .last
198
228
  end
199
229
 
200
- def get_live_app_store_version(platform: nil, includes: Spaceship::ConnectAPI::AppStoreVersion::ESSENTIAL_INCLUDES)
230
+ def get_live_app_store_version(client: nil, platform: nil, includes: Spaceship::ConnectAPI::AppStoreVersion::ESSENTIAL_INCLUDES)
231
+ client ||= Spaceship::ConnectAPI
201
232
  platform ||= Spaceship::ConnectAPI::Platform::IOS
202
233
  filter = {
203
- appStoreState: Spaceship::ConnectAPI::AppStoreVersion::AppStoreState::READY_FOR_SALE,
234
+ appStoreState: [
235
+ Spaceship::ConnectAPI::AppStoreVersion::AppStoreState::READY_FOR_SALE,
236
+ Spaceship::ConnectAPI::AppStoreVersion::AppStoreState::DEVELOPER_REMOVED_FROM_SALE
237
+ ].join(","),
204
238
  platform: platform
205
239
  }
206
- return get_app_store_versions(filter: filter, includes: includes).first
240
+ return get_app_store_versions(client: client, filter: filter, includes: includes).first
207
241
  end
208
242
 
209
- def get_edit_app_store_version(platform: nil, includes: Spaceship::ConnectAPI::AppStoreVersion::ESSENTIAL_INCLUDES)
243
+ def get_edit_app_store_version(client: nil, platform: nil, includes: Spaceship::ConnectAPI::AppStoreVersion::ESSENTIAL_INCLUDES)
244
+ client ||= Spaceship::ConnectAPI
210
245
  platform ||= Spaceship::ConnectAPI::Platform::IOS
211
246
  filter = {
212
247
  appStoreState: [
@@ -221,21 +256,23 @@ module Spaceship
221
256
  }
222
257
 
223
258
  # Get the latest version
224
- return get_app_store_versions(filter: filter, includes: includes)
259
+ return get_app_store_versions(client: client, filter: filter, includes: includes)
225
260
  .sort_by { |v| Gem::Version.new(v.version_string) }
226
261
  .last
227
262
  end
228
263
 
229
- def get_in_review_app_store_version(platform: nil, includes: Spaceship::ConnectAPI::AppStoreVersion::ESSENTIAL_INCLUDES)
264
+ def get_in_review_app_store_version(client: nil, platform: nil, includes: Spaceship::ConnectAPI::AppStoreVersion::ESSENTIAL_INCLUDES)
265
+ client ||= Spaceship::ConnectAPI
230
266
  platform ||= Spaceship::ConnectAPI::Platform::IOS
231
267
  filter = {
232
268
  appStoreState: Spaceship::ConnectAPI::AppStoreVersion::AppStoreState::IN_REVIEW,
233
269
  platform: platform
234
270
  }
235
- return get_app_store_versions(filter: filter, includes: includes).first
271
+ return get_app_store_versions(client: client, filter: filter, includes: includes).first
236
272
  end
237
273
 
238
- def get_pending_release_app_store_version(platform: nil, includes: Spaceship::ConnectAPI::AppStoreVersion::ESSENTIAL_INCLUDES)
274
+ def get_pending_release_app_store_version(client: nil, platform: nil, includes: Spaceship::ConnectAPI::AppStoreVersion::ESSENTIAL_INCLUDES)
275
+ client ||= Spaceship::ConnectAPI
239
276
  platform ||= Spaceship::ConnectAPI::Platform::IOS
240
277
  filter = {
241
278
  appStoreState: [
@@ -244,23 +281,48 @@ module Spaceship
244
281
  ].join(','),
245
282
  platform: platform
246
283
  }
247
- return get_app_store_versions(filter: filter, includes: includes).first
284
+ return get_app_store_versions(client: client, filter: filter, includes: includes).first
248
285
  end
249
286
 
250
- def get_app_store_versions(filter: {}, includes: Spaceship::ConnectAPI::AppStoreVersion::ESSENTIAL_INCLUDES, limit: nil, sort: nil)
251
- resps = Spaceship::ConnectAPI.get_app_store_versions(app_id: id, filter: filter, includes: includes, limit: limit, sort: sort).all_pages
252
- return resps.flat_map(&:to_models)
287
+ def get_app_store_versions(client: nil, filter: {}, includes: Spaceship::ConnectAPI::AppStoreVersion::ESSENTIAL_INCLUDES, limit: nil, sort: nil)
288
+ client ||= Spaceship::ConnectAPI
289
+ if limit.nil?
290
+ resps = client.get_app_store_versions(app_id: id, filter: filter, includes: includes, limit: limit, sort: sort).all_pages
291
+ return resps.flat_map(&:to_models)
292
+ else
293
+ resp = client.get_app_store_versions(app_id: id, filter: filter, includes: includes, limit: limit, sort: sort)
294
+ return resp.to_models
295
+ end
296
+ end
297
+
298
+ #
299
+ # B2B
300
+ #
301
+
302
+ def disable_b2b
303
+ update(attributes: {
304
+ distributionType: DistributionType::APP_STORE,
305
+ education_discount_type: EducationDiscountType::NOT_DISCOUNTED
306
+ })
307
+ end
308
+
309
+ def enable_b2b
310
+ update(attributes: {
311
+ distributionType: App::DistributionType::CUSTOM,
312
+ education_discount_type: EducationDiscountType::NOT_APPLICABLE
313
+ })
253
314
  end
254
315
 
255
316
  #
256
317
  # Beta Feedback
257
318
  #
258
319
 
259
- def get_beta_feedback(filter: {}, includes: "tester,build,screenshots", limit: nil, sort: nil)
320
+ def get_beta_feedback(client: nil, filter: {}, includes: "tester,build,screenshots", limit: nil, sort: nil)
321
+ client ||= Spaceship::ConnectAPI
260
322
  filter ||= {}
261
323
  filter["build.app"] = id
262
324
 
263
- resps = Spaceship::ConnectAPI.get_beta_feedback(filter: filter, includes: includes, limit: limit, sort: sort).all_pages
325
+ resps = client.get_beta_feedback(filter: filter, includes: includes, limit: limit, sort: sort).all_pages
264
326
  return resps.flat_map(&:to_models)
265
327
  end
266
328
 
@@ -268,11 +330,12 @@ module Spaceship
268
330
  # Beta Testers
269
331
  #
270
332
 
271
- def get_beta_testers(filter: {}, includes: nil, limit: nil, sort: nil)
333
+ def get_beta_testers(client: nil, filter: {}, includes: nil, limit: nil, sort: nil)
334
+ client ||= Spaceship::ConnectAPI
272
335
  filter ||= {}
273
336
  filter[:apps] = id
274
337
 
275
- resps = Spaceship::ConnectAPI.get_beta_testers(filter: filter, includes: includes, limit: limit, sort: sort).all_pages
338
+ resps = client.get_beta_testers(filter: filter, includes: includes, limit: limit, sort: sort).all_pages
276
339
  return resps.flat_map(&:to_models)
277
340
  end
278
341
 
@@ -280,40 +343,45 @@ module Spaceship
280
343
  # Builds
281
344
  #
282
345
 
283
- def get_builds(filter: {}, includes: nil, limit: nil, sort: nil)
346
+ def get_builds(client: nil, filter: {}, includes: nil, limit: nil, sort: nil)
347
+ client ||= Spaceship::ConnectAPI
284
348
  filter ||= {}
285
349
  filter[:app] = id
286
350
 
287
- resps = Spaceship::ConnectAPI.get_builds(filter: filter, includes: includes, limit: limit, sort: sort).all_pages
351
+ resps = client.get_builds(filter: filter, includes: includes, limit: limit, sort: sort).all_pages
288
352
  return resps.flat_map(&:to_models)
289
353
  end
290
354
 
291
- def get_build_deliveries(filter: {}, includes: nil, limit: nil, sort: nil)
355
+ def get_build_deliveries(client: nil, filter: {}, includes: nil, limit: nil, sort: nil)
356
+ client ||= Spaceship::ConnectAPI
292
357
  filter ||= {}
293
358
  filter[:app] = id
294
359
 
295
- resps = Spaceship::ConnectAPI.get_build_deliveries(filter: filter, includes: includes, limit: limit, sort: sort).all_pages
360
+ resps = client.get_build_deliveries(filter: filter, includes: includes, limit: limit, sort: sort).all_pages
296
361
  return resps.flat_map(&:to_models)
297
362
  end
298
363
 
299
- def get_beta_app_localizations(filter: {}, includes: nil, limit: nil, sort: nil)
364
+ def get_beta_app_localizations(client: nil, filter: {}, includes: nil, limit: nil, sort: nil)
365
+ client ||= Spaceship::ConnectAPI
300
366
  filter ||= {}
301
367
  filter[:app] = id
302
368
 
303
- resps = Spaceship::ConnectAPI.get_beta_app_localizations(filter: filter, includes: includes, limit: limit, sort: sort).all_pages
369
+ resps = client.get_beta_app_localizations(filter: filter, includes: includes, limit: limit, sort: sort).all_pages
304
370
  return resps.flat_map(&:to_models)
305
371
  end
306
372
 
307
- def get_beta_groups(filter: {}, includes: nil, limit: nil, sort: nil)
373
+ def get_beta_groups(client: nil, filter: {}, includes: nil, limit: nil, sort: nil)
374
+ client ||= Spaceship::ConnectAPI
308
375
  filter ||= {}
309
376
  filter[:app] = id
310
377
 
311
- resps = Spaceship::ConnectAPI.get_beta_groups(filter: filter, includes: includes, limit: limit, sort: sort).all_pages
378
+ resps = client.get_beta_groups(filter: filter, includes: includes, limit: limit, sort: sort).all_pages
312
379
  return resps.flat_map(&:to_models)
313
380
  end
314
381
 
315
- def create_beta_group(group_name: nil, public_link_enabled: false, public_link_limit: 10_000, public_link_limit_enabled: false)
316
- resps = Spaceship::ConnectAPI.create_beta_group(
382
+ def create_beta_group(client: nil, group_name: nil, public_link_enabled: false, public_link_limit: 10_000, public_link_limit_enabled: false)
383
+ client ||= Spaceship::ConnectAPI
384
+ resps = client.create_beta_group(
317
385
  app_id: id,
318
386
  group_name: group_name,
319
387
  public_link_enabled: public_link_enabled,
@@ -323,13 +391,30 @@ module Spaceship
323
391
  return resps.flat_map(&:to_models).first
324
392
  end
325
393
 
394
+ #
395
+ # Education
396
+ #
397
+
398
+ def disable_educational_discount
399
+ update(attributes: {
400
+ education_discount_type: EducationDiscountType::NOT_DISCOUNTED
401
+ })
402
+ end
403
+
404
+ def enable_educational_discount
405
+ update(attributes: {
406
+ education_discount_type: EducationDiscountType::DISCOUNTED
407
+ })
408
+ end
409
+
326
410
  #
327
411
  # Users
328
412
  #
329
413
 
330
- def add_users(user_ids: nil)
414
+ def add_users(client: nil, user_ids: nil)
415
+ client ||= Spaceship::ConnectAPI
331
416
  user_ids.each do |user_id|
332
- Spaceship::ConnectAPI.add_user_visible_apps(user_id: user_id, app_ids: [id])
417
+ client.add_user_visible_apps(user_id: user_id, app_ids: [id])
333
418
  end
334
419
  end
335
420
  end