fastlane 2.150.0.rc2 → 2.150.0.rc7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/deliver/lib/deliver/download_screenshots.rb +48 -26
  3. data/deliver/lib/deliver/runner.rb +4 -1
  4. data/deliver/lib/deliver/submit_for_review.rb +26 -7
  5. data/deliver/lib/deliver/upload_metadata.rb +18 -2
  6. data/deliver/lib/deliver/upload_screenshots.rb +34 -8
  7. data/fastlane/lib/fastlane/actions/.hockey.rb.swp +0 -0
  8. data/fastlane/lib/fastlane/actions/.slack.rb.swp +0 -0
  9. data/fastlane/lib/fastlane/actions/.update_project_provisioning.rb.swp +0 -0
  10. data/fastlane/lib/fastlane/actions/docs/upload_to_app_store.md.erb +4 -0
  11. data/fastlane/lib/fastlane/version.rb +1 -1
  12. data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.xcworkspace/xcuserdata/josh.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  13. data/fastlane_core/lib/fastlane_core/build_watcher.rb +4 -4
  14. data/fastlane_core/lib/fastlane_core/itunes_transporter.rb +89 -52
  15. data/pilot/lib/pilot/.manager.rb.swp +0 -0
  16. data/produce/lib/produce/itunes_connect.rb +29 -2
  17. data/spaceship/lib/spaceship/{.DS_Store → connect_api/.DS_Store} +0 -0
  18. data/spaceship/lib/spaceship/connect_api/client.rb +1 -1
  19. data/spaceship/lib/spaceship/connect_api/file_uploader.rb +42 -10
  20. data/spaceship/lib/spaceship/connect_api/models/age_rating_declaration.rb +1 -1
  21. data/spaceship/lib/spaceship/connect_api/models/app.rb +47 -9
  22. data/spaceship/lib/spaceship/connect_api/models/app_info.rb +4 -0
  23. data/spaceship/lib/spaceship/connect_api/models/app_preview.rb +62 -10
  24. data/spaceship/lib/spaceship/connect_api/models/app_preview_set.rb +2 -2
  25. data/spaceship/lib/spaceship/connect_api/models/app_review_attachment.rb +18 -28
  26. data/spaceship/lib/spaceship/connect_api/models/app_screenshot.rb +86 -37
  27. data/spaceship/lib/spaceship/connect_api/models/app_screenshot_set.rb +26 -2
  28. data/spaceship/lib/spaceship/connect_api/models/app_store_version.rb +20 -1
  29. data/spaceship/lib/spaceship/connect_api/models/user.rb +2 -1
  30. data/spaceship/lib/spaceship/connect_api/tunes/tunes.rb +21 -9
  31. data/spaceship/lib/spaceship/connect_api/users/users.rb +13 -0
  32. metadata +12 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0a5dd73db52643b353f17026fd0cfae042ef1586aa20770a0ed4b60d29f7454e
4
- data.tar.gz: 8d01ca66b6b52465320701478986038cf2416f43dfa307a84504740fa25cc967
3
+ metadata.gz: 34e85dcd86b90ee3b9187bc8417630a13c81188999870ddcc856dda2e11d2a7b
4
+ data.tar.gz: a3f719e25bfaac439e8a5052e68b16d63f94e2c2e2cf66ad5411b55970eb7f34
5
5
  SHA512:
6
- metadata.gz: 66f423b88a3d7fb5b9e7634f0918e5d13685dbc01ec4a332fa3eac07ab092efb392e84f3247fd70818a32665af5c70aa39baac6d533f122956b6c45b515462d7
7
- data.tar.gz: 96d81a5f13c8df5f196f91607d6be870bc57ad8c4fcfdcc515c2eddb80cb83a28b02357cc0ce4319b6259b764167804c7c3d55418449343c6db5acb523d99dca
6
+ metadata.gz: 0b769c9010489fab0525f1966896b3563e97877d2fa562d26614d3732a9f8a9e8cd08dc340043c094e9761892ff1c7aa469a09ff47744458a57f9d053cc06a3c
7
+ data.tar.gz: 5c4165e619e55db0c588a2298d5242103a35b7d785f04d3458f2cd5b73d3c7184e550096791244d15ec4c75541447e2850bbefeb51e4041dfd36d87e656309df
@@ -1,4 +1,5 @@
1
1
  require_relative 'module'
