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
@@ -1,22 +1,60 @@
|
|
1
1
|
protocol ScreengrabfileProtocol: class {
|
2
|
+
|
3
|
+
/// Path to the root of your Android SDK installation, e.g. ~/tools/android-sdk-macosx
|
2
4
|
var androidHome: String? { get }
|
5
|
+
|
6
|
+
/// The Android build tools version to use, e.g. '23.0.2'
|
3
7
|
var buildToolsVersion: String? { get }
|
8
|
+
|
9
|
+
/// A list of locales which should be used
|
4
10
|
var locales: [String] { get }
|
11
|
+
|
12
|
+
/// Enabling this option will automatically clear previously generated screenshots before running screengrab
|
5
13
|
var clearPreviousScreenshots: Bool { get }
|
14
|
+
|
15
|
+
/// The directory where to store the screenshots
|
6
16
|
var outputDirectory: String { get }
|
17
|
+
|
18
|
+
/// Don't open the summary after running _screengrab_
|
7
19
|
var skipOpenSummary: Bool { get }
|
20
|
+
|
21
|
+
/// The package name of the app under test (e.g. com.yourcompany.yourapp)
|
8
22
|
var appPackageName: String { get }
|
23
|
+
|
24
|
+
/// The package name of the tests bundle (e.g. com.yourcompany.yourapp.test)
|
9
25
|
var testsPackageName: String? { get }
|
26
|
+
|
27
|
+
/// Only run tests in these Java packages
|
10
28
|
var useTestsInPackages: [String]? { get }
|
29
|
+
|
30
|
+
/// Only run tests in these Java classes
|
11
31
|
var useTestsInClasses: [String]? { get }
|
32
|
+
|
33
|
+
/// Additional launch arguments
|
12
34
|
var launchArguments: [String]? { get }
|
35
|
+
|
36
|
+
/// The fully qualified class name of your test instrumentation runner
|
13
37
|
var testInstrumentationRunner: String { get }
|
38
|
+
|
39
|
+
/// Return the device to this locale after running tests
|
14
40
|
var endingLocale: String { get }
|
41
|
+
|
42
|
+
/// The path to the APK for the app under test
|
15
43
|
var appApkPath: String? { get }
|
44
|
+
|
45
|
+
/// The path to the APK for the the tests bundle
|
16
46
|
var testsApkPath: String? { get }
|
47
|
+
|
48
|
+
/// Use the device or emulator with the given serial number or qualifier
|
17
49
|
var specificDevice: String? { get }
|
50
|
+
|
51
|
+
/// Type of device used for screenshots. Matches Google Play Types (phone, sevenInch, tenInch, tv, wear)
|
18
52
|
var deviceType: String { get }
|
53
|
+
|
54
|
+
/// Whether or not to exit Screengrab on test failure. Exiting on failure will not copy sceenshots to local machine nor open sceenshots summary
|
19
55
|
var exitOnTestFailure: Bool { get }
|
56
|
+
|
57
|
+
/// Enabling this option will automatically uninstall the application before running it
|
20
58
|
var reinstallApp: Bool { get }
|
21
59
|
}
|
22
60
|
|
@@ -42,7 +80,6 @@ extension ScreengrabfileProtocol {
|
|
42
80
|
var reinstallApp: Bool { return false }
|
43
81
|
}
|
44
82
|
|
45
|
-
|
46
83
|
// Please don't remove the lines below
|
47
84
|
// They are used to detect outdated files
|
48
|
-
// FastlaneRunnerAPIVersion [0.9.
|
85
|
+
// FastlaneRunnerAPIVersion [0.9.11]
|
@@ -1,37 +1,105 @@
|
|
1
1
|
protocol SnapshotfileProtocol: class {
|
2
|
+
|
3
|
+
/// Path the workspace file
|
2
4
|
var workspace: String? { get }
|
5
|
+
|
6
|
+
/// Path the project file
|
3
7
|
var project: String? { get }
|
8
|
+
|
9
|
+
/// Pass additional arguments to xcodebuild for the test phase. Be sure to quote the setting names and values e.g. OTHER_LDFLAGS="-ObjC -lstdc++"
|
4
10
|
var xcargs: String? { get }
|
11
|
+
|
12
|
+
/// Use an extra XCCONFIG file to build your app
|
5
13
|
var xcconfig: String? { get }
|
14
|
+
|
15
|
+
/// A list of devices you want to take the screenshots from
|
6
16
|
var devices: [String]? { get }
|
17
|
+
|
18
|
+
/// A list of languages which should be used
|
7
19
|
var languages: [String] { get }
|
20
|
+
|
21
|
+
/// A list of launch arguments which should be used
|
8
22
|
var launchArguments: [String] { get }
|
23
|
+
|
24
|
+
/// The directory where to store the screenshots
|
9
25
|
var outputDirectory: String { get }
|
26
|
+
|
27
|
+
/// If the logs generated by the app (e.g. using NSLog, perror, etc.) in the Simulator should be written to the output_directory
|
10
28
|
var outputSimulatorLogs: Bool { get }
|
29
|
+
|
30
|
+
/// By default, the latest version should be used automatically. If you want to change it, do it here
|
11
31
|
var iosVersion: String? { get }
|
32
|
+
|
33
|
+
/// Don't open the HTML summary after running _snapshot_
|
12
34
|
var skipOpenSummary: Bool { get }
|
35
|
+
|
36
|
+
/// Do not check for most recent SnapshotHelper code
|
13
37
|
var skipHelperVersionCheck: Bool { get }
|
38
|
+
|
39
|
+
/// Enabling this option will automatically clear previously generated screenshots before running snapshot
|
14
40
|
var clearPreviousScreenshots: Bool { get }
|
41
|
+
|
42
|
+
/// Enabling this option will automatically uninstall the application before running it
|
15
43
|
var reinstallApp: Bool { get }
|
44
|
+
|
45
|
+
/// Enabling this option will automatically erase the simulator before running the application
|
16
46
|
var eraseSimulator: Bool { get }
|
47
|
+
|
48
|
+
/// Enabling this option will configure the Simulator's system language
|
17
49
|
var localizeSimulator: Bool { get }
|
50
|
+
|
51
|
+
/// Enabling this option will configure the Simulator to be in dark mode (false for light, true for dark)
|
18
52
|
var darkMode: Bool? { get }
|
53
|
+
|
54
|
+
/// The bundle identifier of the app to uninstall (only needed when enabling reinstall_app)
|
19
55
|
var appIdentifier: String? { get }
|
56
|
+
|
57
|
+
/// A list of photos that should be added to the simulator before running the application
|
20
58
|
var addPhotos: [String]? { get }
|
59
|
+
|
60
|
+
/// A list of videos that should be added to the simulator before running the application
|
21
61
|
var addVideos: [String]? { get }
|
62
|
+
|
63
|
+
/// The directory where to store the build log
|
22
64
|
var buildlogPath: String { get }
|
65
|
+
|
66
|
+
/// Should the project be cleaned before building it?
|
23
67
|
var clean: Bool { get }
|
68
|
+
|
69
|
+
/// Test without building, requires a derived data path
|
24
70
|
var testWithoutBuilding: Bool? { get }
|
71
|
+
|
72
|
+
/// The configuration to use when building the app. Defaults to 'Release'
|
25
73
|
var configuration: String? { get }
|
74
|
+
|
75
|
+
/// Additional xcpretty arguments
|
26
76
|
var xcprettyArgs: String? { get }
|
77
|
+
|
78
|
+
/// The SDK that should be used for building the application
|
27
79
|
var sdk: String? { get }
|
80
|
+
|
81
|
+
/// The scheme you want to use, this must be the scheme for the UI Tests
|
28
82
|
var scheme: String? { get }
|
83
|
+
|
84
|
+
/// The number of times a test can fail before snapshot should stop retrying
|
29
85
|
var numberOfRetries: Int { get }
|
86
|
+
|
87
|
+
/// Should snapshot stop immediately after the tests completely failed on one device?
|
30
88
|
var stopAfterFirstError: Bool { get }
|
89
|
+
|
90
|
+
/// The directory where build products and other derived data will go
|
31
91
|
var derivedDataPath: String? { get }
|
92
|
+
|
93
|
+
/// Should an Xcode result bundle be generated in the output directory
|
32
94
|
var resultBundle: Bool { get }
|
95
|
+
|
96
|
+
/// The name of the target you want to test (if you desire to override the Target Application from Xcode)
|
33
97
|
var testTargetName: String? { get }
|
98
|
+
|
99
|
+
/// Separate the log files per device and per language
|
34
100
|
var namespaceLogFiles: String? { get }
|
101
|
+
|
102
|
+
/// Take snapshots on multiple simulators concurrently. Note: This option is only applicable when running against Xcode 9
|
35
103
|
var concurrentSimulators: Bool { get }
|
36
104
|
}
|
37
105
|
|
@@ -74,4 +142,4 @@ extension SnapshotfileProtocol {
|
|
74
142
|
|
75
143
|
// Please don't remove the lines below
|
76
144
|
// They are used to detect outdated files
|
77
|
-
// FastlaneRunnerAPIVersion [0.9.
|
145
|
+
// FastlaneRunnerAPIVersion [0.9.6]
|
@@ -93,9 +93,9 @@ module FastlaneCore
|
|
93
93
|
return if short_switch.nil?
|
94
94
|
|
95
95
|
UI.user_error!("Short option #{short_switch} already taken for key #{key}") if used_switches.include?(short_switch)
|
96
|
-
UI.user_error!("-v is already used for the version (key #{key})") if short_switch == "-v"
|
97
|
-
UI.user_error!("-h is already used for the help screen (key #{key})") if short_switch == "-h"
|
98
|
-
UI.user_error!("-t is already used for the trace screen (key #{key})") if short_switch == "-t"
|
96
|
+
UI.user_error!("-v is already used for the fastlane version (key #{key})") if short_switch == "-v"
|
97
|
+
UI.user_error!("-h is already used for the fastlane help screen (key #{key})") if short_switch == "-h"
|
98
|
+
UI.user_error!("-t is already used for the fastlane trace screen (key #{key})") if short_switch == "-t"
|
99
99
|
|
100
100
|
used_switches << short_switch
|
101
101
|
end
|
@@ -120,7 +120,7 @@ module FastlaneCore
|
|
120
120
|
index = @available_options.find_index { |item| item.key == conflicting_option_key }
|
121
121
|
conflicting_option = @available_options[index]
|
122
122
|
|
123
|
-
# ignore conflicts because
|
123
|
+
# ignore conflicts because value of conflict option is nil
|
124
124
|
next if @values[conflicting_option.key].nil?
|
125
125
|
|
126
126
|
if current.conflict_block
|
@@ -307,7 +307,7 @@ module FastlaneCore
|
|
307
307
|
logarchive_dst = File.join(logs_destination_dir, "system_logs-#{log_identity}.logarchive").shellescape
|
308
308
|
FileUtils.rm_rf(logarchive_dst)
|
309
309
|
FileUtils.mkdir_p(File.expand_path("..", logarchive_dst))
|
310
|
-
command = "xcrun simctl spawn #{device.udid} log collect --output #{logarchive_dst} 2>/dev/null"
|
310
|
+
command = "xcrun simctl spawn --standalone #{device.udid} log collect --output #{logarchive_dst} 2>/dev/null"
|
311
311
|
FastlaneCore::CommandExecutor.execute(command: command, print_all: false, print_command: true)
|
312
312
|
end
|
313
313
|
end
|
@@ -45,7 +45,7 @@ module FastlaneCore
|
|
45
45
|
|
46
46
|
def self.show_loader
|
47
47
|
return unless should_be_shown?
|
48
|
-
# sound is disabled as
|
48
|
+
# sound is disabled as I didn't find a royality free nice midi :(
|
49
49
|
@output = StringIO.new
|
50
50
|
# if FastlaneCore::Env.truthy?("FL_DO_SOUND")
|
51
51
|
# @sound_thr = Thread.new do
|
@@ -117,7 +117,7 @@ module Commander
|
|
117
117
|
abort(e.to_s)
|
118
118
|
end
|
119
119
|
end
|
120
|
-
rescue FastlaneCore::Interface::FastlaneCommonException => e # these are exceptions that we
|
120
|
+
rescue FastlaneCore::Interface::FastlaneCommonException => e # these are exceptions that we don't count as crashes
|
121
121
|
display_user_error!(e, e.to_s)
|
122
122
|
rescue FastlaneCore::Interface::FastlaneError => e # user_error!
|
123
123
|
rescue_fastlane_error(e)
|
data/match/lib/match/importer.rb
CHANGED
@@ -17,7 +17,7 @@ module Match
|
|
17
17
|
UI.user_error!("Certificate does not exist at path: #{cert_path}") unless File.exist?(cert_path)
|
18
18
|
UI.user_error!("Private key does not exist at path: #{p12_path}") unless File.exist?(p12_path)
|
19
19
|
|
20
|
-
# Base64
|
20
|
+
# Base64 encode contents to find match from API to find a cert ID
|
21
21
|
cert_contents_base_64 = Base64.strict_encode64(File.open(cert_path).read)
|
22
22
|
|
23
23
|
# Storage
|
@@ -293,6 +293,9 @@ module Match
|
|
293
293
|
end
|
294
294
|
|
295
295
|
def ensure_bucket_is_selected
|
296
|
+
# Skip the instructions if the user provided a bucket name
|
297
|
+
return unless self.bucket_name.to_s.length == 0
|
298
|
+
|
296
299
|
created_bucket = UI.confirm("Did you already create a Google Cloud Storage bucket?")
|
297
300
|
while self.bucket_name.to_s.length == 0
|
298
301
|
unless created_bucket
|
@@ -6,8 +6,13 @@ module Scan
|
|
6
6
|
class << self
|
7
7
|
# @param [String] The output of the errored build
|
8
8
|
# This method should raise an exception in any case, as the return code indicated a failed build
|
9
|
-
def handle_build_error(output)
|
10
|
-
# The order of the handling below is
|
9
|
+
def handle_build_error(output, log_path)
|
10
|
+
# The order of the handling below is important
|
11
|
+
|
12
|
+
instruction = 'See the log'
|
13
|
+
location = Scan.config[:suppress_xcode_output] ? "here: '#{log_path}'" : "above"
|
14
|
+
details = "#{instruction} #{location}."
|
15
|
+
|
11
16
|
case output
|
12
17
|
when /US\-ASCII/
|
13
18
|
print("Your shell environment is not correctly configured")
|
@@ -23,7 +28,7 @@ module Scan
|
|
23
28
|
print("For more information visit this stackoverflow answer:")
|
24
29
|
print("https://stackoverflow.com/a/17031697/445598")
|
25
30
|
when /Testing failed/
|
26
|
-
UI.build_failure!("Error building the application
|
31
|
+
UI.build_failure!("Error building the application. #{details}")
|
27
32
|
when /Executed/, /Failing tests:/
|
28
33
|
# this is *really* important:
|
29
34
|
# we don't want to raise an exception here
|
@@ -38,7 +43,7 @@ module Scan
|
|
38
43
|
# followed by a list of tests that failed.
|
39
44
|
return
|
40
45
|
end
|
41
|
-
UI.build_failure!("Error building/testing the application
|
46
|
+
UI.build_failure!("Error building/testing the application. #{details}")
|
42
47
|
end
|
43
48
|
|
44
49
|
private
|
data/scan/lib/scan/runner.rb
CHANGED
@@ -67,7 +67,7 @@ module Scan
|
|
67
67
|
error: proc do |error_output|
|
68
68
|
begin
|
69
69
|
exit_status = $?.exitstatus
|
70
|
-
ErrorHandler.handle_build_error(error_output)
|
70
|
+
ErrorHandler.handle_build_error(error_output, @test_command_generator.xcodebuild_log_path)
|
71
71
|
rescue => ex
|
72
72
|
SlackPoster.new.run({
|
73
73
|
build_errors: 1
|
data/sigh/lib/assets/resign.sh
CHANGED
@@ -474,7 +474,7 @@ function resign {
|
|
474
474
|
log "Profile app identifier prefix is '$APP_IDENTIFIER_PREFIX'"
|
475
475
|
fi
|
476
476
|
|
477
|
-
# Set new app
|
477
|
+
# Set new app identifier prefix if such entry exists in plist file
|
478
478
|
PlistBuddy -c "Set :AppIdentifierPrefix $APP_IDENTIFIER_PREFIX." "$APP_PATH/Info.plist" 2>/dev/null
|
479
479
|
|
480
480
|
TEAM_IDENTIFIER=$(PlistBuddy -c "Print :Entitlements:com.apple.developer.team-identifier" "$TEMP_DIR/profile.plist" | tr -d '\n')
|
@@ -690,7 +690,7 @@ function resign {
|
|
690
690
|
# Get the old and new app identifier (prefix)
|
691
691
|
APP_ID_KEY="application-identifier"
|
692
692
|
# Extract just the identifier from the value
|
693
|
-
# Use the fact that we are after some
|
693
|
+
# Use the fact that we are after some identifier, which is always at the start of the string
|
694
694
|
OLD_APP_ID=$(PlistBuddy -c "Print $APP_ID_KEY" "$APP_ENTITLEMENTS" | grep -E '^[A-Z0-9]*' -o | tr -d '\n')
|
695
695
|
NEW_APP_ID=$(PlistBuddy -c "Print $APP_ID_KEY" "$PROFILE_ENTITLEMENTS" | grep -E '^[A-Z0-9]*' -o | tr -d '\n')
|
696
696
|
|
@@ -50,7 +50,7 @@ module Snapshot
|
|
50
50
|
language = language[0]
|
51
51
|
end
|
52
52
|
|
53
|
-
# Clear logs so subsequent xcodebuild executions
|
53
|
+
# Clear logs so subsequent xcodebuild executions don't append to old ones
|
54
54
|
log_path = xcodebuild_log_path(language: language, locale: locale)
|
55
55
|
File.delete(log_path) if File.exist?(log_path)
|
56
56
|
|
@@ -619,8 +619,8 @@ module Spaceship
|
|
619
619
|
def with_retry(tries = 5, &_block)
|
620
620
|
return yield
|
621
621
|
rescue \
|
622
|
-
Faraday::
|
623
|
-
Faraday::
|
622
|
+
Faraday::ConnectionFailed,
|
623
|
+
Faraday::TimeoutError,
|
624
624
|
BadGatewayError,
|
625
625
|
AppleTimeoutError,
|
626
626
|
GatewayTimeoutError => ex
|
data/supply/lib/supply.rb
CHANGED
@@ -3,6 +3,7 @@ require 'supply/options'
|
|
3
3
|
require 'supply/client'
|
4
4
|
require 'supply/listing'
|
5
5
|
require 'supply/apk_listing'
|
6
|
+
require 'supply/release_listing'
|
6
7
|
require 'supply/uploader'
|
7
8
|
require 'supply/languages'
|
8
9
|
|
@@ -23,8 +24,30 @@ module Supply
|
|
23
24
|
|
24
25
|
CHANGELOGS_FOLDER_NAME = "changelogs"
|
25
26
|
|
27
|
+
# https://developers.google.com/android-publisher/#publishing
|
28
|
+
module Tracks
|
29
|
+
PRODUCTION = "production"
|
30
|
+
BETA = "beta"
|
31
|
+
ALPHA = "alpha"
|
32
|
+
INTERNAL = "internal"
|
33
|
+
|
34
|
+
DEFAULTS = [PRODUCTION, BETA, ALPHA, INTERNAL]
|
35
|
+
DEFAULT = PRODUCTION
|
36
|
+
end
|
37
|
+
|
38
|
+
# https://developers.google.com/android-publisher/api-ref/edits/tracks
|
39
|
+
module ReleaseStatus
|
40
|
+
COMPLETED = "completed"
|
41
|
+
DRAFT = "draft"
|
42
|
+
HALTED = "halted"
|
43
|
+
IN_PROGRESS = "inProgress"
|
44
|
+
|
45
|
+
ALL = [COMPLETED, DRAFT, HALTED, IN_PROGRESS]
|
46
|
+
end
|
47
|
+
|
26
48
|
Helper = FastlaneCore::Helper # you gotta love Ruby: Helper.* should use the Helper class contained in FastlaneCore
|
27
49
|
UI = FastlaneCore::UI
|
50
|
+
Boolean = Fastlane::Boolean
|
28
51
|
ROOT = Pathname.new(File.expand_path('../..', __FILE__))
|
29
52
|
DESCRIPTION = "Command line tool for updating Android apps and their metadata on the Google Play Store".freeze
|
30
53
|
end
|
Binary file
|
Binary file
|
data/supply/lib/supply/client.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'googleauth'
|
2
|
-
require 'google/apis/
|
3
|
-
|
2
|
+
require 'google/apis/androidpublisher_v3'
|
3
|
+
AndroidPublisher = Google::Apis::AndroidpublisherV3
|
4
4
|
|
5
5
|
require 'net/http'
|
6
6
|
|
@@ -96,8 +96,8 @@ module Supply
|
|
96
96
|
end
|
97
97
|
|
98
98
|
class Client < AbstractGoogleServiceClient
|
99
|
-
SERVICE =
|
100
|
-
SCOPE =
|
99
|
+
SERVICE = AndroidPublisher::AndroidPublisherService
|
100
|
+
SCOPE = AndroidPublisher::AUTH_ANDROIDPUBLISHER
|
101
101
|
|
102
102
|
# Editing something
|
103
103
|
# Reference to the entry we're currently editing. Might be nil if don't have one open
|
@@ -176,7 +176,7 @@ module Supply
|
|
176
176
|
def listings
|
177
177
|
ensure_active_edit!
|
178
178
|
|
179
|
-
result = call_google_api { client.
|
179
|
+
result = call_google_api { client.list_edit_listings(current_package_name, current_edit.id) }
|
180
180
|
|
181
181
|
return result.listings.map do |row|
|
182
182
|
Listing.new(self, row.language, row)
|
@@ -188,7 +188,7 @@ module Supply
|
|
188
188
|
ensure_active_edit!
|
189
189
|
|
190
190
|
begin
|
191
|
-
result = client.
|
191
|
+
result = client.get_edit_listing(
|
192
192
|
current_package_name,
|
193
193
|
current_edit.id,
|
194
194
|
language
|
@@ -205,7 +205,7 @@ module Supply
|
|
205
205
|
def apks_version_codes
|
206
206
|
ensure_active_edit!
|
207
207
|
|
208
|
-
result = call_google_api { client.
|
208
|
+
result = call_google_api { client.list_edit_apks(current_package_name, current_edit.id) }
|
209
209
|
|
210
210
|
return Array(result.apks).map(&:version_code)
|
211
211
|
end
|
@@ -219,23 +219,57 @@ module Supply
|
|
219
219
|
return Array(result.bundles).map(&:version_code)
|
220
220
|
end
|
221
221
|
|
222
|
-
|
223
|
-
def apk_listings(apk_version_code)
|
222
|
+
def release_listings(version)
|
224
223
|
ensure_active_edit!
|
225
224
|
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
225
|
+
# Verify that tracks have releases
|
226
|
+
filtered_tracks = tracks.select { |t| !t.releases.nil? && t.releases.any? { |r| r.name == version } }
|
227
|
+
|
228
|
+
if filtered_tracks.length > 1
|
229
|
+
# Production track takes precedence if version is present in multiple tracks
|
230
|
+
# E.g.: A release might've been promoted from Alpha/Beta track. This means the release will be present in two or more tracks
|
231
|
+
if filtered_tracks.any? { |t| t.track == Supply::Tracks::DEFAULT }
|
232
|
+
filtered_tracks = filtered_tracks.select { |t| t.track == Supply::Tracks::DEFAULT }
|
233
|
+
else
|
234
|
+
# E.g.: A release might be in both Alpha & Beta (not sure if this is possible, just catching if it ever happens), giving Beta precedence.
|
235
|
+
filtered_tracks = filtered_tracks.select { |t| t.track == Supply::Tracks::BETA }
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
filtered_track = filtered_tracks.first
|
240
|
+
if filtered_track.nil?
|
241
|
+
UI.user_error!("Unable to find version '#{version}' for '#{current_package_name}' in all tracks. Please double check the version number.")
|
242
|
+
return nil
|
243
|
+
else
|
244
|
+
UI.message("Found '#{version}' in '#{filtered_track.track}' track.")
|
245
|
+
end
|
246
|
+
|
247
|
+
filtered_release = filtered_track.releases.first { |r| r.name == version }
|
248
|
+
|
249
|
+
# Since we can release on Alpha/Beta without release notes.
|
250
|
+
if filtered_release.release_notes.nil?
|
251
|
+
UI.user_error!("Version '#{version}' for '#{current_package_name}' does not seem to have any release notes. Nothing to download.")
|
252
|
+
return nil
|
232
253
|
end
|
233
254
|
|
234
|
-
return
|
235
|
-
|
255
|
+
return filtered_release.release_notes.map do |row|
|
256
|
+
Supply::ReleaseListing.new(filtered_track, filtered_release.name, filtered_release.version_codes, row.language, row.text)
|
236
257
|
end
|
237
258
|
end
|
238
259
|
|
260
|
+
def latest_version(track)
|
261
|
+
latest_version = tracks.select { |t| t.track == Supply::Tracks::DEFAULT }.map(&:releases).flatten.max_by(&:name)
|
262
|
+
|
263
|
+
# Check if user specified '--track' option if version information from 'production' track is nil
|
264
|
+
if latest_version.nil? && track == Supply::Tracks::DEFAULT
|
265
|
+
UI.user_error!(%(Unable to find latest version information from "#{Supply::Tracks::DEFAULT}" track. Please specify track information by using the '--track' option.))
|
266
|
+
else
|
267
|
+
latest_version = tracks.select { |t| t.track == track }.map(&:releases).flatten.max_by(&:name)
|
268
|
+
end
|
269
|
+
|
270
|
+
return latest_version
|
271
|
+
end
|
272
|
+
|
239
273
|
#####################################################
|
240
274
|
# @!group Modifying data
|
241
275
|
#####################################################
|
@@ -244,7 +278,7 @@ module Supply
|
|
244
278
|
def update_listing_for_language(language: nil, title: nil, short_description: nil, full_description: nil, video: nil)
|
245
279
|
ensure_active_edit!
|
246
280
|
|
247
|
-
listing =
|
281
|
+
listing = AndroidPublisher::Listing.new({
|
248
282
|
language: language,
|
249
283
|
title: title,
|
250
284
|
full_description: full_description,
|
@@ -253,7 +287,7 @@ module Supply
|
|
253
287
|
})
|
254
288
|
|
255
289
|
call_google_api do
|
256
|
-
client.
|
290
|
+
client.update_edit_listing(
|
257
291
|
current_package_name,
|
258
292
|
current_edit.id,
|
259
293
|
language,
|
@@ -266,7 +300,7 @@ module Supply
|
|
266
300
|
ensure_active_edit!
|
267
301
|
|
268
302
|
result_upload = call_google_api do
|
269
|
-
client.
|
303
|
+
client.upload_edit_apk(
|
270
304
|
current_package_name,
|
271
305
|
current_edit.id,
|
272
306
|
upload_source: path_to_apk
|
@@ -306,29 +340,28 @@ module Supply
|
|
306
340
|
return result_upload.version_code
|
307
341
|
end
|
308
342
|
|
309
|
-
#
|
310
|
-
def
|
343
|
+
# Get a list of all tracks - returns the list
|
344
|
+
def tracks(*tracknames)
|
311
345
|
ensure_active_edit!
|
312
346
|
|
313
|
-
|
347
|
+
all_tracks = call_google_api { client.list_edit_tracks(current_package_name, current_edit.id) }.tracks
|
348
|
+
|
349
|
+
if tracknames.length > 0
|
350
|
+
all_tracks = all_tracks.select { |track| tracknames.include?(track.track) }
|
351
|
+
end
|
314
352
|
|
315
|
-
|
316
|
-
|
317
|
-
# https://github.com/fastlane/fastlane/issues/12372
|
318
|
-
rollout = nil unless track == "rollout"
|
353
|
+
return all_tracks
|
354
|
+
end
|
319
355
|
|
320
|
-
|
321
|
-
|
322
|
-
user_fraction: rollout,
|
323
|
-
version_codes: track_version_codes
|
324
|
-
})
|
356
|
+
def update_track(track_name, track_object)
|
357
|
+
ensure_active_edit!
|
325
358
|
|
326
359
|
call_google_api do
|
327
|
-
client.
|
360
|
+
client.update_edit_track(
|
328
361
|
current_package_name,
|
329
362
|
current_edit.id,
|
330
|
-
|
331
|
-
|
363
|
+
track_name,
|
364
|
+
track_object
|
332
365
|
)
|
333
366
|
end
|
334
367
|
end
|
@@ -338,33 +371,27 @@ module Supply
|
|
338
371
|
ensure_active_edit!
|
339
372
|
|
340
373
|
begin
|
341
|
-
result = client.
|
374
|
+
result = client.get_edit_track(
|
342
375
|
current_package_name,
|
343
376
|
current_edit.id,
|
344
377
|
track
|
345
378
|
)
|
346
|
-
return result.version_codes || []
|
379
|
+
return result.releases.flat_map(&:version_codes) || []
|
347
380
|
rescue Google::Apis::ClientError => e
|
348
381
|
return [] if e.status_code == 404 && e.to_s.include?("trackEmpty")
|
349
382
|
raise
|
350
383
|
end
|
351
384
|
end
|
352
385
|
|
353
|
-
def
|
386
|
+
def upload_changelogs(track, track_name)
|
354
387
|
ensure_active_edit!
|
355
388
|
|
356
|
-
apk_listing_object = Androidpublisher::ApkListing.new({
|
357
|
-
language: apk_listing.language,
|
358
|
-
recent_changes: apk_listing.recent_changes
|
359
|
-
})
|
360
|
-
|
361
389
|
call_google_api do
|
362
|
-
client.
|
390
|
+
client.update_edit_track(
|
363
391
|
current_package_name,
|
364
|
-
current_edit.id,
|
365
|
-
|
366
|
-
|
367
|
-
apk_listing_object
|
392
|
+
self.current_edit.id,
|
393
|
+
track_name,
|
394
|
+
track
|
368
395
|
)
|
369
396
|
end
|
370
397
|
end
|
@@ -373,12 +400,12 @@ module Supply
|
|
373
400
|
ensure_active_edit!
|
374
401
|
|
375
402
|
call_google_api do
|
376
|
-
client.
|
403
|
+
client.update_edit_expansionfile(
|
377
404
|
current_package_name,
|
378
405
|
current_edit.id,
|
379
406
|
apk_version_code,
|
380
407
|
expansion_file_type,
|
381
|
-
|
408
|
+
AndroidPublisher::ExpansionFile.new(
|
382
409
|
references_version: references_version,
|
383
410
|
file_size: file_size
|
384
411
|
)
|
@@ -394,7 +421,7 @@ module Supply
|
|
394
421
|
ensure_active_edit!
|
395
422
|
|
396
423
|
result = call_google_api do
|
397
|
-
client.
|
424
|
+
client.list_edit_images(
|
398
425
|
current_package_name,
|
399
426
|
current_edit.id,
|
400
427
|
language,
|
@@ -402,7 +429,26 @@ module Supply
|
|
402
429
|
)
|
403
430
|
end
|
404
431
|
|
405
|
-
(result.images || []).map(&:url)
|
432
|
+
urls = (result.images || []).map(&:url)
|
433
|
+
images = urls.map do |url|
|
434
|
+
uri = URI.parse(url)
|
435
|
+
clean_url = [
|
436
|
+
uri.scheme,
|
437
|
+
uri.userinfo,
|
438
|
+
uri.host,
|
439
|
+
uri.port,
|
440
|
+
uri.path
|
441
|
+
].join
|
442
|
+
|
443
|
+
UI.verbose("Initial URL received: '#{url}'")
|
444
|
+
UI.verbose("Removed params ('#{uri.query}') from the URL")
|
445
|
+
UI.verbose("URL after removing params: '#{clean_url}'")
|
446
|
+
|
447
|
+
full_url = "#{url}=s0" # '=s0' param ensures full image size is returned (https://github.com/fastlane/fastlane/pull/14322#issuecomment-473012462)
|
448
|
+
full_url
|
449
|
+
end
|
450
|
+
|
451
|
+
return images
|
406
452
|
end
|
407
453
|
|
408
454
|
# @param image_type (e.g. phoneScreenshots, sevenInchScreenshots, ...)
|
@@ -410,7 +456,7 @@ module Supply
|
|
410
456
|
ensure_active_edit!
|
411
457
|
|
412
458
|
call_google_api do
|
413
|
-
client.
|
459
|
+
client.upload_edit_image(
|
414
460
|
current_package_name,
|
415
461
|
current_edit.id,
|
416
462
|
language,
|
@@ -425,7 +471,7 @@ module Supply
|
|
425
471
|
ensure_active_edit!
|
426
472
|
|
427
473
|
call_google_api do
|
428
|
-
client.
|
474
|
+
client.deleteall_edit_image(
|
429
475
|
current_package_name,
|
430
476
|
current_edit.id,
|
431
477
|
language,
|
@@ -438,7 +484,7 @@ module Supply
|
|
438
484
|
ensure_active_edit!
|
439
485
|
|
440
486
|
call_google_api do
|
441
|
-
client.
|
487
|
+
client.upload_edit_expansionfile(
|
442
488
|
current_package_name,
|
443
489
|
current_edit.id,
|
444
490
|
apk_version_code,
|