fastlane 2.149.1 → 2.150.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/deliver/lib/deliver.rb +0 -1
  3. data/deliver/lib/deliver/app_screenshot.rb +26 -25
  4. data/deliver/lib/deliver/options.rb +6 -11
  5. data/deliver/lib/deliver/runner.rb +7 -4
  6. data/deliver/lib/deliver/setup.rb +5 -30
  7. data/deliver/lib/deliver/submit_for_review.rb +124 -87
  8. data/deliver/lib/deliver/upload_metadata.rb +284 -143
  9. data/deliver/lib/deliver/upload_price_tier.rb +15 -8
  10. data/deliver/lib/deliver/upload_screenshots.rb +86 -37
  11. data/fastlane/lib/fastlane/actions/docs/capture_ios_screenshots.md +1 -1
  12. data/fastlane/lib/fastlane/actions/docs/upload_to_app_store.md.erb +3 -11
  13. data/fastlane/lib/fastlane/actions/docs/upload_to_play_store.md +3 -2
  14. data/fastlane/lib/fastlane/actions/download_dsyms.rb +7 -1
  15. data/fastlane/lib/fastlane/actions/google_play_track_release_names.rb +74 -0
  16. data/fastlane/lib/fastlane/actions/slack.rb +1 -1
  17. data/fastlane/lib/fastlane/actions/spm.rb +7 -0
  18. data/fastlane/lib/fastlane/actions/upload_symbols_to_crashlytics.rb +1 -32
  19. data/fastlane/lib/fastlane/lane.rb +3 -3
  20. data/fastlane/lib/fastlane/swift_fastlane_function.rb +8 -4
  21. data/fastlane/lib/fastlane/version.rb +1 -1
  22. data/fastlane/swift/ControlCommand.swift +1 -0
  23. data/fastlane/swift/Fastlane.swift +48 -12
  24. data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/xcshareddata/xcschemes/FastlaneRunner.xcscheme +3 -9
  25. data/fastlane/swift/LaneFileProtocol.swift +2 -5
  26. data/fastlane/swift/MatchfileProtocol.swift +1 -1
  27. data/fastlane/swift/RubyCommand.swift +29 -6
  28. data/fastlane/swift/RubyCommandable.swift +1 -0
  29. data/fastlane/swift/Runner.swift +85 -13
  30. data/fastlane/swift/ScanfileProtocol.swift +1 -1
  31. data/fastlane/swift/SnapshotfileProtocol.swift +3 -3
  32. data/fastlane/swift/SocketClient.swift +76 -45
  33. data/fastlane/swift/SocketClientDelegateProtocol.swift +1 -1
  34. data/fastlane/swift/SocketResponse.swift +1 -0
  35. data/fastlane_core/lib/fastlane_core/configuration/config_item.rb +1 -3
  36. data/fastlane_core/lib/fastlane_core/pkg_file_analyser.rb +7 -0
  37. data/frameit/lib/frameit/device_types.rb +100 -100
  38. data/produce/lib/produce/itunes_connect.rb +20 -20
  39. data/produce/lib/produce/options.rb +3 -3
  40. data/sigh/lib/assets/resign.sh +7 -7
  41. data/snapshot/lib/assets/SnapshotHelper.swift +5 -5
  42. data/snapshot/lib/assets/SnapshotHelperXcode8.swift +3 -3
  43. data/snapshot/lib/snapshot/options.rb +0 -1
  44. data/snapshot/lib/snapshot/reports_generator.rb +8 -1
  45. data/spaceship/lib/spaceship/.DS_Store +0 -0
  46. data/spaceship/lib/spaceship/connect_api.rb +21 -2
  47. data/spaceship/lib/spaceship/connect_api/client.rb +47 -11
  48. data/spaceship/lib/spaceship/connect_api/model.rb +1 -1
  49. data/spaceship/lib/spaceship/connect_api/models/age_rating_declaration.rb +109 -0
  50. data/spaceship/lib/spaceship/connect_api/models/app.rb +113 -3
  51. data/spaceship/lib/spaceship/connect_api/models/app_category.rb +94 -0
  52. data/spaceship/lib/spaceship/connect_api/models/app_info.rb +74 -0
  53. data/spaceship/lib/spaceship/connect_api/models/app_info_localization.rb +38 -0
  54. data/spaceship/lib/spaceship/connect_api/models/app_price.rb +22 -0
  55. data/spaceship/lib/spaceship/connect_api/models/app_price_tier.rb +12 -0
  56. data/spaceship/lib/spaceship/connect_api/models/app_review_attachment.rb +81 -0
  57. data/spaceship/lib/spaceship/connect_api/models/app_screenshot.rb +117 -0
  58. data/spaceship/lib/spaceship/connect_api/models/app_screenshot_set.rb +101 -0
  59. data/spaceship/lib/spaceship/connect_api/models/app_store_review_detail.rb +51 -0
  60. data/spaceship/lib/spaceship/connect_api/models/app_store_version.rb +182 -0
  61. data/spaceship/lib/spaceship/connect_api/models/app_store_version_localization.rb +70 -0
  62. data/spaceship/lib/spaceship/connect_api/models/app_store_version_phased_release.rb +36 -0
  63. data/spaceship/lib/spaceship/connect_api/models/app_store_version_submission.rb +26 -0
  64. data/spaceship/lib/spaceship/connect_api/models/build.rb +4 -0
  65. data/spaceship/lib/spaceship/connect_api/models/idfa_declaration.rb +40 -0
  66. data/spaceship/lib/spaceship/connect_api/models/reset_ratings_request.rb +26 -0
  67. data/spaceship/lib/spaceship/connect_api/testflight/testflight.rb +10 -3
  68. data/spaceship/lib/spaceship/connect_api/tunes/client.rb +33 -0
  69. data/spaceship/lib/spaceship/connect_api/tunes/tunes.rb +703 -0
  70. data/spaceship/lib/spaceship/spaceauth_runner.rb +2 -2
  71. data/supply/lib/supply/client.rb +19 -0
  72. data/supply/lib/supply/reader.rb +16 -0
  73. metadata +27 -24
  74. data/deliver/lib/deliver/upload_assets.rb +0 -27
  75. data/scan/lib/scan/.test_command_generator.rb.swp +0 -0
  76. data/snapshot/lib/snapshot/.test_command_generator_base.rb.swp +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7e38d836b49a278f1c3fd95c820aa3fe9dd7fa4d7f3c0fedfa5ff4fdf4ef033a