2
+ require 'spaceship'
2
3
  require 'open-uri'
3
4
 
4
5
  module Deliver
@@ -13,35 +14,56 @@ module Deliver
13
14
  end
14
15
 
15
16
  def self.download(options, folder_path)
16
- v = options[:use_live_version] ? options[:app].live_version(platform: options[:platform]) : options[:app].latest_version(platform: options[:platform])
17
-
18
- v.screenshots.each do |language, screenshots|
19
- screenshots.each do |screenshot|
20
- file_name = [screenshot.sort_order, screenshot.device_type, screenshot.sort_order].join("_")
21
- original_file_extension = File.basename(screenshot.original_file_name)
22
- file_name += "." + original_file_extension
23
-
24
- UI.message("Downloading existing screenshot '#{file_name}' for language '#{language}'")
25
-
26
- # If the screen shot is for an appleTV we need to store it in a way that we'll know it's an appleTV
27
- # screen shot later as the screen size is the same as an iPhone 6 Plus in landscape.
28
- if screenshot.device_type == "appleTV"
29
- containing_folder = File.join(folder_path, "appleTV", screenshot.language)
30
- else
31
- containing_folder = File.join(folder_path, screenshot.language)
32
- end
17
+ legacy_app = options[:app]
18
+ app_id = legacy_app.apple_id
19
+ app = Spaceship::ConnectAPI::App.get(app_id: app_id)
33
20
 
34
- if screenshot.is_imessage
35
- containing_folder = File.join(folder_path, "iMessage", screenshot.language)
36
- end
21
+ platform = Spaceship::ConnectAPI::Platform.map(options[:platform])
22
+ if options[:use_live_version]
23
+ version = app.get_live_app_store_version(platform: platform)
24
+ UI.user_error!("Could not find a live version on App Store Connect. Try using '--use_live_version false'") if version.nil?
25
+ else
26
+ version = app.get_edit_app_store_version(platform: platform)
27
+ UI.user_error!("Could not find an edit version on App Store Connect. Try using '--use_live_version true'") if version.nil?
28
+ end
29
+
30
+ localizations = version.get_app_store_version_localizations
31
+ localizations.each do |localization|
32
+ screenshot_sets = localization.get_app_screenshot_sets
33
+ screenshot_sets.each do |screenshot_set|
34
+ screenshot_set.app_screenshots.each_with_index do |screenshot, index|
35
+ url = screenshot.image_asset_url
36
+ next if url.nil?
37
+
38
+ file_name = [index, screenshot_set.screenshot_display_type, index].join("_")
39
+ original_file_extension = File.basename(screenshot.file_name)
40
+ file_name += "." + original_file_extension
41
+
42
+ language = localization.locale
43
+
44
+ UI.message("Downloading existing screenshot '#{file_name}' for language '#{language}'")
45
+
46
+ # If the screen shot is for an appleTV we need to store it in a way that we'll know it's an appleTV
47
+ # screen shot later as the screen size is the same as an iPhone 6 Plus in landscape.
48
+ if screenshot_set.apple_tv?
49
+ containing_folder = File.join(folder_path, "appleTV", language)
50
+ else
51
+ containing_folder = File.join(folder_path, language)
52
+ end
53
+
54
+ if screenshot_set.imessage?
55
+ containing_folder = File.join(folder_path, "iMessage", language)
56
+ end
57
+
58
+ begin
59
+ FileUtils.mkdir_p(containing_folder)
60
+ rescue
61
+ # if it's already there
62
+ end
37
63
 
