fastlane 2.195.0 → 2.213.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (214) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/README.md +96 -89
  4. data/cert/lib/cert/runner.rb +19 -8
  5. data/deliver/lib/assets/ScreenshotsHelp +29 -6
  6. data/deliver/lib/deliver/app_screenshot.rb +30 -4
  7. data/deliver/lib/deliver/app_screenshot_iterator.rb +1 -1
  8. data/deliver/lib/deliver/options.rb +6 -2
  9. data/deliver/lib/deliver/runner.rb +88 -24
  10. data/deliver/lib/deliver/submit_for_review.rb +25 -3
  11. data/deliver/lib/deliver/upload_price_tier.rb +3 -1
  12. data/deliver/lib/deliver/upload_screenshots.rb +2 -2
  13. data/fastlane/lib/assets/AppfileTemplate +1 -1
  14. data/fastlane/lib/assets/AppfileTemplate.swift +1 -1
  15. data/fastlane/lib/fastlane/actions/app_store_build_number.rb +12 -6
  16. data/fastlane/lib/fastlane/actions/badge.rb +1 -1
  17. data/fastlane/lib/fastlane/actions/changelog_from_git_commits.rb +1 -1
  18. data/fastlane/lib/fastlane/actions/danger.rb +14 -0
  19. data/fastlane/lib/fastlane/actions/docs/build_app.md +5 -5
  20. data/fastlane/lib/fastlane/actions/docs/capture_android_screenshots.md +19 -2
  21. data/fastlane/lib/fastlane/actions/docs/frame_screenshots.md +1 -1
  22. data/fastlane/lib/fastlane/actions/docs/run_tests.md +1 -1
  23. data/fastlane/lib/fastlane/actions/docs/upload_to_app_store.md.erb +1 -1
  24. data/fastlane/lib/fastlane/actions/download_dsyms.rb +62 -46
  25. data/fastlane/lib/fastlane/actions/ensure_git_status_clean.rb +44 -5
  26. data/fastlane/lib/fastlane/actions/ensure_xcode_version.rb +1 -1
  27. data/fastlane/lib/fastlane/actions/get_push_certificate.rb +1 -1
  28. data/fastlane/lib/fastlane/actions/get_version_number.rb +8 -3
  29. data/fastlane/lib/fastlane/actions/git_commit.rb +4 -6
  30. data/fastlane/lib/fastlane/actions/import_certificate.rb +1 -1
  31. data/fastlane/lib/fastlane/actions/latest_testflight_build_number.rb +2 -3
  32. data/fastlane/lib/fastlane/actions/notarize.rb +29 -11
  33. data/fastlane/lib/fastlane/actions/pod_lib_lint.rb +1 -1
  34. data/fastlane/lib/fastlane/actions/pod_push.rb +19 -1
  35. data/fastlane/lib/fastlane/actions/read_podspec.rb +1 -1
  36. data/fastlane/lib/fastlane/actions/run_tests.rb +19 -9
  37. data/fastlane/lib/fastlane/actions/set_github_release.rb +11 -5
  38. data/fastlane/lib/fastlane/actions/setup_ci.rb +13 -4
  39. data/fastlane/lib/fastlane/actions/trainer.rb +49 -0
  40. data/fastlane/lib/fastlane/actions/update_code_signing_settings.rb +31 -4
  41. data/fastlane/lib/fastlane/actions/update_info_plist.rb +1 -1
  42. data/fastlane/lib/fastlane/actions/update_project_provisioning.rb +10 -1
  43. data/fastlane/lib/fastlane/actions/upload_symbols_to_sentry.rb +1 -1
  44. data/fastlane/lib/fastlane/actions/verify_build.rb +1 -1
  45. data/fastlane/lib/fastlane/actions/xcode_install.rb +5 -1
  46. data/fastlane/lib/fastlane/actions/xcode_select.rb +1 -1
  47. data/fastlane/lib/fastlane/actions/xcodebuild.rb +8 -2
  48. data/fastlane/lib/fastlane/actions/xcodes.rb +152 -0
  49. data/fastlane/lib/fastlane/actions/xcov.rb +5 -0
  50. data/fastlane/lib/fastlane/actions/xcversion.rb +17 -7
  51. data/fastlane/lib/fastlane/cli_tools_distributor.rb +5 -0
  52. data/fastlane/lib/fastlane/commands_generator.rb +2 -1
  53. data/fastlane/lib/fastlane/documentation/docs_generator.rb +17 -12
  54. data/fastlane/lib/fastlane/fast_file.rb +18 -5
  55. data/fastlane/lib/fastlane/features.rb +3 -0
  56. data/fastlane/lib/fastlane/helper/xcodebuild_formatter_helper.rb +9 -0
  57. data/fastlane/lib/fastlane/helper/xcodes_helper.rb +28 -0
  58. data/fastlane/lib/fastlane/helper/xcversion_helper.rb +0 -9
  59. data/fastlane/lib/fastlane/lane_manager.rb +1 -1
  60. data/fastlane/lib/fastlane/plugins/template/%gem_name%.gemspec.erb +1 -1
  61. data/fastlane/lib/fastlane/plugins/template/.rubocop.yml +5 -1
  62. data/fastlane/lib/fastlane/setup/setup_ios.rb +1 -1
  63. data/fastlane/lib/fastlane/swift_fastlane_api_generator.rb +1 -1
  64. data/fastlane/lib/fastlane/swift_lane_manager.rb +11 -3
  65. data/fastlane/lib/fastlane/swift_runner_upgrader.rb +54 -1
  66. data/fastlane/lib/fastlane/tools.rb +18 -1
  67. data/fastlane/lib/fastlane/version.rb +1 -1
  68. data/fastlane/swift/Actions.swift +1 -1
  69. data/fastlane/swift/Appfile.swift +2 -2
  70. data/fastlane/swift/ArgumentProcessor.swift +1 -1
  71. data/fastlane/swift/Atomic.swift +150 -0
  72. data/fastlane/swift/ControlCommand.swift +1 -1
  73. data/fastlane/swift/Deliverfile.swift +2 -2
  74. data/fastlane/swift/DeliverfileProtocol.swift +8 -4
  75. data/fastlane/swift/Fastlane.swift +604 -249
  76. data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.pbxproj +30 -20
  77. data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/xcshareddata/xcschemes/FastlaneRunner.xcscheme +1 -1
  78. data/fastlane/swift/Gymfile.swift +2 -2
  79. data/fastlane/swift/GymfileProtocol.swift +20 -8
  80. data/fastlane/swift/LaneFileProtocol.swift +3 -3
  81. data/fastlane/swift/MainProcess.swift +3 -3
  82. data/fastlane/swift/Matchfile.swift +2 -2
  83. data/fastlane/swift/MatchfileProtocol.swift +25 -5
  84. data/fastlane/swift/OptionalConfigValue.swift +1 -1
  85. data/fastlane/swift/Plugins.swift +1 -1
  86. data/fastlane/swift/Precheckfile.swift +2 -2
  87. data/fastlane/swift/PrecheckfileProtocol.swift +3 -3
  88. data/fastlane/swift/RubyCommand.swift +1 -1
  89. data/fastlane/swift/RubyCommandable.swift +1 -1
  90. data/fastlane/swift/Runner.swift +14 -10
  91. data/fastlane/swift/RunnerArgument.swift +1 -1
  92. data/fastlane/swift/Scanfile.swift +2 -2
  93. data/fastlane/swift/ScanfileProtocol.swift +35 -11
  94. data/fastlane/swift/Screengrabfile.swift +2 -2
  95. data/fastlane/swift/ScreengrabfileProtocol.swift +5 -5
  96. data/fastlane/swift/Snapshotfile.swift +2 -2
  97. data/fastlane/swift/SnapshotfileProtocol.swift +12 -8
  98. data/fastlane/swift/SocketClient.swift +9 -5
  99. data/fastlane/swift/SocketClientDelegateProtocol.swift +2 -2
  100. data/fastlane/swift/SocketResponse.swift +1 -1
  101. data/fastlane/swift/formatting/Brewfile.lock.json +47 -24
  102. data/fastlane/swift/main.swift +1 -1
  103. data/fastlane/swift/upgrade_manifest.json +1 -1
  104. data/fastlane_core/README.md +1 -0
  105. data/fastlane_core/lib/fastlane_core/cert_checker.rb +74 -17
  106. data/fastlane_core/lib/fastlane_core/device_manager.rb +5 -1
  107. data/fastlane_core/lib/fastlane_core/ipa_file_analyser.rb +10 -5
  108. data/fastlane_core/lib/fastlane_core/itunes_transporter.rb +409 -26
  109. data/fastlane_core/lib/fastlane_core/keychain_importer.rb +1 -0
  110. data/fastlane_core/lib/fastlane_core/project.rb +19 -2
  111. data/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb +7 -0
  112. data/fastlane_core/lib/fastlane_core/ui/implementations/shell.rb +4 -2
  113. data/frameit/lib/frameit/device.rb +1 -1
  114. data/frameit/lib/frameit/device_types.rb +9 -0
  115. data/frameit/lib/frameit/editor.rb +16 -18
  116. data/frameit/lib/frameit/frame_downloader.rb +1 -1
  117. data/frameit/lib/frameit/trim_box.rb +6 -0
  118. data/gym/lib/gym/generators/build_command_generator.rb +70 -23
  119. data/gym/lib/gym/options.rb +30 -5
  120. data/match/lib/match/change_password.rb +2 -0
  121. data/match/lib/match/commands_generator.rb +2 -1
  122. data/match/lib/match/encryption/openssl.rb +1 -1
  123. data/match/lib/match/encryption.rb +3 -0
  124. data/match/lib/match/generator.rb +1 -0
  125. data/match/lib/match/importer.rb +11 -1
  126. data/match/lib/match/migrate.rb +4 -3
  127. data/match/lib/match/module.rb +54 -2
  128. data/match/lib/match/nuke.rb +115 -47
  129. data/match/lib/match/options.rb +27 -1
  130. data/match/lib/match/runner.rb +26 -6
  131. data/match/lib/match/setup.rb +1 -1
  132. data/match/lib/match/spaceship_ensure.rb +5 -2
  133. data/match/lib/match/storage/gitlab/client.rb +102 -0
  134. data/match/lib/match/storage/gitlab/secure_file.rb +65 -0
  135. data/match/lib/match/storage/gitlab_secure_files.rb +188 -0
  136. data/match/lib/match/storage/google_cloud_storage.rb +7 -6
  137. data/match/lib/match/storage/s3_storage.rb +3 -3
  138. data/match/lib/match/storage.rb +4 -0
  139. data/match/lib/match/table_printer.rb +2 -1
  140. data/match/lib/match/utils.rb +15 -2
  141. data/pem/lib/pem/manager.rb +32 -8
  142. data/pem/lib/pem/options.rb +10 -1
  143. data/pilot/lib/pilot/build_manager.rb +34 -14
  144. data/pilot/lib/pilot/options.rb +6 -1
  145. data/scan/lib/scan/detect_values.rb +14 -1
  146. data/scan/lib/scan/error_handler.rb +9 -0
  147. data/scan/lib/scan/options.rb +54 -9
  148. data/scan/lib/scan/runner.rb +171 -25
  149. data/scan/lib/scan/test_command_generator.rb +65 -5
  150. data/screengrab/lib/screengrab/options.rb +2 -2
  151. data/sigh/lib/assets/resign.sh +8 -5
  152. data/sigh/lib/sigh/download_all.rb +14 -2
  153. data/sigh/lib/sigh/module.rb +3 -1
  154. data/sigh/lib/sigh/options.rb +5 -0
  155. data/sigh/lib/sigh/runner.rb +12 -2
  156. data/snapshot/lib/assets/SnapshotHelper.swift +3 -3
  157. data/snapshot/lib/snapshot/latest_os_version.rb +2 -5
  158. data/snapshot/lib/snapshot/options.rb +24 -8
  159. data/snapshot/lib/snapshot/reports_generator.rb +9 -0
  160. data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb +10 -3
  161. data/snapshot/lib/snapshot/test_command_generator.rb +37 -2
  162. data/spaceship/lib/spaceship/client.rb +71 -40
  163. data/spaceship/lib/spaceship/commands_generator.rb +1 -1
  164. data/spaceship/lib/spaceship/connect_api/api_client.rb +10 -5
  165. data/spaceship/lib/spaceship/connect_api/models/actor.rb +26 -0
  166. data/spaceship/lib/spaceship/connect_api/models/app.rb +52 -6
  167. data/spaceship/lib/spaceship/connect_api/models/app_info.rb +1 -0
  168. data/spaceship/lib/spaceship/connect_api/models/app_info_localization.rb +5 -0
  169. data/spaceship/lib/spaceship/connect_api/models/app_screenshot_set.rb +7 -0
  170. data/spaceship/lib/spaceship/connect_api/models/app_store_version.rb +1 -1
  171. data/spaceship/lib/spaceship/connect_api/models/app_store_version_localization.rb +27 -10
  172. data/spaceship/lib/spaceship/connect_api/models/build.rb +4 -2
  173. data/spaceship/lib/spaceship/connect_api/models/build_bundle.rb +68 -0
  174. data/spaceship/lib/spaceship/connect_api/models/build_bundle_file_sizes.rb +34 -0
  175. data/spaceship/lib/spaceship/connect_api/models/build_delivery.rb +2 -1
  176. data/spaceship/lib/spaceship/connect_api/models/certificate.rb +4 -0
  177. data/spaceship/lib/spaceship/connect_api/models/device.rb +47 -4
  178. data/spaceship/lib/spaceship/connect_api/models/profile.rb +4 -0
  179. data/spaceship/lib/spaceship/connect_api/models/resolution_center_message.rb +29 -0
  180. data/spaceship/lib/spaceship/connect_api/models/resolution_center_thread.rb +67 -0
  181. data/spaceship/lib/spaceship/connect_api/models/review_rejection.rb +19 -0
  182. data/spaceship/lib/spaceship/connect_api/models/review_submission.rb +86 -0
  183. data/spaceship/lib/spaceship/connect_api/models/review_submission_item.rb +40 -0
  184. data/spaceship/lib/spaceship/connect_api/models/user.rb +5 -0
  185. data/spaceship/lib/spaceship/connect_api/provisioning/provisioning.rb +19 -0
  186. data/spaceship/lib/spaceship/connect_api/response.rb +23 -6
  187. data/spaceship/lib/spaceship/connect_api/testflight/testflight.rb +33 -2
  188. data/spaceship/lib/spaceship/connect_api/token.rb +6 -3
  189. data/spaceship/lib/spaceship/connect_api/tunes/tunes.rb +124 -8
  190. data/spaceship/lib/spaceship/connect_api.rb +9 -0
  191. data/spaceship/lib/spaceship/errors.rb +34 -0
  192. data/spaceship/lib/spaceship/globals.rb +9 -0
  193. data/spaceship/lib/spaceship/hashcash.rb +52 -0
  194. data/spaceship/lib/spaceship/portal/certificate.rb +4 -3
  195. data/spaceship/lib/spaceship/spaceauth_runner.rb +1 -1
  196. data/spaceship/lib/spaceship/tunes/app_ratings.rb +6 -6
  197. data/spaceship/lib/spaceship/tunes/iap_families.rb +1 -1
  198. data/spaceship/lib/spaceship/tunes/tunes.rb +0 -1
  199. data/spaceship/lib/spaceship/tunes/tunes_client.rb +79 -21
  200. data/spaceship/lib/spaceship/two_step_or_factor_client.rb +11 -3
  201. data/spaceship/lib/spaceship.rb +1 -0
  202. data/supply/lib/supply/client.rb +5 -10
  203. data/supply/lib/supply/options.rb +8 -0
  204. data/supply/lib/supply/uploader.rb +7 -3
  205. data/trainer/lib/assets/junit.xml.erb +28 -0
  206. data/trainer/lib/trainer/commands_generator.rb +51 -0
  207. data/trainer/lib/trainer/junit_generator.rb +31 -0
  208. data/trainer/lib/trainer/module.rb +10 -0
  209. data/trainer/lib/trainer/options.rb +66 -0
  210. data/trainer/lib/trainer/test_parser.rb +398 -0
  211. data/trainer/lib/trainer/xcresult.rb +403 -0
  212. data/trainer/lib/trainer.rb +7 -0
  213. metadata +73 -37
  214. data/spaceship/lib/spaceship/tunes/user_detail.rb +0 -15
