fastlane 2.136.0 → 2.141.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +85 -72
  3. data/cert/lib/cert/options.rb +12 -5
  4. data/cert/lib/cert/runner.rb +13 -0
  5. data/deliver/lib/deliver/options.rb +2 -2
  6. data/deliver/lib/deliver/runner.rb +13 -2
  7. data/deliver/lib/deliver/submit_for_review.rb +7 -1
  8. data/fastlane/lib/fastlane/action.rb +2 -2
  9. data/fastlane/lib/fastlane/actions/app_store_build_number.rb +1 -1
  10. data/fastlane/lib/fastlane/actions/build_app.rb +157 -6
  11. data/fastlane/lib/fastlane/actions/build_ios_app.rb +28 -132
  12. data/fastlane/lib/fastlane/actions/build_mac_app.rb +46 -0
  13. data/fastlane/lib/fastlane/actions/create_pull_request.rb +71 -2
  14. data/fastlane/lib/fastlane/actions/docs/{build_ios_app.md → build_app.md} +1 -1
  15. data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +19 -0
  16. data/fastlane/lib/fastlane/actions/docs/upload_to_app_store.md.erb +10 -0
  17. data/fastlane/lib/fastlane/actions/docs/upload_to_play_store.md +4 -2
  18. data/fastlane/lib/fastlane/actions/ensure_bundle_exec.rb +3 -3
  19. data/fastlane/lib/fastlane/actions/get_version_number.rb +7 -2
  20. data/fastlane/lib/fastlane/actions/gradle.rb +54 -3
  21. data/fastlane/lib/fastlane/actions/gym.rb +3 -7
  22. data/fastlane/lib/fastlane/actions/import_from_git.rb +4 -0
  23. data/fastlane/lib/fastlane/actions/increment_version_number.rb +6 -3
  24. data/fastlane/lib/fastlane/actions/last_git_tag.rb +14 -5
  25. data/fastlane/lib/fastlane/actions/latest_testflight_build_number.rb +2 -2
  26. data/fastlane/lib/fastlane/actions/register_devices.rb +5 -1
  27. data/fastlane/lib/fastlane/actions/ruby_version.rb +1 -1
  28. data/fastlane/lib/fastlane/actions/run_tests.rb +5 -22
  29. data/fastlane/lib/fastlane/actions/set_github_release.rb +1 -1
  30. data/fastlane/lib/fastlane/actions/setup_ci.rb +14 -8
  31. data/fastlane/lib/fastlane/actions/testfairy.rb +8 -1
  32. data/fastlane/lib/fastlane/actions/update_plist.rb +37 -2
  33. data/fastlane/lib/fastlane/actions/upload_to_app_store.rb +1 -0
  34. data/fastlane/lib/fastlane/actions/upload_to_play_store_internal_app_sharing.rb +78 -0
  35. data/fastlane/lib/fastlane/actions/verify_build.rb +1 -1
  36. data/fastlane/lib/fastlane/actions/xcode_select.rb +6 -1
  37. data/fastlane/lib/fastlane/cli_tools_distributor.rb +2 -2
  38. data/fastlane/lib/fastlane/commands_generator.rb +1 -1
  39. data/fastlane/lib/fastlane/fast_file.rb +13 -3
  40. data/fastlane/lib/fastlane/helper/adb_helper.rb +13 -4
  41. data/fastlane/lib/fastlane/plugins/template/.rubocop.yml +2 -0
  42. data/fastlane/lib/fastlane/runner.rb +23 -18
  43. data/fastlane/lib/fastlane/version.rb +1 -1
  44. data/fastlane/swift/Deliverfile.swift +1 -1
  45. data/fastlane/swift/DeliverfileProtocol.swift +3 -3
  46. data/fastlane/swift/Fastlane.swift +342 -66
  47. data/fastlane/swift/Gymfile.swift +1 -1
  48. data/fastlane/swift/GymfileProtocol.swift +17 -1
  49. data/fastlane/swift/Matchfile.swift +1 -1
  50. data/fastlane/swift/MatchfileProtocol.swift +12 -4
  51. data/fastlane/swift/Precheckfile.swift +1 -1
  52. data/fastlane/swift/Scanfile.swift +1 -1
  53. data/fastlane/swift/ScanfileProtocol.swift +17 -1
  54. data/fastlane/swift/Screengrabfile.swift +1 -1
  55. data/fastlane/swift/ScreengrabfileProtocol.swift +1 -9
  56. data/fastlane/swift/Snapshotfile.swift +1 -1
  57. data/fastlane/swift/SnapshotfileProtocol.swift +9 -1
  58. data/fastlane_core/lib/fastlane_core/build_watcher.rb +6 -2
  59. data/fastlane_core/lib/fastlane_core/cert_checker.rb +28 -0
  60. data/fastlane_core/lib/fastlane_core/device_manager.rb +20 -0
  61. data/fastlane_core/lib/fastlane_core/helper.rb +7 -1
  62. data/fastlane_core/lib/fastlane_core/project.rb +23 -0
  63. data/frameit/lib/frameit/editor.rb +3 -0
  64. data/gym/lib/gym/code_signing_mapping.rb +32 -3
  65. data/gym/lib/gym/detect_values.rb +34 -2
  66. data/gym/lib/gym/generators/build_command_generator.rb +1 -0
  67. data/gym/lib/gym/generators/package_command_generator.rb +4 -0
  68. data/gym/lib/gym/generators/package_command_generator_xcode7.rb +47 -17
  69. data/gym/lib/gym/module.rb +8 -0
  70. data/gym/lib/gym/options.rb +25 -1
  71. data/gym/lib/gym/runner.rb +63 -23
  72. data/match/lib/match/encryption/openssl.rb +1 -1
  73. data/match/lib/match/generator.rb +17 -3
  74. data/match/lib/match/module.rb +4 -1
  75. data/match/lib/match/nuke.rb +54 -16
  76. data/match/lib/match/options.rb +28 -15
  77. data/match/lib/match/runner.rb +21 -8
  78. data/match/lib/match/spaceship_ensure.rb +19 -9
  79. data/match/lib/match/storage/git_storage.rb +11 -3
  80. data/pilot/lib/pilot/build_manager.rb +46 -12
  81. data/pilot/lib/pilot/options.rb +3 -1
  82. data/scan/lib/scan/detect_values.rb +6 -1
  83. data/scan/lib/scan/manager.rb +18 -1
  84. data/scan/lib/scan/options.rb +23 -1
  85. data/scan/lib/scan/runner.rb +6 -0
  86. data/scan/lib/scan/slack_poster.rb +1 -1
  87. data/scan/lib/scan/test_command_generator.rb +1 -1
  88. data/screengrab/lib/screengrab/options.rb +1 -10
  89. data/screengrab/lib/screengrab/runner.rb +16 -19
  90. data/snapshot/lib/snapshot/options.rb +12 -1
  91. data/snapshot/lib/snapshot/simulator_launchers/launcher_configuration.rb +2 -0
  92. data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb +11 -0
  93. data/spaceship/lib/spaceship/client.rb +9 -4
  94. data/spaceship/lib/spaceship/connect_api.rb +2 -0
  95. data/spaceship/lib/spaceship/connect_api/models/app.rb +11 -0
  96. data/spaceship/lib/spaceship/connect_api/models/beta_feedback.rb +75 -0
  97. data/spaceship/lib/spaceship/connect_api/models/beta_screenshot.rb +18 -0
  98. data/spaceship/lib/spaceship/connect_api/models/build.rb +5 -0
  99. data/spaceship/lib/spaceship/connect_api/models/build_beta_detail.rb +5 -0
  100. data/spaceship/lib/spaceship/connect_api/testflight/testflight.rb +15 -0
  101. data/spaceship/lib/spaceship/portal/app.rb +11 -2
  102. data/spaceship/lib/spaceship/tunes/iap.rb +11 -11
  103. data/spaceship/lib/spaceship/tunes/iap_detail.rb +7 -3
  104. data/spaceship/lib/spaceship/tunes/iap_families.rb +12 -1
  105. data/spaceship/lib/spaceship/tunes/iap_family_details.rb +26 -17
  106. data/spaceship/lib/spaceship/tunes/iap_status.rb +5 -1
  107. data/spaceship/lib/spaceship/tunes/tunes_client.rb +4 -7
  108. data/supply/lib/supply/client.rb +27 -0
  109. data/supply/lib/supply/options.rb +8 -2
  110. data/supply/lib/supply/uploader.rb +55 -26
  111. metadata +44 -25
  112. data/supply/lib/supply/.uploader.rb.swp +0 -0
