fastlane 2.133.0 → 2.136.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +78 -78
  3. data/fastlane/lib/fastlane/action.rb +1 -1
  4. data/fastlane/lib/fastlane/actions/actions_helper.rb +1 -1
  5. data/fastlane/lib/fastlane/actions/carthage.rb +7 -0
  6. data/fastlane/lib/fastlane/actions/cocoapods.rb +24 -2
  7. data/fastlane/lib/fastlane/actions/deploygate.rb +1 -1
  8. data/fastlane/lib/fastlane/actions/docs/capture_android_screenshots.md +38 -4
  9. data/fastlane/lib/fastlane/actions/docs/capture_ios_screenshots.md +1 -1
  10. data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +4 -2
  11. data/fastlane/lib/fastlane/actions/docs/upload_to_play_store.md +26 -2
  12. data/fastlane/lib/fastlane/actions/download_dsyms.rb +26 -3
  13. data/fastlane/lib/fastlane/actions/download_from_play_store.rb +1 -1
  14. data/fastlane/lib/fastlane/actions/get_version_number.rb +10 -4
  15. data/fastlane/lib/fastlane/actions/google_play_track_version_codes.rb +5 -1
  16. data/fastlane/lib/fastlane/actions/sonar.rb +16 -0
  17. data/fastlane/lib/fastlane/actions/testfairy.rb +1 -1
  18. data/fastlane/lib/fastlane/actions/update_fastlane.rb +9 -49
  19. data/fastlane/lib/fastlane/actions/update_keychain_access_groups.rb +94 -0
  20. data/fastlane/lib/fastlane/environment_printer.rb +9 -3
  21. data/fastlane/lib/fastlane/fast_file.rb +3 -2
  22. data/fastlane/lib/fastlane/lane_manager.rb +1 -1
  23. data/fastlane/lib/fastlane/plugins/plugin_manager.rb +12 -2
  24. data/fastlane/lib/fastlane/plugins/template/.rubocop.yml +2 -0
  25. data/fastlane/lib/fastlane/runner.rb +2 -2
  26. data/fastlane/lib/fastlane/swift_fastlane_function.rb +9 -0
  27. data/fastlane/lib/fastlane/version.rb +1 -1
  28. data/fastlane/swift/Deliverfile.swift +1 -1
  29. data/fastlane/swift/Fastlane.swift +124 -36
  30. data/fastlane/swift/Gymfile.swift +1 -1
  31. data/fastlane/swift/Matchfile.swift +1 -1
  32. data/fastlane/swift/MatchfileProtocol.swift +2 -2
  33. data/fastlane/swift/Precheckfile.swift +1 -1
  34. data/fastlane/swift/Scanfile.swift +1 -1
  35. data/fastlane/swift/Screengrabfile.swift +1 -1
  36. data/fastlane/swift/ScreengrabfileProtocol.swift +22 -2
  37. data/fastlane/swift/Snapshotfile.swift +1 -1
  38. data/fastlane_core/lib/fastlane_core/configuration/commander_generator.rb +3 -3
  39. data/fastlane_core/lib/fastlane_core/configuration/configuration.rb +1 -1
  40. data/fastlane_core/lib/fastlane_core/device_manager.rb +1 -1
  41. data/fastlane_core/lib/fastlane_core/swag.rb +1 -1
  42. data/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb +1 -1
  43. data/match/lib/match/importer.rb +1 -1
  44. data/scan/lib/scan/error_handler.rb +9 -4
  45. data/scan/lib/scan/runner.rb +1 -1
  46. data/screengrab/lib/screengrab/module.rb +2 -0
  47. data/screengrab/lib/screengrab/options.rb +33 -11
  48. data/screengrab/lib/screengrab/runner.rb +64 -24
  49. data/sigh/lib/assets/resign.sh +2 -2
  50. data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher.rb +1 -1
  51. data/spaceship/lib/spaceship/client.rb +2 -2
  52. data/supply/lib/supply.rb +23 -0
  53. data/supply/lib/supply/.uploader.rb.swp +0 -0
  54. data/supply/lib/supply/client.rb +101 -55
  55. data/supply/lib/supply/options.rb +50 -14
  56. data/supply/lib/supply/release_listing.rb +18 -0
  57. data/supply/lib/supply/setup.rb +42 -34
  58. data/supply/lib/supply/uploader.rb +191 -93
  59. metadata +32 -37
  60. data/fastlane/lib/fastlane/actions/.hockey.rb.swp +0 -0
  61. data/fastlane/lib/fastlane/actions/.slack.rb.swp +0 -0
  62. data/fastlane/lib/fastlane/actions/.update_project_provisioning.rb.swp +0 -0
  63. data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.xcworkspace/xcuserdata/josh.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  64. data/gym/lib/gym/.runner.rb.swp +0 -0
  65. data/pilot/lib/pilot/.manager.rb.swp +0 -0
  66. data/spaceship/lib/spaceship/connect_api/.DS_Store +0 -0
  67. data/spaceship/lib/spaceship/portal/.certificate.rb.swp +0 -0
