fastlane 2.133.0 → 2.136.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +78 -78
  3. data/fastlane/lib/fastlane/action.rb +1 -1
  4. data/fastlane/lib/fastlane/actions/actions_helper.rb +1 -1
  5. data/fastlane/lib/fastlane/actions/carthage.rb +7 -0
  6. data/fastlane/lib/fastlane/actions/cocoapods.rb +24 -2
  7. data/fastlane/lib/fastlane/actions/deploygate.rb +1 -1
  8. data/fastlane/lib/fastlane/actions/docs/capture_android_screenshots.md +38 -4
  9. data/fastlane/lib/fastlane/actions/docs/capture_ios_screenshots.md +1 -1
  10. data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +4 -2
  11. data/fastlane/lib/fastlane/actions/docs/upload_to_play_store.md +26 -2
  12. data/fastlane/lib/fastlane/actions/download_dsyms.rb +26 -3
  13. data/fastlane/lib/fastlane/actions/download_from_play_store.rb +1 -1
  14. data/fastlane/lib/fastlane/actions/get_version_number.rb +10 -4
  15. data/fastlane/lib/fastlane/actions/google_play_track_version_codes.rb +5 -1
  16. data/fastlane/lib/fastlane/actions/sonar.rb +16 -0
  17. data/fastlane/lib/fastlane/actions/testfairy.rb +1 -1
  18. data/fastlane/lib/fastlane/actions/update_fastlane.rb +9 -49
  19. data/fastlane/lib/fastlane/actions/update_keychain_access_groups.rb +94 -0
  20. data/fastlane/lib/fastlane/environment_printer.rb +9 -3
  21. data/fastlane/lib/fastlane/fast_file.rb +3 -2
  22. data/fastlane/lib/fastlane/lane_manager.rb +1 -1
  23. data/fastlane/lib/fastlane/plugins/plugin_manager.rb +12 -2
  24. data/fastlane/lib/fastlane/plugins/template/.rubocop.yml +2 -0
  25. data/fastlane/lib/fastlane/runner.rb +2 -2
  26. data/fastlane/lib/fastlane/swift_fastlane_function.rb +9 -0
  27. data/fastlane/lib/fastlane/version.rb +1 -1
  28. data/fastlane/swift/Deliverfile.swift +1 -1
  29. data/fastlane/swift/Fastlane.swift +124 -36
  30. data/fastlane/swift/Gymfile.swift +1 -1
  31. data/fastlane/swift/Matchfile.swift +1 -1
  32. data/fastlane/swift/MatchfileProtocol.swift +2 -2
  33. data/fastlane/swift/Precheckfile.swift +1 -1
  34. data/fastlane/swift/Scanfile.swift +1 -1
  35. data/fastlane/swift/Screengrabfile.swift +1 -1
  36. data/fastlane/swift/ScreengrabfileProtocol.swift +22 -2
  37. data/fastlane/swift/Snapshotfile.swift +1 -1
  38. data/fastlane_core/lib/fastlane_core/configuration/commander_generator.rb +3 -3
  39. data/fastlane_core/lib/fastlane_core/configuration/configuration.rb +1 -1
  40. data/fastlane_core/lib/fastlane_core/device_manager.rb +1 -1
  41. data/fastlane_core/lib/fastlane_core/swag.rb +1 -1
  42. data/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb +1 -1
  43. data/match/lib/match/importer.rb +1 -1
  44. data/scan/lib/scan/error_handler.rb +9 -4
  45. data/scan/lib/scan/runner.rb +1 -1
  46. data/screengrab/lib/screengrab/module.rb +2 -0
  47. data/screengrab/lib/screengrab/options.rb +33 -11
  48. data/screengrab/lib/screengrab/runner.rb +64 -24
  49. data/sigh/lib/assets/resign.sh +2 -2
  50. data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher.rb +1 -1
  51. data/spaceship/lib/spaceship/client.rb +2 -2
  52. data/supply/lib/supply.rb +23 -0
  53. data/supply/lib/supply/.uploader.rb.swp +0 -0
  54. data/supply/lib/supply/client.rb +101 -55
  55. data/supply/lib/supply/options.rb +50 -14
  56. data/supply/lib/supply/release_listing.rb +18 -0
  57. data/supply/lib/supply/setup.rb +42 -34
  58. data/supply/lib/supply/uploader.rb +191 -93
  59. metadata +32 -37
  60. data/fastlane/lib/fastlane/actions/.hockey.rb.swp +0 -0
  61. data/fastlane/lib/fastlane/actions/.slack.rb.swp +0 -0
  62. data/fastlane/lib/fastlane/actions/.update_project_provisioning.rb.swp +0 -0
  63. data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.xcworkspace/xcuserdata/josh.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  64. data/gym/lib/gym/.runner.rb.swp +0 -0
  65. data/pilot/lib/pilot/.manager.rb.swp +0 -0
  66. data/spaceship/lib/spaceship/connect_api/.DS_Store +0 -0
  67. data/spaceship/lib/spaceship/portal/.certificate.rb.swp +0 -0