@@ -82,10 +82,12 @@ module Sigh
82
82
  @profile_type = Spaceship::ConnectAPI::Profile::ProfileType::TVOS_APP_DEVELOPMENT if Sigh.config[:development]
83
83
  when "macos"
84
84
  @profile_type = Spaceship::ConnectAPI::Profile::ProfileType::MAC_APP_STORE
85
+ @profile_type = Spaceship::ConnectAPI::Profile::ProfileType::MAC_APP_INHOUSE if Spaceship::ConnectAPI.client.in_house?
85
86
  @profile_type = Spaceship::ConnectAPI::Profile::ProfileType::MAC_APP_DEVELOPMENT if Sigh.config[:development]
86
87
  @profile_type = Spaceship::ConnectAPI::Profile::ProfileType::MAC_APP_DIRECT if Sigh.config[:developer_id]
87
88
  when "catalyst"
88
89
  @profile_type = Spaceship::ConnectAPI::Profile::ProfileType::MAC_CATALYST_APP_STORE
90
+ @profile_type = Spaceship::ConnectAPI::Profile::ProfileType::MAC_CATALYST_APP_INHOUSE if Spaceship::ConnectAPI.client.in_house?
89
91
  @profile_type = Spaceship::ConnectAPI::Profile::ProfileType::MAC_CATALYST_APP_DEVELOPMENT if Sigh.config[:development]
