fastlane 2.147.0 → 2.150.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (141) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +82 -82
  3. data/cert/lib/cert/commands_generator.rb +1 -0
  4. data/credentials_manager/lib/credentials_manager/cli.rb +2 -0
  5. data/deliver/lib/deliver.rb +0 -1
  6. data/deliver/lib/deliver/app_screenshot.rb +28 -27
  7. data/deliver/lib/deliver/commands_generator.rb +1 -0
  8. data/deliver/lib/deliver/html_generator.rb +2 -2
  9. data/deliver/lib/deliver/options.rb +6 -11
  10. data/deliver/lib/deliver/runner.rb +7 -4
  11. data/deliver/lib/deliver/setup.rb +5 -30
  12. data/deliver/lib/deliver/submit_for_review.rb +124 -83
  13. data/deliver/lib/deliver/upload_metadata.rb +284 -143
  14. data/deliver/lib/deliver/upload_price_tier.rb +15 -8
  15. data/deliver/lib/deliver/upload_screenshots.rb +86 -37
  16. data/fastlane/lib/assets/s3_html_template.erb +1 -1
  17. data/fastlane/lib/fastlane/actions/crashlytics.rb +0 -4
  18. data/fastlane/lib/fastlane/actions/docs/build_app.md +1 -1
  19. data/fastlane/lib/fastlane/actions/docs/capture_android_screenshots.md +42 -2
  20. data/fastlane/lib/fastlane/actions/docs/capture_ios_screenshots.md +1 -1
  21. data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +2 -2
  22. data/fastlane/lib/fastlane/actions/docs/upload_to_app_store.md.erb +3 -11
  23. data/fastlane/lib/fastlane/actions/docs/upload_to_play_store.md +15 -2
  24. data/fastlane/lib/fastlane/actions/download_dsyms.rb +7 -1
  25. data/fastlane/lib/fastlane/actions/get_managed_play_store_publishing_rights.rb +1 -1
  26. data/fastlane/lib/fastlane/actions/google_play_track_release_names.rb +74 -0
  27. data/fastlane/lib/fastlane/actions/hipchat.rb +1 -1
  28. data/fastlane/lib/fastlane/actions/push_to_git_remote.rb +1 -1
  29. data/fastlane/lib/fastlane/actions/slack.rb +2 -2
  30. data/fastlane/lib/fastlane/actions/slather.rb +8 -1
  31. data/fastlane/lib/fastlane/actions/spm.rb +7 -0
  32. data/fastlane/lib/fastlane/actions/swiftlint.rb +14 -0
  33. data/fastlane/lib/fastlane/actions/sync_code_signing.rb +1 -1
  34. data/fastlane/lib/fastlane/actions/upload_symbols_to_crashlytics.rb +3 -34
  35. data/fastlane/lib/fastlane/actions/xcodebuild.rb +4 -4
  36. data/fastlane/lib/fastlane/cli_tools_distributor.rb +28 -6
  37. data/fastlane/lib/fastlane/commands_generator.rb +1 -1
  38. data/fastlane/lib/fastlane/documentation/actions_list.rb +1 -1
  39. data/fastlane/lib/fastlane/lane.rb +3 -3
  40. data/fastlane/lib/fastlane/lane_manager.rb +0 -10
  41. data/fastlane/lib/fastlane/plugins/plugin_manager.rb +3 -3
  42. data/fastlane/lib/fastlane/plugins/template/.github/workflows/test.yml +29 -0
  43. data/fastlane/lib/fastlane/swift_fastlane_function.rb +22 -5
  44. data/fastlane/lib/fastlane/swift_lane_manager.rb +0 -8
  45. data/fastlane/lib/fastlane/version.rb +1 -1
  46. data/fastlane/swift/ControlCommand.swift +1 -0
  47. data/fastlane/swift/Deliverfile.swift +1 -1
  48. data/fastlane/swift/Fastlane.swift +140 -30
  49. data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/xcshareddata/xcschemes/FastlaneRunner.xcscheme +3 -9
  50. data/fastlane/swift/Gymfile.swift +1 -1
  51. data/fastlane/swift/GymfileProtocol.swift +1 -1
  52. data/fastlane/swift/Matchfile.swift +1 -1
  53. data/fastlane/swift/MatchfileProtocol.swift +5 -1
  54. data/fastlane/swift/Precheckfile.swift +1 -1
  55. data/fastlane/swift/RubyCommand.swift +29 -6
  56. data/fastlane/swift/RubyCommandable.swift +1 -0
  57. data/fastlane/swift/Runner.swift +85 -13
  58. data/fastlane/swift/Scanfile.swift +1 -1
  59. data/fastlane/swift/ScanfileProtocol.swift +10 -2
  60. data/fastlane/swift/Screengrabfile.swift +1 -1
  61. data/fastlane/swift/Snapshotfile.swift +1 -1
  62. data/fastlane/swift/SnapshotfileProtocol.swift +17 -1
  63. data/fastlane/swift/SocketClient.swift +76 -45
  64. data/fastlane/swift/SocketClientDelegateProtocol.swift +1 -1
  65. data/fastlane/swift/SocketResponse.swift +1 -0
  66. data/fastlane_core/lib/fastlane_core/configuration/config_item.rb +1 -3
  67. data/fastlane_core/lib/fastlane_core/pkg_file_analyser.rb +7 -0
  68. data/frameit/lib/frameit/commands_generator.rb +1 -0
  69. data/frameit/lib/frameit/device_types.rb +100 -100
  70. data/gym/lib/gym/generators/package_command_generator.rb +4 -0
  71. data/gym/lib/gym/generators/package_command_generator_xcode7.rb +4 -0
  72. data/gym/lib/gym/options.rb +1 -1
  73. data/gym/lib/gym/runner.rb +14 -0
  74. data/match/lib/match/commands_generator.rb +1 -0
  75. data/match/lib/match/generator.rb +2 -1
  76. data/match/lib/match/nuke.rb +21 -16
  77. data/match/lib/match/options.rb +18 -1
  78. data/match/lib/match/storage/git_storage.rb +4 -0
  79. data/match/lib/match/storage/google_cloud_storage.rb +4 -0
  80. data/match/lib/match/storage/interface.rb +4 -0
  81. data/match/lib/match/storage/s3_storage.rb +4 -0
  82. data/pem/lib/pem/commands_generator.rb +1 -0
  83. data/pilot/lib/pilot/build_manager.rb +23 -7
  84. data/pilot/lib/pilot/options.rb +5 -0
  85. data/produce/lib/produce/commands_generator.rb +1 -0
  86. data/produce/lib/produce/itunes_connect.rb +20 -20
  87. data/produce/lib/produce/options.rb +3 -3
  88. data/scan/lib/scan/detect_values.rb +3 -0
  89. data/scan/lib/scan/options.rb +20 -2
  90. data/scan/lib/scan/test_command_generator.rb +6 -1
  91. data/scan/lib/scan/test_result_parser.rb +9 -2
  92. data/screengrab/lib/screengrab/runner.rb +10 -9
  93. data/sigh/lib/assets/resign.sh +7 -7
  94. data/sigh/lib/sigh/commands_generator.rb +1 -0
  95. data/sigh/lib/sigh/options.rb +7 -1
  96. data/sigh/lib/sigh/runner.rb +2 -1
  97. data/snapshot/lib/assets/SnapshotHelper.swift +16 -37
  98. data/snapshot/lib/assets/SnapshotHelperXcode8.swift +3 -3
  99. data/snapshot/lib/snapshot/detect_values.rb +15 -0
  100. data/snapshot/lib/snapshot/options.rb +31 -0
  101. data/snapshot/lib/snapshot/reports_generator.rb +8 -1
  102. data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb +3 -1
  103. data/snapshot/lib/snapshot/test_command_generator.rb +8 -3
  104. data/snapshot/lib/snapshot/test_command_generator_base.rb +7 -1
  105. data/spaceship/lib/spaceship/.DS_Store +0 -0
  106. data/spaceship/lib/spaceship/client.rb +9 -1
  107. data/spaceship/lib/spaceship/commands_generator.rb +1 -0
  108. data/spaceship/lib/spaceship/connect_api.rb +21 -2
  109. data/spaceship/lib/spaceship/connect_api/client.rb +47 -11
  110. data/spaceship/lib/spaceship/connect_api/model.rb +1 -1
  111. data/spaceship/lib/spaceship/connect_api/models/age_rating_declaration.rb +109 -0
  112. data/spaceship/lib/spaceship/connect_api/models/app.rb +113 -3
  113. data/spaceship/lib/spaceship/connect_api/models/app_category.rb +94 -0
  114. data/spaceship/lib/spaceship/connect_api/models/app_info.rb +74 -0
  115. data/spaceship/lib/spaceship/connect_api/models/app_info_localization.rb +38 -0
  116. data/spaceship/lib/spaceship/connect_api/models/app_price.rb +22 -0
  117. data/spaceship/lib/spaceship/connect_api/models/app_price_tier.rb +12 -0
  118. data/spaceship/lib/spaceship/connect_api/models/app_review_attachment.rb +81 -0
  119. data/spaceship/lib/spaceship/connect_api/models/app_screenshot.rb +117 -0
  120. data/spaceship/lib/spaceship/connect_api/models/app_screenshot_set.rb +101 -0
  121. data/spaceship/lib/spaceship/connect_api/models/app_store_review_detail.rb +51 -0
  122. data/spaceship/lib/spaceship/connect_api/models/app_store_version.rb +182 -0
  123. data/spaceship/lib/spaceship/connect_api/models/app_store_version_localization.rb +70 -0
  124. data/spaceship/lib/spaceship/connect_api/models/app_store_version_phased_release.rb +36 -0
  125. data/spaceship/lib/spaceship/connect_api/models/app_store_version_submission.rb +26 -0
  126. data/spaceship/lib/spaceship/connect_api/models/build.rb +8 -0
  127. data/spaceship/lib/spaceship/connect_api/models/idfa_declaration.rb +40 -0
  128. data/spaceship/lib/spaceship/connect_api/models/reset_ratings_request.rb +26 -0
  129. data/spaceship/lib/spaceship/connect_api/testflight/testflight.rb +10 -3
  130. data/spaceship/lib/spaceship/connect_api/tunes/client.rb +33 -0
  131. data/spaceship/lib/spaceship/connect_api/tunes/tunes.rb +703 -0
  132. data/spaceship/lib/spaceship/errors.rb +3 -0
  133. data/spaceship/lib/spaceship/spaceauth_runner.rb +2 -2
  134. data/supply/lib/supply/client.rb +19 -0
  135. data/supply/lib/supply/commands_generator.rb +1 -0
  136. data/supply/lib/supply/options.rb +9 -0
  137. data/supply/lib/supply/reader.rb +16 -0
  138. data/supply/lib/supply/uploader.rb +4 -0
  139. metadata +52 -47
  140. data/deliver/lib/deliver/upload_assets.rb +0 -27
  141. data/supply/lib/supply/.client.rb.swp +0 -0