4
- data.tar.gz: 7a5d7180b0bf7f32989a7dbc8396a2215d68e645691f0c7afff75817324a3e1e
3
+ metadata.gz: 8a0da99338a957f184c8f61225f84bbea77cf2e295f9a7fc21918095ec2967e3
4
+ data.tar.gz: '0998f1c0adaa75fcabb51584113223c552268c9f86c844771bdc27b1f74f10d1'
5
5
  SHA512:
6
- metadata.gz: 51f0e319102f54e6e1a3878b40adf4a019042e64fcee0047d81564321f5e6b11803ac5701171f7e5ef23403f8ed169204e18635109a94928e61334b16cb36f22
7
- data.tar.gz: 8d86698444bc4f689bc7ada08f30e5e9b335f8f32e8a87c7d9f919bb99f148afd0c4fe84abd421fe2c3114f9c530f75cc26dd360d7108a5f6e93a820ed2bedcc
6
+ metadata.gz: 49d0496a16e951b91d512f972d8e5a5f4af1bae7bc68f8a71f32d328b3e1868e0d3b5dfa948723e7c82414f3c2672a6ec73a99884822ccec740aabd2ef1632a7
7
+ data.tar.gz: 508186460c3e7e4c13bef4f3ad019a5f81374ddaffd32844aa079e02c2165dbb2c454aa2441e150c865aa3c42f526af7dbf494d53911ebfe99cbc02ae2cf5d3d
@@ -6,7 +6,6 @@ require_relative 'deliver/runner'
6
6
  require_relative 'deliver/upload_metadata'
7
7
  require_relative 'deliver/upload_screenshots'
8
8
  require_relative 'deliver/upload_price_tier'
9
- require_relative 'deliver/upload_assets'
10
9
  require_relative 'deliver/submit_for_review'
11
10
  require_relative 'deliver/app_screenshot'
12
11
  require_relative 'deliver/html_generator'