@@ -26,6 +26,7 @@ module Fastlane
26
26
  platform = params[:platform]
27
27
  output_directory = params[:output_directory]
28
28
  wait_for_dsym_processing = params[:wait_for_dsym_processing]
29
+ wait_timeout = params[:wait_timeout]
29
30
  min_version = Gem::Version.new(params[:min_version]) if params[:min_version]
30
31
 
31
32
  # Set version if it is latest
@@ -45,6 +46,20 @@ module Fastlane
45
46
  version = latest_candidate_build.train_version
46
47
  build_number = latest_candidate_build.build_version
47
48
  end
49
+ elsif version == 'live'
50
+ UI.message("Looking for live version...")
51
+ live_version = app.live_version(platform: platform)
52
+
53
+ UI.user_error!("Could not find live version for your app, please try setting 'latest' or a specific version") if live_version.nil?
54
+
55
+ # No need to search for candidates, because released App Store version should only have one build
56
+ version = live_version.version
57
+ build_number = live_version.build_version
58
+ end
59
+
60
+ # Remove leading zeros from version string (eg. 1.02 -> 1.2)
61
+ if version
62
+ version = version.split(".").map(&:to_i).join(".")
48
63
  end
49
64
 
50
65
  # Make sure output_directory has a slash on the end
@@ -101,7 +116,7 @@ module Fastlane
101
116
  end
102
117
 
103
118
  unless download_url
104
- if !wait_for_dsym_processing || (Time.now - start) > (60 * 5)
119
+ if !wait_for_dsym_processing || (Time.now - start) > wait_timeout
105
120
  # In some cases, AppStoreConnect does not process the dSYMs, thus no error should be thrown.
106
121
  UI.message("Could not find any dSYM for #{build.build_version} (#{train.version_string})")
107
122
  else
@@ -231,7 +246,7 @@ module Fastlane
231
246
  FastlaneCore::ConfigItem.new(key: :version,
232
247
  short_option: "-v",
233
248
  env_name: "DOWNLOAD_DSYMS_VERSION",
234
- description: "The app version for dSYMs you wish to download, pass in 'latest' to download only the latest build's dSYMs",
249
+ description: "The app version for dSYMs you wish to download, pass in 'latest' to download only the latest build's dSYMs or 'live' to download only the live version dSYMs",
235
250
  optional: true),
236
251
  FastlaneCore::ConfigItem.new(key: :build_number,
237
252
  short_option: "-b",
@@ -254,7 +269,14 @@ module Fastlane
254
269
  description: "Wait for dSYMs to process",
255
270
  optional: true,
256
271
  default_value: false,
257
- type: Boolean)
272
+ type: Boolean),
273
+ FastlaneCore::ConfigItem.new(key: :wait_timeout,
274
+ short_option: "-t",
275
+ env_name: "DOWNLOAD_DSYMS_WAIT_TIMEOUT",
276
+ description: "Number of seconds to wait for dSYMs to process",
277
+ optional: true,
278
+ default_value: 300,
279
+ type: Integer)
258
280
  ]
259
281
  end
260
282
 
@@ -280,6 +302,7 @@ module Fastlane
280
302
  [
281
303
  'download_dsyms',
282
304
  'download_dsyms(version: "1.0.0", build_number: "345")',
305
+ 'download_dsyms(version: "live")',
283
306
  'download_dsyms(min_version: "1.2.3")'
284
307
  ]