@@ -1,4 +1,5 @@
1
1
  require 'fastlane_core/configuration/config_item'
2
+ require 'fastlane/helper/lane_helper'
2
3
  require 'credentials_manager/appfile_config'
3
4
  require_relative 'module'
4
5
 
@@ -10,6 +11,15 @@ module Match
10
11
  @available_options << option
11
12
  end
12
13
 
14
+ def self.default_platform
15
+ case Fastlane::Helper::LaneHelper.current_platform.to_s
16
+ when "mac"
17
+ "macos"
18
+ else
19
+ "ios"
20
+ end
21
+ end
22
+
13
23
  def self.available_options
14
24
  user = CredentialsManager::AppfileConfig.try_fetch_value(:apple_dev_portal_id)
15
25
  user ||= CredentialsManager::AppfileConfig.try_fetch_value(:apple_id)
@@ -215,7 +225,8 @@ module Match
215
225
  short_option: '-o',
216
226
  env_name: "MATCH_PLATFORM",
217
227
  description: "Set the provisioning profile's platform to work with (i.e. ios, tvos, macos)",
218
- default_value: "ios",
228
+ default_value: default_platform,
229
+ default_value_dynamic: true,
219
230
  verify_block: proc do |value|
220
231
  value = value.to_s
221
232
  pt = %w(tvos ios macos)
