fastlane 2.151.1 → 2.154.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +74 -74
  3. data/deliver/lib/deliver/app_screenshot.rb +1 -1
  4. data/deliver/lib/deliver/commands_generator.rb +7 -4
  5. data/deliver/lib/deliver/detect_values.rb +9 -3
  6. data/deliver/lib/deliver/download_screenshots.rb +36 -31
  7. data/deliver/lib/deliver/options.rb +1 -1
  8. data/deliver/lib/deliver/runner.rb +5 -10
  9. data/deliver/lib/deliver/setup.rb +92 -3
  10. data/deliver/lib/deliver/submit_for_review.rb +4 -6
  11. data/deliver/lib/deliver/upload_metadata.rb +53 -32
  12. data/deliver/lib/deliver/upload_price_tier.rb +1 -3
  13. data/deliver/lib/deliver/upload_screenshots.rb +76 -45
  14. data/{deliver/lib/deliver/.commands_generator.rb.swp → fastlane/lib/fastlane/.erb_template_helper.rb.swp} +0 -0
  15. data/{frameit/lib/frameit/.editor.rb.swp → fastlane/lib/fastlane/actions/.git_commit.rb.swp} +0 -0
  16. data/fastlane/lib/fastlane/actions/carthage.rb +7 -0
  17. data/fastlane/lib/fastlane/actions/docs/frame_screenshots.md +3 -1
  18. data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +21 -2
  19. data/fastlane/lib/fastlane/actions/docs/upload_to_app_store.md.erb +4 -4
  20. data/fastlane/lib/fastlane/actions/download_dsyms.rb +4 -2
  21. data/fastlane/lib/fastlane/actions/erb.rb +10 -2
  22. data/fastlane/lib/fastlane/actions/git_branch.rb +4 -1
  23. data/fastlane/lib/fastlane/actions/git_pull.rb +13 -2
  24. data/fastlane/lib/fastlane/actions/upload_to_testflight.rb +11 -3
  25. data/fastlane/lib/fastlane/helper/s3_client_helper.rb +1 -1
  26. data/fastlane/lib/fastlane/runner.rb +3 -1
  27. data/fastlane/lib/fastlane/version.rb +1 -1
  28. data/fastlane/swift/Deliverfile.swift +1 -1
  29. data/fastlane/swift/DeliverfileProtocol.swift +3 -3
  30. data/fastlane/swift/Fastlane.swift +47 -13
  31. data/fastlane/swift/Gymfile.swift +1 -1
  32. data/fastlane/swift/GymfileProtocol.swift +1 -1
  33. data/fastlane/swift/Matchfile.swift +1 -1
  34. data/fastlane/swift/MatchfileProtocol.swift +5 -1
  35. data/fastlane/swift/Precheckfile.swift +1 -1
  36. data/fastlane/swift/PrecheckfileProtocol.swift +1 -1
  37. data/fastlane/swift/Scanfile.swift +1 -1
  38. data/fastlane/swift/ScanfileProtocol.swift +1 -1
  39. data/fastlane/swift/Screengrabfile.swift +1 -1
  40. data/fastlane/swift/ScreengrabfileProtocol.swift +1 -1
  41. data/fastlane/swift/Snapshotfile.swift +1 -1
  42. data/fastlane/swift/SnapshotfileProtocol.swift +5 -1
  43. data/fastlane_core/lib/fastlane_core/device_manager.rb +25 -6
  44. data/fastlane_core/lib/fastlane_core/itunes_transporter.rb +6 -3
  45. data/frameit/lib/frameit/editor.rb +11 -6
  46. data/gym/lib/gym/module.rb +8 -0
  47. data/gym/lib/gym/runner.rb +16 -9
  48. data/match/lib/match/options.rb +9 -2
  49. data/match/lib/match/runner.rb +5 -4
  50. data/match/lib/match/storage/git_storage.rb +16 -2
  51. data/pilot/lib/pilot/build_manager.rb +9 -0
  52. data/pilot/lib/pilot/options.rb +7 -1
  53. data/scan/lib/scan/runner.rb +19 -6
  54. data/snapshot/lib/snapshot/options.rb +5 -0
  55. data/snapshot/lib/snapshot/simulator_launchers/launcher_configuration.rb +2 -0
  56. data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb +5 -0
  57. data/spaceship/lib/spaceship/connect_api.rb +1 -0
  58. data/spaceship/lib/spaceship/connect_api/client.rb +3 -3
  59. data/spaceship/lib/spaceship/connect_api/model.rb +14 -0
  60. data/spaceship/lib/spaceship/connect_api/models/age_rating_declaration.rb +1 -0
  61. data/spaceship/lib/spaceship/connect_api/models/app.rb +59 -3
  62. data/spaceship/lib/spaceship/connect_api/models/app_info_localization.rb +1 -0
  63. data/spaceship/lib/spaceship/connect_api/models/app_preview.rb +5 -4
  64. data/spaceship/lib/spaceship/connect_api/models/app_screenshot.rb +44 -5
  65. data/spaceship/lib/spaceship/connect_api/models/app_store_review_detail.rb +1 -0
  66. data/spaceship/lib/spaceship/connect_api/models/app_store_version.rb +12 -0
  67. data/spaceship/lib/spaceship/connect_api/models/app_store_version_localization.rb +1 -0
  68. data/spaceship/lib/spaceship/connect_api/models/app_store_version_release_request.rb +12 -0
  69. data/spaceship/lib/spaceship/connect_api/models/build.rb +1 -0
  70. data/spaceship/lib/spaceship/connect_api/models/idfa_declaration.rb +1 -0
  71. data/spaceship/lib/spaceship/connect_api/tunes/tunes.rb +32 -1
  72. metadata +37 -64
  73. data/deliver/lib/deliver/.download_screenshots.rb.swp +0 -0
  74. data/deliver/lib/deliver/.submit_for_review.rb.swp +0 -0
