fastlane 2.179.0 → 2.180.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +84 -84
- data/fastlane/lib/fastlane/actions/app_store_connect_api_key.rb +1 -1
- data/fastlane/lib/fastlane/actions/jira.rb +61 -14
- data/fastlane/lib/fastlane/actions/notarize.rb +98 -51
- data/fastlane/lib/fastlane/actions/sourcedocs.rb +164 -0
- data/fastlane/lib/fastlane/setup/setup.rb +23 -10
- data/fastlane/lib/fastlane/swift_runner_upgrader.rb +2 -0
- data/fastlane/lib/fastlane/version.rb +1 -1
- data/fastlane/swift/Deliverfile.swift +1 -1
- data/fastlane/swift/DeliverfileProtocol.swift +1 -1
- data/fastlane/swift/Fastlane.swift +87 -21
- data/fastlane/swift/Gymfile.swift +1 -1
- data/fastlane/swift/GymfileProtocol.swift +1 -1
- data/fastlane/swift/LaneFileProtocol.swift +9 -3
- data/fastlane/swift/Matchfile.swift +1 -1
- data/fastlane/swift/MatchfileProtocol.swift +1 -1
- data/fastlane/swift/Precheckfile.swift +1 -1
- data/fastlane/swift/PrecheckfileProtocol.swift +1 -1
- data/fastlane/swift/RubyCommand.swift +1 -1
- data/fastlane/swift/Scanfile.swift +1 -1
- data/fastlane/swift/ScanfileProtocol.swift +5 -1
- data/fastlane/swift/Screengrabfile.swift +1 -1
- data/fastlane/swift/ScreengrabfileProtocol.swift +1 -1
- data/fastlane/swift/Snapshotfile.swift +1 -1
- data/fastlane/swift/SnapshotfileProtocol.swift +1 -1
- data/fastlane/swift/SocketClient.swift +2 -1
- data/fastlane/swift/SocketResponse.swift +4 -2
- data/fastlane/swift/formatting/Brewfile.lock.json +3 -3
- data/fastlane_core/lib/fastlane_core/queue_worker.rb +2 -2
- data/fastlane_core/lib/fastlane_core/ui/implementations/shell.rb +12 -1
- data/match/lib/match/change_password.rb +1 -1
- data/scan/lib/scan/options.rb +10 -5
- data/scan/lib/scan/runner.rb +52 -1
- data/scan/lib/scan/test_command_generator.rb +8 -8
- data/snapshot/lib/assets/SnapshotHelper.swift +1 -1
- data/spaceship/lib/spaceship/connect_api/models/app_screenshot.rb +1 -1
- data/spaceship/lib/spaceship/connect_api/token.rb +7 -1
- metadata +18 -18
- data/gym/lib/gym/.runner.rb.swp +0 -0
@@ -17,20 +17,20 @@ public protocol LaneFileProtocol: class {
|
|
17
17
|
func recordLaneDescriptions()
|
18
18
|
func beforeAll(with lane: String)
|
19
19
|
func afterAll(with lane: String)
|
20
|
-
func onError(currentLane: String, errorInfo: String)
|
20
|
+
func onError(currentLane: String, errorInfo: String, errorClass: String?, errorMessage: String?)
|
21
21
|
}
|
22
22
|
|
23
23
|
public extension LaneFileProtocol {
|
24
24
|
var fastlaneVersion: String { return "" } // Defaults to "" because that means any is fine
|
25
25
|
func beforeAll(with _: String) {} // No-op by default
|
26
26
|
func afterAll(with _: String) {} // No-op by default
|
27
|
-
func onError(currentLane _: String, errorInfo _: String) {} // No-op by default
|
28
27
|
func recordLaneDescriptions() {} // No-op by default
|
29
28
|
}
|
30
29
|
|
31
30
|
@objcMembers
|
32
31
|
open class LaneFile: NSObject, LaneFileProtocol {
|
33
32
|
private(set) static var fastfileInstance: LaneFile?
|
33
|
+
private static var onErrorCalled = Set<String>()
|
34
34
|
|
35
35
|
private static func trimLaneFromName(laneName: String) -> String {
|
36
36
|
return String(laneName.prefix(laneName.count - 4))
|
@@ -40,6 +40,10 @@ open class LaneFile: NSObject, LaneFileProtocol {
|
|
40
40
|
return String(laneName.prefix(laneName.count - 12))
|
41
41
|
}
|
42
42
|
|
43
|
+
public func onError(currentLane: String, errorInfo _: String, errorClass _: String?, errorMessage _: String?) {
|
44
|
+
LaneFile.onErrorCalled.insert(currentLane)
|
45
|
+
}
|
46
|
+
|
43
47
|
private static var laneFunctionNames: [String] {
|
44
48
|
var lanes: [String] = []
|
45
49
|
var methodCount: UInt32 = 0
|
@@ -137,7 +141,9 @@ open class LaneFile: NSObject, LaneFileProtocol {
|
|
137
141
|
_ = fastfileInstance.perform(NSSelectorFromString(laneMethod), with: parameters)
|
138
142
|
|
139
143
|
// Call only on success.
|
140
|
-
|
144
|
+
if !LaneFile.onErrorCalled.contains(lane) {
|
145
|
+
fastfileInstance.afterAll(with: lane)
|
146
|
+
}
|
141
147
|
|
142
148
|
log(message: "Done running lane: \(lane) 🚀")
|
143
149
|
return true
|
@@ -51,7 +51,7 @@ struct RubyCommand: RubyCommandable {
|
|
51
51
|
if type == .stringClosure {
|
52
52
|
return "{\"name\" : \"\(name)\", \"value\" : \"ignored_for_closure\"\(typeJson)}"
|
53
53
|
} else if let array = someValue as? [String] {
|
54
|
-
return "{\"name\" : \"\(name)\", \"value\" : \
|
54
|
+
return "{\"name\" : \"\(name)\", \"value\" : \(array)\(typeJson)}"
|
55
55
|
} else if let hash = someValue as? [String: Any] {
|
56
56
|
let jsonData = try! JSONSerialization.data(withJSONObject: hash, options: [])
|
57
57
|
let jsonString = String(data: jsonData, encoding: .utf8)!
|
@@ -209,6 +209,9 @@ public protocol ScanfileProtocol: class {
|
|
209
209
|
/// Lets xcodebuild use system's scm configuration
|
210
210
|
var useSystemScm: Bool { get }
|
211
211
|
|
212
|
+
/// The number of times a test can fail before scan should stop retrying
|
213
|
+
var numberOfRetries: Int { get }
|
214
|
+
|
212
215
|
/// Should this step stop the build if the tests fail? Set this to false if you're using trainer
|
213
216
|
var failBuild: Bool { get }
|
214
217
|
}
|
@@ -283,9 +286,10 @@ public extension ScanfileProtocol {
|
|
283
286
|
var skipPackageDependenciesResolution: Bool { return false }
|
284
287
|
var disablePackageAutomaticUpdates: Bool { return false }
|
285
288
|
var useSystemScm: Bool { return false }
|
289
|
+
var numberOfRetries: Int { return 0 }
|
286
290
|
var failBuild: Bool { return true }
|
287
291
|
}
|
288
292
|
|
289
293
|
// Please don't remove the lines below
|
290
294
|
// They are used to detect outdated files
|
291
|
-
// FastlaneRunnerAPIVersion [0.9.
|
295
|
+
// FastlaneRunnerAPIVersion [0.9.71]
|
@@ -302,7 +302,8 @@ extension SocketClient: StreamDelegate {
|
|
302
302
|
self.closeSession(sendAbort: false)
|
303
303
|
}
|
304
304
|
|
305
|
-
case let .failure(failureInformation):
|
305
|
+
case let .failure(failureInformation, failureClass, failureMessage):
|
306
|
+
LaneFile.fastfileInstance?.onError(currentLane: ArgumentProcessor(args: CommandLine.arguments).currentLane, errorInfo: failureInformation.joined(), errorClass: failureClass, errorMessage: failureMessage)
|
306
307
|
socketDelegate?.commandExecuted(serverResponse: .serverError) {
|
307
308
|
$0.writeSemaphore.signal()
|
308
309
|
self.handleFailure(message: failureInformation)
|
@@ -13,7 +13,7 @@ import Foundation
|
|
13
13
|
struct SocketResponse {
|
14
14
|
enum ResponseType {
|
15
15
|
case parseFailure(failureInformation: [String])
|
16
|
-
case failure(failureInformation: [String])
|
16
|
+
case failure(failureInformation: [String], failureClass: String?, failureMessage: String?)
|
17
17
|
case readyForNext(returnedObject: String?, closureArgumentValue: String?)
|
18
18
|
case clientInitiatedCancel
|
19
19
|
|
@@ -40,7 +40,9 @@ struct SocketResponse {
|
|
40
40
|
return
|
41
41
|
}
|
42
42
|
|
43
|
-
|
43
|
+
let failureClass = statusDictionary["failure_class"] as? String
|
44
|
+
let failureMessage = statusDictionary["failure_message"] as? String
|
45
|
+
self = .failure(failureInformation: failureInformation, failureClass: failureClass, failureMessage: failureMessage)
|
44
46
|
return
|
45
47
|
}
|
46
48
|
self = .parseFailure(failureInformation: ["Message status: \(status) not a supported status"])
|
@@ -33,10 +33,10 @@
|
|
33
33
|
"system": {
|
34
34
|
"macos": {
|
35
35
|
"catalina": {
|
36
|
-
"HOMEBREW_VERSION": "3.0.
|
36
|
+
"HOMEBREW_VERSION": "3.0.11-37-g6d0275f",
|
37
37
|
"HOMEBREW_PREFIX": "/usr/local",
|
38
|
-
"Homebrew/homebrew-core": "
|
39
|
-
"CLT": "11.0.33.12",
|
38
|
+
"Homebrew/homebrew-core": "ef0489237f06f73c1148f10ea1001def194b6808",
|
39
|
+
"CLT": "11.0.0.33.12",
|
40
40
|
"Xcode": "12.2",
|
41
41
|
"macOS": "10.15.7"
|
42
42
|
},
|
@@ -16,12 +16,12 @@ module FastlaneCore
|
|
16
16
|
@queue = Queue.new
|
17
17
|
end
|
18
18
|
|
19
|
-
# @param job (Object) - An
|
19
|
+
# @param job (Object) - An arbitrary object that keeps parameters
|
20
20
|
def enqueue(job)
|
21
21
|
@queue.push(job)
|
22
22
|
end
|
23
23
|
|
24
|
-
# @param jobs (Array<Object>) - An array of
|
24
|
+
# @param jobs (Array<Object>) - An array of arbitrary object that keeps parameters
|
25
25
|
def batch_enqueue(jobs)
|
26
26
|
raise(ArgumentError, "Enqueue Array instead of #{jobs.class}") unless jobs.kind_of?(Array)
|
27
27
|
jobs.each { |job| enqueue(job) }
|
@@ -69,7 +69,7 @@ module FastlaneCore
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def command_output(message)
|
72
|
-
actual = (message.split("\r").last || "") # as clearing the line will remove the `>` and the time stamp
|
72
|
+
actual = (encode_as_utf_8_if_possible(message).split("\r").last || "") # as clearing the line will remove the `>` and the time stamp
|
73
73
|
actual.split("\n").each do |msg|
|
74
74
|
if FastlaneCore::Env.truthy?("FASTLANE_DISABLE_OUTPUT_FORMAT")
|
75
75
|
log.info(msg)
|
@@ -150,6 +150,17 @@ module FastlaneCore
|
|
150
150
|
|
151
151
|
private
|
152
152
|
|
153
|
+
def encode_as_utf_8_if_possible(message)
|
154
|
+
return message if message.valid_encoding?
|
155
|
+
|
156
|
+
# genstrings outputs UTF-16, so we should try to use this encoding if it turns out to be valid
|
157
|
+
test_message = message.dup
|
158
|
+
return message.encode(Encoding::UTF_8, Encoding::UTF_16) if test_message.force_encoding(Encoding::UTF_16).valid_encoding?
|
159
|
+
|
160
|
+
# replace any invalid with empty string
|
161
|
+
message.encode(Encoding::UTF_8, invalid: :replace)
|
162
|
+
end
|
163
|
+
|
153
164
|
def verify_interactive!(message)
|
154
165
|
return if interactive?
|
155
166
|
important(message)
|
@@ -40,7 +40,7 @@ module Match
|
|
40
40
|
encryption.store_password(new_password)
|
41
41
|
|
42
42
|
message = "[fastlane] Changed passphrase"
|
43
|
-
files_to_commit = encryption.encrypt_files(new_password)
|
43
|
+
files_to_commit = encryption.encrypt_files(password: new_password)
|
44
44
|
storage.save_changes!(files_to_commit: files_to_commit, custom_message: message)
|
45
45
|
end
|
46
46
|
|
data/scan/lib/scan/options.rb
CHANGED
@@ -472,11 +472,16 @@ module Scan
|
|
472
472
|
type: Boolean,
|
473
473
|
default_value: false),
|
474
474
|
FastlaneCore::ConfigItem.new(key: :use_system_scm,
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
475
|
+
env_name: "SCAN_USE_SYSTEM_SCM",
|
476
|
+
description: "Lets xcodebuild use system's scm configuration",
|
477
|
+
optional: true,
|
478
|
+
type: Boolean,
|
479
|
+
default_value: false),
|
480
|
+
FastlaneCore::ConfigItem.new(key: :number_of_retries,
|
481
|
+
env_name: 'SCAN_NUMBER_OF_RETRIES',
|
482
|
+
description: "The number of times a test can fail before scan should stop retrying",
|
483
|
+
type: Integer,
|
484
|
+
default_value: 0)
|
480
485
|
|
481
486
|
]
|
482
487
|
end
|
data/scan/lib/scan/runner.rb
CHANGED
@@ -51,7 +51,12 @@ module Scan
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
+
execute(retries: Scan.config[:number_of_retries])
|
55
|
+
end
|
56
|
+
|
57
|
+
def execute(retries: 0)
|
54
58
|
command = @test_command_generator.generate
|
59
|
+
|
55
60
|
prefix_hash = [
|
56
61
|
{
|
57
62
|
prefix: "Running Tests: ",
|
@@ -71,7 +76,12 @@ module Scan
|
|
71
76
|
error: proc do |error_output|
|
72
77
|
begin
|
73
78
|
exit_status = $?.exitstatus
|
74
|
-
|
79
|
+
if retries > 0
|
80
|
+
# If there are retries remaining, run the tests again
|
81
|
+
return retry_execute(retries: retries, error_output: error_output)
|
82
|
+
else
|
83
|
+
ErrorHandler.handle_build_error(error_output, @test_command_generator.xcodebuild_log_path)
|
84
|
+
end
|
75
85
|
rescue => ex
|
76
86
|
SlackPoster.new.run({
|
77
87
|
build_errors: 1
|
@@ -79,9 +89,50 @@ module Scan
|
|
79
89
|
raise ex
|
80
90
|
end
|
81
91
|
end)
|
92
|
+
|
82
93
|
exit_status
|
83
94
|
end
|
84
95
|
|
96
|
+
def retry_execute(retries:, error_output: "")
|
97
|
+
tests = retryable_tests(error_output)
|
98
|
+
|
99
|
+
if tests.empty?
|
100
|
+
UI.crash!("Failed to find failed tests to retry (could not parse error output)")
|
101
|
+
end
|
102
|
+
|
103
|
+
Scan.config[:only_testing] = tests
|
104
|
+
UI.important("Retrying tests: #{Scan.config[:only_testing].join(', ')}")
|
105
|
+
|
106
|
+
retries -= 1
|
107
|
+
UI.important("Number of retries remaining: #{retries}")
|
108
|
+
|
109
|
+
return execute(retries: retries)
|
110
|
+
end
|
111
|
+
|
112
|
+
def retryable_tests(input)
|
113
|
+
input = Helper.strip_ansi_colors(input)
|
114
|
+
|
115
|
+
retryable_tests = []
|
116
|
+
|
117
|
+
failing_tests = input.split("Failing tests:\n").fetch(1, [])
|
118
|
+
.split("\n\n").first
|
119
|
+
|
120
|
+
suites = failing_tests.split(/(?=\n\s+[\w\s]+:\n)/)
|
121
|
+
|
122
|
+
suites.each do |suite|
|
123
|
+
suite_name = suite.match(/\s*([\w\s]+):/).captures.first
|
124
|
+
|
125
|
+
test_cases = suite.split(":\n").fetch(1, []).split("\n").each
|
126
|
+
.select { |line| line.match?(/^\s+/) }
|
127
|
+
.map { |line| line.strip.gsub(".", "/").gsub("()", "") }
|
128
|
+
.map { |line| suite_name + "/" + line }
|
129
|
+
|
130
|
+
retryable_tests += test_cases
|
131
|
+
end
|
132
|
+
|
133
|
+
return retryable_tests.uniq
|
134
|
+
end
|
135
|
+
|
85
136
|
def handle_results(tests_exit_status)
|
86
137
|
if Scan.config[:disable_xcpretty]
|
87
138
|
unless tests_exit_status == 0
|
@@ -162,16 +162,16 @@ module Scan
|
|
162
162
|
Scan.cache[:build_path]
|
163
163
|
end
|
164
164
|
|
165
|
+
# The path to the result bundle
|
165
166
|
def result_bundle_path
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
FileUtils.remove_dir(path)
|
171
|
-
end
|
172
|
-
Scan.cache[:result_bundle_path] = path
|
167
|
+
ext = FastlaneCore::Helper.xcode_version.to_i >= 11 ? '.xcresult' : '.test_result'
|
168
|
+
path = File.join(Scan.config[:output_directory], Scan.config[:scheme]) + ext
|
169
|
+
if File.directory?(path)
|
170
|
+
FileUtils.remove_dir(path)
|
173
171
|
end
|
174
|
-
|
172
|
+
Scan.cache[:result_bundle_path] = path
|
173
|
+
|
174
|
+
return path
|
175
175
|
end
|
176
176
|
end
|
177
177
|
end
|
@@ -112,7 +112,7 @@ module Spaceship
|
|
112
112
|
timeout_minutes = (ENV["SPACESHIP_SCREENSHOT_UPLOAD_TIMEOUT"] || 20).to_i
|
113
113
|
|
114
114
|
loop do
|
115
|
-
# This error handling needs to be revised since any error
|
115
|
+
# This error handling needs to be revised since any error occurred can reach here.
|
116
116
|
# It should handle errors based on what status code is.
|
117
117
|
puts("Waiting for screenshots to appear before uploading. This is unlikely to be recovered unless it's 503 error. error=\"#{error}\"")
|
118
118
|
sleep(30)
|
@@ -60,14 +60,16 @@ module Spaceship
|
|
60
60
|
key_id: key_id,
|
61
61
|
issuer_id: issuer_id,
|
62
62
|
key: OpenSSL::PKey::EC.new(key),
|
63
|
+
key_raw: key,
|
63
64
|
duration: duration,
|
64
65
|
in_house: in_house
|
65
66
|
)
|
66
67
|
end
|
67
68
|
|
68
|
-
def initialize(key_id: nil, issuer_id: nil, key: nil, duration: nil, in_house: nil)
|
69
|
+
def initialize(key_id: nil, issuer_id: nil, key: nil, key_raw: nil, duration: nil, in_house: nil)
|
69
70
|
@key_id = key_id
|
70
71
|
@key = key
|
72
|
+
@key_raw = key_raw
|
71
73
|
@issuer_id = issuer_id
|
72
74
|
@duration = duration
|
73
75
|
@in_house = in_house
|
@@ -97,6 +99,10 @@ module Spaceship
|
|
97
99
|
def expired?
|
98
100
|
@expiration < Time.now
|
99
101
|
end
|
102
|
+
|
103
|
+
def write_key_to_file(path)
|
104
|
+
File.open(path, 'w') { |f| f.write(@key_raw) }
|
105
|
+
end
|
100
106
|
end
|
101
107
|
end
|
102
108
|
end
|
metadata
CHANGED
@@ -1,37 +1,37 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fastlane
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.180.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
8
|
-
- Max Ott
|
9
|
-
- Joshua Liebowitz
|
10
|
-
- Jérôme Lacoste
|
11
|
-
- Manu Wallner
|
12
|
-
- Stefan Natchev
|
13
|
-
- Andrew McBurney
|
7
|
+
- Jimmy Dee
|
14
8
|
- Roger Oba
|
15
9
|
- Daniel Jankowski
|
16
10
|
- Satoshi Namai
|
17
|
-
-
|
18
|
-
-
|
19
|
-
-
|
20
|
-
- Fumiya Nakamura
|
21
|
-
- Josh Holtz
|
22
|
-
- Helmut Januschka
|
11
|
+
- Joshua Liebowitz
|
12
|
+
- Max Ott
|
13
|
+
- Manu Wallner
|
23
14
|
- Felix Krause
|
24
|
-
-
|
15
|
+
- Fumiya Nakamura
|
25
16
|
- Aaron Brager
|
26
17
|
- Maksym Grebenets
|
27
18
|
- Jorge Revuelta H
|
19
|
+
- Helmut Januschka
|
20
|
+
- Olivier Halligon
|
21
|
+
- Iulian Onofrei
|
22
|
+
- Stefan Natchev
|
23
|
+
- Andrew McBurney
|
24
|
+
- Josh Holtz
|
28
25
|
- Danielle Tomlinson
|
26
|
+
- Kohki Miki
|
27
|
+
- Jan Piotrowski
|
28
|
+
- Jérôme Lacoste
|
29
|
+
- Luka Mirosevic
|
29
30
|
- Matthew Ellis
|
30
|
-
- Olivier Halligon
|
31
31
|
autorequire:
|
32
32
|
bindir: bin
|
33
33
|
cert_chain: []
|
34
|
-
date: 2021-
|
34
|
+
date: 2021-04-08 00:00:00.000000000 Z
|
35
35
|
dependencies:
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: slack-notifier
|
@@ -1210,6 +1210,7 @@ files:
|
|
1210
1210
|
- fastlane/lib/fastlane/actions/slather.rb
|
1211
1211
|
- fastlane/lib/fastlane/actions/snapshot.rb
|
1212
1212
|
- fastlane/lib/fastlane/actions/sonar.rb
|
1213
|
+
- fastlane/lib/fastlane/actions/sourcedocs.rb
|
1213
1214
|
- fastlane/lib/fastlane/actions/spaceship_logs.rb
|
1214
1215
|
- fastlane/lib/fastlane/actions/spaceship_stats.rb
|
1215
1216
|
- fastlane/lib/fastlane/actions/splunkmint.rb
|
@@ -1468,7 +1469,6 @@ files:
|
|
1468
1469
|
- gym/lib/assets/GymfileTemplate.swift
|
1469
1470
|
- gym/lib/assets/wrap_xcodebuild/xcbuild-safe.sh
|
1470
1471
|
- gym/lib/gym.rb
|
1471
|
-
- gym/lib/gym/.runner.rb.swp
|
1472
1472
|
- gym/lib/gym/code_signing_mapping.rb
|
1473
1473
|
- gym/lib/gym/commands_generator.rb
|
1474
1474
|
- gym/lib/gym/detect_values.rb
|