38
- begin
39
- FileUtils.mkdir_p(containing_folder)
40
- rescue
41
- # if it's already there
64
+ path = File.join(containing_folder, file_name)
65
+ File.binwrite(path, open(url).read)
42
66
  end
43
- path = File.join(containing_folder, file_name)
44
- File.binwrite(path, open(screenshot.url).read)
45
67
  end
46
68
  end
47
69
  end
@@ -159,7 +159,10 @@ module Deliver
159
159
  end
160
160
 
161
161
  def reject_version_if_possible
162
- app = options[:app]
162
+ legacy_app = options[:app]
163
+ app_id = legacy_app.apple_id
164
+ app = Spaceship::ConnectAPI::App.get(app_id: app_id)
165
+
163
166
  if app.reject_version_if_possible!
164
167
  UI.success("Successfully rejected previous version!")
165
168
  end
@@ -59,6 +59,8 @@ module Deliver
59
59
 
60
60
  def update_export_compliance(options, app, build)
61
61
  submission_information = options[:submission_information] || {}
62
+ submission_information = submission_information.collect { |k, v| [k.to_sym, v] }.to_h
63
+
62
64
  uses_encryption = submission_information[:export_compliance_uses_encryption]
63
65
 
64
66
  if build.uses_non_exempt_encryption.nil?
@@ -70,6 +72,8 @@ module Deliver
70
72
  "Add information to the :submission_information option...",
71
73
  " Docs: http://docs.fastlane.tools/actions/deliver/#compliance-and-idfa-settings",
72
74
  " Example: submission_information: { export_compliance_uses_encryption: false }",
75
+ " Example CLI:",
76
+ " --submission_information \"{\\\"export_compliance_uses_encryption\\\": false}\"",
73
77
  "This can also be set in your Info.plist with key 'ITSAppUsesNonExemptEncryption'"
74
78
  ].join("\n")
75
79
  UI.user_error!(message)
@@ -85,6 +89,8 @@ module Deliver
85
89
 
86
90
  def update_idfa(options, app, version)
87
91
  submission_information = options[:submission_information] || {}
92
+ submission_information = submission_information.collect { |k, v| [k.to_sym, v] }.to_h
93
+
88
94
  uses_idfa = submission_information[:add_id_info_uses_idfa]
89
95
 
90
96
  idfa_declaration = begin
@@ -93,14 +99,17 @@ module Deliver
93
99
  nil
94
100
  end
95
101
 
102
+ updated_idfa = false
103
+
96
104
  # Set IDFA on version
97
- UI.verbose("Updating app store version for IDFA status of '#{uses_idfa}'")
98
105
  unless uses_idfa.nil?
106
+ UI.verbose("Updating app store version for IDFA status of '#{uses_idfa}'")
99
107
  version = version.update(attributes: {
100
108
  usesIdfa: uses_idfa
101
109
  })
110
+ UI.verbose("Updated app store version for IDFA status of '#{version.uses_idfa}'")
111
+ updated_idfa = true
102
112
  end
103
- UI.verbose("Updated app store version for IDFA status of '#{version.uses_idfa}'")
104
113
 
105
114
  # Error if uses_idfa not set
106
115
  if version.uses_idfa.nil?
@@ -115,7 +124,9 @@ module Deliver
115
124
  " add_id_info_serves_ads: false,",
116
125
  " add_id_info_uses_idfa: false,",
117
126
  " add_id_info_tracks_install: false",
118
- " }"
127
+ " }",
128
+ " Example CLI:",
129
+ " --submission_information \"{\\\"add_id_info_uses_idfa\\\": false}\""
119
130
  ].join("\n")
120
131
  UI.user_error!(message)
121
132
  end
@@ -125,6 +136,7 @@ module Deliver
125
136
  if idfa_declaration
126
137
  UI.verbose("Deleting IDFA delcaration")
127
138
  idfa_declaration.delete!
139
+ updated_idfa = true
128
140
  UI.verbose("Deleted IDFA delcaration")