@@ -91,7 +91,7 @@ module Fastlane
91
91
  end
92
92
 
93
93
  def self.get_plist!(folder, target, configuration = nil)
94
- plist_files = target.resolved_build_setting("INFOPLIST_FILE")
94
+ plist_files = target.resolved_build_setting("INFOPLIST_FILE", true)
95
95
  plist_files_count = plist_files.values.compact.uniq.count
96
96
 
97
97
  # Get plist file for specified configuration
@@ -113,7 +113,12 @@ module Fastlane
113
113
  plist_file.gsub!("$(SRCROOT)/", "")
114
114
  end
115
115
 
116
- plist_file = File.absolute_path(File.join(folder, plist_file))
116
+ # plist_file can be `Relative` or `Absolute` path.
117
+ # Make to `Absolute` path when plist_file is `Relative` path
118
+ unless File.exist?(plist_file)
119
+ plist_file = File.absolute_path(File.join(folder, plist_file))
120
+ end
121
+
117
122
  UI.user_error!("Cannot find plist file: #{plist_file}") unless File.exist?(plist_file)
118
123
 
119
124
  plist_file
@@ -10,17 +10,23 @@ module Fastlane
10
10
  GRADLE_ALL_AAB_OUTPUT_PATHS = :GRADLE_ALL_AAB_OUTPUT_PATHS