285
308
  end
@@ -29,7 +29,7 @@ module Fastlane
29
29
  options = Supply::Options.available_options.clone
30
30
 
31
31
  # remove all the unnecessary (for this action) options
32
- options_to_keep = [:package_name, :metadata_path, :json_key, :json_key_data, :root_url, :timeout, :key, :issuer]
32
+ options_to_keep = [:package_name, :version_name, :track, :metadata_path, :json_key, :json_key_data, :root_url, :timeout, :key, :issuer]
33
33
  options.delete_if { |option| options_to_keep.include?(option.key) == false }
34
34
  end
35
35
 
@@ -18,12 +18,18 @@ module Fastlane
18
18
  plist_file = get_plist!(folder, target, configuration)
19
19
  version_number = get_version_number_from_plist!(plist_file)
20
20
 
21
- # Get from build settings if needed (ex: $(MARKETING_VERSION) is default in Xcode 11)
21
+ # Get from build settings (or project settings) if needed (ex: $(MARKETING_VERSION) is default in Xcode 11)
22
22
  if version_number =~ /\$\(([\w\-]+)\)/
23
- version_number = get_version_number_from_build_settings!(target, $1, configuration)
23
+ version_number = get_version_number_from_build_settings!(target, $1, configuration) || get_version_number_from_build_settings!(project, $1, configuration)
24
+
24
25
  # ${MARKETING_VERSION} also works
25
26
  elsif version_number =~ /\$\{([\w\-]+)\}/
26
- version_number = get_version_number_from_build_settings!(target, $1, configuration)
27
+ version_number = get_version_number_from_build_settings!(target, $1, configuration) || get_version_number_from_build_settings!(project, $1, configuration)
28
+ end
29
+
30
+ # Error out if version_number is not set
31
+ if version_number.nil?
32
+ UI.user_error!("Unable to find Xcode build setting: #{$1}")
27
33
  end
28
34
 
29
35
  # Store the number in the shared hash
@@ -81,7 +87,7 @@ module Fastlane
81
87
  end
82
88
  end
83
89
 
84
- UI.user_error!("Unable to find Xcode build setting: #{variable}")
90
+ return nil
85
91
  end
86
92
 
87
93
  def self.get_plist!(folder, target, configuration = nil)
@@ -20,7 +20,11 @@ module Fastlane
20
20
 
21
21
  Supply.config = params
22
22
 
23
- Supply::Reader.new.track_version_codes
23
+ # AndroidpublisherV3 returns version codes as array of strings
24
+ # even though version codes need to be integers
25
+ # https://github.com/fastlane/fastlane/issues/15622
26
+ version_codes = Supply::Reader.new.track_version_codes || []
27
+ return version_codes.compact.map(&:to_i)
24
28
  end
25
29
 
26
30
  #####################################################
@@ -20,10 +20,12 @@ module Fastlane
20
20
  sonar_scanner_args << "-Dsonar.sourceEncoding=\"#{params[:source_encoding]}\"" if params[:source_encoding]
21
21
  sonar_scanner_args << "-Dsonar.login=\"#{params[:sonar_login]}\"" if params[:sonar_login]
22
22
  sonar_scanner_args << "-Dsonar.host.url=\"#{params[:sonar_url]}\"" if params[:sonar_url]
23
+ sonar_scanner_args << "-Dsonar.organization=\"#{params[:sonar_organization]}\"" if params[:sonar_organization]
23
24
  sonar_scanner_args << "-Dsonar.branch.name=\"#{params[:branch_name]}\"" if params[:branch_name]
24
25
  sonar_scanner_args << "-Dsonar.pullrequest.branch=\"#{params[:pull_request_branch]}\"" if params[:pull_request_branch]
25
26
  sonar_scanner_args << "-Dsonar.pullrequest.base=\"#{params[:pull_request_base]}\"" if params[:pull_request_base]
26
27
  sonar_scanner_args << "-Dsonar.pullrequest.key=\"#{params[:pull_request_key]}\"" if params[:pull_request_key]