@@ -0,0 +1,18 @@
1
+ module Supply
2
+ class ReleaseListing
3
+ attr_accessor :track
4
+ attr_accessor :version
5
+ attr_accessor :versioncodes
6
+ attr_accessor :language
7
+ attr_accessor :release_notes
8
+
9
+ # Initializes the release listing with the current listing if available
10
+ def initialize(track, version, versioncodes, language, text)
11
+ self.track = track
12
+ self.version = version
13
+ self.versioncodes = versioncodes
14
+ self.language = language
15
+ self.release_notes = text
16
+ end
17
+ end
18
+ end
@@ -12,16 +12,22 @@ module Supply
12
12
 
13
13
  client.listings.each do |listing|
14
14
  store_metadata(listing)
15
- create_screenshots_folder(listing)
16
15
  download_images(listing)
17
16
  end
18
17
 
19
- client.apks_version_codes.each do |apk_version_code|
20
- client.apk_listings(apk_version_code).each do |apk_listing|
21
- store_apk_listing(apk_listing)
18
+ if Supply.config[:version_name].to_s == ""
19
+ latest_version = client.latest_version(Supply.config[:track])
20
+ if latest_version
21
+ Supply.config[:version_name] = latest_version.name
22
+ else
23
+ UI.user_error!("Could not find the latest version to download metadata, images, and screenshots from")
22
24
  end
23
25
  end
24
26
 
27
+ client.release_listings(Supply.config[:version_name]).each do |release_listing|
28
+ store_release_listing(release_listing)
29
+ end
30
+
25
31
  client.abort_current_edit
26
32
 
27
33
  UI.success("✅ Successfully stored metadata in '#{metadata_path}'")
@@ -43,25 +49,40 @@ module Supply
43
49
  def download_images(listing)
44
50
  UI.message("🖼️ Downloading images (#{listing.language})")
45
51
 
46
- # We cannot download existing screenshots as they are compressed
47
- # But we can at least download the images
48
52
  require 'net/http'
49
53
 
50
- IMAGES_TYPES.each do |image_type|
51
- if ['featureGraphic'].include?(image_type)
52
- # we don't get all files in full resolution :(
53
- UI.message("📵 Due to a limitation of the Google Play API, there is no way for `supply` to download your existing feature graphic. Please copy your feature graphic to `metadata/android/#{listing.language}/images/featureGraphic.png`")
54
- next
55
- end
54
+ allowed_imagetypes = [Supply::IMAGES_TYPES, Supply::SCREENSHOT_TYPES].flatten
56
55
 
56
+ allowed_imagetypes.each do |image_type|
57
57
  begin
58
+ path = File.join(metadata_path, listing.language, IMAGES_FOLDER_NAME, image_type)
59
+
60
+ p = Pathname.new(path)
61
+ if IMAGES_TYPES.include?(image_type) # IMAGE_TYPES are stored in locale/images location
62
+ FileUtils.mkdir_p(p.dirname.to_s)
63
+ else # SCREENSHOT_TYPES go under their respective folders.
64
+ FileUtils.mkdir_p(p.to_s)
65
+ end
66
+
58
67
  UI.message("Downloading `#{image_type}` for #{listing.language}...")
59
68
 