129
141
  end
130
142
  elsif uses_idfa == true
@@ -144,13 +156,16 @@ module Deliver
144
156
  version.create_idfa_declaration(attributes: attributes)
145
157
  UI.verbose("Created IDFA delcaration")
146
158
  end
159
+
160
+ updated_idfa = true
147
161
  end
148
162
 
149
- UI.success("Successfully updated IDFA delcarations on App Store Connect")
163
+ UI.success("Successfully updated IDFA delcarations on App Store Connect") if updated_idfa
150
164
  end
151
165
 
152
166
  def update_submission_information(options, app)
153
167
  submission_information = options[:submission_information] || {}
168
+ submission_information = submission_information.collect { |k, v| [k.to_sym, v] }.to_h
154
169
 
155
170
  content_rights = submission_information[:content_rights_contains_third_party_content]
156
171
 
@@ -171,6 +186,7 @@ module Deliver
171
186
 
172
187
  def wait_for_build_processing_to_be_complete(app: nil, platform: nil, options: nil)
173
188
  app_version = options[:app_version]
189
+
174
190
  app_version ||= FastlaneCore::IpaFileAnalyser.fetch_app_version(options[:ipa]) if options[:ipa]
175
191
  app_version ||= FastlaneCore::PkgFileAnalyser.fetch_app_version(options[:pkg]) if options[:pkg]
176
192
 
@@ -184,11 +200,14 @@ module Deliver
184
200
  build_version: app_build,
185
201
  poll_interval: 15,
186
202
  return_when_build_appears: false,
187
- return_spaceship_testflight_build: false
203
+ return_spaceship_testflight_build: false,
204
+ select_latest: true
188
205
  )
189
206
 
190
- unless latest_build.app_version == app_version && latest_build.version == app_build
191
- UI.important("Uploaded app #{app_version} - #{app_build}, but received build #{latest_build.app_version} - #{latest_build.version}.")
207
+ if !app_version.nil? && !app_build.nil?
208
+ unless latest_build.app_version == app_version && latest_build.version == app_build
209
+ UI.important("Uploaded app #{app_version} - #{app_build}, but received build #{latest_build.app_version} - #{latest_build.version}.")
210
+ end
192
211
  end
193
212
 
194
213
  return latest_build
@@ -106,7 +106,9 @@ module Deliver
106
106
  end
107
107
 
108
108
  # Needed for to filter out release notes from being sent up
109
- is_first_version = app.get_live_app_store_version(platform: platform).nil?
109
+ number_of_versions = app.get_app_store_versions(filter: { platform: platform }, limit: 2).size
110
+ is_first_version = number_of_versions == 1
111
+ UI.verbose("Version '#{version.version_string}' is the first version on App Store Connect") if is_first_version
110
112
 
111
113
  UI.important("Will begin uploading metadata for '#{version.version_string}' on App Store Connect")
112
114
 
@@ -158,7 +160,11 @@ module Deliver
158
160
  end
159
161
 
160
162
  release_type = if options[:auto_release_date]
161
- non_localized_version_attributes['earliestReleaseDate'] = options[:auto_release_date]
163
+ # Convert time format to 2020-06-17T12:00:00-07:00
164
+ time_in_ms = options[:auto_release_date]
165
+ date = convert_ms_to_iso8601(time_in_ms)
166
+
167
+ non_localized_version_attributes['earliestReleaseDate'] = date
162
168
  Spaceship::ConnectAPI::AppStoreVersion::ReleaseType::SCHEDULED
163
169
  elsif options[:automatic_release]
164
170
  Spaceship::ConnectAPI::AppStoreVersion::ReleaseType::AFTER_APPROVAL
@@ -315,6 +321,16 @@ module Deliver
315
321
 
316
322
  # rubocop:enable Metrics/PerceivedComplexity
317
323
 
