fastlane 2.178.0 → 2.182.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (148) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/README.md +97 -84
  4. data/cert/lib/cert/commands_generator.rb +2 -1
  5. data/cert/lib/cert/options.rb +1 -0
  6. data/cert/lib/cert/runner.rb +4 -0
  7. data/deliver/lib/deliver/commands_generator.rb +2 -1
  8. data/deliver/lib/deliver/download_screenshots.rb +1 -2
  9. data/deliver/lib/deliver/languages.rb +1 -1
  10. data/deliver/lib/deliver/options.rb +3 -2
  11. data/deliver/lib/deliver/runner.rb +4 -0
  12. data/deliver/lib/deliver/setup.rb +0 -1
  13. data/deliver/lib/deliver/upload_metadata.rb +2 -1
  14. data/fastlane/lib/fastlane/actions/actions_helper.rb +2 -2
  15. data/fastlane/lib/fastlane/actions/app_store_build_number.rb +5 -0
  16. data/fastlane/lib/fastlane/actions/app_store_connect_api_key.rb +3 -3
  17. data/fastlane/lib/fastlane/actions/backup_xcarchive.rb +1 -1
  18. data/fastlane/lib/fastlane/actions/build_app.rb +4 -0
  19. data/fastlane/lib/fastlane/actions/check_app_store_metadata.rb +4 -0
  20. data/fastlane/lib/fastlane/actions/clipboard.rb +3 -6
  21. data/fastlane/lib/fastlane/actions/docs/capture_ios_screenshots.md +1 -1
  22. data/fastlane/lib/fastlane/actions/docs/frame_screenshots.md +18 -1
  23. data/fastlane/lib/fastlane/actions/docs/upload_to_play_store.md +2 -1
  24. data/fastlane/lib/fastlane/actions/ensure_env_vars.rb +2 -6
  25. data/fastlane/lib/fastlane/actions/get_provisioning_profile.rb +4 -0
  26. data/fastlane/lib/fastlane/actions/get_version_number.rb +17 -10
  27. data/fastlane/lib/fastlane/actions/git_branch.rb +4 -10
  28. data/fastlane/lib/fastlane/actions/git_commit.rb +3 -1
  29. data/fastlane/lib/fastlane/actions/git_submodule_update.rb +16 -8
  30. data/fastlane/lib/fastlane/actions/git_tag_exists.rb +4 -0
  31. data/fastlane/lib/fastlane/actions/import_from_git.rb +5 -5
  32. data/fastlane/lib/fastlane/actions/install_provisioning_profile.rb +4 -0
  33. data/fastlane/lib/fastlane/actions/jira.rb +61 -14
  34. data/fastlane/lib/fastlane/actions/latest_testflight_build_number.rb +1 -0
  35. data/fastlane/lib/fastlane/actions/match_nuke.rb +59 -0
  36. data/fastlane/lib/fastlane/actions/notarize.rb +98 -51
  37. data/fastlane/lib/fastlane/actions/slack.rb +155 -133
  38. data/fastlane/lib/fastlane/actions/sourcedocs.rb +164 -0
  39. data/fastlane/lib/fastlane/actions/spaceship_logs.rb +1 -1
  40. data/fastlane/lib/fastlane/actions/update_project_provisioning.rb +1 -2
  41. data/fastlane/lib/fastlane/actions/upload_symbols_to_crashlytics.rb +4 -2
  42. data/fastlane/lib/fastlane/cli_tools_distributor.rb +1 -1
  43. data/fastlane/lib/fastlane/commands_generator.rb +2 -1
  44. data/fastlane/lib/fastlane/fast_file.rb +10 -2
  45. data/fastlane/lib/fastlane/fastlane_require.rb +7 -1
  46. data/fastlane/lib/fastlane/helper/git_helper.rb +19 -7
  47. data/fastlane/lib/fastlane/lane_manager.rb +3 -2
  48. data/fastlane/lib/fastlane/notification/slack.rb +56 -0
  49. data/fastlane/lib/fastlane/plugins/plugin_fetcher.rb +1 -2
  50. data/fastlane/lib/fastlane/plugins/plugin_info.rb +2 -2
  51. data/fastlane/lib/fastlane/plugins/plugin_info_collector.rb +1 -2
  52. data/fastlane/lib/fastlane/plugins/plugin_manager.rb +1 -2
  53. data/fastlane/lib/fastlane/plugins/template/%gem_name%.gemspec.erb +7 -6
  54. data/fastlane/lib/fastlane/plugins/template/.rubocop.yml +30 -35
  55. data/fastlane/lib/fastlane/plugins/template/spec/spec_helper.rb.erb +1 -1
  56. data/fastlane/lib/fastlane/setup/setup.rb +23 -10
  57. data/fastlane/lib/fastlane/swift_fastlane_function.rb +39 -14
  58. data/fastlane/lib/fastlane/swift_runner_upgrader.rb +2 -0
  59. data/fastlane/lib/fastlane/version.rb +2 -2
  60. data/fastlane/swift/Deliverfile.swift +1 -1
  61. data/fastlane/swift/DeliverfileProtocol.swift +3 -3
  62. data/fastlane/swift/Fastlane.swift +6852 -3824
  63. data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.pbxproj +4 -0
  64. data/fastlane/swift/Gymfile.swift +1 -1
  65. data/fastlane/swift/GymfileProtocol.swift +1 -1
  66. data/fastlane/swift/LaneFileProtocol.swift +9 -3
  67. data/fastlane/swift/Matchfile.swift +1 -1
  68. data/fastlane/swift/MatchfileProtocol.swift +1 -1
  69. data/fastlane/swift/OptionalConfigValue.swift +131 -0
  70. data/fastlane/swift/Precheckfile.swift +1 -1
  71. data/fastlane/swift/PrecheckfileProtocol.swift +3 -3
  72. data/fastlane/swift/RubyCommand.swift +1 -1
  73. data/fastlane/swift/Scanfile.swift +1 -1
  74. data/fastlane/swift/ScanfileProtocol.swift +5 -1
  75. data/fastlane/swift/Screengrabfile.swift +1 -1
  76. data/fastlane/swift/ScreengrabfileProtocol.swift +1 -1
  77. data/fastlane/swift/Snapshotfile.swift +1 -1
  78. data/fastlane/swift/SnapshotfileProtocol.swift +5 -1
  79. data/fastlane/swift/SocketClient.swift +2 -1
  80. data/fastlane/swift/SocketResponse.swift +4 -2
  81. data/fastlane/swift/formatting/Brewfile.lock.json +18 -16
  82. data/fastlane/swift/upgrade_manifest.json +1 -1
  83. data/fastlane_core/lib/fastlane_core.rb +22 -21
  84. data/fastlane_core/lib/fastlane_core/build_watcher.rb +50 -9
  85. data/fastlane_core/lib/fastlane_core/clipboard.rb +20 -0
  86. data/fastlane_core/lib/fastlane_core/configuration/configuration.rb +5 -3
  87. data/fastlane_core/lib/fastlane_core/helper.rb +28 -5
  88. data/fastlane_core/lib/fastlane_core/languages.rb +2 -2
  89. data/fastlane_core/lib/fastlane_core/queue_worker.rb +2 -2
  90. data/fastlane_core/lib/fastlane_core/swag.rb +1 -1
  91. data/fastlane_core/lib/fastlane_core/ui/help.erb +35 -0
  92. data/fastlane_core/lib/fastlane_core/ui/help_formatter.rb +16 -0
  93. data/fastlane_core/lib/fastlane_core/ui/implementations/shell.rb +12 -1
  94. data/frameit/lib/frameit/commands_generator.rb +2 -1
  95. data/gym/lib/gym/commands_generator.rb +2 -1
  96. data/gym/lib/gym/generators/package_command_generator.rb +4 -0
  97. data/gym/lib/gym/generators/package_command_generator_xcode7.rb +13 -8
  98. data/gym/lib/gym/runner.rb +15 -4
  99. data/match/lib/match/change_password.rb +3 -3
  100. data/match/lib/match/commands_generator.rb +2 -1
  101. data/match/lib/match/encryption/interface.rb +1 -1
  102. data/match/lib/match/encryption/openssl.rb +2 -2
  103. data/match/lib/match/module.rb +1 -0
  104. data/pem/lib/pem/commands_generator.rb +2 -1
  105. data/pilot/lib/pilot/commands_generator.rb +2 -1
  106. data/pilot/lib/pilot/manager.rb +4 -0
  107. data/pilot/lib/pilot/options.rb +3 -2
  108. data/pilot/lib/pilot/tester_exporter.rb +0 -1
  109. data/pilot/lib/pilot/tester_manager.rb +0 -1
  110. data/precheck/lib/precheck/commands_generator.rb +2 -1
  111. data/precheck/lib/precheck/options.rb +1 -0
  112. data/precheck/lib/precheck/runner.rb +4 -0
  113. data/produce/lib/produce/commands_generator.rb +2 -1
  114. data/scan/lib/scan/commands_generator.rb +2 -1
  115. data/scan/lib/scan/options.rb +10 -5
  116. data/scan/lib/scan/runner.rb +54 -1
  117. data/scan/lib/scan/test_command_generator.rb +10 -8
  118. data/screengrab/lib/screengrab/android_environment.rb +6 -4
  119. data/screengrab/lib/screengrab/commands_generator.rb +2 -1
  120. data/screengrab/lib/screengrab/runner.rb +1 -1
  121. data/sigh/lib/sigh/commands_generator.rb +2 -1
  122. data/sigh/lib/sigh/options.rb +1 -0
  123. data/sigh/lib/sigh/runner.rb +4 -0
  124. data/snapshot/lib/assets/SnapfileTemplate +1 -1
  125. data/snapshot/lib/assets/SnapshotHelper.swift +1 -1
  126. data/snapshot/lib/snapshot/commands_generator.rb +3 -1
  127. data/snapshot/lib/snapshot/options.rb +5 -0
  128. data/snapshot/lib/snapshot/reports_generator.rb +4 -0
  129. data/snapshot/lib/snapshot/simulator_launchers/launcher_configuration.rb +2 -0
  130. data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher.rb +1 -1
  131. data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb +8 -4
  132. data/spaceship/README.md +2 -12
  133. data/spaceship/lib/spaceship/base.rb +2 -2
  134. data/spaceship/lib/spaceship/commands_generator.rb +4 -2
  135. data/spaceship/lib/spaceship/connect_api/models/app_screenshot.rb +1 -1
  136. data/spaceship/lib/spaceship/connect_api/models/profile.rb +6 -0
  137. data/spaceship/lib/spaceship/connect_api/provisioning/provisioning.rb +6 -2
  138. data/spaceship/lib/spaceship/connect_api/token.rb +7 -1
  139. data/spaceship/lib/spaceship/spaceauth_runner.rb +19 -9
  140. data/spaceship/lib/spaceship/tunes/members.rb +1 -1
  141. data/spaceship/lib/spaceship/ui.rb +2 -2
  142. data/supply/lib/supply/client.rb +3 -1
  143. data/supply/lib/supply/commands_generator.rb +2 -1
  144. data/supply/lib/supply/options.rb +2 -2
  145. data/supply/lib/supply/uploader.rb +1 -0
  146. metadata +53 -64
  147. data/gym/lib/gym/.runner.rb.swp +0 -0
  148. data/pilot/lib/pilot/tester_util.rb +0 -0