60
- url = client.fetch_images(image_type: image_type, language: listing.language).last
61
- next unless url
69
+ urls = client.fetch_images(image_type: image_type, language: listing.language)
70
+ next if urls.nil? || urls.empty?
71
+
72
+ image_counter = 1 # Used to prefix the downloaded files, so order is preserved.
73
+ urls.each do |url|
74
+ if IMAGES_TYPES.include?(image_type) # IMAGE_TYPES are stored in locale/images
75
+ file_path = "#{path}.#{FastImage.type(url)}"
76
+ else # SCREENSHOT_TYPES are stored in locale/images/<screensho_types>
77
+ file_path = File.join(path, "#{image_counter}_#{listing.language}.#{FastImage.type(url)}")
78
+ end
79
+
80
+ File.binwrite(file_path, Net::HTTP.get(URI.parse(url)))
81
+
82
+ UI.message("\tDownloaded - #{file_path}")
62
83
 
63
- path = File.join(metadata_path, listing.language, IMAGES_FOLDER_NAME, "#{image_type}.png")
64
- File.write(path, Net::HTTP.get(URI.parse(url)))
84
+ image_counter += 1
85
+ end
65
86
  rescue => ex
66
87
  UI.error(ex.to_s)
67
88
  UI.error("Error downloading '#{image_type}' for #{listing.language}...")
@@ -69,30 +90,17 @@ module Supply
69
90
  end
70
91
  end
71
92
 
72
- def create_screenshots_folder(listing)
73
- UI.message("📱 Downloading screenshots (#{listing.language})")
74
-
75
- containing = File.join(metadata_path, listing.language)
76
-
77
- FileUtils.mkdir_p(File.join(containing, IMAGES_FOLDER_NAME))
78
- Supply::SCREENSHOT_TYPES.each do |screenshot_type|
79
- FileUtils.mkdir_p(File.join(containing, IMAGES_FOLDER_NAME, screenshot_type))
80
- end
81
-
82
- UI.message("📵 Due to a limitation of the Google Play API, there is no way for `supply` to download your existing screenshots. Please copy your screenshots into `metadata/android/#{listing.language}/images/`")
83
- end
84
-
85
- def store_apk_listing(apk_listing)
86
- UI.message("🔨 Downloading changelogs (#{apk_listing.language}, #{apk_listing.apk_version_code})")
93
+ def store_release_listing(release_listing)
94
+ UI.message("🔨 Downloading changelogs (#{release_listing.language}, #{release_listing.version})")
87
95
 
88
- containing = File.join(metadata_path, apk_listing.language, CHANGELOGS_FOLDER_NAME)
96
+ containing = File.join(metadata_path, release_listing.language, CHANGELOGS_FOLDER_NAME)
89
97
  unless File.exist?(containing)
90
98
  FileUtils.mkdir_p(containing)
91
99
  end
92
100
 
93
- path = File.join(containing, "#{apk_listing.apk_version_code}.txt")
101
+ path = File.join(containing, "#{release_listing.version}.txt")
94
102
  UI.message("Writing to #{path}...")
95
- File.write(path, apk_listing.recent_changes)
103
+ File.write(path, release_listing.release_notes)
96
104
  end
97
105
 
98
106
  private
@@ -1,4 +1,5 @@
1
1
  module Supply
2
+ # rubocop:disable Metrics/ClassLength
2
3
  class Uploader
3
4
  def perform_upload
4
5
  FastlaneCore::PrintTable.print_values(config: Supply.config, hide_keys: [:issuer], mask_keys: [:json_key_data], title: "Summary for supply #{Fastlane::VERSION}")
@@ -7,22 +8,6 @@ module Supply
7
8
 
8
9
  verify_config!
9
10
 
10
- if metadata_path
11
- UI.user_error!("Could not find folder #{metadata_path}") unless File.directory?(metadata_path)
12
-
13
- all_languages.each do |language|
14
- next if language.start_with?('.') # e.g. . or .. or hidden folders
15
- UI.message("Preparing to upload for language '#{language}'...")
16
-
17
- listing = client.listing_for_language(language)
18
-
19
- upload_metadata(language, listing) unless Supply.config[:skip_upload_metadata]
20
- upload_images(language) unless Supply.config[:skip_upload_images]
21
- upload_screenshots(language) unless Supply.config[:skip_upload_screenshots]
22
- upload_changelogs(language) unless Supply.config[:skip_upload_metadata]
23
- end
24
- end
25
-
26
11
  apk_version_codes = []