324
+ def convert_ms_to_iso8601(time_in_ms)
325
+ time_in_s = time_in_ms / 1000
326
+
327
+ # Remove minutes and seconds (whole hour)
328
+ seconds_in_hour = 60 * 60
329
+ time_in_s_to_hour = (time_in_s / seconds_in_hour).to_i * seconds_in_hour
330
+
331
+ return Time.at(time_in_s_to_hour).strftime("%Y-%m-%dT%H:%M:%S%:z")
332
+ end
333
+
318
334
  # If the user is using the 'default' language, then assign values where they are needed
319
335
  def assign_defaults(options)
320
336
  # Normalizes languages keys from symbols to strings
@@ -1,4 +1,5 @@
1
1
  require 'spaceship/tunes/tunes'
2
+ require 'digest/md5'
2
3
 
3
4
  require_relative 'app_screenshot'
4
5
  require_relative 'module'
@@ -91,6 +92,16 @@ module Deliver
91
92
  localizations = version.get_app_store_version_localizations
92
93
  end
93
94
 
95
+ upload_screenshots(screenshots_per_language, localizations)
96
+ end
97
+
98
+ def upload_screenshots(screenshots_per_language, localizations)
99
+ # Check if should wait for processing
100
+ wait_for_processing = !FastlaneCore::Env.truthy?("DELIVER_SKIP_WAIT_FOR_SCREENSHOT_PROCESSING")
101
+ if wait_for_processing
102
+ UI.important("Set environment variable DELIVER_SKIP_WAIT_FOR_SCREENSHOT_PROCESSING=true to skip waiting for screenshots to process")
103
+ end
104
+
94
105
  # Upload screenshots
95
106
  indized = {} # per language and device type
96
107
 
@@ -114,7 +125,13 @@ module Deliver
114
125
  app_screenshot_sets_map[app_screenshot_set.screenshot_display_type] = app_screenshot_set
115
126
 
116
127
  # Set initial screnshot count
117
- indized[localization.locale][app_screenshot_set.screenshot_display_type] ||= app_screenshot_set.app_screenshots.size
128
+ indized[localization.locale][app_screenshot_set.screenshot_display_type] ||= {
129
+ count: app_screenshot_set.app_screenshots.size,
130
+ checksums: []
131
+ }
132
+
133
+ checksums = app_screenshot_set.app_screenshots.map(&:source_file_checksum).uniq
134
+ indized[localization.locale][app_screenshot_set.screenshot_display_type][:checksums] = checksums
118
135
  end
119
136
 
120
137
  UI.message("Uploading #{screenshots_for_language.length} screenshots for language #{language}")
@@ -133,21 +150,30 @@ module Deliver
133
150
  })
134
151
  app_screenshot_sets_map[display_type] = set
135
152
 
136
- indized[localization.locale][set.screenshot_display_type] = 0
153
+ indized[localization.locale][set.screenshot_display_type] = {
154
+ count: 0,
155
+ checksums: []
156
+ }
137
157
  end
138
158
 
139
- index = indized[localization.locale][set.screenshot_display_type]
159
+ index = indized[localization.locale][set.screenshot_display_type][:count]
140
160
 
141
161
  if index >= 10
142
- UI.error("Too many screenshots found for device '#{screenshot.formatted_name}' in '#{screenshot.language}', skipping this one (#{screenshot.path})")
162
+ UI.error("Too many screenshots found for device '#{screenshot.device_type}' in '#{screenshot.language}', skipping this one (#{screenshot.path})")
143
163
  next
144
164
  end
145
165
 
146
- indized[localization.locale][set.screenshot_display_type] += 1
166
+ bytes = File.binread(screenshot.path)
167
+ checksum = Digest::MD5.hexdigest(bytes)
168
+ duplicate = indized[localization.locale][set.screenshot_display_type][:checksums].include?(checksum)
147
169
 