28
+
27
29
  sonar_scanner_args << params[:sonar_runner_args] if params[:sonar_runner_args]
28
30
 
29
31
  command = [
@@ -102,6 +104,11 @@ module Fastlane
102
104
  description: "Pass the url of the Sonar server",
103
105
  optional: true,
104
106
  is_string: true),
107
+ FastlaneCore::ConfigItem.new(key: :sonar_organization,
108
+ env_name: "FL_SONAR_ORGANIZATION",
109
+ description: "Key of the organization on SonarCloud",
110
+ optional: true,
111
+ is_string: true),
105
112
  FastlaneCore::ConfigItem.new(key: :branch_name,
106
113
  env_name: "FL_SONAR_RUNNER_BRANCH_NAME",
107
114
  description: "Pass the branch name which is getting scanned",
@@ -144,6 +151,15 @@ module Fastlane
144
151
  project_version: "1.0",
145
152
  project_name: "iOS - AwesomeApp",
146
153
  sources_path: File.expand_path("../AwesomeApp")
154
+ )',
155
+ 'sonar(
156
+ project_key: "name.gretzki.awesomeApp",
157
+ project_version: "1.0",
158
+ project_name: "iOS - AwesomeApp",
159
+ sources_path: File.expand_path("../AwesomeApp"),
160
+ sonar_organization: "myOrg",
161
+ sonar_login: "123456abcdef",
162
+ sonar_url: "https://sonarcloud.io"
147
163
  )'
148
164
  ]
149
165
  end
@@ -33,7 +33,7 @@ module Fastlane
33
33
  req.url("/api/upload/")
34
34
  req.body = options
35
35
  end
36
- rescue Faraday::Error::TimeoutError
36
+ rescue Faraday::TimeoutError
37
37
  UI.crash!("Uploading build to TestFairy timed out ⏳")
38
38
  end
39
39
  end
@@ -10,18 +10,10 @@ module Fastlane
10
10
  def self.run(options)
11
11
  return if options[:no_update] # this is used to update itself
12
12
 
13
- tools_to_update = options[:tools].split(',') unless options[:tools].nil?
14
- tools_to_update ||= all_installed_tools
15
-
16
- if tools_to_update.count == 0
17
- UI.error("No tools specified or couldn't find any installed fastlane.tools")
18
- return
19
- end
20
-
13
+ tools_to_update = ALL_TOOLS
21
14
  UI.message("Looking for updates for #{tools_to_update.join(', ')}...")
22
15
 
23
16
  updater = Gem::CommandManager.instance[:update]
24
- updater.options[:prerelease] = true if options[:nightly]
25
17
  cleaner = Gem::CommandManager.instance[:cleanup]
26
18
 
27
19
  gem_dir = ENV['GEM_HOME'] || Gem.dir
@@ -49,7 +41,6 @@ module Fastlane
49
41
 
50
42
  if update_needed.count == 0
51
43
  UI.success("Nothing to update ✅")
52
- show_information_about_nightly_builds unless options[:nightly]
53
44
  return
54
45
  end
55
46
 
@@ -58,18 +49,13 @@ module Fastlane
58
49
 
59
50
  update_needed.each do |tool_info|
60
51
  tool = tool_info[0]
61
- gem_version = tool_info[1]
62
52
  local_version = Gem::Version.new(highest_versions[tool].version)
63
53
  latest_official_version = FastlaneCore::UpdateChecker.fetch_latest(tool)
64
54
 
65
- if options[:nightly]
66
- UI.message("Updating #{tool} from #{local_version.to_s.yellow} to nightly build #{gem_version.to_s.yellow}... (last official release #{latest_official_version.to_s.yellow}) 🚀")
67
- else
68
- UI.message("Updating #{tool} from #{local_version.to_s.yellow} to #{latest_official_version.to_s.yellow}... 🚀")
69
- end
55
+ UI.message("Updating #{tool} from #{local_version.to_s.yellow} to #{latest_official_version.to_s.yellow}... 🚀")
70
56
 
71
57
  # Approximate_recommendation will create a string like "~> 0.10" from a version 0.10.0, e.g. one that is valid for versions >= 0.10 and <1.0