11
11
  GRADLE_OUTPUT_JSON_OUTPUT_PATH = :GRADLE_OUTPUT_JSON_OUTPUT_PATH
12
12
  GRADLE_ALL_OUTPUT_JSON_OUTPUT_PATHS = :GRADLE_ALL_OUTPUT_JSON_OUTPUT_PATHS
13
+ GRADLE_MAPPING_TXT_OUTPUT_PATH = :GRADLE_MAPPING_TXT_OUTPUT_PATH
14
+ GRADLE_ALL_MAPPING_TXT_OUTPUT_PATHS = :GRADLE_ALL_MAPPING_TXT_OUTPUT_PATHS
13
15
  GRADLE_FLAVOR = :GRADLE_FLAVOR
14
16
  GRADLE_BUILD_TYPE = :GRADLE_BUILD_TYPE
15
17
  end
16
18
 
17
19
  class GradleAction < Action
20
+ # rubocop:disable Metrics/PerceivedComplexity
18
21
  def self.run(params)
19
22
  task = params[:task]
20
23
  flavor = params[:flavor]
21
24
  build_type = params[:build_type]
25
+ tasks = params[:tasks]
22
26
 
23
- gradle_task = [task, flavor, build_type].join
27
+ gradle_task = gradle_task(task, flavor, build_type, tasks)
28
+
29
+ UI.user_error!('Please pass a gradle task or tasks') if gradle_task.empty?
24
30
 
25
31
  project_dir = params[:project_dir]
26
32
 
@@ -63,6 +69,7 @@ module Fastlane
63
69
  apk_search_path = File.join(project_dir, '**', 'build', 'outputs', 'apk', '**', '*.apk')
64
70
  aab_search_path = File.join(project_dir, '**', 'build', 'outputs', 'bundle', '**', '*.aab')
65
71
  output_json_search_path = File.join(project_dir, '**', 'build', 'outputs', 'apk', '**', 'output.json')
72
+ mapping_txt_search_path = File.join(project_dir, '**', 'build', 'outputs', 'mapping', '**', 'mapping.txt')
66
73
 
67
74
  # Our apk/aab is now built, but there might actually be multiple ones that were built if a flavor was not specified in a multi-flavor project (e.g. `assembleRelease`)