@@ -243,12 +243,16 @@ module Gym
243
243
  # Moves over the binary and dsym file to the output directory
244
244
  # @return (String) The path to the resulting pkg file
245
245
  def move_pkg
246
- FileUtils.mv(PackageCommandGenerator.pkg_path, File.expand_path(Gym.config[:output_directory]), force: true)
247
- pkg_path = File.expand_path(File.join(Gym.config[:output_directory], File.basename(PackageCommandGenerator.pkg_path)))
246
+ binary_path = File.expand_path(File.join(Gym.config[:output_directory], File.basename(PackageCommandGenerator.binary_path)))
247
+ if File.exist?(binary_path)
248
+ UI.important(" Removing #{File.basename(binary_path)}") if FastlaneCore::Globals.verbose?
249
+ FileUtils.rm_rf(binary_path)
250
+ end
251
+ FileUtils.mv(PackageCommandGenerator.binary_path, File.expand_path(Gym.config[:output_directory]), force: true)
248
252
 
249
253
  UI.success("Successfully exported and signed the pkg file:")
250
- UI.message(pkg_path)
251
- pkg_path
254
+ UI.message(binary_path)
255
+ binary_path
252
256
  end
253
257
 
254
258
  # copys framework from temp folder:
@@ -274,6 +278,13 @@ module Gym
274
278
  exe_name = Gym.project.build_settings(key: "EXECUTABLE_NAME")