72
- requirement_version = options[:nightly] ? gem_version : local_version.approximate_recommendation
58
+ requirement_version = local_version.approximate_recommendation
73
59
  updater.update_gem(tool, Gem::Requirement.new(requirement_version))
74
60
 
75
61
  UI.success("Finished updating #{tool}")
@@ -79,34 +65,12 @@ module Fastlane
79
65
  cleaner.options[:args] = tools_to_update
80
66
  cleaner.execute
81
67
 
82
- if options[:nightly]
83
- UI.success("Thanks for using fastlane's nightly builds! This makes it easier for everyone to detect regressions earlier.")
84
- UI.success("Please submit an issue on GitHub if anything behaves differently than it should 🍪")
85
- else
86
- show_information_about_nightly_builds
87
- end
88
-
89
68
  UI.message("fastlane.tools successfully updated! I will now restart myself... 😴")
90
69
 
91
70
  # Set no_update to true so we don't try to update again
92
71
  exec("FL_NO_UPDATE=true #{$PROGRAM_NAME} #{ARGV.join(' ')}")
93
72
  end
94
73
 
95
- def self.show_information_about_nightly_builds
96
- UI.message("")
97
- UI.message("Please help us test early releases of fastlane by opting into nightly builds 🌃")
98
- UI.message("Just replace your `update_fastlane` call with")
99
- UI.message("")
100
- UI.command_output("update_fastlane(nightly: true)")
101
- UI.message("")
102
- UI.message("Nightly builds are reviewed and tested just like the public releases 🚂")
103
- UI.message("")
104
- end
105
-
106
- def self.all_installed_tools
107
- Gem::Specification.select { |s| ALL_TOOLS.include?(s.name) }.map(&:name).uniq
108
- end
109
-
110
74
  def self.description
111
75
  "Makes sure fastlane-tools are up-to-date when running fastlane"
112
76
  end
@@ -134,21 +98,17 @@ module Fastlane
134
98
 
135
99
  def self.available_options
136
100
  [
137
- FastlaneCore::ConfigItem.new(key: :nightly,
138
- env_name: "FL_UPDATE_FASTLANE_NIGHTLY",
139
- description: "Opt-in to install and use nightly fastlane builds",
140
- is_string: false,
141
- default_value: false),
142
101
  FastlaneCore::ConfigItem.new(key: :no_update,
143
102
  env_name: "FL_NO_UPDATE",
144
103
  description: "Don't update during this run. This is used internally",
145
104
  is_string: false,
146
105
  default_value: false),
147
- FastlaneCore::ConfigItem.new(key: :tools,
148
- env_name: "FL_TOOLS_TO_UPDATE",
149
- description: "Comma separated list of fastlane tools to update (e.g. `fastlane,deliver,sigh`)",
150
- deprecated: true,
151
- optional: true)
106
+ FastlaneCore::ConfigItem.new(key: :nightly,
107
+ env_name: "FL_UPDATE_FASTLANE_NIGHTLY",
108
+ description: "Opt-in to install and use nightly fastlane builds",
109
+ is_string: false,
110
+ default_value: false,
111
+ deprecated: "Nightly builds are no longer being made available")
152
112
  ]
153
113
  end
154
114
 
