Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[action] add
xcodes
action, deprecating xcversion
and `xcode-inst…
…all` (#20672) * Move helpers to a separate and centralized file. * Deprecate 'xcode-install' gem (the project has been sunset), adding 'xcodes' action to replace the 'xcode_install' one. * Add 'select_only' option to 'xcodes', deprecating 'xcversion' action. * Update documentation to state it also supports .xcode-version file. * Add TODO for a future improvement. * Lint. * Fix link. * Remove TODO comment. * Lint. * Fix typo in error being raised. * Add ability to select Xcode just for current build, without sudo permissions. - Depends on XcodesOrg/xcodes#220 * Update documentation to point to 'xcodes' instead. * Update xcodes link. * Apply suggestions from code review. Co-authored-by: Iulian Onofrei <5748627+revolter@users.noreply.github.com> * Change "#" by "." in spec descriptions, to indicate class methods. * Apply suggestion from code review. * Improve documentation around requirements to run xcodes. * Remove necessity to authenticate with Apple servers since xcodes v1.0.0. * Use new --update and --selected arguments, which require xcodes v1.1.0. * Fix comparing Gem::Version with String error * Remove unused local variable * Split long lines * Fix lint issues * Address style comments. * Remove superfluous trailing slash This makes it consistent with the rest of the codebase. * Fix unsafe paths concatenation * Fix some WWDR certificates test failure This was caused by the fact that that test calls a method that uses `$?` (https://stackoverflow.com/a/6834572/865175), which, somehow, (I think) was executed right after a call to XcodesHelper's `find_xcodes_binary_path` method. This latter one returned a non-zero code, because `xcodes` can't be installed on Ubuntu, which got picked up by the certificates return code check, so it treated its actual command as failed. * Replace `Actions.sh` call with a native one (reverted from commit 11bd750) * Fix error-prone shell command status check In the case of the tests, `$?` was not mocked, so it looks like it was indeed just a coincidence that it worked. Meaning, some other shell command that somehow was actually executed (so it wasn't stubbed) succeeded, which caused the `$?.success?` to succeed too. Co-authored-by: Iulian Onofrei <5748627+revolter@users.noreply.github.com> Co-authored-by: Iulian Onofrei <iulian.onofrei@yahoo.com>
- Loading branch information
1 parent
7de28ca
commit 4b30089
Showing
14 changed files
with
399 additions
and
52 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
module Fastlane | ||
module Actions | ||
module SharedValues | ||
XCODES_XCODE_PATH = :XCODES_XCODE_PATH | ||
end | ||
|
||
class XcodesAction < Action | ||
def self.run(params) | ||
binary = params[:binary_path] | ||
xcodes_raw_version = Actions.sh("#{binary} version", log: false) | ||
xcodes_version = Gem::Version.new(xcodes_raw_version) | ||
UI.message("Running xcodes version #{xcodes_version}") | ||
if xcodes_version < Gem::Version.new("1.1.0") | ||
UI.user_error!([ | ||
"xcodes action requires the minimum version of xcodes binary to be v1.1.0.", | ||
"Please update xcodes. If you installed it via Homebrew, this can be done via 'brew upgrade xcodes'" | ||
].join(" ")) | ||
end | ||
|
||
version = params[:version] | ||
command = [] | ||
command << binary | ||
|
||
if (xcodes_args = params[:xcodes_args]) | ||
command << xcodes_args | ||
Actions.sh(command.join(" ")) | ||
elsif !params[:select_for_current_build_only] | ||
command << "install" | ||
command << "'#{version}'" | ||
command << "--update" if params[:update_list] | ||
command << "--select" | ||
Actions.sh(command.join(" ")) | ||
end | ||
|
||
command = [] | ||
command << binary | ||
command << "installed" | ||
command << "'#{version}'" | ||
# Prints something like /Applications/Xcode-14.app | ||
xcode_path = Actions.sh(command.join(" ")).strip | ||
xcode_developer_path = File.join(xcode_path, "/Contents/Developer") | ||
|
||
UI.message("Setting Xcode version '#{version}' at '#{xcode_path}' for all build steps") | ||
ENV["DEVELOPER_DIR"] = xcode_developer_path | ||
Actions.lane_context[SharedValues::XCODES_XCODE_PATH] = xcode_developer_path | ||
return xcode_path | ||
end | ||
|
||
##################################################### | ||
# @!group Documentation | ||
##################################################### | ||
|
||
def self.description | ||
"Make sure a certain version of Xcode is installed, installing it only if needed" | ||
end | ||
|
||
def self.details | ||
[ | ||
"Makes sure a specific version of Xcode is installed. If that's not the case, it will automatically be downloaded by [xcodes](https://github.com/RobotsAndPencils/xcodes).", | ||
"This will make sure to use the correct Xcode version for later actions.", | ||
"Note that this action depends on [xcodes](https://github.com/RobotsAndPencils/xcodes) CLI, so make sure you have it installed in your environment. For the installation guide, see: https://github.com/RobotsAndPencils/xcodes#installation" | ||
].join("\n") | ||
end | ||
|
||
def self.available_options | ||
[ | ||
FastlaneCore::ConfigItem.new(key: :version, | ||
env_name: "FL_XCODE_VERSION", | ||
description: "The version number of the version of Xcode to install. Defaults to the value specified in the .xcode-version file", | ||
default_value: Helper::XcodesHelper.read_xcode_version_file, | ||
default_value_dynamic: true, | ||
verify_block: Helper::XcodesHelper::Verify.method(:requirement)), | ||
FastlaneCore::ConfigItem.new(key: :update_list, | ||
env_name: "FL_XCODES_UPDATE_LIST", | ||
description: "Whether the list of available Xcode versions should be updated before running the install command", | ||
type: Boolean, | ||
default_value: true), | ||
FastlaneCore::ConfigItem.new(key: :select_for_current_build_only, | ||
env_name: "FL_XCODES_SELECT_FOR_CURRENT_BUILD_ONLY", | ||
description: [ | ||
"When true, it won't attempt to install an Xcode version, just find the installed Xcode version that best matches the passed version argument, and select it for the current build steps.", | ||
"It doesn't change the global Xcode version (e.g. via 'xcrun xcode-select'), which would require sudo permissions — when this option is true, this action doesn't require sudo permissions" | ||
].join(" "), | ||
type: Boolean, | ||
default_value: false), | ||
FastlaneCore::ConfigItem.new(key: :binary_path, | ||
env_name: "FL_XCODES_BINARY_PATH", | ||
description: "Where the xcodes binary lives on your system (full path)", | ||
default_value: Helper::XcodesHelper.find_xcodes_binary_path, | ||
default_value_dynamic: true, | ||
verify_block: proc do |value| | ||
UI.user_error!("'xcodes' doesn't seem to be installed. Please follow the installation guide at https://github.com/RobotsAndPencils/xcodes#installation before proceeding") if value.empty? | ||
UI.user_error!("Couldn't find xcodes binary at path '#{value}'") unless File.exist?(value) | ||
end), | ||
FastlaneCore::ConfigItem.new(key: :xcodes_args, | ||
env_name: "FL_XCODES_ARGS", | ||
description: "Pass in xcodes command line arguments directly. When present, other parameters are ignored and only this parameter is used to build the command to be executed", | ||
type: :shell_string, | ||
optional: true) | ||
] | ||
end | ||
|
||
def self.output | ||
[ | ||
['XCODES_XCODE_PATH', 'The path to the newly installed Xcode version'] | ||
] | ||
end | ||
|
||
def self.return_value | ||
"The path to the newly installed Xcode version" | ||
end | ||
|
||
def self.return_type | ||
:string | ||
end | ||
|
||
def self.authors | ||
["rogerluan"] | ||
end | ||
|
||
def self.is_supported?(platform) | ||
[:ios, :mac].include?(platform) | ||
end | ||
|
||
def self.example_code | ||
[ | ||
'xcodes(version: "14.1")', | ||
'xcodes # When missing, the version value defaults to the value specified in the .xcode-version file' | ||
] | ||
end | ||
|
||
def self.category | ||
:building | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
module Fastlane | ||
module Helper | ||
class XcodesHelper | ||
def self.read_xcode_version_file | ||
xcode_version_paths = Dir.glob(".xcode-version") | ||
|
||
if xcode_version_paths.first | ||
return File.read(xcode_version_paths.first).strip | ||
end | ||
|
||
return nil | ||
end | ||
|
||
def self.find_xcodes_binary_path | ||
`which xcodes`.strip | ||
end | ||
|
||
module Verify | ||
def self.requirement(req) | ||
UI.user_error!("Version must be specified") if req.nil? || req.to_s.strip.size == 0 | ||
Gem::Requirement.new(req.to_s) | ||
rescue Gem::Requirement::BadRequirementError | ||
UI.user_error!("The requirement '#{req}' is not a valid RubyGems style requirement") | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.