275
279
  app_path = File.join(BuildCommandGenerator.archive_path, "Products/Applications/#{exe_name}.app")
276
280
 
281
+ unless File.exist?(app_path)
282
+ # Apparently the `EXECUTABLE_NAME` is not correct. This can happen when building a workspace which has a project
283
+ # earlier in the build order that has a different `EXECUTABLE_NAME` than the app. Try to find the last `.app` as
284
+ # a fallback for this situation.
285
+ app_path = Dir[File.join(BuildCommandGenerator.archive_path, "Products", "Applications", "*.app")].last
286
+ end
287
+
277
288
  UI.crash!("Couldn't find application in '#{BuildCommandGenerator.archive_path}'") unless File.exist?(app_path)
278
289
 
279
290
  joined_app_path = File.join(Gym.config[:output_directory], File.basename(app_path))
@@ -16,7 +16,7 @@ module Match
16
16
 
17
17
  ensure_ui_interactive
18
18
 
19
- to = FastlaneCore::Helper.ask_password(message: "New passphrase for Git Repo: ", confirm: true)
19
+ new_password = FastlaneCore::Helper.ask_password(message: "New passphrase for Git Repo: ", confirm: true)
20
20
 
21
21
  # Choose the right storage and encryption implementations
22
22
  storage = Storage.for_mode(params[:storage_mode], {
@@ -37,10 +37,10 @@ module Match
37
37
  encryption.decrypt_files
38
38
 
39
39
  encryption.clear_password
40
- encryption.store_password(to)
40
+ encryption.store_password(new_password)
41
41
 
42
42
  message = "[fastlane] Changed passphrase"
43
- files_to_commit = encryption.encrypt_files
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
 
@@ -1,6 +1,7 @@
1
1
  require 'commander'
2
2
 
3
3
  require 'fastlane_core/configuration/configuration'
4
+ require 'fastlane_core/ui/help_formatter'
4
5
 
5
6
  require_relative 'nuke'
6
7
  require_relative 'change_password'
@@ -32,7 +33,7 @@ module Match
32
33
  program :help, 'Author', 'Felix Krause <match@krausefx.com>'
33
34
  program :help, 'Website', 'https://fastlane.tools'
34
35
  program :help, 'Documentation', 'https://docs.fastlane.tools/actions/match/'
35
- program :help_formatter, :compact
36
+ program :help_formatter, FastlaneCore::HelpFormatter
36
37
 
37
38
  global_option('--verbose') { FastlaneCore::Globals.verbose = true }
38
39
  global_option('--env STRING[,STRING2]', String, 'Add environment(s) to use with `dotenv`')
@@ -3,7 +3,7 @@ module Match
3
3
  class Interface
4
4
  # Call this method to trigger the actual
5
5
  # encryption
6
- def encrypt_files
6
+ def encrypt_files(password: nil)
7
7
  not_implemented(__method__)
8
8
  end
9
9
 
@@ -28,9 +28,9 @@ module Match
28
28
  self.working_directory = working_directory
29
29
  end
30
30
 
31
- def encrypt_files
31
+ def encrypt_files(password: nil)
32
32
  files = []
33
- password = fetch_password!
33
+ password ||= fetch_password!
34
34
  iterate(self.working_directory) do |current|
35
35
  files << current
36
36
  encrypt_specific_file(path: current, password: password)
@@ -21,6 +21,7 @@ module Match
21
21
  end
22
22
 
23
23
  def self.cert_type_sym(type)
24
+ type = type.to_s
24
25
  return :mac_installer_distribution if type == "mac_installer_distribution"
25
26
  return :developer_id_installer if type == "developer_id_installer"
26
27
  return :developer_id_application if type == "developer_id"
@@ -2,6 +2,7 @@ require 'commander'
2
2
 
3
3
  require 'fastlane/version'
4
4
  require 'fastlane_core/configuration/configuration'
5
+ require 'fastlane_core/ui/help_formatter'
5
6
  require_relative 'options'
6
7
  require_relative 'manager'
7
8
 
@@ -22,7 +23,7 @@ module PEM
22
23
  program :help, 'Author', 'Felix Krause <pem@krausefx.com>'
23
24
  program :help, 'Website', 'https://fastlane.tools'
24
25
  program :help, 'Documentation', 'https://docs.fastlane.tools/actions/pem/'
25
- program :help_formatter, :compact
26
+ program :help_formatter, FastlaneCore::HelpFormatter
26
27
 
27
28
  global_option('--verbose') { FastlaneCore::Globals.verbose = true }
28
29
  global_option('--env STRING[,STRING2]', String, 'Add environment(s) to use with `dotenv`')
@@ -1,6 +1,7 @@
1
1
  require "commander"
2
2
 
3
3
  require 'fastlane_core/configuration/configuration'
4
+ require 'fastlane_core/ui/help_formatter'
4
5
  require_relative 'module'
5
6
  require_relative 'tester_importer'
6
7
  require_relative 'tester_exporter'
@@ -51,7 +52,7 @@ module Pilot
51
52
  program :help, "Author", "Felix Krause <pilot@krausefx.com>"
52
53
  program :help, "Website", "https://fastlane.tools"
53
54
  program :help, "Documentation", "https://docs.fastlane.tools/actions/pilot/"
54
- program :help_formatter, :compact
55
+ program :help_formatter, FastlaneCore::HelpFormatter
55
56
 
56
57
  global_option("--verbose") { FastlaneCore::Globals.verbose = true }
57
58
 
@@ -23,6 +23,10 @@ module Pilot
23
23
  else
24
24
  config[:username] ||= CredentialsManager::AppfileConfig.try_fetch_value(:apple_id)
25
25
 
26
+ # Username is now optional since addition of App Store Connect API Key
27
+ # Force asking for username to prompt user if not already set
28
+ config.fetch(:username, force_ask: true)
29
+
26
30
  UI.message("Login to App Store Connect (#{config[:username]})")
27
31
  Spaceship::ConnectAPI.login(config[:username], use_portal: false, use_tunes: true, tunes_team_id: config[:team_id], team_name: config[:team_name])
28
32
  UI.message("Login successful")
@@ -31,6 +31,7 @@ module Pilot
31
31
  short_option: "-u",
32
32
  env_name: "PILOT_USERNAME",
33
33
  description: "Your Apple ID Username",
34
+ optional: true,
34
35
  default_value: user,
35
36
  default_value_dynamic: true),
36
37
  FastlaneCore::ConfigItem.new(key: :app_identifier,
@@ -268,12 +269,12 @@ module Pilot
268
269
  verify_block: proc do |value|
269
270
  ENV["FASTLANE_TEAM_ID"] = value.to_s
270
271
  end),
271
- # rubocop:disable Metrics/LineLength
272
+ # rubocop:disable Layout/LineLength
272
273
  FastlaneCore::ConfigItem.new(key: :itc_provider,
273
274
  env_name: "PILOT_ITC_PROVIDER",
274
275
  description: "The provider short name to be used with the iTMSTransporter to identify your team. This value will override the automatically detected provider short name. To get provider short name run `pathToXcode.app/Contents/Applications/Application\\ Loader.app/Contents/itms/bin/iTMSTransporter -m provider -u 'USERNAME' -p 'PASSWORD' -account_type itunes_connect -v off`. The short names of providers should be listed in the second column",
275
276
  optional: true),
276
- # rubocop:enable Metrics/LineLength
277
+ # rubocop:enable Layout/LineLength
277
278
 
278
279
  # waiting and uploaded build
279
280
  FastlaneCore::ConfigItem.new(key: :wait_processing_interval,
@@ -1,5 +1,4 @@
1
1
  require 'spaceship/tunes/application'
2
- require_relative 'tester_util'
3
2
  require_relative 'module'
4
3
  require_relative 'manager'
5
4
 
@@ -1,7 +1,6 @@
1
1
  require 'terminal-table'
2
2
 
3
3
  require_relative 'manager'
4
- require_relative 'tester_util'
5
4
 
6
5
  module Pilot
7
6
  class TesterManager < Manager
@@ -4,6 +4,7 @@ require "fastlane_core/configuration/commander_generator"
4
4
  require "fastlane_core/configuration/configuration"
5
5
  require "fastlane_core/helper"
6
6
  require "fastlane/version"
7
+ require 'fastlane_core/ui/help_formatter'
7
8
 
8
9
  require_relative 'module'
9
10
  require_relative 'options'
@@ -26,7 +27,7 @@ module Precheck
26
27
  program :help, "Author", "Joshua Liebowitz <taquitos@gmail.com>, @taquitos"
27
28
  program :help, "Website", "https://fastlane.tools"
28
29
  program :help, "Documentation", "https://docs.fastlane.tools/actions/precheck/"
29
- program :help_formatter, :compact
30
+ program :help_formatter, FastlaneCore::HelpFormatter
30
31
 
31
32
  global_option("--verbose") { FastlaneCore::Globals.verbose = true }
32
33
 
@@ -52,6 +52,7 @@ module Precheck
52
52
  short_option: "-u",
53
53
  env_name: "PRECHECK_USERNAME",
54
54
  description: "Your Apple ID Username",
55
+ optional: true,
55
56
  default_value: user,
56
57
  default_value_dynamic: true),
57
58
  FastlaneCore::ConfigItem.new(key: :team_id,
@@ -32,6 +32,10 @@ module Precheck
32
32
  UI.message("Creating authorization token for App Store Connect API")
33
33
  Spaceship::ConnectAPI.token = api_token
34
34
  elsif Spaceship::Tunes.client.nil?
35
+ # Username is now optional since addition of App Store Connect API Key
36
+ # Force asking for username to prompt user if not already set
37
+ Precheck.config.fetch(:username, force_ask: true)
38
+
35
39
  # Team selection passed though FASTLANE_ITC_TEAM_ID and FASTLANE_ITC_TEAM_NAME environment variables
36
40
  # Prompts select team if multiple teams and none specified
37
41
  UI.message("Starting login with user '#{Precheck.config[:username]}'")
@@ -1,6 +1,7 @@
1
1
  require 'commander'
2
2
 
3
3
  require 'fastlane/version'
4
+ require 'fastlane_core/ui/help_formatter'
4
5
  require 'fastlane_core/configuration/config_item'
5
6
  require_relative 'module'
6
7
  require_relative 'manager'
@@ -23,7 +24,7 @@ module Produce
23
24
  program :help, 'Author', 'Felix Krause <produce@krausefx.com>'
24
25
  program :help, 'Website', 'https://fastlane.tools'
25
26
  program :help, 'Documentation', 'https://docs.fastlane.tools/actions/produce/'
26
- program :help_formatter, :compact
27
+ program :help_formatter, FastlaneCore::HelpFormatter
27
28
 
28
29
  global_option('--verbose') { FastlaneCore::Globals.verbose = true }
29
30
  global_option('--env STRING[,STRING2]', String, 'Add environment(s) to use with `dotenv`')
@@ -1,6 +1,7 @@
1
1
  require 'commander'
2
2
 
3
3
  require 'fastlane_core/configuration/configuration'
4
+ require 'fastlane_core/ui/help_formatter'
4
5
  require_relative 'module'
5
6
  require_relative 'manager'
6
7
  require_relative 'options'
@@ -28,7 +29,7 @@ module Scan
28
29
  program :help, "Author", "Felix Krause <scan@krausefx.com>"
29
30
  program :help, "Website", "https://fastlane.tools"
30
31
  program :help, "Documentation", "https://docs.fastlane.tools/actions/scan/"
31
- program :help_formatter, :compact
32
+ program :help_formatter, FastlaneCore::HelpFormatter
32
33
 
33
34
  global_option("--verbose") { FastlaneCore::Globals.verbose = true }
34
35
 
@@ -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
- 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)
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
@@ -51,7 +51,14 @@ 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)
58
+ Scan.cache[:retry_attempt] = Scan.config[:number_of_retries] - retries
59
+
54
60
  command = @test_command_generator.generate