@@ -14,4 +14,4 @@ class Gymfile: GymfileProtocol {
14
14
  // during the `init` process, and you won't see this message
15
15
  }
16
16
 
17
- // Generated with fastlane 2.151.1
17
+ // Generated with fastlane 2.154.0
@@ -181,4 +181,4 @@ extension GymfileProtocol {
181
181
 
182
182
  // Please don't remove the lines below
183
183
  // They are used to detect outdated files
184
- // FastlaneRunnerAPIVersion [0.9.26]
184
+ // FastlaneRunnerAPIVersion [0.9.31]
@@ -14,4 +14,4 @@ class Matchfile: MatchfileProtocol {
14
14
  // during the `init` process, and you won't see this message
15
15
  }
16
16
 
17
- // Generated with fastlane 2.151.1
17
+ // Generated with fastlane 2.154.0
@@ -53,6 +53,9 @@ protocol MatchfileProtocol: class {
53
53
  /// Use a bearer authorization header to access the git repo (e.g.: access to an Azure Devops repository), usually a string in Base64
54
54
  var gitBearerAuthorization: String? { get }
55
55
 
56
+ /// Use a private key to access the git repo (e.g.: access to GitHub repository via Deploy keys), usually a id_rsa named file or the contents hereof
57
+ var gitPrivateKey: String? { get }
58
+
56
59
  /// Name of the Google Cloud Storage bucket to use
57
60
  var googleCloudBucketName: String? { get }
58
61
 
@@ -133,6 +136,7 @@ extension MatchfileProtocol {
133
136
  var cloneBranchDirectly: Bool { return false }
134
137
  var gitBasicAuthorization: String? { return nil }
135
138
  var gitBearerAuthorization: String? { return nil }
139
+ var gitPrivateKey: String? { return nil }
136
140
  var googleCloudBucketName: String? { return nil }
137
141
  var googleCloudKeysFile: String? { return nil }
138
142
  var googleCloudProjectId: String? { return nil }
@@ -157,4 +161,4 @@ extension MatchfileProtocol {
157
161
 
158
162
  // Please don't remove the lines below
159
163
  // They are used to detect outdated files
160
- // FastlaneRunnerAPIVersion [0.9.20]
164
+ // FastlaneRunnerAPIVersion [0.9.25]
@@ -14,4 +14,4 @@ class Precheckfile: PrecheckfileProtocol {
14
14
  // during the `init` process, and you won't see this message
15
15
  }
16
16
 
17
- // Generated with fastlane 2.151.1
17
+ // Generated with fastlane 2.154.0
@@ -33,4 +33,4 @@ extension PrecheckfileProtocol {
33
33
 
34
34
  // Please don't remove the lines below
35
35
  // They are used to detect outdated files
36
- // FastlaneRunnerAPIVersion [0.9.19]
36
+ // FastlaneRunnerAPIVersion [0.9.24]
@@ -14,4 +14,4 @@ class Scanfile: ScanfileProtocol {
14
14
  // during the `init` process, and you won't see this message
15
15
  }
16
16
 
17
- // Generated with fastlane 2.151.1
17
+ // Generated with fastlane 2.154.0
@@ -257,4 +257,4 @@ extension ScanfileProtocol {
257
257
 
258
258
  // Please don't remove the lines below
259
259
  // They are used to detect outdated files
260
- // FastlaneRunnerAPIVersion [0.9.31]
260
+ // FastlaneRunnerAPIVersion [0.9.36]
@@ -14,4 +14,4 @@ class Screengrabfile: ScreengrabfileProtocol {
14
14
  // during the `init` process, and you won't see this message
15
15
  }
16
16
 
17
- // Generated with fastlane 2.151.1
17
+ // Generated with fastlane 2.154.0
@@ -93,4 +93,4 @@ extension ScreengrabfileProtocol {
93
93
 
94
94
  // Please don't remove the lines below
95
95
  // They are used to detect outdated files
96
- // FastlaneRunnerAPIVersion [0.9.21]
96
+ // FastlaneRunnerAPIVersion [0.9.26]
@@ -14,4 +14,4 @@ class Snapshotfile: SnapshotfileProtocol {
14
14
  // during the `init` process, and you won't see this message
15
15
  }
16
16
 
17
- // Generated with fastlane 2.151.1
17
+ // Generated with fastlane 2.154.0
@@ -44,6 +44,9 @@ protocol SnapshotfileProtocol: class {
44
44
  /// Enabling this option will automatically erase the simulator before running the application
45
45
  var eraseSimulator: Bool { get }
46
46
 
47
+ /// Enabling this option will prevent displaying the simulator window
48
+ var headless: Bool { get }
49
+
47
50
  /// Enabling this option wil automatically override the status bar to show 9:41 AM, full battery, and full reception
48
51
  var overrideStatusBar: Bool { get }
49
52
 
@@ -142,6 +145,7 @@ extension SnapshotfileProtocol {
142
145
  var clearPreviousScreenshots: Bool { return false }
143
146
  var reinstallApp: Bool { return false }
144
147
  var eraseSimulator: Bool { return false }
148
+ var headless: Bool { return true }
145
149
  var overrideStatusBar: Bool { return false }
146
150
  var localizeSimulator: Bool { return false }
147
151
  var darkMode: Bool? { return nil }
@@ -173,4 +177,4 @@ extension SnapshotfileProtocol {
173
177
 
174
178
  // Please don't remove the lines below
175
179
  // They are used to detect outdated files
176
- // FastlaneRunnerAPIVersion [0.9.15]
180
+ // FastlaneRunnerAPIVersion [0.9.20]
@@ -199,18 +199,37 @@ module FastlaneCore
199
199
  self.name
200
200
  end
201
201
 
202
+ def boot
203
+ return unless is_simulator
204
+ return unless os_type == "iOS"
205
+ return if self.state == 'Booted'
206
+
207
+ UI.message("Booting #{self}")
208
+
209
+ `xcrun simctl boot #{self.udid} 2>/dev/null`
210
+ self.state = 'Booted'
211
+ end
212
+
213
+ def shutdown
214
+ return unless is_simulator
215
+ return unless os_type == "iOS"
216
+ return if self.state != 'Booted'
217
+
218
+ UI.message("Shutting down #{self.udid}")
219
+ `xcrun simctl shutdown #{self.udid} 2>/dev/null`
220
+ self.state = 'Shutdown'
221
+ end
222
+
202
223
  def reset
203
224
  UI.message("Resetting #{self}")
204
- `xcrun simctl shutdown #{self.udid}` if self.state == "Booted"
225
+ shutdown
205
226
  `xcrun simctl erase #{self.udid}`
206
- return
207
227
  end
208
228
 
209
229
  def delete
210
230
  UI.message("Deleting #{self}")
211
- `xcrun simctl shutdown #{self.udid}` unless self.state == "Shutdown"
231
+ shutdown
212
232
  `xcrun simctl delete #{self.udid}`
213
- return
214
233
  end
215
234
 
216
235
  def disable_slide_to_type
@@ -324,10 +343,10 @@ module FastlaneCore
324
343
  def copy_logarchive(device, log_identity, logs_destination_dir)
325
344
  require 'shellwords'
326
345
 
327
- logarchive_dst = File.join(logs_destination_dir, "system_logs-#{log_identity}.logarchive").shellescape
346
+ logarchive_dst = File.join(logs_destination_dir, "system_logs-#{log_identity}.logarchive")
328
347
  FileUtils.rm_rf(logarchive_dst)
329
348
  FileUtils.mkdir_p(File.expand_path("..", logarchive_dst))
330
- command = "xcrun simctl spawn --standalone #{device.udid} log collect --output #{logarchive_dst} 2>/dev/null"
349
+ command = "xcrun simctl spawn #{device.udid} log collect --output #{logarchive_dst.shellescape} 2>/dev/null"
331
350
  FastlaneCore::CommandExecutor.execute(command: command, print_all: false, print_command: true)
332
351
  end
333
352
  end
@@ -249,10 +249,11 @@ module FastlaneCore
249
249
  def build_upload_command(username, password, source = "/tmp", provider_short_name = "")
250
250
  if Helper.mac? && Helper.xcode_at_least?(11)
251
251
  [
252
+ "ITMS_TRANSPORTER_PASSWORD=#{password.shellescape}",
252
253
  'xcrun iTMSTransporter',
253
254
  '-m upload',
254
255
  "-u #{username.shellescape}",
255
- "-p #{password.shellescape}",
256
+ "-p @env:ITMS_TRANSPORTER_PASSWORD",
256
257
  "-f #{source.shellescape}",
257
258
  additional_upload_parameters, # that's here, because the user might overwrite the -t option
258
259
  '-k 100000',
@@ -285,10 +286,11 @@ module FastlaneCore
285
286
  def build_download_command(username, password, apple_id, destination = "/tmp", provider_short_name = "")
286
287
  if Helper.mac? && Helper.xcode_at_least?(11)
287
288
  [
289
+ "ITMS_TRANSPORTER_PASSWORD=#{password.shellescape}",
288
290
  'xcrun iTMSTransporter',
289
291
  '-m lookupMetadata',
290
292
  "-u #{username.shellescape}",
291
- "-p #{password.shellescape}",
293
+ "-p @env:ITMS_TRANSPORTER_PASSWORD",
292
294
  "-apple_id #{apple_id.shellescape}",
293
295
  "-destination #{destination.shellescape}",
294
296
  ("-itc_provider #{provider_short_name}" unless provider_short_name.to_s.empty?),
@@ -319,10 +321,11 @@ module FastlaneCore
319
321
  def build_provider_ids_command(username, password)
320
322
  if Helper.mac? && Helper.xcode_at_least?(11)
321
323
  [
324
+ "ITMS_TRANSPORTER_PASSWORD=#{password.shellescape}",
322
325
  'xcrun iTMSTransporter',
323
326
  '-m provider',
324
327
  "-u #{username.shellescape}",
325
- "-p #{password.shellescape}",
328
+ "-p @env:ITMS_TRANSPORTER_PASSWORD",
326
329
  '2>&1' # cause stderr to be written to stdout
327
330
  ].compact.join(' ')
328
331
  else
@@ -298,7 +298,7 @@ module Frameit
298
298
  resize_text(keyword)
299
299
 
300
300
  vertical_padding = vertical_frame_padding # assign padding to variable
301
- spacing_between_title_and_keyword = (actual_font_size / 2)
301
+ spacing_between_title_and_keyword = (actual_font_size('keyword') / 2)
302
302
  title_left_space = (background.width / 2.0 - title.width / 2.0).round
303
303
  keyword_left_space = (background.width / 2.0 - keyword.width / 2.0).round
304
304
 
@@ -359,7 +359,7 @@ module Frameit
359
359
  vertical_padding = vertical_frame_padding # assign padding to variable
360
360
  left_space = (background.width / 2.0 - sum_width / 2.0).round
361
361
 
362
- self.space_to_device += actual_font_size + vertical_padding
362
+ self.space_to_device += actual_font_size('title') + vertical_padding
363
363
 
364
364
  if title_below_image
365
365
  title_top = background.height - effective_text_height / 2 - title.height / 2
@@ -385,7 +385,10 @@ module Frameit
385
385
  background
386
386
  end
387
387
 
388
- def actual_font_size
388
+ def actual_font_size(key)
389
+ font_size = @config[key.to_s]['font_size']
390
+ return font_size if !font_size.nil? && font_size > 0
391
+
389
392
  font_scale_factor = @config['font_scale_factor'] || 0.1
390
393
  UI.user_error!("Parameter 'font_scale_factor' can not be 0. Please provide a value larger than 0.0 (default = 0.1).") if font_scale_factor == 0.0
391
394
  [@image.width * font_scale_factor].max.round
@@ -393,7 +396,7 @@ module Frameit
393
396
 
394
397
  # The space between the keyword and the title
395
398
  def keyword_padding
396
- (actual_font_size / 3.0).round
399
+ (actual_font_size('keyword') / 3.0).round
397
400
  end
398
401
 
399
402
  # This will build up to 2 individual images with the title and optional keyword, which will then be added to the real image
@@ -427,7 +430,7 @@ module Frameit
427
430
  text_image.combine_options do |i|
428
431
  i.font(current_font) if current_font
429
432
  i.gravity("Center")
430
- i.pointsize(actual_font_size)
433
+ i.pointsize(actual_font_size(key))
431
434
  i.draw("text 0,0 '#{text}'")
432
435
  i.interline_spacing(interline_spacing) if interline_spacing
433
436
  i.fill(@config[key.to_s]['color'])
@@ -497,7 +500,9 @@ module Frameit
497
500
  UI.user_error!("Valid parameters :keyword, :title") unless [:keyword, :title].include?(type)
498
501
 
499
502
  # Try to get it from a keyword.strings or title.strings file
500
- strings_path = File.join(File.expand_path("..", screenshot.path), "#{type}.strings")
503
+ strings_path = File.join(File.expand_path("../", screenshot.path), "#{type}.strings")
504
+ strings_path = File.join(File.expand_path("../../", screenshot.path), "#{type}.strings") unless File.exist?(strings_path)
505
+ strings_path = File.join(File.expand_path("../../../", screenshot.path), "#{type}.strings") unless File.exist?(strings_path)
501
506
  if File.exist?(strings_path)
502
507
  parsed = StringsParser.parse(strings_path)
503
508
  text_array = parsed.find { |k, v| screenshot.path.upcase.include?(k.upcase) }
@@ -32,6 +32,14 @@ module Gym
32
32
  def building_mac_catalyst_for_mac?
33
33
  Gym.project.supports_mac_catalyst? && Gym.config[:catalyst_platform] == "macos"
34
34
  end
35
+
36
+ def export_destination_upload?
37
+ config_path = Gym.cache[:config_path]
38
+ return false if config_path.nil?
39
+
40
+ result = CFPropertyList.native_types(CFPropertyList::List.new(file: config_path).value)
41
+ return result["destination"] == "upload"
42
+ end
35
43
  end
36
44
 
37
45
  Helper = FastlaneCore::Helper # you gotta love Ruby: Helper.* should use the Helper class contained in FastlaneCore
@@ -13,6 +13,7 @@ require_relative 'error_handler'
13
13
  module Gym
14
14
  class Runner
15
15
  # @return (String) The path to the resulting ipa
16
+ # rubocop:disable Metrics/PerceivedComplexity
16
17
  def run
17
18
  unless Gym.config[:skip_build_archive]
18
19
  build_app
@@ -34,13 +35,16 @@ module Gym
34
35
 
35
36
  package_app
36
37
  compress_and_move_dsym
37
- path = move_ipa
38
- move_manifest
39
- move_app_thinning
40
- move_app_thinning_size_report
41
- move_apps_folder
42
- move_asset_packs
43
- move_appstore_info
38
+
39
+ unless Gym.export_destination_upload?
40
+ path = move_ipa
41
+ move_manifest
42
+ move_app_thinning
43
+ move_app_thinning_size_report
44
+ move_apps_folder
45
+ move_asset_packs
46
+ move_appstore_info
47
+ end
44
48
  elsif is_mac
45
49
  path = File.expand_path(Gym.config[:output_directory])
46
50
  compress_and_move_dsym
@@ -49,14 +53,17 @@ module Gym
49
53
  return path if Gym.config[:skip_package_pkg]
50
54
 
51
55
  package_app
52
- path = move_pkg
53
- move_appstore_info
56
+ unless Gym.export_destination_upload?
57
+ path = move_pkg
58
+ move_appstore_info
59
+ end
54
60
  return path
55
61
  end
56
62
  copy_files_from_path(File.join(BuildCommandGenerator.archive_path, "Products/usr/local/bin/*")) if Gym.project.command_line_tool?
57
63
  end
58
64
  return path
59
65
  end
66
+ # rubocop:enable Metrics/PerceivedComplexity
60
67
 
61
68
  #####################################################
62
69
  # @!group Printing out things
@@ -141,14 +141,21 @@ module Match
141
141
  env_name: "MATCH_GIT_BASIC_AUTHORIZATION",
142
142
  sensitive: true,
143
143
  description: "Use a basic authorization header to access the git repo (e.g.: access via HTTPS, GitHub Actions, etc), usually a string in Base64",
144
- conflicting_options: [:git_bearer_authorization],
144
+ conflicting_options: [:git_bearer_authorization, :git_private_key],
145
145
  optional: true,
146
146
  default_value: nil),
147
147
  FastlaneCore::ConfigItem.new(key: :git_bearer_authorization,
148
148
  env_name: "MATCH_GIT_BEARER_AUTHORIZATION",
149
149
  sensitive: true,
150
150
  description: "Use a bearer authorization header to access the git repo (e.g.: access to an Azure Devops repository), usually a string in Base64",
151
- conflicting_options: [:git_basic_authorization],
151
+ conflicting_options: [:git_basic_authorization, :git_private_key],
152
+ optional: true,
153
+ default_value: nil),
154
+ FastlaneCore::ConfigItem.new(key: :git_private_key,
155
+ env_name: "MATCH_GIT_PRIVATE_KEY",
156
+ sensitive: true,
157
+ description: "Use a private key to access the git repo (e.g.: access to GitHub repository via Deploy keys), usually a id_rsa named file or the contents hereof",
158
+ conflicting_options: [:git_basic_authorization, :git_bearer_authorization],
152
159
  optional: true,
153
160
  default_value: nil),
154
161
 
@@ -40,16 +40,17 @@ module Match
40
40
  clone_branch_directly: params[:clone_branch_directly],
41
41
  git_basic_authorization: params[:git_basic_authorization],
42
42
  git_bearer_authorization: params[:git_bearer_authorization],
43
+ git_private_key: params[:git_private_key],
43
44
  type: params[:type].to_s,
44
45
  generate_apple_certs: params[:generate_apple_certs],
45
46
  platform: params[:platform].to_s,
46
47
  google_cloud_bucket_name: params[:google_cloud_bucket_name].to_s,
47
48
  google_cloud_keys_file: params[:google_cloud_keys_file].to_s,
48
49
  google_cloud_project_id: params[:google_cloud_project_id].to_s,
49
- s3_region: params[:s3_region].to_s,
50
- s3_access_key: params[:s3_access_key].to_s,
51
- s3_secret_access_key: params[:s3_secret_access_key].to_s,
52
- s3_bucket: params[:s3_bucket].to_s,
50
+ s3_region: params[:s3_region],
51
+ s3_access_key: params[:s3_access_key],
52
+ s3_secret_access_key: params[:s3_secret_access_key],
53
+ s3_bucket: params[:s3_bucket],
53
54
  s3_object_prefix: params[:s3_object_prefix],
54
55
  readonly: params[:readonly],
55
56
  username: params[:readonly] ? nil : params[:username], # only pass username if not readonly
@@ -19,6 +19,7 @@ module Match
19
19
  attr_accessor :platform
20
20
  attr_accessor :git_basic_authorization
21
21
  attr_accessor :git_bearer_authorization
22
+ attr_accessor :git_private_key
22
23
 
23
24
  def self.configure(params)
24
25
  return self.new(
@@ -32,7 +33,8 @@ module Match
32
33
  git_user_email: params[:git_user_email],
33
34
  clone_branch_directly: params[:clone_branch_directly],
34
35
  git_basic_authorization: params[:git_basic_authorization],
35
- git_bearer_authorization: params[:git_bearer_authorization]
36
+ git_bearer_authorization: params[:git_bearer_authorization],
37
+ git_private_key: params[:git_private_key]
36
38
  )
37
39
  end
38
40
 
@@ -46,7 +48,8 @@ module Match
46
48
  git_user_email: nil,
47
49
  clone_branch_directly: false,
48
50
  git_basic_authorization: nil,
49
- git_bearer_authorization: nil)
51
+ git_bearer_authorization: nil,
52
+ git_private_key: nil)
50
53
  self.git_url = git_url
51
54
  self.shallow_clone = shallow_clone
52
55
  self.skip_docs = skip_docs
@@ -56,6 +59,7 @@ module Match
56
59
  self.clone_branch_directly = clone_branch_directly
57
60
  self.git_basic_authorization = git_basic_authorization
58
61
  self.git_bearer_authorization = git_bearer_authorization
62
+ self.git_private_key = git_private_key
59
63
 
60
64
  self.type = type if type
61
65
  self.platform = platform if platform
@@ -85,6 +89,16 @@ module Match
85
89
  command += " -b #{self.branch.shellescape} --single-branch"
86
90
  end
87
91
 
92
+ unless self.git_private_key.nil?
93
+ if File.file?(self.git_private_key)
94
+ ssh_add = File.expand_path(self.git_private_key).shellescape.to_s
95
+ else
96
+ UI.message("Private key file does not exist, will continue by using it as a raw key.")
97
+ ssh_add = "- <<< \"#{self.git_private_key}\""
98
+ end
99
+ command = "ssh-agent bash -c 'ssh-add #{ssh_add}; #{command}'"
100
+ end
101
+
88
102
  UI.message("Cloning remote git repo...")
89
103
  if self.branch && !self.clone_branch_directly
90
104
  UI.message("If cloning the repo takes too long, you can use the `clone_branch_directly` option in match.")
@@ -281,8 +281,17 @@ module Pilot
281
281
  changelog
282
282
  end
283
283
 
284
+ def self.strip_less_than_sign(changelog)
285
+ if changelog && changelog.include?("<")
286
+ changelog.delete!("<")
287
+ UI.important("Less than signs (<) have been removed from the changelog, since they're not allowed by Apple.")
288
+ end
289
+ changelog
290
+ end
291
+
284
292
  def self.sanitize_changelog(changelog)
285
293
  changelog = strip_emoji(changelog)
294
+ changelog = strip_less_than_sign(changelog)
286
295
  truncate_changelog(changelog)
287
296
  end
288
297