90
92
  @profile_type = Spaceship::ConnectAPI::Profile::ProfileType::MAC_CATALYST_APP_DIRECT if Sigh.config[:developer_id]
91
93
  end
@@ -251,7 +253,13 @@ module Sigh
251
253
  ]
252
254
  elsif profile_type == Spaceship::ConnectAPI::Profile::ProfileType::MAC_APP_DIRECT || profile_type == Spaceship::ConnectAPI::Profile::ProfileType::MAC_CATALYST_APP_DIRECT
253
255
  types = [
254
- Spaceship::ConnectAPI::Certificate::CertificateType::DEVELOPER_ID_APPLICATION
256
+ Spaceship::ConnectAPI::Certificate::CertificateType::DEVELOPER_ID_APPLICATION,
257
+ Spaceship::ConnectAPI::Certificate::CertificateType::DEVELOPER_ID_APPLICATION_G2
258
+ ]
259
+ elsif profile_type == Spaceship::ConnectAPI::Profile::ProfileType::MAC_APP_INHOUSE || profile_type == Spaceship::ConnectAPI::Profile::ProfileType::MAC_CATALYST_APP_INHOUSE
260
+ # Enterprise accounts don't have access to Apple Distribution certificates
261
+ types = [
262
+ Spaceship::ConnectAPI::Certificate::CertificateType::MAC_APP_DISTRIBUTION
255
263
  ]
256
264
  else