61
+
55
62
  prefix_hash = [
56
63
  {
57
64
  prefix: "Running Tests: ",
@@ -71,7 +78,12 @@ module Scan
71
78
  error: proc do |error_output|
72
79
  begin
73
80
  exit_status = $?.exitstatus
74
- ErrorHandler.handle_build_error(error_output, @test_command_generator.xcodebuild_log_path)
81
+ if retries > 0
82
+ # If there are retries remaining, run the tests again
83
+ return retry_execute(retries: retries, error_output: error_output)
84
+ else
85
+ ErrorHandler.handle_build_error(error_output, @test_command_generator.xcodebuild_log_path)
86
+ end
75
87
  rescue => ex
76
88
  SlackPoster.new.run({
77
89
  build_errors: 1
@@ -79,9 +91,50 @@ module Scan
79
91
  raise ex
80
92
  end
81
93
  end)
94
+
82
95
  exit_status
83
96
  end
84
97
 
98
+ def retry_execute(retries:, error_output: "")
99
+ tests = retryable_tests(error_output)
100
+
101
+ if tests.empty?
102
+ UI.crash!("Failed to find failed tests to retry (could not parse error output)")
103
+ end
104
+
105
+ Scan.config[:only_testing] = tests
106
+ UI.important("Retrying tests: #{Scan.config[:only_testing].join(', ')}")
107
+
108
+ retries -= 1
109
+ UI.important("Number of retries remaining: #{retries}")
110
+
111
+ return execute(retries: retries)
112
+ end
113
+
114
+ def retryable_tests(input)
115
+ input = Helper.strip_ansi_colors(input)
116
+
117
+ retryable_tests = []
118
+
119
+ failing_tests = input.split("Failing tests:\n").fetch(1, [])
120
+ .split("\n\n").first
121
+
122
+ suites = failing_tests.split(/(?=\n\s+[\w\s]+:\n)/)
123
+
124
+ suites.each do |suite|
125
+ suite_name = suite.match(/\s*([\w\s]+):/).captures.first
126
+
127
+ test_cases = suite.split(":\n").fetch(1, []).split("\n").each
128
+ .select { |line| line.match?(/^\s+/) }
129
+ .map { |line| line.strip.gsub(".", "/").gsub("()", "") }
130
+ .map { |line| suite_name + "/" + line }
131
+
132
+ retryable_tests += test_cases
133
+ end
134
+
135
+ return retryable_tests.uniq
136
+ end
137
+
85
138
  def handle_results(tests_exit_status)
86
139
  if Scan.config[:disable_xcpretty]
87
140
  unless tests_exit_status == 0
@@ -162,16 +162,18 @@ 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
- unless Scan.cache[:result_bundle_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)
171
- end
172
- Scan.cache[:result_bundle_path] = path
167
+ retry_count = Scan.cache[:retry_attempt] || 0
168
+ attempt = retry_count > 0 ? "-#{retry_count}" : ""
169
+ ext = FastlaneCore::Helper.xcode_version.to_i >= 11 ? '.xcresult' : '.test_result'
170
+ path = File.join(Scan.config[:output_directory], Scan.config[:scheme]) + attempt + ext
171
+ if File.directory?(path)
172
+ FileUtils.remove_dir(path)
173
173
  end
174
- return Scan.cache[:result_bundle_path]
174
+ Scan.cache[:result_bundle_path] = path
175
+
176
+ return path
175
177
  end
176
178
  end
177
179
  end
@@ -34,22 +34,22 @@ module Screengrab
34
34
  def find_platform_tools(android_home)
35
35
  return nil unless android_home
36
36
 
37
- platform_tools_path = File.join(android_home, 'platform-tools')
37
+ platform_tools_path = Helper.localize_file_path(File.join(android_home, 'platform-tools'))
38
38
  File.directory?(platform_tools_path) ? platform_tools_path : nil
39
39
  end
40
40
 
41
41
  def find_build_tools(android_home, build_tools_version)
42
42
  return nil unless android_home
43
43
 
44
- build_tools_dir = File.join(android_home, 'build-tools')
44
+ build_tools_dir = Helper.localize_file_path(File.join(android_home, 'build-tools'))
45
45
 
46
46
  return nil unless build_tools_dir && File.directory?(build_tools_dir)
47
47
 
48
- return File.join(build_tools_dir, build_tools_version) if build_tools_version
48
+ return Helper.localize_file_path(File.join(build_tools_dir, build_tools_version)) if build_tools_version
49
49
 
50
50
  version = select_build_tools_version(build_tools_dir)
51
51
 
52
- return version ? File.join(build_tools_dir, version) : nil
52
+ return version ? Helper.localize_file_path(File.join(build_tools_dir, version)) : nil
53
53
  end
54
54
 
55
55
  def select_build_tools_version(build_tools_dir)
@@ -74,6 +74,7 @@ module Screengrab
74
74
  return FastlaneCore::CommandExecutor.which('adb') unless platform_tools_path
75
75
 
76
76
  adb_path = Helper.get_executable_path(File.join(platform_tools_path, 'adb'))
77
+ adb_path = Helper.localize_file_path(adb_path)
77
78
  return executable_command?(adb_path) ? adb_path : nil
78
79
  end
79
80
 
@@ -81,6 +82,7 @@ module Screengrab
81
82
  return FastlaneCore::CommandExecutor.which('aapt') unless build_tools_path
82
83
 
83
84
  aapt_path = Helper.get_executable_path(File.join(build_tools_path, 'aapt'))
85
+ aapt_path = Helper.localize_file_path(aapt_path)
84
86
  return executable_command?(aapt_path) ? aapt_path : nil
85
87
  end
86
88
 
@@ -1,6 +1,7 @@
1
1
  require 'commander'
2
2
 
3
3
  require 'fastlane/version'
4
+ require 'fastlane_core/ui/help_formatter'
4
5
  require 'fastlane_core/fastlane_folder'
5
6
  require 'fastlane_core/configuration/configuration'
6
7
  require_relative 'android_environment'
@@ -26,7 +27,7 @@ module Screengrab
26
27
  program :help, 'Authors', 'Andrea Falcone <asfalcone@google.com>, Michael Furtak <mfurtak@google.com>'
27
28
  program :help, 'Website', 'https://fastlane.tools'
28
29
  program :help, 'Documentation', 'https://docs.fastlane.tools/actions/screengrab/'
29
- program :help_formatter, :compact
30
+ program :help_formatter, FastlaneCore::HelpFormatter
30
31
 
31
32
  global_option('--verbose', 'Shows a more verbose output') { FastlaneCore::Globals.verbose = true }
32
33