@@ -1,6 +1,7 @@
1
1
  require 'fastimage'
2
2
 
3
3
  require_relative 'module'
4
+ require 'spaceship/connect_api/models/app_screenshot_set'
4
5
 
5
6
  module Deliver
6
7
  # AppScreenshot represents one screenshots for one specific locale and
@@ -95,31 +96,31 @@ module Deliver
95
96
  # The iTC API requires a different notation for the device
96
97
  def device_type
97
98
  matching = {
98
- ScreenSize::IOS_35 => "iphone35",
99
- ScreenSize::IOS_40 => "iphone4",
100
- ScreenSize::IOS_47 => "iphone6", # also 7 & 8
101
- ScreenSize::IOS_55 => "iphone6Plus", # also 7 Plus & 8 Plus
102
- ScreenSize::IOS_58 => "iphone58",
103
- ScreenSize::IOS_65 => "iphone65",
104
- ScreenSize::IOS_IPAD => "ipad",
105
- ScreenSize::IOS_IPAD_10_5 => "ipad105",
106
- ScreenSize::IOS_IPAD_11 => "ipadPro11",
107
- ScreenSize::IOS_IPAD_PRO => "ipadPro",
108
- ScreenSize::IOS_IPAD_PRO_12_9 => "ipadPro129",
109
- ScreenSize::IOS_40_MESSAGES => "iphone4",
110
- ScreenSize::IOS_47_MESSAGES => "iphone6", # also 7 & 8
111
- ScreenSize::IOS_55_MESSAGES => "iphone6Plus", # also 7 Plus & 8 Plus
112
- ScreenSize::IOS_58_MESSAGES => "iphone58",
113
- ScreenSize::IOS_65_MESSAGES => "iphone65",
114
- ScreenSize::IOS_IPAD_MESSAGES => "ipad",
115
- ScreenSize::IOS_IPAD_PRO_MESSAGES => "ipadPro",
116
- ScreenSize::IOS_IPAD_PRO_12_9_MESSAGES => "ipadPro129",
117
- ScreenSize::IOS_IPAD_10_5_MESSAGES => "ipad105",
118
- ScreenSize::IOS_IPAD_11_MESSAGES => "ipadPro11",
119
- ScreenSize::MAC => "desktop",
120
- ScreenSize::IOS_APPLE_WATCH => "watch",
121
- ScreenSize::IOS_APPLE_WATCH_SERIES4 => "watchSeries4",
122
- ScreenSize::APPLE_TV => "appleTV"
99
+ ScreenSize::IOS_35 => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_IPHONE_35,
100
+ ScreenSize::IOS_40 => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_IPHONE_40,
101
+ ScreenSize::IOS_47 => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_IPHONE_47, # also 7 & 8
102
+ ScreenSize::IOS_55 => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_IPHONE_55, # also 7 Plus & 8 Plus
103
+ ScreenSize::IOS_58 => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_IPHONE_58,
104
+ ScreenSize::IOS_65 => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_IPHONE_65,
105
+ ScreenSize::IOS_IPAD => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_IPAD_97,
106
+ ScreenSize::IOS_IPAD_10_5 => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_IPAD_105,
107
+ ScreenSize::IOS_IPAD_11 => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_IPAD_PRO_3GEN_11,
108
+ ScreenSize::IOS_IPAD_PRO => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_IPAD_PRO_129,
109
+ ScreenSize::IOS_IPAD_PRO_12_9 => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_IPAD_PRO_3GEN_129,
110
+ ScreenSize::IOS_40_MESSAGES => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::IMESSAGE_APP_IPHONE_40,
111
+ ScreenSize::IOS_47_MESSAGES => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::IMESSAGE_APP_IPHONE_47, # also 7 & 8
112
+ ScreenSize::IOS_55_MESSAGES => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::IMESSAGE_APP_IPHONE_55, # also 7 Plus & 8 Plus
113
+ ScreenSize::IOS_58_MESSAGES => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::IMESSAGE_APP_IPHONE_58,
114
+ ScreenSize::IOS_65_MESSAGES => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::IMESSAGE_APP_IPHONE_65,
115
+ ScreenSize::IOS_IPAD_MESSAGES => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::IMESSAGE_APP_IPAD_97,
116
+ ScreenSize::IOS_IPAD_PRO_MESSAGES => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_IPAD_PRO_129,
117
+ ScreenSize::IOS_IPAD_PRO_12_9_MESSAGES => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_IPAD_PRO_3GEN_129,
118
+ ScreenSize::IOS_IPAD_10_5_MESSAGES => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::IMESSAGE_APP_IPAD_105,
119
+ ScreenSize::IOS_IPAD_11_MESSAGES => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::IMESSAGE_APP_IPAD_PRO_3GEN_11,
120
+ ScreenSize::MAC => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_DESKTOP,
121
+ ScreenSize::IOS_APPLE_WATCH => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_WATCH_SERIES_3,
122
+ ScreenSize::IOS_APPLE_WATCH_SERIES4 => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::APP_WATCH_SERIES_4,
123
+ # ScreenSize::APPLE_TV => Spaceship::ConnectAPI::AppScreenshotSet::DisplayType::
123
124
  }