68
75
  # However, we're not interested in unaligned apk's...
@@ -72,11 +79,14 @@ module Fastlane
72
79
  new_aabs = new_aabs.map { |path| File.expand_path(path) }
73
80
  new_output_jsons = Dir[output_json_search_path]
74
81
  new_output_jsons = new_output_jsons.map { |path| File.expand_path(path) }
82
+ new_mapping_txts = Dir[mapping_txt_search_path]
83
+ new_mapping_txts = new_mapping_txts.map { |path| File.expand_path(path) }
75
84
 
76
85
  # We expose all of these new apks and aabs
77
86
  Actions.lane_context[SharedValues::GRADLE_ALL_APK_OUTPUT_PATHS] = new_apks
78
87
  Actions.lane_context[SharedValues::GRADLE_ALL_AAB_OUTPUT_PATHS] = new_aabs
79
88
  Actions.lane_context[SharedValues::GRADLE_ALL_OUTPUT_JSON_OUTPUT_PATHS] = new_output_jsons
89
+ Actions.lane_context[SharedValues::GRADLE_ALL_MAPPING_TXT_OUTPUT_PATHS] = new_mapping_txts
80
90
 
81
91
  # We also take the most recent apk and aab to return as SharedValues::GRADLE_APK_OUTPUT_PATH and SharedValues::GRADLE_AAB_OUTPUT_PATH
82
92
  # This is the one that will be relevant for most projects that just build a single build variant (flavor + build type combo).
@@ -84,15 +94,39 @@ module Fastlane
84
94
  last_apk_path = new_apks.sort_by(&File.method(:mtime)).last
85
95
  last_aab_path = new_aabs.sort_by(&File.method(:mtime)).last
86
96
  last_output_json_path = new_output_jsons.sort_by(&File.method(:mtime)).last
97
+ last_mapping_txt_path = new_mapping_txts.sort_by(&File.method(:mtime)).last
87
98
  Actions.lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH] = File.expand_path(last_apk_path) if last_apk_path
88
99
  Actions.lane_context[SharedValues::GRADLE_AAB_OUTPUT_PATH] = File.expand_path(last_aab_path) if last_aab_path
89
100
  Actions.lane_context[SharedValues::GRADLE_OUTPUT_JSON_OUTPUT_PATH] = File.expand_path(last_output_json_path) if last_output_json_path
101
+ Actions.lane_context[SharedValues::GRADLE_MAPPING_TXT_OUTPUT_PATH] = File.expand_path(last_mapping_txt_path) if last_mapping_txt_path
90
102
 
91
103
  # Give a helpful message in case there were no new apks or aabs. Remember we're only running this code when assembling, in which case we certainly expect there to be an apk or aab
92
104
  UI.message('Couldn\'t find any new signed apk files...') if new_apks.empty? && new_aabs.empty?
93
105
 
94
106
  return result
95
107
  end
108
+ # rubocop:enable Metrics/PerceivedComplexity
109
+
110
+ def self.gradle_task(task, flavor, build_type, tasks)
111
+ gradle_task = [task, flavor, build_type].join
112
+
113
+ if gradle_task.empty? && !tasks.nil?
114
+ gradle_task = tasks.join(' ')
115
+ end
116
+
117
+ gradle_task
118
+ end
119
+
120
+ def self.step_text(params)
121
+ task = params[:task]
122
+ flavor = params[:flavor]
123
+ build_type = params[:build_type]
124
+ tasks = params[:tasks]
125
+
126
+ gradle_task = gradle_task(task, flavor, build_type, tasks)
127
+
128
+ return gradle_task
129
+ end
96
130
 
97
131
  #####################################################
98
132
  # @!group Documentation
@@ -111,7 +145,8 @@ module Fastlane
111
145
  FastlaneCore::ConfigItem.new(key: :task,
112
146
  env_name: 'FL_GRADLE_TASK',
113
147
  description: 'The gradle task you want to execute, e.g. `assemble`, `bundle` or `test`. For tasks such as `assembleMyFlavorRelease` you should use gradle(task: \'assemble\', flavor: \'Myflavor\', build_type: \'Release\')',
114
- optional: false,
148
+ conflicting_options: [:tasks],
149
+ optional: true,
115
150
  is_string: true),