27
12
  apk_version_codes.concat(upload_apks) unless Supply.config[:skip_upload_apk]
28
13
  apk_version_codes.concat(upload_bundles) unless Supply.config[:skip_upload_aab]
@@ -34,19 +19,110 @@ module Supply
34
19
  # Updating a track with empty version codes can completely clear out a track
35
20
  update_track(apk_version_codes) unless apk_version_codes.empty?
36
21
 
37
- promote_track if Supply.config[:track_promote_to]
22
+ if Supply.config[:track_promote_to]
23
+ promote_track
24
+ elsif !Supply.config[:rollout].nil? && Supply.config[:track].to_s != ""
25
+ update_rollout
26
+ end
27
+
28
+ if Supply.config[:validate_only]
29
+ UI.message("Validating all track and release changes with Google Play...")
30
+ client.validate_current_edit!
31
+ UI.success("Successfully validated the upload to Google Play")
32
+ else
33
+ UI.message("Uploading all track and release changes to Google Play...")
34
+ client.commit_current_edit!
35
+ UI.success("Successfully finished the upload to Google Play")
36
+ end
37
+
38
+ perform_upload_meta(apk_version_codes)
39
+ end
40
+
41
+ def perform_upload_meta(version_codes)
42
+ client.begin_edit(package_name: Supply.config[:package_name])
43
+
44
+ if (!Supply.config[:skip_upload_metadata] || !Supply.config[:skip_upload_images] || !Supply.config[:skip_upload_changelogs] || !Supply.config[:skip_upload_screenshots]) && metadata_path
45
+ # Use version code from config if version codes is empty and no nil or empty string
46
+ version_codes = [Supply.config[:version_code]] if version_codes.empty?
47
+ version_codes = version_codes.reject do |version_code|
48
+ version_codes.to_s == ""
49
+ end
50
+
51
+ version_codes.each do |version_code|
52
+ UI.user_error!("Could not find folder #{metadata_path}") unless File.directory?(metadata_path)
53
+
54
+ track, release = fetch_track_and_release!(Supply.config[:track], version_code)
55
+ UI.user_error!("Unable to find the requested track - '#{Supply.config[:track]}'") unless track
56
+ UI.user_error!("Could not find release for version code '#{version_code}' to update changelog") unless release
57
+
58
+ release_notes = []
59
+ all_languages.each do |language|
60
+ next if language.start_with?('.') # e.g. . or .. or hidden folders
61
+ UI.message("Preparing to upload for language '#{language}'...")
62
+
63
+ listing = client.listing_for_language(language)
64
+
65
+ upload_metadata(language, listing) unless Supply.config[:skip_upload_metadata]
66
+ upload_images(language) unless Supply.config[:skip_upload_images]
67
+ upload_screenshots(language) unless Supply.config[:skip_upload_screenshots]
68
+ release_notes << upload_changelog(language, version_code) unless Supply.config[:skip_upload_changelogs]
69
+ end
70
+
71
+ upload_changelogs(release_notes, release, track) unless release_notes.empty?
72
+ end
73
+ end
38
74
 
39
75
  if Supply.config[:validate_only]
40
- UI.message("Validating all changes with Google Play...")
76
+ UI.message("Validating all meta changes with Google Play...")
41
77
  client.validate_current_edit!
42
78
  UI.success("Successfully validated the upload to Google Play")
43
79
  else
44
- UI.message("Uploading all changes to Google Play...")
80
+ UI.message("Uploading all meta changes to Google Play...")
45
81
  client.commit_current_edit!
46
82
  UI.success("Successfully finished the upload to Google Play")
47
83
  end
48
84
  end
49
85
 