124
125
  return matching[self.screen_size]
125
126
  end
@@ -2,7 +2,6 @@ require 'fastlane_core/configuration/config_item'
2
2
  require 'credentials_manager/appfile_config'
3
3
 
4
4
  require_relative 'module'
5
- require_relative 'upload_assets'
6
5
 
7
6
  module Deliver
8
7
  # rubocop:disable Metrics/ClassLength
@@ -206,6 +205,7 @@ module Deliver
206
205
  short_option: "-b",
207
206
  description: "Extra information for the submission (e.g. compliance specifications, IDFA settings)",
208
207
  is_string: false,
208
+ type: Hash,
209
209
  optional: true),
210
210
 
211
211
  # affiliation
@@ -283,6 +283,7 @@ module Deliver
283
283
  FastlaneCore::ConfigItem.new(key: :individual_metadata_items,
284
284
  env_name: "DELIVER_INDIVUDAL_METADATA_ITEMS",
285
285
  description: "An array of localized metadata items to upload individually by language so that errors can be identified. E.g. ['name', 'keywords', 'description']. Note: slow",
286
+ deprecated: "Removed after the migration to the new App Store Connect API in June 2020",
286
287
  is_string: false,
287
288
  type: Array,
288
289
  default_value: []),
@@ -291,21 +292,15 @@ module Deliver
291
292
  FastlaneCore::ConfigItem.new(key: :app_icon,
292
293
  env_name: "DELIVER_APP_ICON_PATH",
293
294
  description: "Metadata: The path to the app icon",
295
+ deprecated: "Removed after the migration to the new App Store Connect API in June 2020",
294
296
  optional: true,
295
- short_option: "-l",
296
- verify_block: proc do |value|
297
- UI.user_error!("Could not find png file at path '#{File.expand_path(value)}'") unless File.exist?(value)
298
- UI.user_error!("'#{value}' doesn't seem to be one of the supported files. supported: #{Deliver::UploadAssets::SUPPORTED_ICON_EXTENSIONS.join(',')}") unless Deliver::UploadAssets::SUPPORTED_ICON_EXTENSIONS.include?(File.extname(value).downcase)
299
- end),
297
+ short_option: "-l"),
300
298
  FastlaneCore::ConfigItem.new(key: :apple_watch_app_icon,
301
299
  env_name: "DELIVER_APPLE_WATCH_APP_ICON_PATH",
302
300
  description: "Metadata: The path to the Apple Watch app icon",
301
+ deprecated: "Removed after the migration to the new App Store Connect API in June 2020",
303
302
  optional: true,
304
- short_option: "-q",
305
- verify_block: proc do |value|
306
- UI.user_error!("Could not find png file at path '#{File.expand_path(value)}'") unless File.exist?(value)
307
- UI.user_error!("'#{value}' doesn't seem to be one of the supported files. supported: #{Deliver::UploadAssets::SUPPORTED_ICON_EXTENSIONS.join(',')}") unless Deliver::UploadAssets::SUPPORTED_ICON_EXTENSIONS.include?(File.extname(value).downcase)
308
- end),
303
+ short_option: "-q"),
309
304
  FastlaneCore::ConfigItem.new(key: :copyright,
310
305
  env_name: "DELIVER_COPYRIGHT",
311
306
  description: "Metadata: The copyright notice",
@@ -7,7 +7,6 @@ require 'fastlane_core/itunes_transporter'
7
7
  require 'spaceship'
8
8
  require_relative 'html_generator'
9
9
  require_relative 'submit_for_review'
10
- require_relative 'upload_assets'
11
10
  require_relative 'upload_price_tier'
12
11
  require_relative 'upload_metadata'
13
12
  require_relative 'upload_screenshots'
@@ -87,9 +86,14 @@ module Deliver
87
86
  # If not, the new version will automatically be created
88
87
  def verify_version
89
88
  app_version = options[:app_version]
90
- UI.message("Making sure the latest version on App Store Connect matches '#{app_version}' from the ipa file...")
89
+ UI.message("Making sure the latest version on App Store Connect matches '#{app_version}'...")
91
90
 
92
- changed = options[:app].ensure_version!(app_version, platform: options[:platform])
91
+ legacy_app = options[:app]
92
+ app_id = legacy_app.apple_id
93
+ app = Spaceship::ConnectAPI::App.get(app_id: app_id)
94
+
95
+ platform = Spaceship::ConnectAPI::Platform.map(options[:platform])
96
+ changed = app.ensure_version!(app_version, platform: platform)
93
97
 
94
98
  if changed
95
99
  UI.success("Successfully set the version to '#{app_version}'")
@@ -120,7 +124,6 @@ module Deliver
120
124
  upload_metadata.upload(options)
121
125
  upload_screenshots.upload(options, screenshots)
122
126
  UploadPriceTier.new.upload(options)
123
- UploadAssets.new.upload(options) # e.g. app icon
124
127
  end
125
128
 
126
129
  # If options[:app_icon]/options[:apple_watch_app_icon]
@@ -60,9 +60,9 @@ module Deliver
60
60
  app_details = v.application.details
61
61
 
62
62
  # All the localised metadata
63
- (UploadMetadata::LOCALISED_VERSION_VALUES + UploadMetadata::LOCALISED_APP_VALUES).each do |key|
63
+ (UploadMetadata::LOCALISED_VERSION_VALUES.keys + UploadMetadata::LOCALISED_APP_VALUES.keys).each do |key|
64
64
  v.description.languages.each do |language|
65
- if UploadMetadata::LOCALISED_VERSION_VALUES.include?(key)
65
+ if UploadMetadata::LOCALISED_VERSION_VALUES.keys.include?(key)
66
66
  content = v.send(key)[language].to_s
67
67
  else
68
68
  content = app_details.send(key)[language].to_s
@@ -76,8 +76,8 @@ module Deliver
76
76
  end
77
77
 
78
78
  # All non-localised metadata
79
- (UploadMetadata::NON_LOCALISED_VERSION_VALUES + UploadMetadata::NON_LOCALISED_APP_VALUES).each do |key|
80
- if UploadMetadata::NON_LOCALISED_VERSION_VALUES.include?(key)
79
+ (UploadMetadata::NON_LOCALISED_VERSION_VALUES.keys + UploadMetadata::NON_LOCALISED_APP_VALUES).each do |key|
80
+ if UploadMetadata::NON_LOCALISED_VERSION_VALUES.keys.include?(key)
81
81
  content = v.send(key).to_s
82
82
  else
83
83
  content = app_details.send(key).to_s
@@ -88,19 +88,8 @@ module Deliver
88
88
  UI.message("Writing to '#{resulting_path}'")
89
89
  end
90
90
 
91
- # Trade Representative Contact Information
92
- UploadMetadata::TRADE_REPRESENTATIVE_CONTACT_INFORMATION_VALUES.each do |key, option_name|
93
- content = v.send(key).to_s
94
- content += "\n"
95
- base_dir = File.join(path, UploadMetadata::TRADE_REPRESENTATIVE_CONTACT_INFORMATION_DIR)
96
- FileUtils.mkdir_p(base_dir)
97
- resulting_path = File.join(base_dir, "#{option_name}.txt")
98
- File.write(resulting_path, content)
99
- UI.message("Writing to '#{resulting_path}'")
100
- end
101
-
102
91
  # Review information
103
- UploadMetadata::REVIEW_INFORMATION_VALUES.each do |key, option_name|
92
+ UploadMetadata::REVIEW_INFORMATION_VALUES_LEGACY.each do |key, option_name|
104
93
  content = v.send(key).to_s
105
94
  content += "\n"
106
95
  base_dir = File.join(path, UploadMetadata::REVIEW_INFORMATION_DIR)
@@ -111,20 +100,6 @@ module Deliver
111
100
  end
112
101
 
113
102
  UI.success("Successfully created new configuration files.")
114
-
115
- # get App icon + watch icon
116
- if v.large_app_icon.asset_token
117
- app_icon_extension = File.extname(v.large_app_icon.url)
118
- app_icon_path = File.join(path, "app_icon#{app_icon_extension}")
119
- File.write(app_icon_path, open(v.large_app_icon.url).read)
120
- UI.success("Successfully downloaded large app icon")
121
- end
122
- if v.watch_app_icon.asset_token
123
- watch_app_icon_extension = File.extname(v.watch_app_icon.url)
124
- watch_icon_path = File.join(path, "watch_icon#{watch_app_icon_extension}")
125
- File.write(watch_icon_path, open(v.watch_app_icon.url).read)
126
- UI.success("Successfully downloaded watch icon")
127
- end
128
103
  end
129
104
 
130
105
  def download_screenshots(path, options)
@@ -1,132 +1,169 @@
1
1
  require_relative 'module'
2
2
 
3
+ require 'fastlane_core/build_watcher'
4
+ require 'fastlane_core/ipa_file_analyser'
5
+ require 'fastlane_core/pkg_file_analyser'
6
+
3
7
  module Deliver
4
8
  class SubmitForReview
5
9
  def submit!(options)
6
- app = options[:app]
7
- select_build(options)
8
-
9
- UI.message("Submitting the app for review...")
10
- submission = app.create_submission(platform: options[:platform])
11
-
12
- # Set app submission information
13
- # Default Values
14
- submission.content_rights_contains_third_party_content = false
15
- submission.content_rights_has_rights = true
16
- submission.add_id_info_uses_idfa = false
17
-
18
- # User Values
19
- if options[:submission_information]
20
- options[:submission_information].each do |key, value|
21
- UI.message("Setting '#{key}' to '#{value}'...")
22
- submission.send("#{key}=", value)
23
- end
10
+ legacy_app = options[:app]
11
+ app_id = legacy_app.apple_id
12
+ app = Spaceship::ConnectAPI::App.get(app_id: app_id)
13
+
14
+ platform = Spaceship::ConnectAPI::Platform.map(options[:platform])
15
+ version = app.get_edit_app_store_version(platform: platform)
16
+
17
+ unless version
18
+ UI.user_error!("Cannot submit for review - could not find an editable version for '#{platform}'")
19
+ return
24
20
  end
25
21
 
26
- # Finalize app submission
27
- submission.complete!
22
+ build = select_build(options, app, version, platform)
23
+
24
+ update_export_compliance(options, app, build)
25
+ update_idfa(options, app, version)
26
+ update_submission_information(options, app)
27
+
28
+ version.create_app_store_version_submission
28
29
 
29
30
  UI.success("Successfully submitted the app for review!")
30
31
  end
31
32
 
32
- private def select_build(options)
33
- app = options[:app]
34
- app_version = options[:app_version]
35
- v = app.edit_version(platform: options[:platform])
36
-
33
+ private def select_build(options, app, version, platform)
37
34
  if options[:build_number] && options[:build_number] != "latest"
38
35
  UI.message("Selecting existing build-number: #{options[:build_number]}")
39
- if app_version
40
- build = v.candidate_builds.detect { |a| a.build_version == options[:build_number] && a.train_version == app_version }
41
- else
42
- build = v.candidate_builds.detect { |a| a.build_version == options[:build_number] }
43
- end
36
+
37
+ build = Spaceship::ConnectAPI::Build.all(
38
+ app_id: app.id,
39
+ version: options[:app_version],
40
+ build_number: options[:build_number],
41
+ platform: platform
42
+ ).first
43
+
44
44
  unless build
45
45
  UI.user_error!("Build number: #{options[:build_number]} does not exist")
46
46
  end
47
47
  else
48
48
  UI.message("Selecting the latest build...")
49
- build = wait_for_build(app, app_version)
49
+ build = wait_for_build_processing_to_be_complete(app: app, platform: platform, options: options)
50
50
  end
51
- UI.message("Selecting build #{app_version} (#{build.build_version})...")
51
+ UI.message("Selecting build #{build.app_version} (#{build.version})...")
52
52
 
53
- v.select_build(build)
54
- v.save!
53
+ version.select_build(build_id: build.id)
55
54
 
56
55
  UI.success("Successfully selected build")
57
- end
58
56
 
59
- def wait_for_build(app, app_version)
60
- UI.user_error!("Could not find app with app identifier") unless app
57
+ return build
58
+ end
61
59
 
62
- start = Time.now
63
- build = nil
60
+ def update_export_compliance(options, app, build)
61
+ submission_information = options[:submission_information] || {}
62
+ uses_encryption = submission_information[:export_compliance_uses_encryption]
64
63
 
65
- use_latest_version = app_version.nil?
64
+ UI.verbose("Updating build for export compliance status of '#{uses_encryption}'")
65
+ if build.uses_non_exempt_encryption.nil?
66
+ build = build.update(attributes: {
67
+ usesNonExemptEncryption: uses_encryption
68
+ })
69
+ end
70
+ UI.verbose("Updated build for export compliance status of '#{build.uses_non_exempt_encryption}'")
71
+ end
66
72
 
67
- loop do
68
- # Sometimes candidate_builds don't appear immediately after submission
69
- # Wait for candidate_builds to appear on App Store Connect
70
- # Issue https://github.com/fastlane/fastlane/issues/10411
71
- if use_latest_version
72
- candidate_builds = app.latest_version.candidate_builds
73
- else
74
- candidate_builds = app.tunes_all_builds_for_train(train: app_version)
73
+ def update_idfa(options, app, version)
74
+ submission_information = options[:submission_information] || {}
75
+ return unless submission_information.include?(:add_id_info_uses_idfa)
76
+
77
+ uses_idfa = submission_information[:add_id_info_uses_idfa]
78
+ idfa_declaration = begin
79
+ version.fetch_idfa_declaration
80
+ rescue
81
+ nil
82
+ end
83
+
84
+ UI.verbose("Updating app store version for IDFA status of '#{uses_idfa}'")
85
+ version = version.update(attributes: {
86
+ usesIdfa: uses_idfa
87
+ })
88
+ UI.verbose("Updated app store version for IDFA status of '#{version.uses_idfa}'")
89
+
90
+ if uses_idfa == false
91
+ if idfa_declaration
92
+ UI.verbose("Deleting IDFA delcaration")
93
+ idfa_declaration.delete!
94
+ UI.verbose("Deleted IDFA delcaration")
75
95
  end
76
- if (candidate_builds || []).count == 0
77
- UI.message("Waiting for candidate builds to appear...")
78
- if (Time.now - start) > (60 * 5)
79
- UI.user_error!("Could not find any available candidate builds on App Store Connect to submit")
80
- else
81
- sleep(30)
82
- next
83
- end
96
+ else
97
+ attributes = {}
98
+ if submission_information.include?(:add_id_info_limits_tracking)
99
+ attributes[:honorsLimitedAdTracking] = submission_information[:add_id_info_limits_tracking]
84
100
  end
85
101
 
86
- latest_build = find_build(candidate_builds)
87
-
88
- # if the app version isn't present in the hash (could happen if we are waiting for submission, but didn't provide
89
- # it explicitly and no ipa was passed to grab it from), then fall back to the best guess, which is the train_version
90
- # of the most recently uploaded build
91
- app_version ||= latest_build.train_version
92
-
93
- # Sometimes latest build will disappear and a different build would get selected
94
- # Only set build if no latest build found or if same build versions as previously fetched build
95
- # Issue: https://github.com/fastlane/fastlane/issues/10945
96
- if build.nil? || (latest_build && latest_build.build_version == build.build_version && latest_build.train_version == app_version)
97
- build = latest_build
102
+ if submission_information.include?(:add_id_info_serves_ads)
103
+ attributes[:servesAds] = submission_information[:add_id_info_serves_ads]
98
104
  end
99
105
 
100
- return build if build && build.processing == false
106
+ if submission_information.include?(:add_id_info_tracks_install)
107
+ attributes[:attributesAppInstallationToPreviousAd] = submission_information[:add_id_info_tracks_install]
108
+ end
101
109
 
102
- if build
103
- UI.message("Waiting App Store Connect processing for build #{app_version} (#{build.build_version})... this might take a while...")
104
- else
105
- UI.message("Waiting App Store Connect processing for build... this might take a while...")
110
+ if submission_information.include?(:add_id_info_tracks_action)
111
+ attributes[:attributesActionWithPreviousAd] = submission_information[:add_id_info_tracks_action]
106
112
  end
107
113
 
108
- if (Time.now - start) > (60 * 5)
109
- UI.message("")
110
- UI.message("You can tweet: \"App Store Connect #iosprocessingtime #{((Time.now - start) / 60).round} minutes\"")
114
+ if idfa_declaration
115
+ UI.verbose("Updating IDFA delcaration")
116
+ idfa_declaration.update(attributes: attributes)
117
+ UI.verbose("Updated IDFA delcaration")
118
+ else
119
+ UI.verbose("Creating IDFA delcaration")
120
+ version.create_idfa_declaration(attributes: attributes)
121
+ UI.verbose("Created IDFA delcaration")
111
122
  end
112
- sleep(30)
113
123
  end
114
- nil
124
+
125
+ UI.success("Successfully updated IDFA delcarations")
115
126
  end
116
127
 
117
- def find_build(candidate_builds)
118
- if (candidate_builds || []).count == 0
119
- UI.user_error!("Could not find any available candidate builds on App Store Connect to submit")
128
+ def update_submission_information(options, app)
129
+ submission_information = options[:submission_information] || {}
130
+ if submission_information.include?(:content_rights_contains_third_party_content)
131
+ value = if submission_information[:content_rights_contains_third_party_content]
132
+ Spaceship::ConnectAPI::App::ContentRightsDeclaration::USES_THIRD_PARTY_CONTENT
133
+ else
134
+ Spaceship::ConnectAPI::App::ContentRightsDeclaration::DOES_NOT_USE_THIRD_PARTY_CONTENT
135
+ end
136
+
137
+ UI.success("Updating contents rights declaration on App Store Connect")
138
+ app.update(attributes: {
139
+ contentRightsDeclaration: value
140
+ })
120
141
  end
142
+ end
121
143
 
122
- build = candidate_builds.first
123
- candidate_builds.each do |b|
124
- if b.upload_date > build.upload_date
125
- build = b
126
- end
144
+ def wait_for_build_processing_to_be_complete(app: nil, platform: nil, options: nil)
145
+ app_version = options[:app_version]
146
+ app_version ||= FastlaneCore::IpaFileAnalyser.fetch_app_version(options[:ipa]) if options[:ipa]
147
+ app_version ||= FastlaneCore::PkgFileAnalyser.fetch_app_version(options[:pkg]) if options[:pkg]
148
+
149
+ app_build ||= FastlaneCore::IpaFileAnalyser.fetch_app_build(options[:ipa]) if options[:ipa]
150
+ app_build ||= FastlaneCore::PkgFileAnalyser.fetch_app_build(options[:pkg]) if options[:pkg]
151
+
152
+ latest_build = FastlaneCore::BuildWatcher.wait_for_build_processing_to_be_complete(
153
+ app_id: app.id,
154
+ platform: platform,
155
+ app_version: app_version,
156
+ build_version: app_build,
157
+ poll_interval: 15,
158
+ return_when_build_appears: false,
159
+ return_spaceship_testflight_build: false
160
+ )
161
+
162
+ unless latest_build.app_version == app_version && latest_build.version == app_build
163
+ UI.important("Uploaded app #{app_version} - #{app_build}, but received build #{latest_build.app_version} - #{latest_build.version}.")
127
164
  end
128
165
 
129
- return build
166
+ return latest_build
130
167
  end
131
168
  end
132
169
  end