148
- # Also.. what is the messages type even for?
149
- UI.message("Uploading '#{screenshot.path}'...")
150
- set.upload_screenshot(path: screenshot.path)
170
+ if duplicate
171
+ UI.message("Previous uploaded. Skipping '#{screenshot.path}'...")
172
+ else
173
+ indized[localization.locale][set.screenshot_display_type][:count] += 1
174
+ UI.message("Uploading '#{screenshot.path}'...")
175
+ set.upload_screenshot(path: screenshot.path, wait_for_processing: wait_for_processing)
176
+ end
151
177
  end
152
178
  end
153
179
  UI.success("Successfully uploaded screenshots to App Store Connect")
@@ -435,6 +435,10 @@ Omit `build_number` to let _fastlane_ automatically select the latest build numb
435
435
 
436
436
  Use the `submission_information` parameter for additional submission specifiers, including compliance and IDFA settings. Look at the Spaceship's [`app_submission.rb`](https://github.com/fastlane/fastlane/blob/master/spaceship/lib/spaceship/tunes/app_submission.rb) file for options. See [this example](https://github.com/artsy/eigen/blob/faa02e2746194d8d7c11899474de9c517435eca4/fastlane/Fastfile#L131-L149).
437
437
 
438
+ ```no-highlight
439
+ fastlane deliver submit_build --build_number 830 --submission_information "{\"export_compliance_uses_encryption\": false, \"add_id_info_uses_idfa\": false }"
440
+ ```
441
+
438
442
  # Credentials
439
443
 