116
151
  FastlaneCore::ConfigItem.new(key: :flavor,
117
152
  env_name: 'FL_GRADLE_FLAVOR',
@@ -123,6 +158,13 @@ module Fastlane
123
158
  description: 'The build type that you want the task for, e.g. `Release`. Useful for some tasks such as `assemble`',
124
159
  optional: true,
125
160
  is_string: true),
161
+ FastlaneCore::ConfigItem.new(key: :tasks,
162
+ type: Array,
163
+ env_name: 'FL_GRADLE_TASKS',
164
+ description: 'The multiple gradle tasks that you want to execute, e.g. `[assembleDebug, bundleDebug]`',
165
+ conflicting_options: [:task],
166
+ optional: true,
167
+ is_string: false),
126
168
  FastlaneCore::ConfigItem.new(key: :flags,
127
169
  env_name: 'FL_GRADLE_FLAGS',
128
170
  description: 'All parameter flags you want to pass to the gradle command, e.g. `--exitcode --xml file.xml`',
@@ -175,7 +217,9 @@ module Fastlane
175
217
  ['GRADLE_AAB_OUTPUT_PATH', 'The path to the most recent Android app bundle'],
176
218
  ['GRADLE_ALL_AAB_OUTPUT_PATHS', 'The paths to the most recent Android app bundles'],
177
219
  ['GRADLE_OUTPUT_JSON_OUTPUT_PATH', 'The path to the most recent output.json file'],
178
- ['GRADLE_ALL_OUTPUT_JSON_OUTPUT_PATHS', 'The path to the newly generated output.json files']
220
+ ['GRADLE_ALL_OUTPUT_JSON_OUTPUT_PATHS', 'The path to the newly generated output.json files'],
221
+ ['GRADLE_MAPPING_TXT_OUTPUT_PATH', 'The path to the most recent mapping.txt file'],
222
+ ['GRADLE_ALL_MAPPING_TXT_OUTPUT_PATHS', 'The path to the newly generated mapping.txt files']
179
223
  ]
180
224
  end
181
225
 
@@ -209,6 +253,13 @@ module Fastlane
209
253
  )
210
254
  ```
211
255
 
256
+ You can pass multiple gradle tasks:
257
+ ```ruby
258
+ gradle(
259
+ tasks: ["assembleDebug", "bundleDebug"]
260
+ )
261
+ ```
262
+
212
263
  You can pass properties to gradle:
213
264
  ```ruby
214
265
  gradle(
@@ -1,13 +1,9 @@
1
1
  module Fastlane
2
2
  module Actions
3
- require 'fastlane/actions/build_ios_app'
4
- class GymAction < BuildIosAppAction
5
- #####################################################
6
- # @!group Documentation
7
- #####################################################
8
-
3
+ require 'fastlane/actions/build_app'
4
+ class GymAction < BuildAppAction
9
5
  def self.description
10
- "Alias for the `build_ios_app` action"
6
+ "Alias for the `build_app` action"
11
7
  end
12
8
  end
13
9
  end
@@ -26,6 +26,10 @@ module Fastlane
26
26
  description: "The branch or tag to check-out on the repository",
27
27
  default_value: 'HEAD',
28
28
  optional: true),