86
+ def fetch_track_and_release!(track, version_code, status = nil)
87
+ tracks = client.tracks(track)
88
+ return nil, nil if tracks.empty?
89
+
90
+ track = tracks.first
91
+ releases = track.releases
92
+
93
+ releases = releases.select { |r| r.status == status } if status
94
+ releases = releases.select { |r| r.version_codes.map(&:to_s).include?(version_code.to_s) } if version_code
95
+
96
+ if releases.size > 1
97
+ UI.user_error!("More than one release found in this track. Please specify with the :version_code option to select a release.")
98
+ end
99
+
100
+ return track, releases.first
101
+ end
102
+
103
+ def update_rollout
104
+ track, release = fetch_track_and_release!(Supply.config[:track], Supply.config[:version_code], Supply::ReleaseStatus::IN_PROGRESS)
105
+ UI.user_error!("Unable to find the requested track - '#{Supply.config[:track]}'") unless track
106
+ UI.user_error!("Unable to find the requested release on track - '#{Supply.config[:track]}'") unless release
107
+
108
+ version_code = release.version_codes.first
109
+
110
+ UI.message("Updating #{version_code}'s rollout to '#{Supply.config[:rollout]}' on track '#{Supply.config[:track]}'...")
111
+
112
+ if track && release
113
+ completed = Supply.config[:rollout].to_f == 1
114
+ release.user_fraction = completed ? nil : Supply.config[:rollout]
115
+ release.status = Supply::ReleaseStatus::COMPLETED if completed
116
+
117
+ # Deleted other version codes if completed because only allowed on completed version in a release
118
+ track.releases.delete_if { |r| !(r.version_codes || []).map(&:to_s).include?(version_code) } if completed
119
+ else
120
+ UI.user_error!("Unable to find version to rollout in track '#{Supply.config[:track]}'")
121
+ end
122
+
123
+ client.update_track(Supply.config[:track], track)
124
+ end
125
+
50
126
  def verify_config!
51
127
  unless metadata_path || Supply.config[:apk] || Supply.config[:apk_paths] || Supply.config[:aab] || Supply.config[:aab_paths] || (Supply.config[:track] && Supply.config[:track_promote_to])
52
128
  UI.user_error!("No local metadata, apks, aab, or track to promote were found, make sure to run `fastlane supply init` to setup supply")
@@ -60,32 +136,85 @@ module Supply
60
136
  if could_upload_apk && could_upload_aab
61
137
  UI.user_error!("Cannot provide both apk(s) and aab - use `skip_upload_apk`, `skip_upload_aab`, or make sure to remove any existing .apk or .aab files that are no longer needed")
62
138
  end
139
+
140
+ if Supply.config[:release_status] == Supply::ReleaseStatus::DRAFT && Supply.config[:rollout]
141
+ UI.user_error!(%(Cannot specify rollout percentage when the release status is set to 'draft'))
142
+ end
143
+
144
+ unless Supply.config[:version_codes_to_retain].nil?
145
+ Supply.config[:version_codes_to_retain] = Supply.config[:version_codes_to_retain].map(&:to_i)
146
+ end
63
147
  end
64
148
 
65
149
  def promote_track
66
- version_codes = client.track_version_codes(Supply.config[:track])
67
- # the actual value passed for the rollout argument does not matter because it will be ignored by the Google Play API
68
- # but it has to be between 0.0 and 1.0 to pass the validity check. So we are passing the default value 0.1
69
- client.update_track(Supply.config[:track], 0.1, nil) if Supply.config[:deactivate_on_promote]
70
- client.update_track(Supply.config[:track_promote_to], Supply.config[:rollout] || 0.1, version_codes)
71
- end
150
+ track_from = client.tracks(Supply.config[:track]).first
151
+ unless track_from
152
+ UI.user_error!("Cannot promote from track '#{Supply.config[:track]}' - track doesn't exist")
153
+ end
72
154
 
73
- def upload_changelogs(language)
74
- client.apks_version_codes.each do |apk_version_code|
75
- upload_changelog(language, apk_version_code)
155
+ releases = track_from.releases
156
+ if Supply.config[:version_code].to_s != ""
157
+ releases = releases.select do |release|
158
+ release.version_codes.include?(Supply.config[:version_code].to_s)
159
+ end
160
+ else
161
+ releases = releases.select do |release|
162
+ release.status == Supply::ReleaseStatus::COMPLETED
163
+ end
76
164
  end