@@ -231,6 +242,12 @@ module Match
231
242
  description: "A custom name for the provisioning profile. This will replace the default provisioning profile name if specified",
232
243
  optional: true,
233
244
  default_value: nil),
245
+ FastlaneCore::ConfigItem.new(key: :fail_on_name_taken,
246
+ env_name: "MATCH_FAIL_ON_NAME_TAKEN",
247
+ description: "Should the command fail if it was about to create a duplicate of an existing provisioning profile. It can happen due to issues on Apple Developer Portal, when profile to be recreated was not properly deleted first",
248
+ optional: true,
249
+ type: Boolean,
250
+ default_value: false),
234
251
  FastlaneCore::ConfigItem.new(key: :output_path,
235
252
  env_name: "MATCH_OUTPUT_PATH",
236
253
  description: "Path in which to export certificates, key and profile",
@@ -152,6 +152,10 @@ module Match
152
152
  return "git_url(\"#{url}\")"
153
153
  end
154
154
 
155
+ def list_files(file_name: "", file_ext: "")
156
+ Dir[File.join(working_directory, "**", file_name, "*.#{file_ext}")]
157
+ end
158
+
155
159
  private
156
160
 
157
161
  # Create and checkout an specific branch in the git repo
@@ -180,6 +180,10 @@ module Match
180
180
  false
181
181
  end
182
182
 
183
+ def list_files(file_name: "", file_ext: "")
184
+ Dir[File.join(working_directory, self.team_id, "**", file_name, "*.#{file_ext}")]
185
+ end
186
+
183
187
  def generate_matchfile_content
184
188
  return "google_cloud_bucket_name(\"#{self.bucket_name}\")"
185
189
  end
@@ -96,6 +96,10 @@ module Match
96
96
  not_implemented(__method__)
97
97
  end
98
98
 
99
+ def list_files(file_name: "", file_ext: "")
100
+ not_implemented(__method__)
101
+ end
102
+
99
103
  # Implement this for the `fastlane match init` command
100
104
  # This method must return the content of the Matchfile
101
105
  # that should be generated
@@ -139,6 +139,10 @@ module Match
139
139
  false
140
140
  end
141
141
 
142
+ def list_files(file_name: "", file_ext: "")
143
+ Dir[File.join(working_directory, self.team_id, "**", file_name, "*.#{file_ext}")]
144
+ end
145
+
142
146
  # Implement this for the `fastlane match init` command
143
147
  # This method must return the content of the Matchfile
144
148
  # that should be generated
@@ -25,6 +25,7 @@ module PEM
25
25
  program :help_formatter, :compact
26
26
 
27
27
  global_option('--verbose') { FastlaneCore::Globals.verbose = true }
28
+ global_option('--env STRING[,STRING2]', String, 'Add environment(s) to use with `dotenv`')
28
29
 
29
30
  command :renew do |c|
30
31
  c.syntax = 'fastlane pem renew'
@@ -154,13 +154,11 @@ module Pilot
154
154
 
155
155
  return if config[:skip_submission]
156
156
  if options[:reject_build_waiting_for_review]
157
- waiting_for_review_build = build.app.get_builds(filter: { "betaAppReviewSubmission.betaReviewState" => "WAITING_FOR_REVIEW" }, includes: "betaAppReviewSubmission,preReleaseVersion").first
158
- unless waiting_for_review_build.nil?
159
- UI.important("Another build is already in review. Going to remove that build and submit the new one.")
160
- UI.important("Deleting beta app review submission for build: #{waiting_for_review_build.app_version} - #{waiting_for_review_build.version}")
161
- waiting_for_review_build.beta_app_review_submission.delete!
162
- UI.success("Deleted beta app review submission for previous build: #{waiting_for_review_build.app_version} - #{waiting_for_review_build.version}")
163
- end
157
+ reject_build_waiting_for_review(build)
158
+ end
159
+
160
+ if options[:expire_previous_builds]
161
+ expire_previous_builds(build)
164
162
  end
165
163
 
166
164
  if !build.ready_for_internal_testing? && options[:skip_waiting_for_build_processing]
@@ -318,6 +316,24 @@ module Pilot
318
316
  !options[:localized_build_info].nil?
319
317
  end
320
318
 
319
+ def reject_build_waiting_for_review(build)
320
+ waiting_for_review_build = build.app.get_builds(filter: { "betaAppReviewSubmission.betaReviewState" => "WAITING_FOR_REVIEW" }, includes: "betaAppReviewSubmission,preReleaseVersion").first
321
+ unless waiting_for_review_build.nil?
322
+ UI.important("Another build is already in review. Going to remove that build and submit the new one.")
323
+ UI.important("Deleting beta app review submission for build: #{waiting_for_review_build.app_version} - #{waiting_for_review_build.version}")
324
+ waiting_for_review_build.beta_app_review_submission.delete!
325
+ UI.success("Deleted beta app review submission for previous build: #{waiting_for_review_build.app_version} - #{waiting_for_review_build.version}")
326
+ end
327
+ end
328
+
329
+ def expire_previous_builds(build)
330
+ builds_to_expire = build.app.get_builds.reject do |asc_build|
331
+ asc_build.id == build.id
332
+ end
333
+
334
+ builds_to_expire.each(&:expire!)
335
+ end
336
+
321
337
  # If itc_provider was explicitly specified, use it.
322
338
  # If there are multiple teams, infer the provider from the selected team name.
323
339
  # If there are fewer than two teams, don't infer the provider.
@@ -170,6 +170,11 @@ module Pilot
170
170
  env_name: "PILOT_BUILD_NUMBER",
171
171
  description: "The build number of the application build to distribute. If the build number is not specified, the most recent build is distributed",
172
172
  optional: true),
