fastlane 2.132.0 → 2.135.2
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.
- checksums.yaml +5 -5
- data/README.md +74 -74
- data/fastlane/lib/fastlane/action.rb +1 -1
- data/fastlane/lib/fastlane/actions/actions_helper.rb +1 -1
- data/fastlane/lib/fastlane/actions/carthage.rb +7 -0
- data/fastlane/lib/fastlane/actions/cocoapods.rb +24 -2
- data/fastlane/lib/fastlane/actions/deploygate.rb +1 -1
- data/fastlane/lib/fastlane/actions/docs/capture_ios_screenshots.md +1 -1
- data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +4 -2
- data/fastlane/lib/fastlane/actions/docs/upload_to_play_store.md +26 -2
- data/fastlane/lib/fastlane/actions/download_dsyms.rb +26 -3
- data/fastlane/lib/fastlane/actions/download_from_play_store.rb +1 -1
- data/fastlane/lib/fastlane/actions/get_version_number.rb +10 -4
- data/fastlane/lib/fastlane/actions/google_play_track_version_codes.rb +5 -1
- data/fastlane/lib/fastlane/actions/sonar.rb +16 -0
- data/fastlane/lib/fastlane/actions/testfairy.rb +1 -1
- data/fastlane/lib/fastlane/actions/update_fastlane.rb +9 -49
- data/fastlane/lib/fastlane/actions/update_keychain_access_groups.rb +94 -0
- data/fastlane/lib/fastlane/environment_printer.rb +9 -3
- data/fastlane/lib/fastlane/fast_file.rb +3 -2
- data/fastlane/lib/fastlane/lane_manager.rb +1 -1
- data/fastlane/lib/fastlane/plugins/plugin_manager.rb +12 -2
- data/fastlane/lib/fastlane/plugins/template/.rubocop.yml +1 -0
- data/fastlane/lib/fastlane/runner.rb +2 -2
- data/fastlane/lib/fastlane/swift_fastlane_api_generator.rb +10 -2
- data/fastlane/lib/fastlane/swift_fastlane_function.rb +72 -3
- data/fastlane/lib/fastlane/version.rb +1 -1
- data/fastlane/swift/Deliverfile.swift +1 -1
- data/fastlane/swift/DeliverfileProtocol.swift +121 -1
- data/fastlane/swift/Fastlane.swift +3900 -16
- data/fastlane/swift/Gymfile.swift +1 -1
- data/fastlane/swift/GymfileProtocol.swift +81 -1
- data/fastlane/swift/Matchfile.swift +1 -1
- data/fastlane/swift/MatchfileProtocol.swift +60 -2
- data/fastlane/swift/Precheckfile.swift +1 -1
- data/fastlane/swift/PrecheckfileProtocol.swift +15 -2
- data/fastlane/swift/Scanfile.swift +1 -1
- data/fastlane/swift/ScanfileProtocol.swift +109 -1
- data/fastlane/swift/Screengrabfile.swift +1 -1
- data/fastlane/swift/ScreengrabfileProtocol.swift +39 -2
- data/fastlane/swift/Snapshotfile.swift +1 -1
- data/fastlane/swift/SnapshotfileProtocol.swift +69 -1
- data/fastlane_core/lib/fastlane_core/configuration/commander_generator.rb +3 -3
- data/fastlane_core/lib/fastlane_core/configuration/configuration.rb +1 -1
- data/fastlane_core/lib/fastlane_core/device_manager.rb +1 -1
- data/fastlane_core/lib/fastlane_core/swag.rb +1 -1
- data/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb +1 -1
- data/match/lib/match/importer.rb +1 -1
- data/match/lib/match/storage/google_cloud_storage.rb +3 -0
- data/scan/lib/scan/error_handler.rb +9 -4
- data/scan/lib/scan/runner.rb +1 -1
- data/sigh/lib/assets/resign.sh +2 -2
- data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher.rb +1 -1
- data/spaceship/lib/spaceship/client.rb +2 -2
- data/supply/lib/supply.rb +23 -0
- data/supply/lib/supply/.options.rb.swp +0 -0
- data/supply/lib/supply/.uploader.rb.swp +0 -0
- data/supply/lib/supply/client.rb +101 -55
- data/supply/lib/supply/options.rb +50 -14
- data/supply/lib/supply/release_listing.rb +18 -0
- data/supply/lib/supply/setup.rb +42 -34
- data/supply/lib/supply/uploader.rb +171 -93
- metadata +36 -41
- data/fastlane/lib/fastlane/actions/.hockey.rb.swp +0 -0
- data/fastlane/lib/fastlane/actions/.slack.rb.swp +0 -0
- data/fastlane/lib/fastlane/actions/.update_project_provisioning.rb.swp +0 -0
- data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.xcworkspace/xcuserdata/josh.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- data/gym/lib/gym/.runner.rb.swp +0 -0
- data/pilot/lib/pilot/.manager.rb.swp +0 -0
- data/spaceship/lib/spaceship/connect_api/.DS_Store +0 -0
- data/spaceship/lib/spaceship/portal/.certificate.rb.swp +0 -0
@@ -5,7 +5,6 @@ module Supply
|
|
5
5
|
class Options
|
6
6
|
# rubocop:disable Metrics/PerceivedComplexity
|
7
7
|
def self.available_options
|
8
|
-
default_tracks = %w(production beta alpha internal rollout)
|
9
8
|
@options ||= [
|
10
9
|
FastlaneCore::ConfigItem.new(key: :package_name,
|
11
10
|
env_name: "SUPPLY_PACKAGE_NAME",
|
@@ -14,11 +13,37 @@ module Supply
|
|
14
13
|
code_gen_sensitive: true,
|
15
14
|
default_value: CredentialsManager::AppfileConfig.try_fetch_value(:package_name),
|
16
15
|
default_value_dynamic: true),
|
16
|
+
FastlaneCore::ConfigItem.new(key: :version_name,
|
17
|
+
env_name: "SUPPLY_VERSION_NAME",
|
18
|
+
short_option: "-n",
|
19
|
+
optional: true,
|
20
|
+
description: "Version name (used when uploading new apks/aabs) - defaults to 'versionName' in build.gradle or AndroidManifest.xml",
|
21
|
+
default_value: CredentialsManager::AppfileConfig.try_fetch_value(:version_name),
|
22
|
+
default_value_dynamic: true),
|
23
|
+
FastlaneCore::ConfigItem.new(key: :version_code,
|
24
|
+
env_name: "SUPPLY_VERSION_CODE",
|
25
|
+
short_option: "-C",
|
26
|
+
optional: true,
|
27
|
+
type: Integer,
|
28
|
+
description: "Version code (used when updating rollout or promoting specific versions)",
|
29
|
+
default_value: CredentialsManager::AppfileConfig.try_fetch_value(:version_code),
|
30
|
+
default_value_dynamic: true),
|
31
|
+
FastlaneCore::ConfigItem.new(key: :release_status,
|
32
|
+
env_name: "SUPPLY_RELEASE_STATUS",
|
33
|
+
short_option: "-e",
|
34
|
+
optional: true,
|
35
|
+
description: "Release status (used when uploading new apks/aabs) - valid values are #{Supply::ReleaseStatus::ALL.join(', ')}",
|
36
|
+
default_value: Supply::ReleaseStatus::COMPLETED,
|
37
|
+
default_value_dynamic: true,
|
38
|
+
verify_block: proc do |value|
|
39
|
+
UI.user_error!("Value must be one of '#{Supply::RELEASE_STATUS}'") unless Supply::ReleaseStatus::ALL.include?(value)
|
40
|
+
end),
|
17
41
|
FastlaneCore::ConfigItem.new(key: :track,
|
18
42
|
short_option: "-a",
|
19
43
|
env_name: "SUPPLY_TRACK",
|
20
|
-
description: "The track of the application to use. The default available tracks are: #{
|
21
|
-
default_value:
|
44
|
+
description: "The track of the application to use. The default available tracks are: #{Supply::Tracks::DEFAULTS.join(', ')}",
|
45
|
+
default_value: Supply::Tracks::DEFAULT,
|
46
|
+
type: String),
|
22
47
|
FastlaneCore::ConfigItem.new(key: :rollout,
|
23
48
|
short_option: "-r",
|
24
49
|
description: "The percentage of the user fraction when uploading to the rollout track",
|
@@ -104,6 +129,7 @@ module Supply
|
|
104
129
|
FastlaneCore::ConfigItem.new(key: :apk_paths,
|
105
130
|
env_name: "SUPPLY_APK_PATHS",
|
106
131
|
conflicting_options: [:apk, :aab, :aab_paths],
|
132
|
+
code_gen_sensitive: true,
|
107
133
|
optional: true,
|
108
134
|
type: Array,
|
109
135
|
description: "An array of paths to APK files to upload",
|
@@ -131,6 +157,7 @@ module Supply
|
|
131
157
|
FastlaneCore::ConfigItem.new(key: :aab_paths,
|
132
158
|
env_name: "SUPPLY_AAB_PATHS",
|
133
159
|
conflicting_options: [:apk, :apk_paths, :aab],
|
160
|
+
code_gen_sensitive: true,
|
134
161
|
optional: true,
|
135
162
|
type: Array,
|
136
163
|
description: "An array of paths to AAB files to upload",
|
@@ -146,41 +173,47 @@ module Supply
|
|
146
173
|
env_name: "SUPPLY_SKIP_UPLOAD_APK",
|
147
174
|
optional: true,
|
148
175
|
description: "Whether to skip uploading APK",
|
149
|
-
|
176
|
+
type: Boolean,
|
150
177
|
default_value: false),
|
151
178
|
FastlaneCore::ConfigItem.new(key: :skip_upload_aab,
|
152
179
|
env_name: "SUPPLY_SKIP_UPLOAD_AAB",
|
153
180
|
optional: true,
|
154
181
|
description: "Whether to skip uploading AAB",
|
155
|
-
|
182
|
+
type: Boolean,
|
156
183
|
default_value: false),
|
157
184
|
FastlaneCore::ConfigItem.new(key: :skip_upload_metadata,
|
158
185
|
env_name: "SUPPLY_SKIP_UPLOAD_METADATA",
|
159
186
|
optional: true,
|
160
|
-
description: "Whether to skip uploading metadata",
|
161
|
-
|
187
|
+
description: "Whether to skip uploading metadata, changelogs not included",
|
188
|
+
type: Boolean,
|
189
|
+
default_value: false),
|
190
|
+
FastlaneCore::ConfigItem.new(key: :skip_upload_changelogs,
|
191
|
+
env_name: "SUPPLY_SKIP_UPLOAD_CHANGELOGS",
|
192
|
+
optional: true,
|
193
|
+
description: "Whether to skip uploading changelogs",
|
194
|
+
type: Boolean,
|
162
195
|
default_value: false),
|
163
196
|
FastlaneCore::ConfigItem.new(key: :skip_upload_images,
|
164
197
|
env_name: "SUPPLY_SKIP_UPLOAD_IMAGES",
|
165
198
|
optional: true,
|
166
199
|
description: "Whether to skip uploading images, screenshots not included",
|
167
|
-
|
200
|
+
type: Boolean,
|
168
201
|
default_value: false),
|
169
202
|
FastlaneCore::ConfigItem.new(key: :skip_upload_screenshots,
|
170
203
|
env_name: "SUPPLY_SKIP_UPLOAD_SCREENSHOTS",
|
171
204
|
optional: true,
|
172
205
|
description: "Whether to skip uploading SCREENSHOTS",
|
173
|
-
|
206
|
+
type: Boolean,
|
174
207
|
default_value: false),
|
175
208
|
FastlaneCore::ConfigItem.new(key: :track_promote_to,
|
176
209
|
env_name: "SUPPLY_TRACK_PROMOTE_TO",
|
177
210
|
optional: true,
|
178
|
-
description: "The track to promote to. The default available tracks are: #{
|
211
|
+
description: "The track to promote to. The default available tracks are: #{Supply::Tracks::DEFAULTS.join(', ')}"),
|
179
212
|
FastlaneCore::ConfigItem.new(key: :validate_only,
|
180
213
|
env_name: "SUPPLY_VALIDATE_ONLY",
|
181
214
|
optional: true,
|
182
215
|
description: "Only validate changes with Google Play rather than actually publish",
|
183
|
-
|
216
|
+
type: Boolean,
|
184
217
|
default_value: false),
|
185
218
|
FastlaneCore::ConfigItem.new(key: :mapping,
|
186
219
|
env_name: "SUPPLY_MAPPING",
|
@@ -215,7 +248,8 @@ module Supply
|
|
215
248
|
env_name: "SUPPLY_CHECK_SUPERSEDED_TRACKS",
|
216
249
|
optional: true,
|
217
250
|
description: "Check the other tracks for superseded versions and disable them",
|
218
|
-
|
251
|
+
deprecated: "Google Play does this automatically now",
|
252
|
+
type: Boolean,
|
219
253
|
default_value: false),
|
220
254
|
FastlaneCore::ConfigItem.new(key: :timeout,
|
221
255
|
env_name: "SUPPLY_TIMEOUT",
|
@@ -227,16 +261,18 @@ module Supply
|
|
227
261
|
env_name: "SUPPLY_DEACTIVATE_ON_PROMOTE",
|
228
262
|
optional: true,
|
229
263
|
description: "When promoting to a new track, deactivate the binary in the origin track",
|
230
|
-
|
264
|
+
deprecated: "Google Play does this automatically now",
|
265
|
+
type: Boolean,
|
231
266
|
default_value: true),
|
232
267
|
FastlaneCore::ConfigItem.new(key: :version_codes_to_retain,
|
233
268
|
optional: true,
|
234
269
|
type: Array,
|
235
270
|
description: "An array of version codes to retain when publishing a new APK",
|
236
271
|
verify_block: proc do |version_codes|
|
272
|
+
version_codes = version_codes.map(&:to_i)
|
237
273
|
UI.user_error!("Could not evaluate array from '#{version_codes}'") unless version_codes.kind_of?(Array)
|
238
274
|
version_codes.each do |version_code|
|
239
|
-
UI.user_error!("Version code '#{version_code}' is not an integer")
|
275
|
+
UI.user_error!("Version code '#{version_code}' is not an integer") if version_code == 0
|
240
276
|
end
|
241
277
|
end),
|
242
278
|
FastlaneCore::ConfigItem.new(key: :obb_main_references_version,
|
@@ -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
|
data/supply/lib/supply/setup.rb
CHANGED
@@ -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
|
-
|
20
|
-
client.
|
21
|
-
|
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.
|
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
|
-
|
61
|
-
next
|
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
|
-
|
64
|
-
|
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
|
73
|
-
UI.message("
|
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,
|
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, "#{
|
101
|
+
path = File.join(containing, "#{release_listing.version}.txt")
|
94
102
|
UI.message("Writing to #{path}...")
|
95
|
-
File.write(path,
|
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,102 @@ 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
|
|
22
|
+
if !Supply.config[:rollout].nil? && Supply.config[:track].to_s != ""
|
23
|
+
update_rollout
|
24
|
+
end
|
25
|
+
|
37
26
|
promote_track if Supply.config[:track_promote_to]
|
38
27
|
|
39
28
|
if Supply.config[:validate_only]
|
40
|
-
UI.message("Validating all changes with Google Play...")
|
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
|
+
version_codes = [Supply.config[:version_code]] if version_codes.empty?
|
46
|
+
version_codes.each do |version_code|
|
47
|
+
UI.user_error!("Could not find folder #{metadata_path}") unless File.directory?(metadata_path)
|
48
|
+
|
49
|
+
track, release = fetch_track_and_release!(Supply.config[:track], version_code)
|
50
|
+
UI.user_error!("Unable to find the requested track - '#{Supply.config[:track]}'") unless track
|
51
|
+
UI.user_error!("Could not find release for version code '#{version_code}' to update changelog") unless release
|
52
|
+
|
53
|
+
release_notes = []
|
54
|
+
all_languages.each do |language|
|
55
|
+
next if language.start_with?('.') # e.g. . or .. or hidden folders
|
56
|
+
UI.message("Preparing to upload for language '#{language}'...")
|
57
|
+
|
58
|
+
listing = client.listing_for_language(language)
|
59
|
+
|
60
|
+
upload_metadata(language, listing) unless Supply.config[:skip_upload_metadata]
|
61
|
+
upload_images(language) unless Supply.config[:skip_upload_images]
|
62
|
+
upload_screenshots(language) unless Supply.config[:skip_upload_screenshots]
|
63
|
+
release_notes << upload_changelog(language, release.name) unless Supply.config[:skip_upload_changelogs]
|
64
|
+
end
|
65
|
+
|
66
|
+
upload_changelogs(release_notes, release, track) unless release_notes.empty?
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
if Supply.config[:validate_only]
|
71
|
+
UI.message("Validating all meta changes with Google Play...")
|
41
72
|
client.validate_current_edit!
|
42
73
|
UI.success("Successfully validated the upload to Google Play")
|
43
74
|
else
|
44
|
-
UI.message("Uploading all changes to Google Play...")
|
75
|
+
UI.message("Uploading all meta changes to Google Play...")
|
45
76
|
client.commit_current_edit!
|
46
77
|
UI.success("Successfully finished the upload to Google Play")
|
47
78
|
end
|
48
79
|
end
|
49
80
|
|
81
|
+
def fetch_track_and_release!(track, version_code, status = nil)
|
82
|
+
tracks = client.tracks(track)
|
83
|
+
return nil, nil if tracks.empty?
|
84
|
+
|
85
|
+
track = tracks.first
|
86
|
+
releases = track.releases
|
87
|
+
releases = releases.select { |r| r.status == status } if status
|
88
|
+
releases = releases.select { |r| r.version_codes.map(&:to_s).include?(version_code.to_s) }
|
89
|
+
|
90
|
+
if releases.size > 1
|
91
|
+
UI.user_error!("More than one release found in this track. Please specify with the :version_code option to select a release.")
|
92
|
+
end
|
93
|
+
|
94
|
+
return track, releases.first
|
95
|
+
end
|
96
|
+
|
97
|
+
def update_rollout
|
98
|
+
track, release = fetch_track_and_release!(Supply.config[:track], Supply.config[:version_code], Supply::ReleaseStatus::IN_PROGRESS)
|
99
|
+
version_code = release.version_codes.first
|
100
|
+
|
101
|
+
UI.message("Updating #{version_code}'s rollout to '#{Supply.config[:rollout]}' on track '#{Supply.config[:track]}'...")
|
102
|
+
UI.user_error!("Unable to find the requested track - '#{Supply.config[:track]}'") unless track
|
103
|
+
|
104
|
+
if track && release
|
105
|
+
completed = Supply.config[:rollout].to_f == 1
|
106
|
+
release.user_fraction = completed ? nil : Supply.config[:rollout]
|
107
|
+
release.status = Supply::ReleaseStatus::COMPLETED if completed
|
108
|
+
|
109
|
+
# Deleted other version codes if completed because only allowed on completed version in a release
|
110
|
+
track.releases.delete_if { |r| !(r.version_codes || []).map(&:to_s).include?(version_code) } if completed
|
111
|
+
else
|
112
|
+
UI.user_error!("Unable to find version to rollout in track '#{Supply.config[:track]}'")
|
113
|
+
end
|
114
|
+
|
115
|
+
client.update_track(Supply.config[:track], track)
|
116
|
+
end
|
117
|
+
|
50
118
|
def verify_config!
|
51
119
|
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
120
|
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 +128,73 @@ module Supply
|
|
60
128
|
if could_upload_apk && could_upload_aab
|
61
129
|
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
130
|
end
|
131
|
+
|
132
|
+
if Supply.config[:release_status] == Supply::ReleaseStatus::DRAFT && Supply.config[:rollout]
|
133
|
+
UI.user_error!(%(Cannot specify rollout percentage when the release status is set to 'draft'))
|
134
|
+
end
|
135
|
+
|
136
|
+
unless Supply.config[:version_codes_to_retain].nil?
|
137
|
+
Supply.config[:version_codes_to_retain] = Supply.config[:version_codes_to_retain].map(&:to_i)
|
138
|
+
end
|
63
139
|
end
|
64
140
|
|
65
141
|
def promote_track
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
142
|
+
track_from = client.tracks(Supply.config[:track]).first
|
143
|
+
unless track_from
|
144
|
+
UI.user_error!("Cannot promote from track '#{Supply.config[:track]}' - track doesn't exist")
|
145
|
+
end
|
146
|
+
|
147
|
+
releases = track_from.releases
|
148
|
+
if Supply.config[:version_code].to_s != ""
|
149
|
+
releases = releases.select do |release|
|
150
|
+
release.version_codes.include?(Supply.config[:version_code].to_s)
|
151
|
+
end
|
152
|
+
end
|
72
153
|
|
73
|
-
|
74
|
-
|
75
|
-
|
154
|
+
if releases.size == 0
|
155
|
+
UI.user_error!("Track '#{Supply.config[:track]}' doesn't have any releases")
|
156
|
+
elsif releases.size > 1
|
157
|
+
UI.user_error!("Track '#{Supply.config[:track]}' has more than one release - use :version_code to filter the release to promote")
|
76
158
|
end
|
77
|
-
|
78
|
-
|
159
|
+
|
160
|
+
release = track_from.releases.first
|
161
|
+
track_to = client.tracks(Supply.config[:track_promote_to]).first
|
162
|
+
|
163
|
+
if track_to
|
164
|
+
# Its okay to set releases to an array containing the newest release
|
165
|
+
# Google Play will keep previous releases there this release is a partial rollout
|
166
|
+
track_to.releases = [release]
|
167
|
+
else
|
168
|
+
track_to = AndroidPublisher::Track.new(
|
169
|
+
track: Supply.config[:track_promote_to],
|
170
|
+
releases: [release]
|
171
|
+
)
|
79
172
|
end
|
173
|
+
|
174
|
+
client.update_track(Supply.config[:track_promote_to], track_to)
|
80
175
|
end
|
81
176
|
|
82
|
-
def upload_changelog(language,
|
83
|
-
|
177
|
+
def upload_changelog(language, version_name)
|
178
|
+
UI.user_error!("Cannot find changelog because no version name given - please specify :version_name") unless version_name
|
179
|
+
|
180
|
+
path = File.join(Supply.config[:metadata_path], language, Supply::CHANGELOGS_FOLDER_NAME, "#{version_name}.txt")
|
181
|
+
changelog_text = ''
|
84
182
|
if File.exist?(path)
|
85
|
-
UI.message("Updating changelog for
|
86
|
-
|
87
|
-
|
183
|
+
UI.message("Updating changelog for '#{version_name}' and language '#{language}'...")
|
184
|
+
changelog_text = File.read(path, encoding: 'UTF-8')
|
185
|
+
else
|
186
|
+
UI.message("Could not find changelog for '#{version_name}' and language '#{language}' at path #{path}...")
|
88
187
|
end
|
188
|
+
|
189
|
+
AndroidPublisher::LocalizedText.new({
|
190
|
+
language: language,
|
191
|
+
text: changelog_text
|
192
|
+
})
|
193
|
+
end
|
194
|
+
|
195
|
+
def upload_changelogs(release_notes, release, track)
|
196
|
+
release.release_notes = release_notes
|
197
|
+
client.upload_changelogs(track, Supply.config[:track])
|
89
198
|
end
|
90
199
|
|
91
200
|
def upload_metadata(language, listing)
|
@@ -163,14 +272,6 @@ module Supply
|
|
163
272
|
aab_paths.each do |aab_path|
|
164
273
|
UI.message("Preparing aab at path '#{aab_path}' for upload...")
|
165
274
|
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
275
|
aab_version_codes.push(bundle_version_code)
|
175
276
|
end
|
176
277
|
|
@@ -188,6 +289,7 @@ module Supply
|
|
188
289
|
# @return [Integer] The apk version code returned after uploading, or nil if there was a problem
|
189
290
|
def upload_binary_data(apk_path)
|
190
291
|
apk_version_code = nil
|
292
|
+
|
191
293
|
if apk_path
|
192
294
|
UI.message("Preparing apk at path '#{apk_path}' for upload...")
|
193
295
|
apk_version_code = client.upload_apk(apk_path)
|
@@ -208,16 +310,11 @@ module Supply
|
|
208
310
|
end
|
209
311
|
|
210
312
|
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
313
|
else
|
219
314
|
UI.message("No apk file found, you can pass the path to your apk using the `apk` option")
|
220
315
|
end
|
316
|
+
|
317
|
+
UI.message("\tVersion Code: #{apk_version_code}")
|
221
318
|
apk_version_code
|
222
319
|
end
|
223
320
|
|
@@ -230,55 +327,35 @@ module Supply
|
|
230
327
|
end
|
231
328
|
|
232
329
|
def update_track(apk_version_codes)
|
233
|
-
|
234
|
-
check_superseded_tracks(apk_version_codes) if Supply.config[:check_superseded_tracks]
|
235
|
-
|
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
|
330
|
+
return if apk_version_codes.empty?
|
242
331
|
|
243
|
-
|
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
|
332
|
+
UI.message("Updating track '#{Supply.config[:track]}'...")
|
270
333
|
|
271
|
-
|
272
|
-
|
273
|
-
|
334
|
+
track_release = AndroidPublisher::TrackRelease.new(
|
335
|
+
name: Supply.config[:version_name],
|
336
|
+
status: Supply.config[:release_status],
|
337
|
+
version_codes: apk_version_codes
|
338
|
+
)
|
274
339
|
|
275
|
-
|
340
|
+
if Supply.config[:rollout]
|
341
|
+
track_release.status = Supply::ReleaseStatus::IN_PROGRESS
|
342
|
+
track_release.user_fraction = Supply.config[:rollout].to_f
|
343
|
+
end
|
276
344
|
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
345
|
+
tracks = client.tracks(Supply.config[:track])
|
346
|
+
track = tracks.first
|
347
|
+
if track
|
348
|
+
# Its okay to set releases to an array containing the newest release
|
349
|
+
# Google Play will keep previous releases there this release is a partial rollout
|
350
|
+
track.releases = [track_release]
|
351
|
+
else
|
352
|
+
track = AndroidPublisher::Track.new(
|
353
|
+
track: Supply.config[:track],
|
354
|
+
releases: [track_release]
|
355
|
+
)
|
281
356
|
end
|
357
|
+
|
358
|
+
client.update_track(Supply.config[:track], track)
|
282
359
|
end
|
283
360
|
|
284
361
|
# returns only language directories from metadata_path
|
@@ -346,4 +423,5 @@ module Supply
|
|
346
423
|
end
|
347
424
|
end
|
348
425
|
end
|
426
|
+
# rubocop:enable Metrics/ClassLength
|
349
427
|
end
|