77
- client.aab_version_codes.each do |aab_version_code|
78
- upload_changelog(language, aab_version_code)
165
+
166
+ if releases.size == 0
167
+ UI.user_error!("Track '#{Supply.config[:track]}' doesn't have any releases")
168
+ elsif releases.size > 1
169
+ UI.user_error!("Track '#{Supply.config[:track]}' has more than one release - use :version_code to filter the release to promote")
170
+ end
171
+
172
+ release = releases.first
173
+ track_to = client.tracks(Supply.config[:track_promote_to]).first
174
+
175
+ if Supply.config[:rollout]
176
+ release.status = Supply::ReleaseStatus::IN_PROGRESS
177
+ release.user_fraction = Supply.config[:rollout]
178
+ else
179
+ release.status = Supply::ReleaseStatus::COMPLETED
180
+ release.user_fraction = nil
79
181
  end
182
+
183
+ if track_to
184
+ # Its okay to set releases to an array containing the newest release
185
+ # Google Play will keep previous releases there this release is a partial rollout
186
+ track_to.releases = [release]
187
+ else
188
+ track_to = AndroidPublisher::Track.new(
189
+ track: Supply.config[:track_promote_to],
190
+ releases: [release]
191
+ )
192
+ end
193
+
194
+ client.update_track(Supply.config[:track_promote_to], track_to)
80
195
  end
81
196
 
82
197
  def upload_changelog(language, version_code)
83
- path = File.join(metadata_path, language, Supply::CHANGELOGS_FOLDER_NAME, "#{version_code}.txt")
198
+ UI.user_error!("Cannot find changelog because no version code given - please specify :version_code") unless version_code
199
+
200
+ path = File.join(Supply.config[:metadata_path], language, Supply::CHANGELOGS_FOLDER_NAME, "#{version_code}.txt")
201
+ changelog_text = ''
84
202
  if File.exist?(path)
85
- UI.message("Updating changelog for code version '#{version_code}' and language '#{language}'...")
86
- apk_listing = ApkListing.new(File.read(path, encoding: 'UTF-8'), language, version_code)
87
- client.update_apk_listing_for_language(apk_listing)
203
+ UI.message("Updating changelog for '#{version_code}' and language '#{language}'...")
204
+ changelog_text = File.read(path, encoding: 'UTF-8')
205
+ else
206
+ UI.message("Could not find changelog for '#{version_code}' and language '#{language}' at path #{path}...")
88
207
  end
208
+
209
+ AndroidPublisher::LocalizedText.new({
210
+ language: language,
211
+ text: changelog_text
212
+ })
213
+ end
214
+
215
+ def upload_changelogs(release_notes, release, track)
216
+ release.release_notes = release_notes
217
+ client.upload_changelogs(track, Supply.config[:track])
89
218
  end
90
219
 
91
220
  def upload_metadata(language, listing)
@@ -163,14 +292,6 @@ module Supply
163
292
  aab_paths.each do |aab_path|
164
293
  UI.message("Preparing aab at path '#{aab_path}' for upload...")
165
294
  bundle_version_code = client.upload_bundle(aab_path)
166
-
167
- if metadata_path
168
- all_languages.each do |language|
169
- next if language.start_with?('.') # e.g. . or .. or hidden folders
170
- upload_changelog(language, bundle_version_code)
171
- end
172
- end
173
-
174
295
  aab_version_codes.push(bundle_version_code)
175
296
  end
176
297
 
@@ -188,6 +309,7 @@ module Supply
188
309
  # @return [Integer] The apk version code returned after uploading, or nil if there was a problem
189
310
  def upload_binary_data(apk_path)
190
311
  apk_version_code = nil
312
+
191
313
  if apk_path
192
314
  UI.message("Preparing apk at path '#{apk_path}' for upload...")
193
315
  apk_version_code = client.upload_apk(apk_path)
@@ -208,16 +330,11 @@ module Supply
208
330
  end
209
331
 
210
332
  upload_obbs(apk_path, apk_version_code)
211
-
212
- if metadata_path
213
- all_languages.each do |language|
214
- next if language.start_with?('.') # e.g. . or .. or hidden folders
215
- upload_changelog(language, apk_version_code)
216
- end
217
- end
218
333
  else