440
444
  A detailed description about how your credentials are handled is available in a [credentials_manager](https://github.com/fastlane/fastlane/tree/master/credentials_manager).
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
- VERSION = '2.150.0.rc2'.freeze
2
+ VERSION = '2.150.0.rc7'.freeze
3
3
  DESCRIPTION = "The easiest way to automate beta deployments and releases for your iOS and Android apps".freeze
4
4
  MINIMUM_XCODE_RELEASE = "7.0".freeze
5
5
  RUBOCOP_REQUIREMENT = '0.49.1'.freeze
@@ -6,7 +6,7 @@ module FastlaneCore
6
6
  class BuildWatcher
7
7
  class << self
8
8
  # @return The build we waited for. This method will always return a build
9
- def wait_for_build_processing_to_be_complete(app_id: nil, platform: nil, train_version: nil, app_version: nil, build_version: nil, poll_interval: 10, strict_build_watch: false, return_when_build_appears: false, return_spaceship_testflight_build: true)
9
+ def wait_for_build_processing_to_be_complete(app_id: nil, platform: nil, train_version: nil, app_version: nil, build_version: nil, poll_interval: 10, strict_build_watch: false, return_when_build_appears: false, return_spaceship_testflight_build: true, select_latest: false)
10
10
  # Warn about train_version being removed in the future
11
11
  if train_version
12
12
  UI.deprecated(":train_version is no longer a used argument on FastlaneCore::BuildWatcher. Please use :app_version instead.")
@@ -23,7 +23,7 @@ module FastlaneCore
23
23
 
24
24
  showed_info = false
25
25
  loop do
26
- matched_build = matching_build(watched_app_version: app_version, watched_build_version: build_version, app_id: app_id, platform: platform)
26
+ matched_build = matching_build(watched_app_version: app_version, watched_build_version: build_version, app_id: app_id, platform: platform, select_latest: select_latest)
27
27
 
28
28
  if matched_build.nil? && !showed_info
29
29
  UI.important("Read more information on why this build isn't showing up yet - https://github.com/fastlane/fastlane/issues/14997")
@@ -55,7 +55,7 @@ module FastlaneCore
55
55
  return version.instance_of?(String) ? version.split('.').map { |s| s.to_i.to_s }.join('.') : version
56
56
  end
57
57
 
58
- def matching_build(watched_app_version: nil, watched_build_version: nil, app_id: nil, platform: nil)
58
+ def matching_build(watched_app_version: nil, watched_build_version: nil, app_id: nil, platform: nil, select_latest: false)
59
59
  # Get build deliveries (newly uploaded processing builds)
60
60
  watched_app_version = remove_version_leading_zeros(version: watched_app_version)
61
61
  watched_build_version = remove_version_leading_zeros(version: watched_build_version)
@@ -69,7 +69,7 @@ module FastlaneCore
69
69
 
70
70
  # Raise error if more than 1 build is returned
71
71
  # This should never happen but need to inform the user if it does
72
- if matched_builds.size > 1
72
+ if matched_builds.size > 1 && !select_latest
73
73
  error_builds = matched_builds.map do |build|
74
74
  "#{build.app_version}(#{build.version}) for #{build.platform} - #{build.processing_state}"
75
75
  end.join("\n")
@@ -239,64 +239,101 @@ module FastlaneCore
239
239
  # escaping problems in its accompanying shell script.
240
240
  class JavaTransporterExecutor < TransporterExecutor
241
241
  def build_upload_command(username, password, source = "/tmp", provider_short_name = "")
242
- [
243
- Helper.transporter_java_executable_path.shellescape,
244
- "-Djava.ext.dirs=#{Helper.transporter_java_ext_dir.shellescape}",
245
- '-XX:NewSize=2m',
246
- '-Xms32m',
247
- '-Xmx1024m',
248
- '-Xms1024m',
249
- '-Djava.awt.headless=true',
250
- '-Dsun.net.http.retryPost=false',
251
- java_code_option,
252
- '-m upload',
253
- "-u #{username.shellescape}",
254
- "-p #{password.shellescape}",
255
- "-f #{source.shellescape}",
256
- additional_upload_parameters, # that's here, because the user might overwrite the -t option
257
- '-k 100000',
258
- ("-itc_provider #{provider_short_name}" unless provider_short_name.to_s.empty?),
259
- '2>&1' # cause stderr to be written to stdout
260
- ].compact.join(' ') # compact gets rid of the possibly nil ENV value
242
+ if Helper.mac? && Helper.xcode_at_least?(11)
243
+ [
244
+ 'xcrun iTMSTransporter',
245
+ '-m upload',
246
+ "-u #{username.shellescape}",
247
+ "-p #{password.shellescape}",
248
+ "-f #{source.shellescape}",
249
+ additional_upload_parameters, # that's here, because the user might overwrite the -t option
250
+ '-k 100000',
251
+ ("-itc_provider #{provider_short_name}" unless provider_short_name.to_s.empty?),
252
+ '2>&1' # cause stderr to be written to stdout
253
+ ].compact.join(' ') # compact gets rid of the possibly nil ENV value
254
+ else
255
+ [
256
+ Helper.transporter_java_executable_path.shellescape,
257
+ "-Djava.ext.dirs=#{Helper.transporter_java_ext_dir.shellescape}",
258
+ '-XX:NewSize=2m',
259
+ '-Xms32m',
260
+ '-Xmx1024m',
261
+ '-Xms1024m',
262
+ '-Djava.awt.headless=true',
263
+ '-Dsun.net.http.retryPost=false',
264
+ java_code_option,
265
+ '-m upload',
266
+ "-u #{username.shellescape}",
267
+ "-p #{password.shellescape}",
268
+ "-f #{source.shellescape}",
269
+ additional_upload_parameters, # that's here, because the user might overwrite the -t option
270
+ '-k 100000',
271
+ ("-itc_provider #{provider_short_name}" unless provider_short_name.to_s.empty?),
272
+ '2>&1' # cause stderr to be written to stdout
273
+ ].compact.join(' ') # compact gets rid of the possibly nil ENV value
274
+ end
261
275
  end
262
276
 
263
277
  def build_download_command(username, password, apple_id, destination = "/tmp", provider_short_name = "")
264
- [
265
- Helper.transporter_java_executable_path.shellescape,
266
- "-Djava.ext.dirs=#{Helper.transporter_java_ext_dir.shellescape}",
267
- '-XX:NewSize=2m',
268
- '-Xms32m',
269
- '-Xmx1024m',
270
- '-Xms1024m',
271
- '-Djava.awt.headless=true',
272
- '-Dsun.net.http.retryPost=false',
273
- java_code_option,
274
- '-m lookupMetadata',
275
- "-u #{username.shellescape}",
276
- "-p #{password.shellescape}",
277
- "-apple_id #{apple_id.shellescape}",
278
- "-destination #{destination.shellescape}",
279
- ("-itc_provider #{provider_short_name}" unless provider_short_name.to_s.empty?),
280
- '2>&1' # cause stderr to be written to stdout
281
- ].compact.join(' ')
278
+ if Helper.mac? && Helper.xcode_at_least?(11)
279
+ [
280
+ 'xcrun iTMSTransporter',
281
+ '-m lookupMetadata',
282
+ "-u #{username.shellescape}",
283
+ "-p #{password.shellescape}",
284
+ "-apple_id #{apple_id.shellescape}",
285
+ "-destination #{destination.shellescape}",
286
+ ("-itc_provider #{provider_short_name}" unless provider_short_name.to_s.empty?),
287
+ '2>&1' # cause stderr to be written to stdout
288
+ ].compact.join(' ')
289
+ else
290
+ [
291
+ Helper.transporter_java_executable_path.shellescape,
292
+ "-Djava.ext.dirs=#{Helper.transporter_java_ext_dir.shellescape}",
293
+ '-XX:NewSize=2m',
294
+ '-Xms32m',
295
+ '-Xmx1024m',
296
+ '-Xms1024m',
297
+ '-Djava.awt.headless=true',
298
+ '-Dsun.net.http.retryPost=false',
299
+ java_code_option,
300
+ '-m lookupMetadata',
301
+ "-u #{username.shellescape}",
302
+ "-p #{password.shellescape}",
303
+ "-apple_id #{apple_id.shellescape}",
304
+ "-destination #{destination.shellescape}",
305
+ ("-itc_provider #{provider_short_name}" unless provider_short_name.to_s.empty?),
306
+ '2>&1' # cause stderr to be written to stdout
307
+ ].compact.join(' ')
308
+ end
282
309
  end
283
310
 
284
311
  def build_provider_ids_command(username, password)
285
- [
286
- Helper.transporter_java_executable_path.shellescape,
287
- "-Djava.ext.dirs=#{Helper.transporter_java_ext_dir.shellescape}",
288
- '-XX:NewSize=2m',
289
- '-Xms32m',
290
- '-Xmx1024m',
291
- '-Xms1024m',
292
- '-Djava.awt.headless=true',
293
- '-Dsun.net.http.retryPost=false',
294
- java_code_option,
295
- '-m provider',
296
- "-u #{username.shellescape}",
297
- "-p #{password.shellescape}",
298
- '2>&1' # cause stderr to be written to stdout
299
- ].compact.join(' ')
312
+ if Helper.mac? && Helper.xcode_at_least?(11)
313
+ [
314
+ 'xcrun iTMSTransporter',
315
+ '-m provider',
316
+ "-u #{username.shellescape}",
317
+ "-p #{password.shellescape}",
318
+ '2>&1' # cause stderr to be written to stdout
319
+ ].compact.join(' ')
320
+ else
321
+ [
322
+ Helper.transporter_java_executable_path.shellescape,
323
+ "-Djava.ext.dirs=#{Helper.transporter_java_ext_dir.shellescape}",
324
+ '-XX:NewSize=2m',
325
+ '-Xms32m',
326
+ '-Xmx1024m',
327
+ '-Xms1024m',
328
+ '-Djava.awt.headless=true',
329
+ '-Dsun.net.http.retryPost=false',
330
+ java_code_option,
331
+ '-m provider',
332
+ "-u #{username.shellescape}",
333
+ "-p #{password.shellescape}",
334
+ '2>&1' # cause stderr to be written to stdout
335
+ ].compact.join(' ')
336
+ end
300
337
  end
301
338
 
302
339
  def java_code_option