fastlane 2.149.1 → 2.150.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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