173
+ FastlaneCore::ConfigItem.new(key: :expire_previous_builds,
174
+ is_string: false,
175
+ env_name: "PILOT_EXPIRE_PREVIOUS_BUILDS",
176
+ description: "Should expire previous builds?",
177
+ default_value: false),
173
178
 
174
179
  # testers
175
180
  FastlaneCore::ConfigItem.new(key: :first_name,
@@ -26,6 +26,7 @@ module Produce
26
26
  program :help_formatter, :compact
27
27
 
28
28
  global_option('--verbose') { FastlaneCore::Globals.verbose = true }
29
+ global_option('--env STRING[,STRING2]', String, 'Add environment(s) to use with `dotenv`')
29
30
 
30
31
  command :create do |c|
31
32
  c.syntax = 'fastlane produce create'
@@ -1,7 +1,7 @@
1
1
  require 'spaceship'
2
2
  require 'spaceship/tunes/tunes'
3
+ require 'fastlane_core/languages'
3
4
  require_relative 'module'
4
- require_relative 'available_default_languages'
5
5
 
6
6
  module Produce
7
7
  class ItunesConnect
@@ -18,24 +18,27 @@ module Produce
18
18
  def create_new_app
19
19
  application = fetch_application
20
20
  if application
21
- UI.success("App '#{Produce.config[:app_identifier]}' already exists (#{application.apple_id}), nothing to do on App Store Connect")
21
+ UI.success("App '#{Produce.config[:app_identifier]}' already exists (#{application.id}), nothing to do on App Store Connect")
22
22
  # Nothing to do here
23
23
  else
24
24
  UI.success("Creating new app '#{Produce.config[:app_name]}' on App Store Connect")
25
25
 
26
26
  platforms = Produce.config[:platforms] || [Produce.config[:platform]]
27
27
 
28
- Produce.config[:bundle_identifier_suffix] = '' unless wildcard_bundle?
29
- generated_app = Spaceship::Tunes::Application.create!(name: Produce.config[:app_name],
30
- primary_language: language,
31
- sku: Produce.config[:sku].to_s, # might be an int
32
- bundle_id: app_identifier,
33
- bundle_id_suffix: Produce.config[:bundle_identifier_suffix],
34
- company_name: Produce.config[:company_name],
35
- platforms: platforms,
36
- itunes_connect_users: Produce.config[:itc_users])
28
+ platforms = platforms.map do |platform|
29
+ Spaceship::ConnectAPI::Platform.map(platform)
30
+ end
37
31
 
38
- UI.crash!("Something went wrong when creating the new app on iTC") if generated_app["adamId"].to_s.empty?
32
+ # Produce.config[:company_name]
33
+ # Produce.config[:itc_users]
34
+ application = Spaceship::ConnectAPI::App.create(
35
+ name: Produce.config[:app_name],
36
+ version_string: Produce.config[:app_version] || "1.0",
37
+ sku: Produce.config[:sku].to_s,
38
+ primary_locale: language,
39
+ bundle_id: app_identifier,
40
+ platforms: platforms
41
+ )
39
42
 
40
43
  application = fetch_application
41
44
  counter = 0
@@ -57,10 +60,10 @@ module Produce
57
60
  application.ensure_version!(Produce.config[:app_version], platform: platform) if Produce.config[:app_version]
58
61
  end
59
62
 
60
- UI.success("Successfully created new app '#{Produce.config[:app_name]}' on App Store Connect with ID #{application.apple_id}")
63
+ UI.success("Successfully created new app '#{Produce.config[:app_name]}' on App Store Connect with ID #{application.id}")
61
64
  end
62
65
 
63
- return Spaceship::Tunes::Application.find(@full_bundle_identifier, mac: platform == "osx").apple_id
66
+ return application.id
64
67
  end
65
68
 
66
69
  private
@@ -70,7 +73,7 @@ module Produce
70
73
  end
71
74
 
72
75
  def fetch_application
73
- Spaceship::Tunes::Application.find(@full_bundle_identifier)
76
+ Spaceship::ConnectAPI::App.find(@full_bundle_identifier)
74
77
  end
75
78
 
76
79
  def wildcard_bundle?
@@ -87,11 +90,8 @@ module Produce
87
90
  def language
88
91
  @language = Produce.config[:language]
89
92
 
90
- converted = Spaceship::Tunes::LanguageConverter.from_itc_readable_to_itc(@language)
91
- @language = converted if converted # overwrite it with the actual value
92
-
93
- unless AvailableDefaultLanguages.all_languages.include?(@language)
94
- UI.user_error!("Please enter one of available languages: #{AvailableDefaultLanguages.all_languages}")
93
+ unless FastlaneCore::Languages::ALL_LANGUAGES.include?(@language)
94
+ UI.user_error!("Please enter one of available languages: #{FastlaneCore::Languages::ALL_LANGUAGES}")
95
95
  end
96
96
 
97
97
  return @language
@@ -54,7 +54,7 @@ module Produce
54
54
  optional: true,
55
55
  default_value: "ios",
56
56
  verify_block: proc do |value|
57
- UI.user_error!("The platform can only be ios or osx") unless %('ios', 'osx').include?(value)
57
+ UI.user_error!("The platform can only be ios or osx") unless %('ios', 'osx', 'tvos').include?(value)
58
58
  end),