257
265
  types = [
@@ -281,7 +289,9 @@ module Sigh
281
289
  when 'macos', 'catalyst'
282
290
  [Spaceship::ConnectAPI::Device::DeviceClass::MAC]
283
291
  end
284
-
292
+ if Sigh.config[:platform].to_s == 'ios' && Sigh.config[:include_mac_in_profiles]
293
+ device_classes += [Spaceship::ConnectAPI::Device::DeviceClass::APPLE_SILICON_MAC]
294
+ end
285
295
  if Spaceship::ConnectAPI.token
286
296
  return Spaceship::ConnectAPI::Device.all.select do |device|
287
297
  device_classes.include?(device.device_class)
@@ -165,7 +165,7 @@ open class Snapshot: NSObject {
165
165
  }
166
166
 
167
167
  let screenshot = XCUIScreen.main.screenshot()
168
- #if os(iOS)
168
+ #if os(iOS) && !targetEnvironment(macCatalyst)
169
169
  let image = XCUIDevice.shared.orientation.isLandscape ? fixLandscapeOrientation(image: screenshot.image) : screenshot.image
170
170
  #else
171
171
  let image = screenshot.image
@@ -181,7 +181,7 @@ open class Snapshot: NSObject {
181
181
 
182
182
  let path = screenshotsDir.appendingPathComponent("\(simulator)-\(name).png")
183
183
  #if swift(<5.0)
184
- UIImagePNGRepresentation(image)?.write(to: path, options: .atomic)
184
+ try UIImagePNGRepresentation(image)?.write(to: path, options: .atomic)
185
185
  #else
186
186
  try image.pngData()?.write(to: path, options: .atomic)
187
187
  #endif
@@ -306,4 +306,4 @@ private extension CGFloat {
306
306
 
307
307
  // Please don't remove the lines below
308
308
  // They are used to detect outdated configuration files
309
- // SnapshotHelperVersion [1.27]
309
+ // SnapshotHelperVersion [1.29]
@@ -16,12 +16,9 @@ module Snapshot
16
16
  def self.version_for_os(os)
17
17
  # We do all this, because we would get all kind of crap output generated by xcodebuild
18
18
  # so we need to ignore stderror
19
- output = ''
20
- Open3.popen3('xcodebuild -version -sdk') do |stdin, stdout, stderr, wait_thr|
21
- output = stdout.read
22
- end
19
+ stdout, _stderr, _status = Open3.capture3('xcodebuild -version -sdk')
23
20
 
24
- matched = output.match(/#{os} ([\d\.]+) \(.*/)
21
+ matched = stdout.match(/#{os} ([\d\.]+) \(.*/)
25
22
  if matched.nil?
26
23
  FastlaneCore::UI.user_error!("Could not determine installed #{os} SDK version. Try running the _xcodebuild_ command manually to ensure it works.")
27
24
  elsif matched.length > 1
@@ -1,5 +1,6 @@
1
1
  require 'fastlane_core/configuration/config_item'
2
2
  require 'fastlane_core/device_manager'
3
+ require 'fastlane/helper/xcodebuild_formatter_helper'
3
4
  require 'credentials_manager/appfile_config'
4
5
  require_relative 'module'
5
6
 
@@ -11,9 +12,13 @@ module Snapshot
11
12
  end
12
13
 
13
14
  def self.available_options
15
+ @options ||= plain_options
16
+ end
17
+
18
+ def self.plain_options
14
19
  output_directory = (File.directory?("fastlane") ? "fastlane/screenshots" : "screenshots")
15
20
 
16
- @options ||= [
21
+ [
17
22
  FastlaneCore::ConfigItem.new(key: :workspace,
18
23
  short_option: "-w",
19
24
  env_name: "SNAPSHOT_WORKSPACE",
@@ -128,7 +133,7 @@ module Snapshot
128
133
  is_string: false),
129
134
  FastlaneCore::ConfigItem.new(key: :override_status_bar_arguments,
130
135
  env_name: 'SNAPSHOT_OVERRIDE_STATUS_BAR_ARGUMENTS',
131
- description: "Fully customize the status bar by setting each option here. See `xcrun simctl status_bar --help`",
136
+ description: "Fully customize the status bar by setting each option here. Requires `override_status_bar` to be set to `true`. See `xcrun simctl status_bar --help`",
132
137
  optional: true,
133
138
  type: String),
134
139
  FastlaneCore::ConfigItem.new(key: :localize_simulator,
@@ -194,12 +199,6 @@ module Snapshot
194
199
  description: "The configuration to use when building the app. Defaults to 'Release'",
195
200
  default_value_dynamic: true,
196
201
  optional: true),
197
- FastlaneCore::ConfigItem.new(key: :xcpretty_args,
198
- short_option: "-x",
199
- env_name: "SNAPSHOT_XCPRETTY_ARGS",
200
- description: "Additional xcpretty arguments",
201
- is_string: true,
202
- optional: true),
203
202
  FastlaneCore::ConfigItem.new(key: :sdk,
204
203
  short_option: "-k",
205
204
  env_name: "SNAPSHOT_SDK",
@@ -289,11 +288,28 @@ module Snapshot
289
288
  verify_block: proc do |value|
290
289
  verify_type('skip_testing', [Array, String], value)
291
290
  end),
291
+
292
+ FastlaneCore::ConfigItem.new(key: :xcodebuild_formatter,
293
+ env_names: ["SNAPSHOT_XCODEBUILD_FORMATTER", "FASTLANE_XCODEBUILD_FORMATTER"],
294
+ description: "xcodebuild formatter to use (ex: 'xcbeautify', 'xcbeautify --quieter', 'xcpretty', 'xcpretty -test'). Use empty string (ex: '') to disable any formatter (More information: https://docs.fastlane.tools/best-practices/xcodebuild-formatters/)",
295
+ type: String,
296
+ default_value: Fastlane::Helper::XcodebuildFormatterHelper.xcbeautify_installed? ? 'xcbeautify' : 'xcpretty',
297
+ default_value_dynamic: true),
298
+
299
+ # xcpretty
300
+ FastlaneCore::ConfigItem.new(key: :xcpretty_args,
301
+ short_option: "-x",
302
+ env_name: "SNAPSHOT_XCPRETTY_ARGS",
303
+ deprecated: "Use `xcodebuild_formatter: ''` instead",
304
+ description: "Additional xcpretty arguments",
305
+ is_string: true,
306
+ optional: true),
292
307
  FastlaneCore::ConfigItem.new(key: :disable_xcpretty,
293
308
  env_name: "SNAPSHOT_DISABLE_XCPRETTY",
294
309
  description: "Disable xcpretty formatting of build",
295
310
  type: Boolean,
296
311
  optional: true),
312
+
297
313
  FastlaneCore::ConfigItem.new(key: :suppress_xcode_output,
298
314
  env_name: "SNAPSHOT_SUPPRESS_XCODE_OUTPUT",
299
315
  description: "Suppress the output of xcodebuild to stdout. Output is still saved in buildlog_path",
@@ -84,6 +84,10 @@ module Snapshot
84
84
  {
85
85
  # snapshot in Xcode 9 saves screenshots with the SIMULATOR_DEVICE_NAME
86
86
  # which includes spaces
87
+ 'iPhone 13 Pro Max' => "iPhone 13 Pro Max",
88
+ 'iPhone 13 Pro' => "iPhone 13 Pro",
89
+ 'iPhone 13 mini' => "iPhone 13 mini",
90
+ 'iPhone 13' => "iPhone 13",
87
91
  'iPhone 12 Pro Max' => "iPhone 12 Pro Max",
88
92
  'iPhone 12 Pro' => "iPhone 12 Pro",
89
93
  'iPhone 12 mini' => "iPhone 12 mini",
@@ -113,6 +117,10 @@ module Snapshot
113
117
  'iPad Air' => 'iPad Air',
114
118
  'iPad (5th generation)' => 'iPad (5th generation)',
115
119
  'iPad (7th generation)' => 'iPad (7th generation)',
120
+ 'iPad mini 2' => 'iPad mini 2',
121
+ 'iPad mini 3' => 'iPad mini 3',
122
+ 'iPad mini 4' => 'iPad mini 4',
123
+ 'iPad mini (6th generation)' => 'iPad mini (6th generation)',
116
124
  'iPad Pro (9.7-inch)' => 'iPad Pro (9.7-inch)',
117
125
  'iPad Pro (9.7 inch)' => 'iPad Pro (9.7-inch)', # iOS 10.3.1 simulator
118
126
  'iPad Pro (10.5-inch)' => 'iPad Pro (10.5-inch)',
@@ -124,6 +132,7 @@ module Snapshot
124
132
  'iPad Pro (12.9-inch)' => 'iPad Pro (12.9-inch)',
125
133
  'iPad Pro (12.9 inch)' => 'iPad Pro (12.9-inch)', # iOS 10.3.1 simulator
126
134
  'iPad Pro' => 'iPad Pro (12.9-inch)', # iOS 9.3 simulator
135
+ 'iPod touch (7th generation)' => 'iPod touch (7th generation)',
127
136
  'Apple TV 1080p' => 'Apple TV',
128
137
  'Apple TV 4K (at 1080p)' => 'Apple TV 4K (at 1080p)',
129
138
  'Apple TV 4K' => 'Apple TV 4K',
@@ -94,7 +94,11 @@ module Snapshot
94
94
  device_udid = TestCommandGenerator.device_udid(device_type)
95
95
 
96
96
  UI.message("Launch Simulator #{device_type}")
97
- Helper.backticks("xcrun instruments -w #{device_udid} &> /dev/null")
97
+ if FastlaneCore::Helper.xcode_at_least?("13")
98
+ Helper.backticks("open -a Simulator.app --args -CurrentDeviceUDID #{device_udid} &> /dev/null")
99
+ else
100
+ Helper.backticks("xcrun instruments -w #{device_udid} &> /dev/null")
101
+ end
98
102
 
99
103
  paths.each do |path|
100
104
  UI.message("Adding '#{path}'")
@@ -123,7 +127,7 @@ module Snapshot
123
127
  # Simulator could stil be booting with Apple logo
124
128
  # Need to wait "some amount of time" until home screen shows
125
129
  boot_sleep = ENV["SNAPSHOT_SIMULATOR_WAIT_FOR_BOOT_TIMEOUT"].to_i || 10
126
- UI.message("Waiting #{boot_sleep} seconds for device to fully boot before overriding status bar... Set 'SNAPSHOT_SIMULATOR_WAIT_FOR_BOOT_TIMEOUT' environemnt variable to adjust timeout")
130
+ UI.message("Waiting #{boot_sleep} seconds for device to fully boot before overriding status bar... Set 'SNAPSHOT_SIMULATOR_WAIT_FOR_BOOT_TIMEOUT' environment variable to adjust timeout")
127
131
  sleep(boot_sleep) if boot_sleep > 0
128
132
 
129
133
  UI.message("Overriding Status Bar")
@@ -131,7 +135,10 @@ module Snapshot
131
135
  if arguments.nil? || arguments.empty?
132
136
  # The time needs to be passed as ISO8601 so the simulator formats it correctly
133
137
  time = Time.new(2007, 1, 9, 9, 41, 0)
134
- arguments = "--time #{time.iso8601} --dataNetwork wifi --wifiMode active --wifiBars 3 --cellularMode active --cellularBars 4 --batteryState charged --batteryLevel 100"
138
+
139
+ # If you don't override the operator name, you'll get "Carrier" in the status bar on no-notch devices such as iPhone 8. Pass an empty string to blank it out.
140
+
141
+ arguments = "--time #{time.iso8601} --dataNetwork wifi --wifiMode active --wifiBars 3 --cellularMode active --operatorName '' --cellularBars 4 --batteryState charged --batteryLevel 100"
135
142
  end
136
143
 
137
144
  Helper.backticks("xcrun simctl status_bar #{device_udid} override #{arguments} &> /dev/null")
@@ -27,10 +27,45 @@ module Snapshot
27
27
  tee_command << log_path.shellescape if log_path
28
28
 
29
29
  pipe = ["| #{tee_command.join(' ')}"]
30
- if Snapshot.config[:disable_xcpretty]
31
- return pipe
30
+
31
+ formatter = Snapshot.config[:xcodebuild_formatter].chomp
32
+ options = legacy_xcpretty_options
33
+
34
+ if Snapshot.config[:disable_xcpretty] || formatter == ''
35
+ UI.verbose("Not using an xcodebuild formatter")
36
+ elsif !options.empty?
37
+ UI.important("Detected legacy xcpretty being used so formatting wth xcpretty")
38
+ UI.important("Option(s) used: #{options.join(', ')}")
39
+ pipe += pipe_xcpretty
40
+ elsif formatter == 'xcpretty'
41
+ pipe += pipe_xcpretty
42
+ elsif formatter == 'xcbeautify'
43
+ pipe += pipe_xcbeautify
44
+ else
45
+ pipe << "| #{formatter}"
46
+ end
47
+
48
+ pipe
49
+ end
50
+
51
+ def pipe_xcbeautify
52
+ pipe = ['| xcbeautify']
53
+
54
+ if FastlaneCore::Helper.colors_disabled?
55
+ pipe << '--disable-colored-output'
32
56
  end
33
57
 
58
+ return pipe
59
+ end
60
+
61
+ def legacy_xcpretty_options
62
+ options = []
63
+ options << "xcpretty_args" if Snapshot.config[:xcpretty_args]
64
+ return options
65
+ end
66
+
67
+ def pipe_xcpretty
68
+ pipe = []
34
69
  xcpretty = "xcpretty #{Snapshot.config[:xcpretty_args]}"
35
70
  xcpretty << "--no-color" if Helper.colors_disabled?
36
71
  pipe << "| #{xcpretty}"
@@ -18,6 +18,7 @@ require_relative 'tunes/errors'
18
18
  require_relative 'globals'
19
19
  require_relative 'provider'
20
20
  require_relative 'stats_middleware'
21
+ require_relative 'hashcash'
21
22
 
22
23
  Faraday::Utils.default_params_encoder = Faraday::FlatParamsEncoder
23
24
 
@@ -70,10 +71,10 @@ module Spaceship
70
71
 
71
72
  # @return (Array) A list of all available teams
72
73
  def teams
73
- user_details_data['associatedAccounts'].sort_by do |team|
74
+ user_details_data['availableProviders'].sort_by do |team|
74
75
  [
75
- team['contentProvider']['name'],
76
- team['contentProvider']['contentProviderId']
76
+ team['name'],
77
+ team['providerId']
77
78
  ]
78
79
  end
79
80
  end
@@ -124,8 +125,8 @@ module Spaceship
124
125
  # "userName"=>"detlef@krausefx.com"}
125
126
  def user_details_data
126
127
  return @_cached_user_details if @_cached_user_details
127
- r = request(:get, '/WebObjects/iTunesConnect.woa/ra/user/detail')
128
- @_cached_user_details = parse_response(r, 'data')
128
+ r = request(:get, "https://appstoreconnect.apple.com/olympus/v1/session")
129
+ @_cached_user_details = parse_response(r)
129
130
  end
130
131
 
131
132
  # @return (String) The currently selected Team ID
@@ -135,7 +136,7 @@ module Spaceship
135
136
  if teams.count > 1
136
137
  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.")
137
138
  end
138
- @current_team_id ||= user_details_data['sessionToken']['contentProviderId']
139
+ @current_team_id ||= user_details_data['provider']['providerId']
139
140
  end
140
141
 
141
142
  # Set a new team ID which will be used from now on
@@ -144,12 +145,11 @@ module Spaceship
144
145
  # following confusing error message
145
146
  #
146
147
  # invalid content provider id
147
- #
148
148
  available_teams = teams.collect do |team|
149
149
  {
150
- team_id: (team["contentProvider"] || {})["contentProviderId"],
151
- public_team_id: (team["contentProvider"] || {})["contentProviderPublicId"],
152
- team_name: (team["contentProvider"] || {})["name"]
150
+ team_id: team["providerId"],
151
+ public_team_id: team["publicProviderId"],
152
+ team_name: team["name"]
153
153
  }
154
154
  end
155
155
 
@@ -163,21 +163,10 @@ module Spaceship
163
163
  end
164
164
 
165
165
  response = request(:post) do |req|
166
- req.url("https://appstoreconnect.apple.com/olympus/v1/providerSwitchRequests")
167
- req.body = {
168
- "data": {
169
- "type": "providerSwitchRequests",
170
- "relationships": {
171
- "provider": {
172
- "data": {
173
- "type": "providers",
174
- "id": result[:public_team_id]
175
- }
176
- }
177
- }
178
- }
179
- }.to_json
166
+ req.url("https://appstoreconnect.apple.com/olympus/v1/session")
167
+ req.body = { "provider": { "providerId": result[:team_id] } }.to_json
180
168
  req.headers['Content-Type'] = 'application/json'
169
+ req.headers['X-Requested-With'] = 'olympus-ui'
181
170
  end
182
171
 
183
172
  handle_itc_response(response.body)
@@ -391,10 +380,11 @@ module Spaceship
391
380
 
392
381
  keychain_entry = CredentialsManager::AccountManager.new(user: user, password: password)
393
382
  user ||= keychain_entry.user
394
- password = keychain_entry.password
383
+ password = keychain_entry.password(ask_if_missing: !Spaceship::Globals.check_session)
395
384
  end
396
385
 
397
386
  if user.to_s.strip.empty? || password.to_s.strip.empty?
387
+ exit_with_session_state(user, false) if Spaceship::Globals.check_session
398
388
  raise NoUserCredentialsError.new, "No login data provided"
399
389
  end
400
390
 
@@ -413,21 +403,16 @@ module Spaceship
413
403
  end
414
404
  end
415
405
 
416
- # This method is used for both the Apple Dev Portal and App Store Connect
417
- # This will also handle 2 step verification and 2 factor authentication
406
+ # Check if we have a cached/valid session
418
407
  #
419
- # It is called in `send_login_request` of sub classes (which the method `login`, above, transferred over to via `do_login`)
420
- # rubocop:disable Metrics/PerceivedComplexity
421
- def send_shared_login_request(user, password)
422
- # Check if we have a cached/valid session
423
- #
424
- # Background:
425
- # December 4th 2017 Apple introduced a rate limit - which is of course fine by itself -
426
- # but unfortunately also rate limits successful logins. If you call multiple tools in a
427
- # lane (e.g. call match 5 times), this would lock you out of the account for a while.
428
- # By loading existing sessions and checking if they're valid, we're sending less login requests.
429
- # More context on why this change was necessary https://github.com/fastlane/fastlane/pull/11108
430
- #
408
+ # Background:
409
+ # December 4th 2017 Apple introduced a rate limit - which is of course fine by itself -
410
+ # but unfortunately also rate limits successful logins. If you call multiple tools in a
411
+ # lane (e.g. call match 5 times), this would lock you out of the account for a while.
412
+ # By loading existing sessions and checking if they're valid, we're sending less login requests.
413
+ # More context on why this change was necessary https://github.com/fastlane/fastlane/pull/11108
414
+ #
415
+ def has_valid_session
431
416
  # If there was a successful manual login before, we have a session on disk
432
417
  if load_session_from_file
433
418
  # Check if the session is still valid here
@@ -462,6 +447,23 @@ module Spaceship
462
447
  #
463
448
  # After this point, we sure have no valid session any more and have to create a new one
464
449
  #
450
+ return false
451
+ end
452
+
453
+ # This method is used for both the Apple Dev Portal and App Store Connect
454
+ # This will also handle 2 step verification and 2 factor authentication
455
+ #
456
+ # It is called in `send_login_request` of sub classes (which the method `login`, above, transferred over to via `do_login`)
457
+ # rubocop:disable Metrics/PerceivedComplexity
458
+ def send_shared_login_request(user, password)
459
+ # Check if the cache or FASTLANE_SESSION is still valid
460
+ has_valid_session = self.has_valid_session
461
+
462
+ # Exit if `--check_session` flag was passed
463
+ exit_with_session_state(user, has_valid_session) if Spaceship::Globals.check_session
464
+
465
+ # If the session is valid no need to attempt to generate a new one.
466
+ return true if has_valid_session
465
467
 
466
468
  data = {
467
469
  accountName: user,
@@ -489,6 +491,12 @@ module Spaceship
489
491
  modified_cookie.gsub!(unescaped_important_cookie, escaped_important_cookie)
490
492
  end
491
493
 
494
+ # Fixes issue https://github.com/fastlane/fastlane/issues/21071
495
+ # On 2023-02-23, Apple added a custom implementation
496
+ # of hashcash to their auth flow
497
+ # hashcash = nil
498
+ hashcash = self.fetch_hashcash
499
+
492
500
  response = request(:post) do |req|
493
501
  req.url("https://idmsa.apple.com/appleauth/auth/signin")
494
502
  req.body = data.to_json
@@ -497,6 +505,7 @@ module Spaceship
497
505
  req.headers['X-Apple-Widget-Key'] = self.itc_service_key
498
506
  req.headers['Accept'] = 'application/json, text/javascript'
499
507
  req.headers["Cookie"] = modified_cookie if modified_cookie
508
+ req.headers["X-Apple-HC"] = hashcash if hashcash
500
509
  end
501
510
  rescue UnauthorizedAccessError
502
511
  raise InvalidUserCredentialsError.new, "Invalid username and password combination. Used '#{user}' as the username."
@@ -533,7 +542,7 @@ module Spaceship
533
542
  raise AppleIDAndPrivacyAcknowledgementNeeded.new, "Need to acknowledge to Apple's Apple ID and Privacy statement. " \
534
543
  "Please manually log into https://appleid.apple.com (or https://appstoreconnect.apple.com) to acknowledge the statement. " \
535
544
  "Your account might also be asked to upgrade to 2FA. " \
536
- "Set SPACESHIP_SKIP_2FA_UPGRADE=1 for fastlane to automaticaly bypass 2FA upgrade if possible."
545
+ "Set SPACESHIP_SKIP_2FA_UPGRADE=1 for fastlane to automatically bypass 2FA upgrade if possible."
537
546
  elsif (response['Set-Cookie'] || "").include?("itctx")
538
547
  raise "Looks like your Apple ID is not enabled for App Store Connect, make sure to be able to login online"
539
548
  else
@@ -544,6 +553,21 @@ module Spaceship
544
553
  end
545
554
  # rubocop:enable Metrics/PerceivedComplexity
546
555
 
556
+ def fetch_hashcash
557
+ response = request(:get, "https://idmsa.apple.com/appleauth/auth/signin?widgetKey=#{self.itc_service_key}")
558
+ headers = response.headers
559
+
560
+ bits = headers["X-Apple-HC-Bits"]
561
+ challenge = headers["X-Apple-HC-Challenge"]
562
+
563
+ if bits.nil? || challenge.nil?
564
+ puts("Unable to find 'X-Apple-HC-Bits' and 'X-Apple-HC-Challenge' to make hashcash")
565
+ return nil
566
+ end
567
+
568
+ return Spaceship::Hashcash.make(bits: bits, challenge: challenge)
569
+ end
570
+
547
571
  # Get the `itctx` from the new (22nd May 2017) API endpoint "olympus"
548
572
  # Update (29th March 2019) olympus migrates to new appstoreconnect API
549
573
  def fetch_olympus_session
@@ -566,6 +590,13 @@ module Spaceship
566
590
  return false
567
591
  end
568
592
 
593
+ # This method is used to log if the session is valid or not and then exit
594
+ # It is called when the `--check_session` flag is passed
595
+ def exit_with_session_state(user, has_valid_session)
596
+ puts("#{has_valid_session ? 'Valid' : 'No valid'} session found (#{user}). Exiting.")
597
+ exit(has_valid_session)
598
+ end
599
+
569
600
  def itc_service_key
570
601
  return @service_key if @service_key
571
602
 
@@ -41,7 +41,7 @@ module Spaceship
41
41
  c.syntax = 'fastlane spaceship spaceauth'
42
42
  c.description = 'Authentication helper for spaceship/fastlane to work with Apple 2-Step/2FA'
43
43
  c.option('--copy_to_clipboard', 'Whether the session string should be copied to clipboard. For more info see https://docs.fastlane.tools/best-practices/continuous-integration/#storing-a-manually-verified-session-using-spaceauth`')
44
-
44
+ c.option('--check_session', 'Check to see if there is a valid session (either in the cache or via FASTLANE_SESSION). Sets the exit code to 0 if the session is valid or 1 if not.') { Spaceship::Globals.check_session = true }
45
45
  c.action do |args, options|
46
46
  Spaceship::SpaceauthRunner.new(username: options.user, copy_to_clipboard: options.copy_to_clipboard).run
47
47
  end
@@ -157,8 +157,6 @@ module Spaceship
157
157
  end
158
158
 
159
159
  def with_asc_retry(tries = 5, &_block)
160
- tries = 1 if Object.const_defined?("SpecHelper")
161
-
162
160
  response = yield
163
161
 
164
162
  status = response.status if response
@@ -170,9 +168,16 @@ module Spaceship
170
168
 
171
169
  return response
172
170
  rescue UnauthorizedAccessError => error
173
- # Catch unathorized access and re-raising
174
- # There is no need to try again
175
- raise error
171
+ tries -= 1
172
+ puts(error) if Spaceship::Globals.verbose?
173
+ if tries.zero?
174
+ raise error
175
+ else
176
+ msg = "Token has expired or has been revoked! Trying to refresh..."
177
+ puts(msg) if Spaceship::Globals.verbose?
178
+ @token.refresh!
179
+ retry
180
+ end
176
181
  rescue TimeoutRetryError => error
177
182
  tries -= 1
178
183
  puts(error) if Spaceship::Globals.verbose?
@@ -0,0 +1,26 @@
1
+ require_relative '../model'
2
+ module Spaceship
3
+ class ConnectAPI
4
+ class Actor
5
+ include Spaceship::ConnectAPI::Model
6
+
7
+ attr_accessor :actor_type
8
+ attr_accessor :user_first_name
9
+ attr_accessor :user_last_name
10
+ attr_accessor :user_email
11
+ attr_accessor :api_key_id
12
+
13
+ attr_mapping({
14
+ actorType: 'actor_type',
15
+ userFirstName: 'user_first_name',
16
+ userLastName: 'user_last_name',
17
+ userEmail: 'user_email',
18
+ apiKeyId: 'api_key_id'
19
+ })
20
+
21
+ def self.type
22
+ return 'actors'
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,6 +1,7 @@
1
1
  require_relative '../model'
2
2
  require_relative './build'
3
3
 
4
+ # rubocop:disable Metrics/ClassLength
4
5
  module Spaceship
5
6
  class ConnectAPI
6
7
  class App
@@ -53,12 +54,12 @@ module Spaceship
53
54
  "contentRightsDeclaration" => "content_rights_declaration",
54
55
 
55
56
  "appStoreVersions" => "app_store_versions",
57
+ # This attribute is already deprecated. It will be removed in a future release.
56
58
  "prices" => "prices"
57
59
  })
58
60
 
59
61
  ESSENTIAL_INCLUDES = [
60
- "appStoreVersions",
61
- "prices"
62
+ "appStoreVersions"
62
63
  ].join(",")
63
64
 
64
65
  def self.type
@@ -100,10 +101,12 @@ module Spaceship
100
101
  return client.get_app(app_id: app_id, includes: includes).first
101
102
  end
102
103
 
103
- def update(client: nil, attributes: nil, app_price_tier_id: nil, territory_ids: nil)
104
+ # Updates app attributes, price tier and availability of an app in territories
105
+ # Check Tunes patch_app method for explanation how to use territory_ids parameter with allow_removing_from_sale to remove app from sale
106
+ def update(client: nil, attributes: nil, app_price_tier_id: nil, territory_ids: nil, allow_removing_from_sale: false)
104
107
  client ||= Spaceship::ConnectAPI
105
108
  attributes = reverse_attr_mapping(attributes)
106
- return client.patch_app(app_id: id, attributes: attributes, app_price_tier_id: app_price_tier_id, territory_ids: territory_ids)
109
+ return client.patch_app(app_id: id, attributes: attributes, app_price_tier_id: app_price_tier_id, territory_ids: territory_ids, allow_removing_from_sale: allow_removing_from_sale)
107
110
  end
108
111
 
109
112
  #
@@ -361,9 +364,8 @@ module Spaceship
361
364
  def get_build_deliveries(client: nil, filter: {}, includes: nil, limit: nil, sort: nil)
362
365
  client ||= Spaceship::ConnectAPI
363
366
  filter ||= {}
364
- filter[:app] = id
365
367
 
366
- resps = client.get_build_deliveries(filter: filter, includes: includes, limit: limit, sort: sort).all_pages
368
+ resps = client.get_build_deliveries(app_id: id, filter: filter, includes: includes, limit: limit, sort: sort).all_pages
367
369
  return resps.flat_map(&:to_models)
368
370
  end
369
371
 
@@ -414,6 +416,49 @@ module Spaceship
414
416
  })
415
417
  end
416
418
 
419
+ #
420
+ # Review Submissions
421
+ #
422
+
423
+ def get_ready_review_submission(client: nil, platform:, includes: nil)
424
+ client ||= Spaceship::ConnectAPI
425
+ filter = {
426
+ state: [
427
+ Spaceship::ConnectAPI::ReviewSubmission::ReviewSubmissionState::READY_FOR_REVIEW
428
+ ].join(","),
429
+ platform: platform
430
+ }
431
+
432
+ return get_review_submissions(client: client, filter: filter, includes: includes).first
433
+ end
434
+
435
+ def get_in_progress_review_submission(client: nil, platform:, includes: nil)
436
+ client ||= Spaceship::ConnectAPI
437
+ filter = {
438
+ state: [
439
+ Spaceship::ConnectAPI::ReviewSubmission::ReviewSubmissionState::WAITING_FOR_REVIEW,
440
+ Spaceship::ConnectAPI::ReviewSubmission::ReviewSubmissionState::IN_REVIEW,
441
+ Spaceship::ConnectAPI::ReviewSubmission::ReviewSubmissionState::UNRESOLVED_ISSUES
442
+ ].join(","),
443
+ platform: platform
444
+ }
445
+
446
+ return get_review_submissions(client: client, filter: filter, includes: includes).first
447
+ end
448
+
449
+ # appStoreVersionForReview,items
450
+ def get_review_submissions(client: nil, filter: {}, includes: nil, limit: nil, sort: nil)
451
+ client ||= Spaceship::ConnectAPI
452
+ resps = client.get_review_submissions(app_id: id, filter: filter, includes: includes, limit: limit, sort: sort).all_pages
453
+ return resps.flat_map(&:to_models)
454
+ end
455
+
456
+ def create_review_submission(client: nil, platform:)
457
+ client ||= Spaceship::ConnectAPI
458
+ resp = client.post_review_submission(app_id: id, platform: platform)
459
+ return resp.to_models.first
460
+ end
461
+
417
462
  #
418
463
  # Users
419
464
  #
@@ -434,3 +479,4 @@ module Spaceship
434
479
  end
435
480
  end
436
481
  end
482
+ # rubocop:enable Metrics/ClassLength
@@ -25,6 +25,7 @@ module Spaceship
25
25
  WAITING_FOR_REVIEW = "WAITING_FOR_REVIEW"
26
26
  DEVELOPER_REJECTED = "DEVELOPER_REJECTED"
27
27
  DEVELOPER_REMOVED_FROM_SALE = "DEVELOPER_REMOVED_FROM_SALE"
28
+ READY_FOR_REVIEW = "READY_FOR_REVIEW"
28
29
  REJECTED = "REJECTED"
29
30
  PREPARE_FOR_SUBMISSION = "PREPARE_FOR_SUBMISSION"
30
31
  METADATA_REJECTED = "METADATA_REJECTED"