29
+ FastlaneCore::ConfigItem.new(key: :dependencies,
30
+ description: "The array of additional Fastfiles in the repository",
31
+ default_value: [],
32
+ optional: true),
29
33
  FastlaneCore::ConfigItem.new(key: :path,
30
34
  description: "The path of the Fastfile in the repository",
31
35
  default_value: 'fastlane/Fastfile',
@@ -43,6 +43,9 @@ module Fastlane
43
43
  version_array = current_version.split(".").map(&:to_i)
44
44
 
45
45
  case params[:bump_type]
46
+ when "bump"
47
+ version_array[-1] = version_array[-1] + 1
48
+ next_version_number = version_array.join(".")
46
49
  when "patch"
47
50
  UI.user_error!(version_token_error) if version_array.count < 3
48
51
  version_array[2] = version_array[2] + 1
@@ -109,9 +112,9 @@ module Fastlane
109
112
  FastlaneCore::ConfigItem.new(key: :bump_type,
110
113
  env_name: "FL_VERSION_NUMBER_BUMP_TYPE",
111
114
  description: "The type of this version bump. Available: patch, minor, major",
112
- default_value: "patch",
115
+ default_value: "bump",
113
116
  verify_block: proc do |value|
114
- UI.user_error!("Available values are 'patch', 'minor' and 'major'") unless ['patch', 'minor', 'major'].include?(value)
117
+ UI.user_error!("Available values are 'patch', 'minor' and 'major'") unless ['bump', 'patch', 'minor', 'major'].include?(value)
115
118
  end),
116
119
  FastlaneCore::ConfigItem.new(key: :version_number,
117
120
  env_name: "FL_VERSION_NUMBER_VERSION_NUMBER",
@@ -148,7 +151,7 @@ module Fastlane
148
151
 
149
152
  def self.example_code
150
153
  [
151
- 'increment_version_number # Automatically increment patch version number',
154
+ 'increment_version_number # Automatically increment version number',
152
155
  'increment_version_number(
153
156
  bump_type: "patch" # Automatically increment patch version number
154
157
  )',
@@ -2,7 +2,7 @@ module Fastlane
2
2
  module Actions
3
3
  class LastGitTagAction < Action
4
4
  def self.run(params)
5
- Actions.last_git_tag_name
5
+ Actions.last_git_tag_name(true, params[:pattern])
6
6
  end
7
7
 
8
8
  #####################################################
@@ -14,7 +14,12 @@ module Fastlane
14
14
  end
15
15
 
16
16
  def self.available_options
17
- []
17
+ [
18
+ FastlaneCore::ConfigItem.new(key: :pattern,
19
+ description: "Pattern to filter tags when looking for last one. Limit tags to ones matching given shell glob. If pattern lacks ?, *, or [, * at the end is implied",
20
+ default_value: nil,
21
+ optional: true)
22
+ ]
18
23
  end
19
24
 
20
25
  def self.output
@@ -26,7 +31,7 @@ module Fastlane
26
31
  end
27
32
 
28
33
  def self.authors
29
- ["KrauseFx"]
34
+ ["KrauseFx", "wedkarz"]
30
35
  end
31
36
 
32
37
  def self.is_supported?(platform)
@@ -34,12 +39,16 @@ module Fastlane
34
39
  end
35
40
 
36
41
  def self.details
37
- "If you are using this action on a **shallow clone**, *the default with some CI systems like Bamboo*, you need to ensure that you have also pulled all the git tags appropriately. Assuming your git repo has the correct remote set you can issue `sh('git fetch --tags')`."
42
+ [
43
+ "If you are using this action on a **shallow clone**, *the default with some CI systems like Bamboo*, you need to ensure that you have also pulled all the git tags appropriately. Assuming your git repo has the correct remote set you can issue `sh('git fetch --tags')`.",
44
+ "Pattern parameter allows you to filter to a subset of tags."
45
+ ].join("\n")
38
46
  end
39
47
 
40
48
  def self.example_code
41
49
  [
42
- 'last_git_tag'
50
+ 'last_git_tag',
51
+ 'last_git_tag(pattern: "release/v1.0/")'
43
52
  ]
44
53
  end
45
54
 
@@ -64,7 +64,7 @@ module Fastlane
64
64
  is_string: true,
65
65
  default_value: "ios",
66
66
  verify_block: proc do |value|
67
- UI.user_error!("The platform can only be ios, or appletvos") unless %('ios', 'appletvos').include?(value)
67
+ UI.user_error!("The platform can only be ios, osx, or appletvos") unless %('osx', ios', 'appletvos').include?(value)
68
68
  end),
69
69
  FastlaneCore::ConfigItem.new(key: :initial_build_number,
70
70
  env_name: "INITIAL_BUILD_NUMBER",
@@ -110,7 +110,7 @@ module Fastlane
110
110
  end
111
111
 
112
112
  def self.is_supported?(platform)
113
- platform == :ios
113
+ [:ios, :mac].include?(platform)
114
114
  end
115
115
 
116
116
  def self.example_code
@@ -25,7 +25,11 @@ module Fastlane
25
25
  end
26
26
 
27
27
  new_devices = devices_file.drop(1).map do |row|
28
- UI.user_error!("Invalid device line, please provide a file according to the Apple Sample UDID file (https://developer.apple.com/account/resources/downloads/Multiple-Upload-Samples.zip)") unless (2..3).cover?(row.count)
28
+ if row.count == 1
29
+ UI.user_error!("Invalid device line, ensure you are using tabs (NOT spaces). See Apple's sample/spec here: https://developer.apple.com/account/resources/downloads/Multiple-Upload-Samples.zip")
30
+ elsif !(2..3).cover?(row.count)
31
+ UI.user_error!("Invalid device line, please provide a file according to the Apple Sample UDID file (https://developer.apple.com/account/resources/downloads/Multiple-Upload-Samples.zip)")
32
+ end
29
33
  row
30
34
  end
31
35
  else
@@ -40,7 +40,7 @@ module Fastlane
40
40
  def self.details
41
41
  [
42
42
  "Add this to your `Fastfile` to require a certain version of _ruby_.",
43
- "Put it at the top of your `Fastfile to ensure that _fastlane_ is executed appropriately."
43
+ "Put it at the top of your `Fastfile` to ensure that _fastlane_ is executed appropriately."
44
44
  ].join("\n")
45
45
  end
46
46
 
@@ -10,17 +10,10 @@ module Fastlane
10
10
  class RunTestsAction < Action
11
11
  def self.run(values)
12
12
  require 'scan'
13
- plist_files_before = []
13
+ manager = Scan::Manager.new
14
14
 
15
15
  begin
16
- destination = values[:destination] # save destination value which can be later overridden
17
- Scan.config = values # we set this here to auto-detect missing values, which we need later on
18
- unless values[:derived_data_path].to_s.empty?
19
- plist_files_before = test_summary_filenames(values[:derived_data_path])
20
- end
21
-
22
- values[:destination] = destination # restore destination value
23
- Scan::Manager.new.work(values)
16
+ manager.work(values)
24
17
 
25
18
  zip_build_products_path = Scan.cache[:zip_build_products_path]
26
19
  Actions.lane_context[SharedValues::SCAN_ZIP_BUILD_PRODUCTS_PATH] = zip_build_products_path if zip_build_products_path
@@ -37,8 +30,10 @@ module Fastlane
37
30
  end
38
31
  ensure
39
32
  unless values[:derived_data_path].to_s.empty?
33
+ plist_files_before = manager.plist_files_before || []
34
+
40
35
  Actions.lane_context[SharedValues::SCAN_DERIVED_DATA_PATH] = values[:derived_data_path]
41
- plist_files_after = test_summary_filenames(values[:derived_data_path])
36
+ plist_files_after = manager.test_summary_filenames(values[:derived_data_path])
42
37
  all_test_summaries = (plist_files_after - plist_files_before)
43
38
  Actions.lane_context[SharedValues::SCAN_GENERATED_PLIST_FILES] = all_test_summaries
44
39
  Actions.lane_context[SharedValues::SCAN_GENERATED_PLIST_FILE] = all_test_summaries.last
@@ -85,18 +80,6 @@ module Fastlane
85
80
 
86
81
  private_class_method
87
82
 
88
- def self.test_summary_filenames(derived_data_path)
89
- files = []
90
-
91
- # Xcode < 10
92
- files += Dir["#{derived_data_path}/**/Logs/Test/*TestSummaries.plist"]
93
-
94
- # Xcode 10
95
- files += Dir["#{derived_data_path}/**/Logs/Test/*.xcresult/TestSummaries.plist"]
96
-
97
- return files
98
- end
99
-
100
83
  def self.example_code
101
84
  [
102
85
  'run_tests',
@@ -241,7 +241,7 @@ module Fastlane
241
241
  end
242
242
 
243
243
  def self.return_type
244
- :hash_of_strings
244
+ :hash
245
245
  end
246
246
 
247
247
  def self.authors
@@ -7,19 +7,22 @@ module Fastlane
7
7
  return
8
8
  end
9
9
 
10
- case params[:provider]
11
- when 'travis'
12
- setup_keychain
10
+ case detect_provider(params)
13
11
  when 'circleci'
14
- setup_keychain
15
12
  setup_output_paths
16
13
  end
14
+
15
+ setup_keychain
17
16
  end
18
17
 
19
18
  def self.should_run?(params)
20
19
  Helper.ci? || params[:force]
21
20
  end
22
21
 
22
+ def self.detect_provider(params)
23
+ params[:provider] || (Helper.is_circle_ci? ? 'circleci' : nil)
24
+ end
25
+
23
26
  def self.setup_keychain
24
27
  unless ENV["MATCH_KEYCHAIN_NAME"].nil?
25
28
  UI.message("Skipping Keychain setup as a keychain was already specified")
@@ -37,7 +40,8 @@ module Fastlane
37
40
  unlock: true,
38
41
  timeout: 3600,
39
42
  lock_when_sleeps: true,
40
- password: ""
43
+ password: "",
44
+ add_to_search_list: true
41
45
  )
42
46
 
43
47
  UI.message("Enabling match readonly mode.")
@@ -87,18 +91,20 @@ module Fastlane
87
91
  default_value: false),
88
92
  FastlaneCore::ConfigItem.new(key: :provider,
89
93
  env_name: "FL_SETUP_CI_PROVIDER",
90
- description: "CI provider",
94
+ description: "CI provider. If none is set, the provider is detected automatically",
91
95
  is_string: true,
92
96
  default_value: false,
93
97
  verify_block: proc do |value|
94
98
  value = value.to_s
99
+ # Validate both 'travis' and 'circleci' for backwards compatibility, even
100
+ # though only the latter receives special treatment by this action
95
101
  UI.user_error!("A given CI provider '#{value}' is not supported. Available CI providers: 'travis', 'circleci'") unless ["travis", "circleci"].include?(value)
96
102
  end)
97
103
  ]
98
104
  end
99
105
 
100
106
  def self.authors
101
- ["mollyIV"]
107
+ ["mollyIV", "svenmuennich"]
102
108
  end
103
109
 
104
110
  def self.is_supported?(platform)
@@ -108,7 +114,7 @@ module Fastlane
108
114
  def self.example_code
109
115
  [
110
116
  'setup_ci(
111
- provider: "travis"
117
+ provider: "circleci"
112
118
  )'
113
119
  ]