59
59
  FastlaneCore::ConfigItem.new(key: :platforms,
60
60
  short_option: "-J",
@@ -64,13 +64,13 @@ module Produce
64
64
  optional: true,
65
65
  type: Array,
66
66
  verify_block: proc do |values|
67
- types = %w(ios osx)
67
+ types = %w(ios osx tvos)
68
68
  UI.user_error!("The platform can only be #{types}") unless (values - types).empty?
69
69
  end),
70
70
  FastlaneCore::ConfigItem.new(key: :language,
71
71
  short_option: "-m",
72
72
  env_name: "PRODUCE_LANGUAGE",
73
- description: "Primary Language (e.g. 'English', 'German')",
73
+ description: "Primary Language (e.g. 'en-US', 'fr-FR')",
74
74
  default_value: "English",
75
75
  verify_block: proc do |language|
76
76
  end),
@@ -45,6 +45,9 @@ module Scan
45
45
  coerce_to_array_of_strings(:only_testing)
46
46
  coerce_to_array_of_strings(:skip_testing)
47
47
 
48
+ coerce_to_array_of_strings(:only_test_configurations)
49
+ coerce_to_array_of_strings(:skip_test_configurations)
50
+
48
51
  return config
49
52
  end
50
53
 
@@ -123,12 +123,30 @@ module Scan
123
123
  verify_type('skip_testing', [Array, String], value)
