fastlane 2.195.0 → 2.198.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +80 -80
  3. data/cert/lib/cert/runner.rb +5 -2
  4. data/deliver/lib/assets/ScreenshotsHelp +29 -6
  5. data/deliver/lib/deliver/app_screenshot.rb +5 -4
  6. data/deliver/lib/deliver/runner.rb +1 -1
  7. data/deliver/lib/deliver/upload_screenshots.rb +1 -1
  8. data/fastlane/lib/fastlane/actions/app_store_build_number.rb +12 -6
  9. data/fastlane/lib/fastlane/actions/docs/upload_to_app_store.md.erb +1 -1
  10. data/fastlane/lib/fastlane/actions/download_dsyms.rb +47 -30
  11. data/fastlane/lib/fastlane/actions/get_push_certificate.rb +1 -1
  12. data/fastlane/lib/fastlane/actions/get_version_number.rb +6 -2
  13. data/fastlane/lib/fastlane/actions/latest_testflight_build_number.rb +2 -3
  14. data/fastlane/lib/fastlane/actions/notarize.rb +29 -11
  15. data/fastlane/lib/fastlane/actions/set_github_release.rb +11 -5
  16. data/fastlane/lib/fastlane/version.rb +1 -1
  17. data/fastlane/swift/Deliverfile.swift +1 -1
  18. data/fastlane/swift/DeliverfileProtocol.swift +1 -1
  19. data/fastlane/swift/Fastlane.swift +57 -17
  20. data/fastlane/swift/Gymfile.swift +1 -1
  21. data/fastlane/swift/GymfileProtocol.swift +5 -1
  22. data/fastlane/swift/LaneFileProtocol.swift +1 -1
  23. data/fastlane/swift/Matchfile.swift +1 -1
  24. data/fastlane/swift/MatchfileProtocol.swift +1 -1
  25. data/fastlane/swift/Precheckfile.swift +1 -1
  26. data/fastlane/swift/PrecheckfileProtocol.swift +1 -1
  27. data/fastlane/swift/Runner.swift +1 -1
  28. data/fastlane/swift/Scanfile.swift +1 -1
  29. data/fastlane/swift/ScanfileProtocol.swift +1 -1
  30. data/fastlane/swift/Screengrabfile.swift +1 -1
  31. data/fastlane/swift/ScreengrabfileProtocol.swift +3 -3
  32. data/fastlane/swift/Snapshotfile.swift +1 -1
  33. data/fastlane/swift/SnapshotfileProtocol.swift +1 -1
  34. data/fastlane/swift/formatting/Brewfile.lock.json +27 -22
  35. data/fastlane_core/lib/fastlane_core/itunes_transporter.rb +38 -7
  36. data/frameit/lib/frameit/editor.rb +16 -18
  37. data/frameit/lib/frameit/trim_box.rb +6 -0
  38. data/gym/lib/gym/generators/build_command_generator.rb +1 -1
  39. data/gym/lib/gym/options.rb +6 -0
  40. data/match/lib/match/nuke.rb +79 -1
  41. data/match/lib/match/spaceship_ensure.rb +1 -0
  42. data/pem/lib/pem/manager.rb +31 -7
  43. data/pem/lib/pem/options.rb +10 -1
  44. data/pilot/lib/pilot/build_manager.rb +1 -1
  45. data/scan/lib/scan/runner.rb +1 -1
  46. data/screengrab/lib/screengrab/options.rb +2 -2
  47. data/sigh/lib/assets/resign.sh +8 -5
  48. data/snapshot/lib/snapshot/reports_generator.rb +8 -0
  49. data/spaceship/lib/spaceship/connect_api/models/build.rb +4 -2
  50. data/spaceship/lib/spaceship/connect_api/models/build_bundle.rb +59 -0
  51. data/spaceship/lib/spaceship/connect_api/models/certificate.rb +3 -0
  52. data/spaceship/lib/spaceship/connect_api/testflight/.testflight.rb.swp +0 -0
  53. data/spaceship/lib/spaceship/connect_api/token.rb +1 -1
  54. data/spaceship/lib/spaceship/connect_api.rb +1 -0
  55. data/supply/lib/supply/client.rb +3 -3
  56. data/supply/lib/supply/uploader.rb +1 -1
  57. metadata +38 -32