219
334
  UI.message("No apk file found, you can pass the path to your apk using the `apk` option")
220
335
  end
336
+
337
+ UI.message("\tVersion Code: #{apk_version_code}")
221
338
  apk_version_code
222
339
  end
223
340
 
@@ -230,55 +347,35 @@ module Supply
230
347
  end
231
348
 
232
349
  def update_track(apk_version_codes)
233
- UI.message("Updating track '#{Supply.config[:track]}'...")
234
- check_superseded_tracks(apk_version_codes) if Supply.config[:check_superseded_tracks]
350
+ return if apk_version_codes.empty?
235
351
 
236
- if Supply.config[:track].eql?("rollout")
237
- client.update_track(Supply.config[:track], Supply.config[:rollout] || 0.1, apk_version_codes)
238
- else
239
- client.update_track(Supply.config[:track], 1.0, apk_version_codes)
240
- end
241
- end
242
-
243
- # Remove any version codes that is:
244
- # - Lesser than the greatest of any later (i.e. production) track
245
- # - Or lesser than the currently being uploaded if it's in an earlier (i.e. alpha) track
246
- def check_superseded_tracks(apk_version_codes)
247
- UI.message("Checking superseded tracks, uploading '#{apk_version_codes}' to '#{Supply.config[:track]}'...")
248
- max_apk_version_code = apk_version_codes.max
249
- max_tracks_version_code = nil
250
-
251
- tracks = ["production", "rollout", "beta", "alpha", "internal"]
252
- config_track_index = tracks.index(Supply.config[:track])
253
-
254
- # Custom "closed" tracks are now allowed (https://support.google.com/googleplay/android-developer/answer/3131213)
255
- # Custom tracks have an equal level with alpha (alpha is considered a closed track as well)
256
- # If a track index is not found, we will assume is a custom track so an alpha index is given
257
- config_track_index = tracks.index("alpha") unless config_track_index
258
-
259
- tracks.each_index do |track_index|
260
- track = tracks[track_index]
261
- track_version_codes = client.track_version_codes(track).sort
262
- UI.verbose("Found '#{track_version_codes}' on track '#{track}'")
263
-
264
- next if track_index.eql?(config_track_index)
265
- next if track_version_codes.empty?
266
-
267
- if max_tracks_version_code.nil?
268
- max_tracks_version_code = track_version_codes.max
269
- end
352
+ UI.message("Updating track '#{Supply.config[:track]}'...")
270
353
 
271
- removed_version_codes = track_version_codes.take_while do |v|
272
- v < max_tracks_version_code || (v < max_apk_version_code && track_index > config_track_index)
273
- end
354
+ track_release = AndroidPublisher::TrackRelease.new(
355
+ name: Supply.config[:version_name],
356
+ status: Supply.config[:release_status],
357
+ version_codes: apk_version_codes
358
+ )
274
359
 
275
- next if removed_version_codes.empty?
360
+ if Supply.config[:rollout]
361
+ track_release.status = Supply::ReleaseStatus::IN_PROGRESS
362
+ track_release.user_fraction = Supply.config[:rollout].to_f
363
+ end
276
364
 
277
- keep_version_codes = track_version_codes - removed_version_codes
278
- max_tracks_version_code = keep_version_codes[0] unless keep_version_codes.empty?
279
- client.update_track(track, 1.0, keep_version_codes)
280
- UI.message("Superseded track '#{track}', removed '#{removed_version_codes}'")
365
+ tracks = client.tracks(Supply.config[:track])
366
+ track = tracks.first
367
+ if track
368
+ # Its okay to set releases to an array containing the newest release
369
+ # Google Play will keep previous releases there this release is a partial rollout
370
+ track.releases = [track_release]
371
+ else
372
+ track = AndroidPublisher::Track.new(
373
+ track: Supply.config[:track],
374
+ releases: [track_release]
375
+ )
281
376
  end
377
+
378
+ client.update_track(Supply.config[:track], track)
282
379
  end
283
380
 
284
381
  # returns only language directories from metadata_path
@@ -346,4 +443,5 @@ module Supply
346
443
  end
347
444
  end
348
445
  end
446
+ # rubocop:enable Metrics/ClassLength
349
447
  end