124
124
  end),
125
125
 
126
- # other test options
126
+ # test plans to run
127
127
  FastlaneCore::ConfigItem.new(key: :testplan,
128
128
  env_name: "SCAN_TESTPLAN",
129
129
  description: "The testplan associated with the scheme that should be used for testing",
130
130
  is_string: true,
131
131
  optional: true),
132
+ FastlaneCore::ConfigItem.new(key: :only_test_configurations,
133
+ env_name: "SCAN_ONLY_TEST_CONFIGURATIONS",
134
+ description: "Array of strings matching test plan configurations to run",
135
+ optional: true,
136
+ is_string: false,
137
+ verify_block: proc do |value|
138
+ verify_type('only_test_configurations', [Array, String], value)
139
+ end),
140
+ FastlaneCore::ConfigItem.new(key: :skip_test_configurations,
141
+ env_name: "SCAN_SKIP_TEST_CONFIGURATIONS",
142
+ description: "Array of strings matching test plan configurations to skip",
143
+ optional: true,
144
+ is_string: false,
145
+ verify_block: proc do |value|
146
+ verify_type('skip_test_configurations', [Array, String], value)
147
+ end),
148
+
149
+ # other test options
132
150
  FastlaneCore::ConfigItem.new(key: :xctestrun,
133
151
  short_option: "-X",
134
152
  env_name: "SCAN_XCTESTRUN",
@@ -380,7 +398,7 @@ module Scan
380
398
  FastlaneCore::ConfigItem.new(key: :slack_icon_url,
381
399
  env_name: "SCAN_SLACK_ICON_URL",
382
400
  description: "Overrides the webhook's image property if slack_use_webhook_configured_username_and_icon is false",
383
- default_value: "https://s3-eu-west-1.amazonaws.com/fastlane.tools/fastlane.png",
401
+ default_value: "https://fastlane.tools/assets/img/fastlane_icon.png",
384
402
  is_string: true,
385
403
  optional: true),
386
404
  FastlaneCore::ConfigItem.new(key: :skip_slack,
@@ -37,8 +37,8 @@ module Scan
37
37
  options << "-toolchain '#{config[:toolchain]}'" if config[:toolchain]
38
38
  options << "-derivedDataPath '#{config[:derived_data_path]}'" if config[:derived_data_path]
39
39
  options << "-resultBundlePath '#{result_bundle_path}'" if config[:result_bundle]
40
- options << "-parallel-testing-worker-count #{config[:concurrent_workers]}" if config[:concurrent_workers]
41
40
  if FastlaneCore::Helper.xcode_at_least?(10)
41
+ options << "-parallel-testing-worker-count #{config[:concurrent_workers]}" if config[:concurrent_workers]
42
42
  options << "-maximum-concurrent-test-simulator-destinations #{config[:max_concurrent_simulators]}" if config[:max_concurrent_simulators]
43
43
  options << "-disable-concurrent-testing" if config[:disable_concurrent_testing]
44
44
  end
@@ -47,6 +47,11 @@ module Scan
47
47
  options << "-enableThreadSanitizer #{config[:thread_sanitizer] ? 'YES' : 'NO'}" unless config[:thread_sanitizer].nil?
48
48
  if FastlaneCore::Helper.xcode_at_least?(11)
49
49
  options << "-testPlan '#{config[:testplan]}'" if config[:testplan]
50
+
51
+ # detect_values will ensure that these values are present as Arrays if
52
+ # they are present at all
53
+ options += config[:only_test_configurations].map { |name| "-only-test-configuration '#{name}'" } if config[:only_test_configurations]
54
+ options += config[:skip_test_configurations].map { |name| "-skip-test-configuration '#{name}'" } if config[:skip_test_configurations]
50
55
  end
51
56
  options << "-xctestrun '#{config[:xctestrun]}'" if config[:xctestrun]
52
57
  options << config[:xcargs] if config[:xcargs]
@@ -3,6 +3,13 @@ require_relative 'module'
3
3
  module Scan
4
4
  class TestResultParser
5
5
  def parse_result(output)
6
+ unless output
7
+ return {
8
+ tests: 0,
9
+ failures: 0
10
+ }
11
+ end
12
+
6
13
  # e.g. ...<testsuites tests='2' failures='1'>...
7
14
  matched = output.scan(/<testsuites\b(?=[^<>]*\s+tests='(\d+)')(?=[^<>]*\s+failures='(\d+)')[^<>]+>/)
8
15
 
@@ -10,13 +17,13 @@ module Scan
10
17
  tests = matched[0][0].to_i
11
18
  failures = matched[0][1].to_i
12
19
 
13
- return {
20
+ {
14
21
  tests: tests,
15
22
  failures: failures
16
23
  }
17
24
  else
18
25
  UI.error("Couldn't parse the number of tests from the output")
19
- return {
26
+ {
20
27
  tests: 0,
21
28
  failures: 0
22
29
  }
@@ -57,7 +57,7 @@ module Screengrab
57
57
  device_serial = select_device
58
58
 
59
59
  device_screenshots_paths = [
60
- determine_external_screenshots_path(device_serial),
60
+ determine_external_screenshots_path(device_serial, @config[:locales]),
61
61
  determine_internal_screenshots_paths(@config[:app_package_name], @config[:locales])
62
62
  ].flatten
63
63
 
@@ -130,7 +130,7 @@ module Screengrab
130
130
  Dir.glob(File.join(output_directory, '**', device_type, '*.png'), File::FNM_CASEFOLD)
131
131
  end
132
132
 
133
- def determine_external_screenshots_path(device_serial)
133
+ def determine_external_screenshots_path(device_serial, locales)
134
134
  # macOS evaluates $foo in `echo $foo` before executing the command,
135
135
  # Windows doesn't - hence the double backslash vs. single backslash
136
136
  command = Helper.windows? ? "shell echo \$EXTERNAL_STORAGE " : "shell echo \\$EXTERNAL_STORAGE"
@@ -138,22 +138,23 @@ module Screengrab
138
138
  print_all: true,
139
139
  print_command: true)
140
140
  device_ext_storage = device_ext_storage.strip
141
- File.join(device_ext_storage, @config[:app_package_name], 'screengrab')
141
+ return locales.map do |locale|
142
+ File.join(device_ext_storage, @config[:app_package_name], 'screengrab', locale, "images", "screenshots")
143
+ end.flatten
142
144
  end
143
145
 
144
146
  def determine_internal_screenshots_paths(app_package_name, locales)
145
- locale_paths = locales.map do |locale|
147
+ return locales.map do |locale|
146
148
  [
147
149
  "/data/user/0/#{app_package_name}/files/#{app_package_name}/screengrab/#{locale}/images/screenshots",
148
150
 
149
151
  # https://github.com/fastlane/fastlane/issues/15653#issuecomment-578541663
150
- "/data/data/#{app_package_name}/files/#{app_package_name}/screengrab/#{locale}/images/screenshots"
152
+ "/data/data/#{app_package_name}/files/#{app_package_name}/screengrab/#{locale}/images/screenshots",
153
+
154
+ "/data/data/#{app_package_name}/app_screengrab/#{locale}/images/screenshots",
155
+ "/data/data/#{app_package_name}/screengrab/#{locale}/images/screenshots"
151
156
  ]
152
157
  end.flatten
153
-
154
- return ["/data/data/#{app_package_name}/app_screengrab"] +
155
- ["/data/data/#{app_package_name}/screengrab"] +
156
- locale_paths
157
158
  end
158
159
 
159
160
  def clear_device_previous_screenshots(device_serial, device_screenshots_paths)
@@ -620,7 +620,7 @@ function resign {
620
620
  # Start with using what comes in provisioning profile entitlements before patching
621
621
  cp -f "$PROFILE_ENTITLEMENTS" "$PATCHED_ENTITLEMENTS"
622
622
 
623
- log "Removing blacklisted keys from patched profile"
623
+ log "Removing denylisted keys from patched profile"
624
624
  # See https://github.com/facebook/buck/issues/798 and https://github.com/facebook/buck/pull/802/files
625
625
 
626
626
  # Update in https://github.com/facebook/buck/commit/99c0fbc3ab5ecf04d186913374f660683deccdef
@@ -628,7 +628,7 @@ function resign {
628
628
 
629
629
  # Buck changes referenced above are not self-explanatory and do not seem exhaustive or up-to-date
630
630
  # Comments below explain the rules applied to each key in order to make realignment with future Xcode export logic easier
631
- BLACKLISTED_KEYS=(\
631
+ DENYLISTED_KEYS=(\
632
632
  # PP list identifiers inconsistent with app-defined ones and this key does not seem to appear in IPA entitlements, so ignore it
633
633
  "com.apple.developer.icloud-container-development-container-identifiers" \
634
634
  # This key has an invalid generic value in PP (actual value is set by Xcode during export), see dedicated processing a few blocks below
@@ -637,7 +637,7 @@ function resign {
637
637
  "com.apple.developer.icloud-container-identifiers" \
638
638
  # PP enable all available services and not app-defined ones, must use App entitlements value
639
639
  "com.apple.developer.icloud-services" \
640
- # Was already blacklisted in previous version, but has someone ever seen this key in a PP?
640
+ # Was already denylisted in previous version, but has someone ever seen this key in a PP?
641
641
  "com.apple.developer.restricted-resource-mode" \
642
642
  # If actually used by the App, this value will be set in its entitlements
643
643
  "com.apple.developer.nfc.readersession.formats" \
@@ -675,15 +675,15 @@ function resign {
675
675
  "com.apple.developer.default-data-protection" \
676
676
  # PP seem to list the same groups as the App, but use App entitlements value to be sure
677
677
  "com.apple.security.application-groups" \
678
- # Was already blacklisted in previous version, seems to be an artifact from an old Xcode release
678
+ # Was already denylisted in previous version, seems to be an artifact from an old Xcode release
679
679
  "com.apple.developer.maps" \
680
680
  # If actually used by the App, this value will be set in its entitlements
681
681
  "com.apple.external-accessory.wireless-configuration"
682
682
  )
683
683
 
684
- # Blacklisted keys must not be included into new profile, so remove them from patched profile
685
- for KEY in "${BLACKLISTED_KEYS[@]}"; do
686
- log "Removing blacklisted key: $KEY"
684
+ # Denylisted keys must not be included into new profile, so remove them from patched profile
685
+ for KEY in "${DENYLISTED_KEYS[@]}"; do
686
+ log "Removing denylisted key: $KEY"
687
687
  PlistBuddy -c "Delete $KEY" "$PATCHED_ENTITLEMENTS" 2>/dev/null
688
688
  done
689
689