@@ -47,7 +47,7 @@ public protocol ScreengrabfileProtocol: class {
47
47
  /// The path to the APK for the app under test
48
48
  var appApkPath: String? { get }
49
49
 
50
- /// The path to the APK for the the tests bundle
50
+ /// The path to the APK for the tests bundle
51
51
  var testsApkPath: String? { get }
52
52
 
53
53
  /// Use the device or emulator with the given serial number or qualifier
@@ -56,7 +56,7 @@ public protocol ScreengrabfileProtocol: class {
56
56
  /// Type of device used for screenshots. Matches Google Play Types (phone, sevenInch, tenInch, tv, wear)
57
57
  var deviceType: String { get }
58
58
 
59
- /// Whether or not to exit Screengrab on test failure. Exiting on failure will not copy sceenshots to local machine nor open sceenshots summary
59
+ /// Whether or not to exit Screengrab on test failure. Exiting on failure will not copy screenshots to local machine nor open screenshots summary
60
60
  var exitOnTestFailure: Bool { get }
61
61
 
62
62
  /// Enabling this option will automatically uninstall the application before running it
@@ -96,4 +96,4 @@ public extension ScreengrabfileProtocol {
96
96
 
97
97
  // Please don't remove the lines below
98
98
  // They are used to detect outdated files
99
- // FastlaneRunnerAPIVersion [0.9.82]
99
+ // FastlaneRunnerAPIVersion [0.9.86]
@@ -17,4 +17,4 @@ public class Snapshotfile: SnapshotfileProtocol {
17
17
  // during the `init` process, and you won't see this message
18
18
  }
19
19
 
20
- // Generated with fastlane 2.195.0
20
+ // Generated with fastlane 2.198.1
@@ -200,4 +200,4 @@ public extension SnapshotfileProtocol {
200
200
 
201
201
  // Please don't remove the lines below
202
202
  // They are used to detect outdated files
203
- // FastlaneRunnerAPIVersion [0.9.76]
203
+ // FastlaneRunnerAPIVersion [0.9.80]
@@ -2,30 +2,35 @@
2
2
  "entries": {
3
3
  "brew": {
4
4
  "swiftformat": {
5
- "version": "0.48.11",
5
+ "version": "0.48.18",
6
6
  "bottle": {
7
7
  "rebuild": 0,
8
8
  "root_url": "https://ghcr.io/v2/homebrew/core",
9
9
  "files": {
10
+ "arm64_monterey": {
11
+ "cellar": ":any_skip_relocation",
12
+ "url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:adbb11cdda0596a1f40e920f826a2e1ffe6aeb1643c43ddb108f25f30755be39",
13
+ "sha256": "adbb11cdda0596a1f40e920f826a2e1ffe6aeb1643c43ddb108f25f30755be39"
14
+ },
10
15
  "arm64_big_sur": {
11
16
  "cellar": ":any_skip_relocation",
12
- "url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:e0a851cfa2ff5d04f0fc98a9e624d1411f1b5b1e55e3cbc0901f4913c02e716a",
13
- "sha256": "e0a851cfa2ff5d04f0fc98a9e624d1411f1b5b1e55e3cbc0901f4913c02e716a"
17
+ "url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:74691b21c40d34459c5825306828039bdbdfdd02c80d1cea5c449c3f59760ab1",
18
+ "sha256": "74691b21c40d34459c5825306828039bdbdfdd02c80d1cea5c449c3f59760ab1"
14
19
  },
15
- "big_sur": {
20
+ "monterey": {
16
21
  "cellar": ":any_skip_relocation",
17
- "url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:a5327283fe32b2ef2c6f264e14c966a9a60cb291415d3d05ed659c92a93c4987",
18
- "sha256": "a5327283fe32b2ef2c6f264e14c966a9a60cb291415d3d05ed659c92a93c4987"
22
+ "url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:14e4b90f29b55b06c92f90b6e81e8dd55c54ff258ee8b0bab2bb479ce0cc8daf",
23
+ "sha256": "14e4b90f29b55b06c92f90b6e81e8dd55c54ff258ee8b0bab2bb479ce0cc8daf"
19
24
  },
20
- "catalina": {
25
+ "big_sur": {
21
26
  "cellar": ":any_skip_relocation",
22
- "url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:ba95e49ecc71bb19734698dee565e3b0ced6470729206cb434675cfa051f2755",
23
- "sha256": "ba95e49ecc71bb19734698dee565e3b0ced6470729206cb434675cfa051f2755"
27
+ "url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:73f0497b504f87159bc2d133371014e0372799d89f62bc78068b3b5427ae614f",
28
+ "sha256": "73f0497b504f87159bc2d133371014e0372799d89f62bc78068b3b5427ae614f"
24
29
  },
25
- "mojave": {
30
+ "catalina": {
26
31
  "cellar": ":any_skip_relocation",
27
- "url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:c7e00eae9d46dddf040999f0f2832d08110f093c7a403aaaaaa18d8830213967",
28
- "sha256": "c7e00eae9d46dddf040999f0f2832d08110f093c7a403aaaaaa18d8830213967"
32
+ "url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:11543d157b589acdf9de93133a68fa32aa00372b574a64c40292aead20f6f6cb",
33
+ "sha256": "11543d157b589acdf9de93133a68fa32aa00372b574a64c40292aead20f6f6cb"
29
34
  }
30
35
  }
31
36
  }
@@ -43,20 +48,20 @@
43
48
  "macOS": "10.15.7"
44
49
  },
45
50
  "big_sur": {
46
- "HOMEBREW_VERSION": "3.2.10-50-ge3f851d",
51
+ "HOMEBREW_VERSION": "3.2.17",
47
52
  "HOMEBREW_PREFIX": "/opt/homebrew",
48
- "Homebrew/homebrew-core": "73588fb5f5edccfe62f1b290a3298b402fbd71d5",
49
- "CLT": "12.5.1.0.1.1623191612",
53
+ "Homebrew/homebrew-core": "d975bb4c6f50e8cafd6df9fc7f2ebf04d22ffa41",
54
+ "CLT": "13.0.0.0.1.1630607135",
50
55
  "Xcode": "13.0",
51
- "macOS": "11.5.2"
56
+ "macOS": "11.6"
52
57
  },
53
58
  "monterey": {
54
- "HOMEBREW_VERSION": "3.2.13-55-ga6959e4",
55
- "HOMEBREW_PREFIX": "/usr/local",
56
- "Homebrew/homebrew-core": "3fb109275770551bba03c7055d75ceec2c38b1b2",
57
- "CLT": "13.0.0.0.1.1628499445",
58
- "Xcode": "13.0",
59
- "macOS": "12.0"
59
+ "HOMEBREW_VERSION": "3.3.4-45-gf1121fc",
60
+ "HOMEBREW_PREFIX": "/opt/homebrew",
61
+ "Homebrew/homebrew-core": "1a81a8d5115937649ea67e238c9b8cb94a571592",
62
+ "CLT": "13.1.0.0.1.1633545042",
63
+ "Xcode": "13.1",
64
+ "macOS": "12.0.1"
60
65
  }
61
66
  }
62
67
  }
@@ -1,4 +1,5 @@
1
1
  require 'shellwords'
2
+ require 'tmpdir'
2
3
  require 'fileutils'
3
4
  require 'credentials_manager/account_manager'
4
5
 
@@ -148,6 +149,17 @@ module FastlaneCore
148
149
  end
149
150
  end
150
151
 
152
+ def file_upload_option(source)
153
+ ext = File.extname(source).downcase
154
+ is_asset_file_type = !File.directory?(source) && [".ipa", ".pkg", ".dmg", ".zip"].include?(ext)
155
+
156
+ if is_asset_file_type
157
+ return "-assetFile #{source.shellescape}"
158
+ else
159
+ return "-f #{source.shellescape}"
160
+ end
161
+ end
162
+
151
163
  def additional_upload_parameters
152
164
  # As Apple recommends in Transporter User Guide we shouldn't specify the -t transport parameter
153
165
  # and instead allow Transporter to use automatic transport discovery
@@ -177,7 +189,7 @@ module FastlaneCore
177
189
  ("-u #{username.shellescape}" unless use_jwt),
178
190
  ("-p #{shell_escaped_password(password)}" unless use_jwt),
179
191
  ("-jwt #{jwt}" if use_jwt),
180
- "-f \"#{source}\"",
192
+ file_upload_option(source),
181
193
  additional_upload_parameters, # that's here, because the user might overwrite the -t option
182
194
  "-k 100000",
183
195
  ("-WONoPause true" if Helper.windows?), # Windows only: process instantly returns instead of waiting for key press
@@ -261,7 +273,7 @@ module FastlaneCore
261
273
  ("-u #{username.shellescape}" unless use_jwt),
262
274
  ("-p @env:ITMS_TRANSPORTER_PASSWORD" unless use_jwt),
263
275
  ("-jwt #{jwt}" if use_jwt),
264
- "-f #{source.shellescape}",
276
+ file_upload_option(source),
265
277
  additional_upload_parameters, # that's here, because the user might overwrite the -t option
266
278
  '-k 100000',
267
279
  ("-itc_provider #{provider_short_name}" if jwt.nil? && !provider_short_name.to_s.empty?),
@@ -282,7 +294,7 @@ module FastlaneCore
282
294
  ("-u #{username.shellescape}" unless use_jwt),
283
295
  ("-p #{password.shellescape}" unless use_jwt),
284
296
  ("-jwt #{jwt}" if use_jwt),
285
- "-f #{source.shellescape}",
297
+ file_upload_option(source),
286
298
  additional_upload_parameters, # that's here, because the user might overwrite the -t option
287
299
  '-k 100000',
288
300
  ("-itc_provider #{provider_short_name}" if jwt.nil? && !provider_short_name.to_s.empty?),
@@ -472,12 +484,31 @@ module FastlaneCore
472
484
  # @param app_id [Integer] The unique App ID
473
485
  # @param dir [String] the path in which the package file is located
474
486
  # @param package_path [String] the path to the package file (used instead of app_id and dir)
487
+ # @param asset_path [String] the path to the ipa/dmg/pkg file (used instead of package_path if running on macOS)
475
488
  # @return (Bool) True if everything worked fine
476
489
  # @raise [Deliver::TransporterTransferError] when something went wrong
477
490
  # when transferring
478
- def upload(app_id = nil, dir = nil, package_path: nil)
479
- raise "app_id and dir are required or package_path is required" if (app_id.nil? || dir.nil?) && package_path.nil?
480
- actual_dir = package_path || File.join(dir, "#{app_id}.itmsp")
491
+ def upload(app_id = nil, dir = nil, package_path: nil, asset_path: nil)
492
+ raise "app_id and dir are required or package_path or asset_path is required" if (app_id.nil? || dir.nil?) && package_path.nil? && asset_path.nil?
493
+
494
+ # Transport can upload .ipa, .dmg, and .pkg files directly with -assetFile
495
+ # However, -assetFile requires -assetDescription if Linux or Windows
496
+ # This will give the asset directly if macOS and asset_path exists
497
+ # otherwise it will use the .itmsp package
498
+
499
+ force_itmsp = FastlaneCore::Env.truthy?("ITMSTRANSPORTER_FORCE_ITMS_PACKAGE_UPLOAD")
500
+ can_use_asset_path = Helper.is_mac? && asset_path
501
+
502
+ actual_dir = if can_use_asset_path && !force_itmsp
503
+ # The asset gets deleted upon completion so copying to a temp directory
504
+ tmp_asset_path = File.join(Dir.tmpdir, File.basename(asset_path))
505
+ FileUtils.cp(asset_path, tmp_asset_path)
506
+ tmp_asset_path
507
+ elsif package_path
508
+ package_path
509
+ else
510
+ File.join(dir, "#{app_id}.itmsp")
511
+ end
481
512
 
482
513
  UI.message("Going to upload updated app to App Store Connect")
483
514
  UI.success("This might take a few minutes. Please don't interrupt the script.")
@@ -492,7 +523,7 @@ module FastlaneCore
492
523
  result = @transporter_executor.execute(command, ItunesTransporter.hide_transporter_output?)
493
524
  rescue TransporterRequiresApplicationSpecificPasswordError => ex
494
525
  handle_two_step_failure(ex)
495
- return upload(app_id, dir, package_path: package_path)
526
+ return upload(app_id, dir, package_path: package_path, asset_path: asset_path)
496
527
  end
497
528
 
498
529
  if result
@@ -467,26 +467,24 @@ module Frameit
467
467
  # Get matching trim box:
468
468
  trim_box = trim_boxes[key]
469
469
 
470
- # For side-by-side text images (e.g. stack_title is false) adjust the trim box based on top_vertical_trim_offset and bottom_vertical_trim_offset to maintain the text baseline:
471
- unless stack_title
472
- # Determine the trim area by maintaining the same vertical top offset based on the smallest value from all trim boxes (top_vertical_trim_offset).
473
- # When the vertical top offset is larger than the smallest vertical top offset, the trim box needs to be adjusted:
474
- if trim_box.offset_y > top_vertical_trim_offset
475
- # Increase the height of the trim box with the difference in vertical top offset:
476
- trim_box.height += trim_box.offset_y - top_vertical_trim_offset
477
- # Change the vertical top offset to match that of the others:
478
- trim_box.offset_y = top_vertical_trim_offset
479
-
480
- UI.verbose("Trim box for key \"#{key}\" is adjusted to align top: #{trim_box}\n")
481
- end
470
+ # Adjust the trim box based on top_vertical_trim_offset and bottom_vertical_trim_offset to maintain the text baseline:
471
+ # Determine the trim area by maintaining the same vertical top offset based on the smallest value from all trim boxes (top_vertical_trim_offset).
472
+ # When the vertical top offset is larger than the smallest vertical top offset, the trim box needs to be adjusted:
473
+ if trim_box.offset_y > top_vertical_trim_offset
474
+ # Increase the height of the trim box with the difference in vertical top offset:
475
+ trim_box.height += trim_box.offset_y - top_vertical_trim_offset
476
+ # Change the vertical top offset to match that of the others:
477
+ trim_box.offset_y = top_vertical_trim_offset
478
+
479
+ UI.verbose("Trim box for key \"#{key}\" is adjusted to align top: #{trim_box.json_string_format}")
480
+ end
482
481
 
483
- # Check if the height needs to be adjusted to reach the bottom offset:
484
- if (trim_box.offset_y + trim_box.height) < bottom_vertical_trim_offset
485
- # Set the height of the trim box to the difference between vertical bottom and top offset:
486
- trim_box.height = bottom_vertical_trim_offset - trim_box.offset_y
482
+ # Check if the height needs to be adjusted to reach the bottom offset:
483
+ if (trim_box.offset_y + trim_box.height) < bottom_vertical_trim_offset
484
+ # Set the height of the trim box to the difference between vertical bottom and top offset:
485
+ trim_box.height = bottom_vertical_trim_offset - trim_box.offset_y
487
486
 
488
- UI.verbose("Trim box for key \"#{key}\" is adjusted to align bottom: #{trim_box}\n")
489
- end
487
+ UI.verbose("Trim box for key \"#{key}\" is adjusted to align bottom: #{trim_box.json_string_format}")
490
488
  end
491
489
 
492
490
  # Crop image with (adjusted) trim box parameters in MiniMagick string format:
@@ -31,5 +31,11 @@ module Frameit
31
31
  # Convert trim box parameters to string with syntax: "<width>x<height>+<offset_x>+<offset_y>":
32
32
  return "#{@width}x#{@height}+#{@offset_x}+#{@offset_y}"
33
33
  end
34
+
35
+ # Get the trimbox parameters in a human readable JSON string format
36
+ def json_string_format
37
+ # Create a JSON string from the trim box parameters:
38
+ return "{\"width\" : #{@width}, \"height\" : #{@height} , \"offset_x\" : #{@offset_x}, \"offset_y\" : #{@offset_y}}"
39
+ end
34
40
  end
35
41
  end
@@ -7,7 +7,7 @@ module Gym
7
7
  class << self
8
8
  def generate
9
9
  parts = prefix
10
- parts << "xcodebuild"
10
+ parts << Gym.config[:xcodebuild_command]
11
11
  parts += options
12
12
  parts += buildactions
13
13
  parts += setting
@@ -275,6 +275,12 @@ module Gym
275
275
  optional: true,
276
276
  type: Boolean,
277
277
  default_value: false),
278
+ FastlaneCore::ConfigItem.new(key: :xcodebuild_command,
279
+ env_name: "GYM_XCODE_BUILD_COMMAND",
280
+ description: "Allows for override of the default `xcodebuild` command",
281
+ type: String,
282
+ optional: true,
283
+ default_value: "xcodebuild"),
278
284
  FastlaneCore::ConfigItem.new(key: :cloned_source_packages_path,
279
285
  env_name: "GYM_CLONED_SOURCE_PACKAGES_PATH",
280
286
  description: "Sets a custom path for Swift Package Manager dependencies",
@@ -9,7 +9,11 @@ require_relative 'module'
9
9
  require_relative 'storage'
10
10
  require_relative 'encryption'
11
11
 
12
+ require 'tempfile'
13
+ require 'base64'
14
+
12
15
  module Match
16
+ # rubocop:disable Metrics/ClassLength
13
17
  class Nuke
14
18
  attr_accessor :params
15
19
  attr_accessor :type
@@ -67,6 +71,7 @@ module Match
67
71
  title: "Summary for match nuke #{Fastlane::VERSION}")
68
72
 
69
73
  prepare_list
74
+ filter_by_cert
70
75
  print_tables
71
76
 
72
77
  if params[:readonly]
@@ -139,7 +144,7 @@ module Match
139
144
  types = profile_types(prov_type)
140
145
  # Filtering on 'profileType' seems to be undocumented as of 2020-07-30
141
146
  # but works on both web session and official API
142
- self.profiles += Spaceship::ConnectAPI::Profile.all(filter: { profileType: types.join(",") })
147
+ self.profiles += Spaceship::ConnectAPI::Profile.all(filter: { profileType: types.join(",") }, includes: "certificates")
143
148
  end
144
149
 
145
150
  # Gets the main and additional cert types
@@ -173,6 +178,78 @@ module Match
173
178
  self.files = certs + keys + profiles
174
179
  end
175
180
 
181
+ def filter_by_cert
182
+ # Force will continue to revoke and delete all certificates and profiles
183
+ return if self.params[:force] || !UI.interactive?
184
+ return if self.certs.count < 2
185
+
186
+ # Print table showing certificates that can be revoked
187
+ puts("")
188
+ rows = self.certs.each_with_index.collect do |cert, i|
189
+ cert_expiration = cert.expiration_date.nil? ? "Unknown" : Time.parse(cert.expiration_date).strftime("%Y-%m-%d")
190
+ [i + 1, cert.name, cert.id, cert.class.to_s.split("::").last, cert_expiration]
191
+ end
192
+ puts(Terminal::Table.new({
193
+ title: "Certificates that can be revoked".green,
194
+ headings: ["Option", "Name", "ID", "Type", "Expires"],
195
+ rows: FastlaneCore::PrintTable.transform_output(rows)
196
+ }))
197
+ puts("")
198
+
199
+ UI.important("By default, all listed certificates and profiles will be nuked")
200
+ if UI.confirm("Do you want to only nuke specific certificates and their associated profiles?")
201
+ input_indexes = UI.input("Enter the \"Option\" number(s) from the table above? (comma-separated)").split(',')
202
+
203
+ # Get certificates from option indexes
204
+ self.certs = input_indexes.map do |index|
205
+ self.certs[index.to_i - 1]
206
+ end.compact
207
+
208
+ if self.certs.empty?
209
+ UI.user_error!("No certificates were selected based on option number(s) entered")
210
+ end
211
+
212
+ # Do profile selection logic
213
+ cert_ids = self.certs.map(&:id)
214
+ self.profiles = self.profiles.select do |profile|
215
+ profile_cert_ids = profile.certificates.map(&:id)
216
+ (cert_ids & profile_cert_ids).any?
217
+ end
218
+
219
+ # Do file selection logic
220
+ self.files = self.files.select do |f|
221
+ found = false
222
+
223
+ ext = File.extname(f)
224
+ filename = File.basename(f, ".*")
225
+
226
+ # Attempt to find cert based on filename
227
+ if ext == ".cer" || ext == ".p12"
228
+ found ||= self.certs.any? do |cert|
229
+ filename == cert.id.to_s
230
+ end
231
+ end
232
+
233
+ # Attempt to find profile matched on UUIDs in profile
234
+ if ext == ".mobileprovision" || ext == ".provisionprofile"
235
+ storage_uuid = FastlaneCore::ProvisioningProfile.uuid(f)
236
+
237
+ found ||= self.profiles.any? do |profile|
238
+ tmp_file = Tempfile.new
239
+ tmp_file.write(Base64.decode64(profile.profile_content))
240
+ tmp_file.close
241
+
242
+ # Compare profile uuid in storage to profile uuid on developer portal
243
+ portal_uuid = FastlaneCore::ProvisioningProfile.uuid(tmp_file.path)
244
+ storage_uuid == portal_uuid
245
+ end
246
+ end
247
+
248
+ found
249
+ end
250
+ end
251
+ end
252
+
176
253
  # Print tables to ask the user
177
254
  def print_tables
178
255
  puts("")
@@ -351,4 +428,5 @@ module Match
351
428
  end
352
429
  end
353
430
  end
431
+ # rubocop:disable Metrics/ClassLength
354
432
  end
@@ -70,6 +70,7 @@ module Match
70
70
  UI.error("for the user #{username}")
71
71
  UI.error("Make sure to use the same user and team every time you run 'match' for this")
72
72
  UI.error("Git repository. This might be caused by revoking the certificate on the Dev Portal")
73
+ UI.error("If missing certificate is a Developer ID Installer, you may need to auth with Apple ID instead of App Store API Key")
73
74
  UI.user_error!("To reset the certificates of your Apple account, you can use the `fastlane match nuke` feature, more information on https://docs.fastlane.tools/actions/match/")
74
75
  end
75
76
 
@@ -18,7 +18,13 @@ module PEM
18
18
 
19
19
  if existing_certificate
20
20
  remaining_days = (existing_certificate.expires - Time.now) / 60 / 60 / 24
21
- UI.message("Existing push notification profile for '#{existing_certificate.owner_name}' is valid for #{remaining_days.round} more days.")
21
+
22
+ display_platform = ''
23
+ unless PEM.config[:website_push]
24
+ display_platform = "#{PEM.config[:platform]} "
25
+ end
26
+
27
+ UI.message("Existing #{display_platform}push notification profile for '#{existing_certificate.owner_name}' is valid for #{remaining_days.round} more days.")
22
28
  if remaining_days > PEM.config[:active_days_limit]
23
29
  if PEM.config[:force]
24
30
  UI.success("You already have an existing push certificate, but a new one will be created since the --force option has been set.")
@@ -59,7 +65,7 @@ module PEM
59
65
 
60
66
  x509_certificate = cert.download
61
67
 
62
- filename_base = PEM.config[:pem_name] || "#{certificate_type}_#{PEM.config[:app_identifier]}"
68
+ filename_base = PEM.config[:pem_name] || "#{certificate_type}_#{PEM.config[:app_identifier]}_#{PEM.config[:platform]}"
63
69
  filename_base = File.basename(filename_base, ".pem") # strip off the .pem if it was provided.
64
70
 
65
71
  output_path = File.expand_path(PEM.config[:output_path])
@@ -73,7 +79,8 @@ module PEM
73
79
 
74
80
  if PEM.config[:generate_p12]
75
81
  p12_cert_path = File.join(output_path, "#{filename_base}.p12")
76
- p12 = OpenSSL::PKCS12.create(PEM.config[:p12_password], certificate_type, pkey, x509_certificate)
82
+ p12_password = PEM.config[:p12_password] == "" ? nil : PEM.config[:p12_password]
83
+ p12 = OpenSSL::PKCS12.create(p12_password, certificate_type, pkey, x509_certificate)
77
84
  File.write(p12_cert_path, p12.to_der)
78
85
  UI.message("p12 certificate: ".green + Pathname.new(p12_cert_path).realpath.to_s)
79
86
  end
@@ -85,12 +92,29 @@ module PEM
85
92
  end
86
93
 
87
94
  def certificate
88
- if PEM.config[:development]
89
- Spaceship.certificate.development_push
90
- elsif PEM.config[:website_push]
95
+ if PEM.config[:website_push]
91
96
  Spaceship.certificate.website_push
92
97
  else
93
- Spaceship.certificate.production_push
98
+ platform = PEM.config[:platform]
99
+ UI.user_error!('platform parameter is unspecified.') unless platform
100
+
101
+ case platform
102
+ when 'ios'
103
+ if PEM.config[:development]
104
+ Spaceship.certificate.development_push
105
+ else
106
+ Spaceship.certificate.production_push
107
+ end
108
+ when 'macos'
109
+ if PEM.config[:development]
110
+ Spaceship.certificate.mac_development_push
111
+ else
112
+ Spaceship.certificate.mac_production_push
113
+ end
114
+ else
115
+ UI.user_error!("Unsupported platform '#{platform}'. Supported platforms for development and production certificates are 'ios' & 'macos'")
116
+ end
117
+
94
118
  end
95
119
  end
96
120
 
@@ -1,5 +1,6 @@
1
1
  require 'fastlane_core/configuration/config_item'
2
2
  require 'credentials_manager/appfile_config'
3
+ require 'fastlane/helper/lane_helper'
3
4
 
4
5
  require_relative 'module'
5
6
 
@@ -10,6 +11,14 @@ module PEM
10
11
  user ||= CredentialsManager::AppfileConfig.try_fetch_value(:apple_id)
11
12
 
12
13
  [
14
+ FastlaneCore::ConfigItem.new(key: :platform,
15
+ description: "Set certificate's platform. Used for creation of production & development certificates. Supported platforms: ios, macos",
16
+ short_option: "-m",
17
+ env_name: "PEM_PLATFORM",
18
+ default_value: "ios",
19
+ verify_block: proc do |value|
20
+ UI.user_error!("The platform can only be ios or macos") unless ['ios', 'macos'].include?(value)
21
+ end),
13
22
  FastlaneCore::ConfigItem.new(key: :development,
14
23
  env_name: "PEM_DEVELOPMENT",
15
24
  description: "Renew the development push certificate instead of the production one",
@@ -86,7 +95,7 @@ module PEM
86
95
  env_name: "PEM_P12_PASSWORD",
87
96
  sensitive: true,
88
97
  description: "The password that is used for your p12 file",
89
- default_value: ""),
98
+ optional: true),
90
99
  FastlaneCore::ConfigItem.new(key: :pem_name,
91
100
  short_option: "-o",
92
101
  env_name: "PEM_FILE_NAME",
@@ -38,7 +38,7 @@ module Pilot
38
38
  end
39
39
 
40
40
  transporter = transporter_for_selected_team(options)
41
- result = transporter.upload(package_path: package_path)
41
+ result = transporter.upload(package_path: package_path, asset_path: options[:ipa] || options[:pkg])
42
42
 
43
43
  unless result
44
44
  transporter_errors = transporter.displayable_errors
@@ -226,7 +226,7 @@ module Scan
226
226
  FileUtils.cp(xctestrun_file, output_path)
227
227
  UI.message("Successfully copied xctestrun file: #{output_path}")
228
228
  else
229
- UI.user_error!("Could not find .xctextrun file to copy")
229
+ UI.user_error!("Could not find .xctestrun file to copy")
230
230
  end
231
231
  end
232
232
 
@@ -105,7 +105,7 @@ module Screengrab
105
105
  FastlaneCore::ConfigItem.new(key: :tests_apk_path,
106
106
  env_name: 'SCREENGRAB_TESTS_APK_PATH',
107
107
  optional: true,
108
- description: "The path to the APK for the the tests bundle",
108
+ description: "The path to the APK for the tests bundle",
109
109
  short_option: "-b",
110
110
  code_gen_sensitive: true,
111
111
  default_value: Dir[File.join("app", "build", "outputs", "apk", "app-debug-androidTest-unaligned.apk")].last,
@@ -128,7 +128,7 @@ module Screengrab
128
128
  end),
129
129
  FastlaneCore::ConfigItem.new(key: :exit_on_test_failure,
130
130
  env_name: 'EXIT_ON_TEST_FAILURE',
131
- description: "Whether or not to exit Screengrab on test failure. Exiting on failure will not copy sceenshots to local machine nor open sceenshots summary",
131
+ description: "Whether or not to exit Screengrab on test failure. Exiting on failure will not copy screenshots to local machine nor open screenshots summary",
132
132
  default_value: true,
133
133
  type: Boolean),
134
134
  FastlaneCore::ConfigItem.new(key: :reinstall_app,
@@ -80,6 +80,9 @@
80
80
  #
81
81
  # new features June 2021
82
82
  # 1. fix the way app entitlements are extracted
83
+ #
84
+ # new features October 2021
85
+ # 1. change codesign signatue to use --generate-entitlement-der to include DER encoded entitlements
83
86
 
84
87
  # Logging functions
85
88
 
@@ -546,7 +549,7 @@ function resign {
546
549
  do
547
550
  if [[ "$assetpack" == *.assetpack ]]; then
548
551
  rm -rf $assetpack/_CodeSignature
549
- /usr/bin/codesign ${VERBOSE} ${KEYCHAIN_FLAG} -f -s "$CERTIFICATE" "$assetpack"
552
+ /usr/bin/codesign ${VERBOSE} --generate-entitlement-der ${KEYCHAIN_FLAG} -f -s "$CERTIFICATE" "$assetpack"
550
553
  checkStatus
551
554
  else
552
555
  log "Ignoring non-assetpack: $assetpack"
@@ -568,7 +571,7 @@ function resign {
568
571
  log "Resigning '$framework'"
569
572
  # Must not qote KEYCHAIN_FLAG because it needs to be unwrapped and passed to codesign with spaces
570
573
  # shellcheck disable=SC2086
571
- /usr/bin/codesign ${VERBOSE} ${KEYCHAIN_FLAG} -f -s "$CERTIFICATE" "$framework"
574
+ /usr/bin/codesign ${VERBOSE} --generate-entitlement-der ${KEYCHAIN_FLAG} -f -s "$CERTIFICATE" "$framework"
572
575
  checkStatus
573
576
  else
574
577
  log "Ignoring non-framework: $framework"
@@ -622,7 +625,7 @@ function resign {
622
625
  log "Creating an archived-expanded-entitlements.xcent file for Xcode 9 builds or earlier"
623
626
  cp -f "$ENTITLEMENTS" "$APP_PATH/archived-expanded-entitlements.xcent"
624
627
  fi
625
- /usr/bin/codesign ${VERBOSE} -f -s "$CERTIFICATE" --entitlements "$ENTITLEMENTS" "$APP_PATH"
628
+ /usr/bin/codesign ${VERBOSE} --generate-entitlement-der -f -s "$CERTIFICATE" --entitlements "$ENTITLEMENTS" "$APP_PATH"
626
629
  checkStatus
627
630
  elif [[ -n "${USE_APP_ENTITLEMENTS}" ]]; then
628
631
  # Extract entitlements from provisioning profile and from the app binary
@@ -867,7 +870,7 @@ function resign {
867
870
  log "Creating an archived-expanded-entitlements.xcent file for Xcode 9 builds or earlier"
868
871
  cp -f "$PATCHED_ENTITLEMENTS" "$APP_PATH/archived-expanded-entitlements.xcent"
869
872
  fi
870
- /usr/bin/codesign ${VERBOSE} -f -s "$CERTIFICATE" --entitlements "$PATCHED_ENTITLEMENTS" "$APP_PATH"
873
+ /usr/bin/codesign ${VERBOSE} --generate-entitlement-der -f -s "$CERTIFICATE" --entitlements "$PATCHED_ENTITLEMENTS" "$APP_PATH"
871
874
  checkStatus
872
875
  else
873
876
  log "Extracting entitlements from provisioning profile"
@@ -881,7 +884,7 @@ function resign {
881
884
  fi
882
885
  # Must not qote KEYCHAIN_FLAG because it needs to be unwrapped and passed to codesign with spaces
883
886
  # shellcheck disable=SC2086
884
- /usr/bin/codesign ${VERBOSE} ${KEYCHAIN_FLAG} -f -s "$CERTIFICATE" --entitlements "$TEMP_DIR/newEntitlements" "$APP_PATH"
887
+ /usr/bin/codesign ${VERBOSE} --generate-entitlement-der ${KEYCHAIN_FLAG} -f -s "$CERTIFICATE" --entitlements "$TEMP_DIR/newEntitlements" "$APP_PATH"
885
888
  checkStatus
886
889
  fi
887
890
 
@@ -84,6 +84,10 @@ module Snapshot
84
84
  {
85
85
  # snapshot in Xcode 9 saves screenshots with the SIMULATOR_DEVICE_NAME
86
86
  # which includes spaces
87
+ 'iPhone 13 Pro Max' => "iPhone 13 Pro Max",
88
+ 'iPhone 13 Pro' => "iPhone 13 Pro",
89
+ 'iPhone 13 mini' => "iPhone 13 mini",
90
+ 'iPhone 13' => "iPhone 13",
87
91
  'iPhone 12 Pro Max' => "iPhone 12 Pro Max",
88
92
  'iPhone 12 Pro' => "iPhone 12 Pro",
89
93
  'iPhone 12 mini' => "iPhone 12 mini",
@@ -113,6 +117,10 @@ module Snapshot
113
117
  'iPad Air' => 'iPad Air',
114
118
  'iPad (5th generation)' => 'iPad (5th generation)',
115
119
  'iPad (7th generation)' => 'iPad (7th generation)',
120
+ 'iPad mini 2' => 'iPad mini 2',
121
+ 'iPad mini 3' => 'iPad mini 3',
122
+ 'iPad mini 4' => 'iPad mini 4',
123
+ 'iPad mini (6th generation)' => 'iPad mini (6th generation)',
116
124
  'iPad Pro (9.7-inch)' => 'iPad Pro (9.7-inch)',
117
125
  'iPad Pro (9.7 inch)' => 'iPad Pro (9.7-inch)', # iOS 10.3.1 simulator
118
126
  'iPad Pro (10.5-inch)' => 'iPad Pro (10.5-inch)',