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