114
120
  end
@@ -92,6 +92,8 @@ module Fastlane
92
92
  [key, value]
93
93
  when :options
94
94
  [key, options_to_client.call(value).join(',')]
95
+ when :custom
96
+ [key, value]
95
97
  else
96
98
  UI.user_error!("Unknown parameter: #{key}")
97
99
  end
@@ -223,6 +225,11 @@ module Fastlane
223
225
  env_name: "FL_TESTFAIRY_OPTIONS",
224
226
  description: "Array of options (shake,video_only_wifi,anonymous)",
225
227
  default_value: []),
228
+ FastlaneCore::ConfigItem.new(key: :custom,
229
+ optional: true,
230
+ env_name: "FL_TESTFAIRY_CUSTOM",
231
+ description: "Array of custom options. Contact support@testfairy.com for more information",
232
+ default_value: ''),
226
233
  FastlaneCore::ConfigItem.new(key: :timeout,
227
234
  env_name: "FL_TESTFAIRY_TIMEOUT",
228
235
  description: "Request timeout in seconds",
@@ -252,7 +259,7 @@ module Fastlane
252
259
  end
253
260
 
254
261
  def self.authors
255
- ["taka0125", "tcurdt"]
262
+ ["taka0125", "tcurdt", "vijaysharm"]
256
263
  end
257
264
 
258
265
  def self.is_supported?(platform)