-
Notifications
You must be signed in to change notification settings - Fork 5.9k
[Fastlane.swift] fix issue where failing lanes would exit with a success exit code #20552
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
Any updates to this? I'd love to be able to exit(1) from fastlane when it fails (or even manually) to offload some shell scripts to more powerful and easier to work with lanes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kalinjul thanks for this PR!
Could provide steps to reproduce the issue ("how to test"), this would help us significantly!
@rogerluan please find attached a small example Swift Package to reproduce the described issue:
// swift-tools-version: 5.9
import PackageDescription
let package = Package(
name: "FastlaneSwift",
platforms: [
.macOS(.v10_13)
],
products: [
.executable(
name: "FastlaneSwift",
targets: ["FastlaneSwift"]
)
],
dependencies: [
.package(
url: "https://github.com/fastlane/fastlane",
from: "2.219.0"
)
],
targets: [
.executableTarget(
name: "FastlaneSwift",
dependencies: [
.product(
name: "Fastlane",
package: "fastlane"
)
],
path: "Sources"
)
]
)
import Foundation
import Fastlane
@main
class Fastfile: Fastlane.LaneFile {
static func main() {
Fastlane.Main().run(with: Fastfile())
}
func exampleLane() {
// Execute a non existing command to trigger a fastlane error
Fastlane.sh(command: "Non_Existing_Command_Which_Should_Cause_a_Failure")
}
} Run example lane via: $ swift run FastlaneSwift lane example The command exits with a zero success code although the execution of the lane failed. $ swift run FastlaneSwift lane example
[...]
error encountered while executing command:
serverError
Encountered a problem: No such file or directory - Non_Existing_Command_Which_Should_Cause_a_Failure
Errno::ENOENT:
[...]
$ echo $?
0 |
1748c63
to
0884689
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Run example lane via:
$ swift run FastlaneSwift lane example
According to https://docs.fastlane.tools/getting-started/ios/fastlane-swift/, it looks like you're supposed to run it like:
fastlane example
instead.
From my tests, the latest version of fastlane correctly exits with code 1
, with a nice and clean output, while these changes actually causes another crash that hides the original one:
[19:31:06]: ▸ FastlaneRunner/LaneFileProtocol.swift:155: Fatal error: Aborting run due to lane failure
[19:31:06]: ▸ sh: line 1: 78180 Trace/BPT trap: 5 ./fastlane/FastlaneRunner lane testCrash swiftServerPort 2000 > /dev/null
#<Thread:0x0000000104edc600 /Users/revolt/Development/GitHub/fastlane/fastlane/fastlane/lib/fastlane/swift_lane_manager.rb:98 run> terminated with exception (report_on_exception is true):
/Users/revolt/Development/GitHub/fastlane/fastlane/fastlane_core/lib/fastlane_core/ui/interface.rb:153:in `shell_error!': Exit status of command './fastlane/FastlaneRunner lane testCrash swiftServerPort 2000 > /dev/null' was 133 instead of 0. (FastlaneCore::Interface::FastlaneShellError)
FastlaneRunner/LaneFileProtocol.swift:155: Fatal error: Aborting run due to lane failure
sh: line 1: 78180 Trace/BPT trap: 5 ./fastlane/FastlaneRunner lane testCrash swiftServerPort 2000 > /dev/null
from /Users/revolt/Development/GitHub/fastlane/fastlane/fastlane_core/lib/fastlane_core/ui/ui.rb:17:in `method_missing'
from /Users/revolt/Development/GitHub/fastlane/fastlane/fastlane/lib/fastlane/helper/sh_helper.rb:80:in `sh_control_output'
from /Users/revolt/Development/GitHub/fastlane/fastlane/fastlane/lib/fastlane/helper/sh_helper.rb:12:in `sh'
from /Users/revolt/Development/GitHub/fastlane/fastlane/fastlane/lib/fastlane/swift_lane_manager.rb:103:in `block in cruise_swift_lane_in_thread'
Please try using the documented command (or, if you're using Bundler, then use bundle exec fastlane example
instead), and let me know what happens.
@revolter I think this PR references the "Get Started (SPM) (Beta)" section which describes in Step 5 that you can build your Swift Package via The invocation via Since the PR #20563 is merged, this problem can be fixed by manually overriding the Of course this code shouldn't be mandatory as it would be better if Fastlane.Swift exits with the correct status code when executed via the Swift CLI ( import Foundation
import Fastlane
@main
class Fastfile: Fastlane.LaneFile {
static func main() {
Fastlane.Main().run(with: Fastfile())
}
func exampleLane() {
// Execute a non existing command to trigger a fastlane error
Fastlane.sh(command: "Non_Existing_Command_Which_Should_Cause_a_Failure")
}
open override func onError(
currentLane: String,
errorInfo: String,
errorClass: String?,
errorMessage: String?
) {
super.onError(
currentLane: currentLane,
errorInfo: errorInfo,
errorClass: errorClass,
errorMessage: errorMessage
)
Foundation.exit(Foundation.EXIT_FAILURE)
}
} |
Thanks for the clarification @SvenTiigi 🙏🏻 What I worry about is that these changes are not be backwards compatible. So merging this PR would make a handful of people happy, but potentially make many more people unhappy. I found these releases that had some sort of migration notes: https://github.com/fastlane/fastlane/releases/tag/1.30.0, https://github.com/fastlane/fastlane/releases/tag/2.4.0, https://github.com/fastlane/fastlane/releases/tag/2.188.0 (cc @joshdholtz). Since I never used Fastlane.swift, would someone more experienced be so kind to test:
|
I think one way to ensure that this PR does not introduce any kind of of backwards incompatibility or regression the required exit code should be wrapped in an This way the code to exit the program (Swift executable) with a bad status code in case of a failure only gets executed in the context of a Swift Package and not in the case of the Xcode Project (FastlaneSwiftRunner). // Call all methods that need to be called before we start calling lanes.
fastfileInstance.beforeAll(with: lane)
// We need to catch all possible errors here and display a nice message.
_ = fastfileInstance.perform(NSSelectorFromString(laneMethod), with: parameters)
#if SWIFT_PACKAGE
// Call only on error
if LaneFile.onErrorCalled.contains(lane) {
// TODO: Logging needed? `log(message "...")`
Foundation.exit(Foundation.EXIT_FAILURE)
}
#endif
// Call only on success.
if !LaneFile.onErrorCalled.contains(lane) {
fastfileInstance.afterAll(with: lane)
}
log(message: "Done running lane: \(lane) 🚀") |
Checklist
bundle exec rspec
from the root directory to see all new and existing tests passbundle exec rubocop -a
to ensure the code style is validci/circleci
builds in the "All checks have passed" section of my PR (connect CircleCI to GitHub if not)Motivation and Context
Fastlane Swift does not abort when lanes fail.
Resolves #20419
Resolves #20649
Description
This just adds a fatalError()