@@ -0,0 +1,94 @@
1
+ module Fastlane
2
+ module Actions
3
+ module SharedValues
4
+ KEYCHAIN_ACCESS_GROUPS = :KEYCHAIN_ACCESS_GROUPS
5
+ end
6
+
7
+ class UpdateKeychainAccessGroupsAction < Action
8
+ require 'plist'
9
+
10
+ def self.run(params)
11
+ UI.message("Entitlements File: #{params[:entitlements_file]}")
12
+ UI.message("New keychain access groups: #{params[:identifiers]}")
13
+
14
+ entitlements_file = params[:entitlements_file]
15
+ UI.user_error!("Could not find entitlements file at path '#{entitlements_file}'") unless File.exist?(entitlements_file)
16
+
17
+ # parse entitlements
18
+ result = Plist.parse_xml(entitlements_file)
19
+ UI.user_error!("Entitlements file at '#{entitlements_file}' cannot be parsed.") unless result
20
+
21
+ # keychain access groups key
22
+ keychain_access_groups_key = 'keychain-access-groups'
23
+
24
+ # get keychain access groups
25
+ keychain_access_groups_field = result[keychain_access_groups_key]
26
+ UI.user_error!("No existing keychain access groups field specified. Please specify an keychain access groups in the entitlements file.") unless keychain_access_groups_field
27
+
28
+ # set new keychain access groups
29
+ UI.message("Old keychain access groups: #{keychain_access_groups_field}")
30
+ result[keychain_access_groups_key] = params[:identifiers]
31
+
32
+ # save entitlements file
33
+ result.save_plist(entitlements_file)
34
+ UI.message("New keychain access groups: #{result[keychain_access_groups_key]}")
35
+
36
+ Actions.lane_context[SharedValues::KEYCHAIN_ACCESS_GROUPS] = result[keychain_access_groups_key]
37
+ end
38
+
39
+ def self.description
40
+ "This action changes the keychain access groups in the entitlements file"
41
+ end
42
+
43
+ def self.details
44
+ "Updates the Keychain Group Access Groups in the given Entitlements file, so you can have keychain access groups for the app store build and keychain access groups for an enterprise build."
45
+ end
46
+
47
+ def self.available_options
48
+ [
49
+ FastlaneCore::ConfigItem.new(key: :entitlements_file,
50
+ env_name: "FL_UPDATE_KEYCHAIN_ACCESS_GROUPS_ENTITLEMENTS_FILE_PATH", # The name of the environment variable
51
+ description: "The path to the entitlement file which contains the keychain access groups", # a short description of this parameter
52
+ verify_block: proc do |value|
53
+ UI.user_error!("Please pass a path to an entitlements file. ") unless value.include?(".entitlements")
54
+ UI.user_error!("Could not find entitlements file") if !File.exist?(value) && !Helper.test?
55
+ end),
56
+ FastlaneCore::ConfigItem.new(key: :identifiers,
57
+ env_name: "FL_UPDATE_KEYCHAIN_ACCESS_GROUPS_IDENTIFIERS",
58
+ description: "An Array of unique identifiers for the keychain access groups. Eg. ['your.keychain.access.groups.identifiers']",
59
+ is_string: false,
60
+ verify_block: proc do |value|
61
+ UI.user_error!("The parameter identifiers need to be an Array.") unless value.kind_of?(Array)
62
+ end)
63
+ ]
64
+ end
65
+
66
+ def self.output
67
+ [
68
+ ['KEYCHAIN_ACCESS_GROUPS', 'The new Keychain Access Groups']
69
+ ]
70
+ end
71
+
72
+ def self.authors
73
+ ["yutae"]
74
+ end
75
+
76
+ def self.is_supported?(platform)
77
+ platform == :ios
78
+ end
79
+
80
+ def self.example_code
81
+ [
82
+ 'update_keychain_access_groups(
83
+ entitlements_file: "/path/to/entitlements_file.entitlements",
84
+ identifiers: ["your.keychain.access.groups.identifiers"]
85
+ )'
86
+ ]
87
+ end
88
+
89
+ def self.category
90
+ :project
91
+ end
92
+ end
93
+ end
94
+ end
@@ -50,11 +50,11 @@ module Fastlane
50
50
  end
51
51
 
52
52
  def self.print_loaded_plugins
53
- ENV["FASTLANE_ENV_PRINTER"] = "enabled"
54
53
  env_output = "### Loaded fastlane plugins:\n"
55
54
  env_output << "\n"
56
55
  plugin_manager = Fastlane::PluginManager.new
57
- plugin_manager.load_plugins
56
+ plugin_manager.load_plugins(print_table: false)
57
+
58
58
  if plugin_manager.available_plugins.length <= 0
59
59
  env_output << "**No plugins Loaded**\n"
60
60
  else
@@ -211,7 +211,7 @@ module Fastlane
211
211
  "OS" => os_version,
212
212
  "Ruby" => RUBY_VERSION,
213
213
  "Bundler?" => Helper.bundler?,
214
- "Git" => `git --version`.strip.split("\n").first,
214
+ "Git" => git_version,
215
215
  "Installation Source" => anonymized_path($PROGRAM_NAME),
216
216
  "Host" => "#{product} #{version} (#{build})",
217
217
  "Ruby Lib Dir" => anonymized_path(RbConfig::CONFIG['libdir']),
@@ -293,5 +293,11 @@ module Fastlane
293
293
  require 'open3'
294
294
  Open3.popen3('pbcopy') { |input, _, _| input << string }
295
295
  end
296
+
297
+ def self.git_version
298
+ return `git --version`.strip.split("\n").first
299
+ rescue
300
+ return "not found"
301
+ end
296
302
  end
297
303
  end
@@ -195,6 +195,7 @@ module Fastlane
195
195
  # sh("ls")
196
196
  # sh("ls", log: false)
197
197
  # sh(command: "ls")
198
+ # sh(command: "ls", step_name: "listing the files")
198
199
  # sh(command: "ls", log: false)
199
200
  def sh(*args, &b)
200
201
  # First accepts hash (or named keywords) like other actions
@@ -212,8 +213,8 @@ module Fastlane
212
213
  end
213
214
  end
214
215
 
215
- def self.sh(*command, log: true, error_callback: nil, &b)
216
- command_header = log ? Actions.shell_command_from_args(*command) : "shell command"
216
+ def self.sh(*command, step_name: nil, log: true, error_callback: nil, &b)
217
+ command_header = log ? step_name || Actions.shell_command_from_args(*command) : "shell command"
217
218
  Actions.execute_action(command_header) do
218
219
  Actions.sh_no_action(*command, log: log, error_callback: error_callback, &b)
219
220
  end
@@ -113,7 +113,7 @@ module Fastlane
113
113
  rows: FastlaneCore::PrintTable.transform_output(rows)
114
114
  )
115
115
 
116
- UI.message("Welcome to fastlane! Here's what your app is setup to do:")
116
+ UI.message("Welcome to fastlane! Here's what your app is set up to do:")
117
117
 
118
118
  puts(table)
119
119
 
@@ -278,7 +278,7 @@ module Fastlane
278
278
  # fastlane-plugin-[plugin_name]
279
279
  # This will make sure to load the action
280
280
  # and all its helpers
281
- def load_plugins
281
+ def load_plugins(print_table: true)
282
282
  UI.verbose("Checking if there are any plugins that should be loaded...")
283
283
 
284
284
  loaded_plugins = false
@@ -311,7 +311,7 @@ module Fastlane
311
311
  UI.error("Please follow the troubleshooting guide: #{TROUBLESHOOTING_URL}")
312
312
  end
313
313
 
314
- skip_print_plugin_info = self.plugin_references.empty? || CLIToolsDistributor.running_version_command? || FastlaneCore::Env.truthy?("FASTLANE_ENV_PRINTER")
314
+ skip_print_plugin_info = self.plugin_references.empty? || CLIToolsDistributor.running_version_command? || !print_table
315
315
 
316
316
  # We want to avoid printing output other than the version number if we are running `fastlane -v`
317
317
  print_plugin_information(self.plugin_references) unless skip_print_plugin_info
@@ -319,9 +319,12 @@ module Fastlane
319
319
 
320
320
  # Prints a table all the plugins that were loaded
321
321
  def print_plugin_information(references)
322
+ no_action_found = false
323
+
322
324
  rows = references.collect do |current|
323
325
  if current[1][:actions].empty?
324
326
  # Something is wrong with this plugin, no available actions
327
+ no_action_found = true
325
328
  [current[0].red, current[1][:version_number], "No actions found".red]
326
329
  else
327
330
  [current[0], current[1][:version_number], current[1][:actions].join("\n")]
@@ -335,6 +338,13 @@ module Fastlane
335
338
  headings: ["Plugin", "Version", "Action"]
336
339
  }))
337
340
  puts("")
341
+
342
+ if no_action_found
343
+ puts("[!] No actions were found while loading one or more plugins".red)
344
+ puts(" Please use `bundle exec fastlane` with plugins".red)
345
+ puts(" More info - https://docs.fastlane.tools/plugins/using-plugins/#run-with-plugins".red)
346
+ puts("")
347
+ end
338
348
  end
339
349
 
340
350
  #####################################################