fastlane 2.197.0 → 2.200.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/README.md +72 -72
  4. data/cert/lib/cert/runner.rb +5 -2
  5. data/deliver/lib/deliver/app_screenshot.rb +8 -0
  6. data/deliver/lib/deliver/app_screenshot_iterator.rb +1 -1
  7. data/deliver/lib/deliver/runner.rb +1 -1
  8. data/fastlane/lib/.DS_Store +0 -0
  9. data/fastlane/lib/fastlane/.DS_Store +0 -0
  10. data/fastlane/lib/fastlane/actions/.DS_Store +0 -0
  11. data/fastlane/lib/fastlane/actions/download_dsyms.rb +26 -27
  12. data/fastlane/lib/fastlane/actions/ensure_xcode_version.rb +1 -1
  13. data/fastlane/lib/fastlane/actions/get_push_certificate.rb +1 -1
  14. data/fastlane/lib/fastlane/actions/get_version_number.rb +7 -2
  15. data/fastlane/lib/fastlane/actions/notarize.rb +29 -11
  16. data/fastlane/lib/fastlane/actions/set_github_release.rb +11 -5
  17. data/fastlane/lib/fastlane/actions/update_code_signing_settings.rb +18 -1
  18. data/fastlane/lib/fastlane/actions/xcversion.rb +18 -3
  19. data/fastlane/lib/fastlane/documentation/docs_generator.rb +17 -12
  20. data/fastlane/lib/fastlane/version.rb +1 -1
  21. data/fastlane/swift/Actions.swift +1 -1
  22. data/fastlane/swift/Appfile.swift +1 -1
  23. data/fastlane/swift/ArgumentProcessor.swift +1 -1
  24. data/fastlane/swift/ControlCommand.swift +1 -1
  25. data/fastlane/swift/Deliverfile.swift +2 -2
  26. data/fastlane/swift/DeliverfileProtocol.swift +2 -2
  27. data/fastlane/swift/Fastlane.swift +65 -20
  28. data/fastlane/swift/Gymfile.swift +2 -2
  29. data/fastlane/swift/GymfileProtocol.swift +6 -2
  30. data/fastlane/swift/LaneFileProtocol.swift +1 -1
  31. data/fastlane/swift/MainProcess.swift +1 -1
  32. data/fastlane/swift/Matchfile.swift +2 -2
  33. data/fastlane/swift/MatchfileProtocol.swift +2 -2
  34. data/fastlane/swift/OptionalConfigValue.swift +1 -1
  35. data/fastlane/swift/Plugins.swift +1 -1
  36. data/fastlane/swift/Precheckfile.swift +2 -2
  37. data/fastlane/swift/PrecheckfileProtocol.swift +2 -2
  38. data/fastlane/swift/RubyCommand.swift +1 -1
  39. data/fastlane/swift/RubyCommandable.swift +1 -1
  40. data/fastlane/swift/Runner.swift +4 -8
  41. data/fastlane/swift/RunnerArgument.swift +1 -1
  42. data/fastlane/swift/Scanfile.swift +2 -2
  43. data/fastlane/swift/ScanfileProtocol.swift +4 -4
  44. data/fastlane/swift/Screengrabfile.swift +2 -2
  45. data/fastlane/swift/ScreengrabfileProtocol.swift +2 -2
  46. data/fastlane/swift/Snapshotfile.swift +2 -2
  47. data/fastlane/swift/SnapshotfileProtocol.swift +2 -2
  48. data/fastlane/swift/SocketClient.swift +1 -1
  49. data/fastlane/swift/SocketClientDelegateProtocol.swift +1 -1
  50. data/fastlane/swift/SocketResponse.swift +1 -1
  51. data/fastlane/swift/formatting/Brewfile.lock.json +23 -18
  52. data/fastlane/swift/main.swift +1 -1
  53. data/fastlane_core/lib/fastlane_core/ipa_file_analyser.rb +10 -5
  54. data/fastlane_core/lib/fastlane_core/itunes_transporter.rb +41 -7
  55. data/gym/lib/gym/generators/build_command_generator.rb +2 -2
  56. data/gym/lib/gym/options.rb +6 -0
  57. data/match/lib/match/nuke.rb +79 -1
  58. data/match/lib/match/spaceship_ensure.rb +1 -0
  59. data/pem/lib/pem/manager.rb +29 -6
  60. data/pem/lib/pem/options.rb +9 -0
  61. data/pilot/lib/pilot/build_manager.rb +1 -1
  62. data/scan/lib/scan/options.rb +2 -2
  63. data/scan/lib/scan/runner.rb +2 -2
  64. data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb +1 -1
  65. data/spaceship/lib/spaceship/client.rb +35 -15
  66. data/spaceship/lib/spaceship/commands_generator.rb +1 -1
  67. data/spaceship/lib/spaceship/connect_api/models/app.rb +43 -0
  68. data/spaceship/lib/spaceship/connect_api/models/app_info.rb +1 -0
  69. data/spaceship/lib/spaceship/connect_api/models/app_screenshot_set.rb +2 -0
  70. data/spaceship/lib/spaceship/connect_api/models/certificate.rb +3 -0
  71. data/spaceship/lib/spaceship/connect_api/models/review_submission.rb +73 -0
  72. data/spaceship/lib/spaceship/connect_api/models/review_submission_item.rb +40 -0
  73. data/spaceship/lib/spaceship/connect_api/response.rb +13 -0
  74. data/spaceship/lib/spaceship/connect_api/tunes/tunes.rb +83 -0
  75. data/spaceship/lib/spaceship/connect_api.rb +2 -0
  76. data/spaceship/lib/spaceship/globals.rb +9 -0
  77. data/spaceship/lib/spaceship/spaceauth_runner.rb +1 -1
  78. data/supply/lib/supply/options.rb +8 -0
  79. data/supply/lib/supply/uploader.rb +6 -2
  80. data/trainer/lib/.DS_Store +0 -0
  81. metadata +25 -19
  82. data/spaceship/lib/spaceship/connect_api/models/.build.rb.swp +0 -0
@@ -1,5 +1,5 @@
1
1
  // Scanfile.swift
2
- // Copyright (c) 2021 FastlaneTools
2
+ // Copyright (c) 2022 FastlaneTools
3
3
 
4
4
  // This class is automatically included in FastlaneRunner during build
5
5
 
@@ -17,4 +17,4 @@ public class Scanfile: ScanfileProtocol {
17
17
  // during the `init` process, and you won't see this message
18
18
  }
19
19
 
20
- // Generated with fastlane 2.197.0
20
+ // Generated with fastlane 2.200.0
@@ -1,5 +1,5 @@
1
1
  // ScanfileProtocol.swift
2
- // Copyright (c) 2021 FastlaneTools
2
+ // Copyright (c) 2022 FastlaneTools
3
3
 
4
4
  public protocol ScanfileProtocol: class {
5
5
  /// Path to the workspace file
@@ -14,10 +14,10 @@ public protocol ScanfileProtocol: class {
14
14
  /// The project's scheme. Make sure it's marked as `Shared`
15
15
  var scheme: String? { get }
16
16
 
17
- /// The name of the simulator type you want to run tests on (e.g. 'iPhone 6')
17
+ /// The name of the simulator type you want to run tests on (e.g. 'iPhone 6' or 'iPhone SE (2nd generation) (14.5)')
18
18
  var device: String? { get }
19
19
 
20
- /// Array of devices to run the tests on (e.g. ['iPhone 6', 'iPad Air'])
20
+ /// Array of devices to run the tests on (e.g. ['iPhone 6', 'iPad Air', 'iPhone SE (2nd generation) (14.5)'])
21
21
  var devices: [String]? { get }
22
22
 
23
23
  /// Should skip auto detecting of devices if none were specified
@@ -296,4 +296,4 @@ public extension ScanfileProtocol {
296
296
 
297
297
  // Please don't remove the lines below
298
298
  // They are used to detect outdated files
299
- // FastlaneRunnerAPIVersion [0.9.94]
299
+ // FastlaneRunnerAPIVersion [0.9.98]
@@ -1,5 +1,5 @@
1
1
  // Screengrabfile.swift
2
- // Copyright (c) 2021 FastlaneTools
2
+ // Copyright (c) 2022 FastlaneTools
3
3
 
4
4
  // This class is automatically included in FastlaneRunner during build
5
5
 
@@ -17,4 +17,4 @@ public class Screengrabfile: ScreengrabfileProtocol {
17
17
  // during the `init` process, and you won't see this message
18
18
  }
19
19
 
20
- // Generated with fastlane 2.197.0
20
+ // Generated with fastlane 2.200.0
@@ -1,5 +1,5 @@
1
1
  // ScreengrabfileProtocol.swift
2
- // Copyright (c) 2021 FastlaneTools
2
+ // Copyright (c) 2022 FastlaneTools
3
3
 
4
4
  public protocol ScreengrabfileProtocol: class {
5
5
  /// Path to the root of your Android SDK installation, e.g. ~/tools/android-sdk-macosx
@@ -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.84]
99
+ // FastlaneRunnerAPIVersion [0.9.88]
@@ -1,5 +1,5 @@
1
1
  // Snapshotfile.swift
2
- // Copyright (c) 2021 FastlaneTools
2
+ // Copyright (c) 2022 FastlaneTools
3
3
 
4
4
  // This class is automatically included in FastlaneRunner during build
5
5
 
@@ -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.197.0
20
+ // Generated with fastlane 2.200.0
@@ -1,5 +1,5 @@
1
1
  // SnapshotfileProtocol.swift
2
- // Copyright (c) 2021 FastlaneTools
2
+ // Copyright (c) 2022 FastlaneTools
3
3
 
4
4
  public protocol SnapshotfileProtocol: class {
5
5
  /// Path the workspace file
@@ -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.78]
203
+ // FastlaneRunnerAPIVersion [0.9.82]
@@ -1,5 +1,5 @@
1
1
  // SocketClient.swift
2
- // Copyright (c) 2021 FastlaneTools
2
+ // Copyright (c) 2022 FastlaneTools
3
3
 
4
4
  //
5
5
  // ** NOTE **
@@ -1,5 +1,5 @@
1
1
  // SocketClientDelegateProtocol.swift
2
- // Copyright (c) 2021 FastlaneTools
2
+ // Copyright (c) 2022 FastlaneTools
3
3
 
4
4
  //
5
5
  // ** NOTE **
@@ -1,5 +1,5 @@
1
1
  // SocketResponse.swift
2
- // Copyright (c) 2021 FastlaneTools
2
+ // Copyright (c) 2022 FastlaneTools
3
3
 
4
4
  //
5
5
  // ** NOTE **
@@ -2,30 +2,35 @@
2
2
  "entries": {
3
3
  "brew": {
4
4
  "swiftformat": {
5
- "version": "0.48.17",
5
+ "version": "0.49.1",
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:c43caffb4d2cf9546b0a8fa732ffe5d95b1b1fd7ab03f1c5da39c8e7a0e8ecb4",
13
+ "sha256": "c43caffb4d2cf9546b0a8fa732ffe5d95b1b1fd7ab03f1c5da39c8e7a0e8ecb4"
14
+ },
10
15
  "arm64_big_sur": {
11
16
  "cellar": ":any_skip_relocation",
12
- "url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:e19dbc72ddf213203e940708f3de6d9ca9c88663b5176494d04b4c418e16954f",
13
- "sha256": "e19dbc72ddf213203e940708f3de6d9ca9c88663b5176494d04b4c418e16954f"
17
+ "url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:ad0ce5fc15fe1d339d366ece18694fdc1d14021684462a126ed20b537a1a9bf5",
18
+ "sha256": "ad0ce5fc15fe1d339d366ece18694fdc1d14021684462a126ed20b537a1a9bf5"
14
19
  },
15
- "big_sur": {
20
+ "monterey": {
16
21
  "cellar": ":any_skip_relocation",
17
- "url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:90056a4e3b03ef31cecfb5b9e278a44bea2abecdd26a202d00bc390dfbbeb352",
18
- "sha256": "90056a4e3b03ef31cecfb5b9e278a44bea2abecdd26a202d00bc390dfbbeb352"
22
+ "url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:33652b8015d31dbe45e00bdc598f1b228cb63c7083b90137fdec66318a88010f",
23
+ "sha256": "33652b8015d31dbe45e00bdc598f1b228cb63c7083b90137fdec66318a88010f"
19
24
  },
20
- "catalina": {
25
+ "big_sur": {
21
26
  "cellar": ":any_skip_relocation",
22
- "url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:9647fdbfed2e7e2361974a5bfb99be4a112d914bd3e582afb4cdf7dc81e44cbf",
23
- "sha256": "9647fdbfed2e7e2361974a5bfb99be4a112d914bd3e582afb4cdf7dc81e44cbf"
27
+ "url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:f0ad88e5594a6a3e5a35834a9a22473a05511375942dbb046d1085cc537d60b8",
28
+ "sha256": "f0ad88e5594a6a3e5a35834a9a22473a05511375942dbb046d1085cc537d60b8"
24
29
  },
25
- "mojave": {
30
+ "catalina": {
26
31
  "cellar": ":any_skip_relocation",
27
- "url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:83231c218cca811795688e175d88ac4584d1c424566926f9d6ed36e9dbdfed75",
28
- "sha256": "83231c218cca811795688e175d88ac4584d1c424566926f9d6ed36e9dbdfed75"
32
+ "url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:564f5daf9cd82407843aed590bd4190f3e5aaa73a30b3bc8ae07135f1319ac97",
33
+ "sha256": "564f5daf9cd82407843aed590bd4190f3e5aaa73a30b3bc8ae07135f1319ac97"
29
34
  }
30
35
  }
31
36
  }
@@ -51,12 +56,12 @@
51
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.10-21-g3ba6afb",
60
+ "HOMEBREW_PREFIX": "/opt/homebrew",
61
+ "Homebrew/homebrew-core": "54f307bcd04cec374c7fd3f22fe7e6b13f1ad783",
62
+ "CLT": "13.1.0.0.1.1633545042",
63
+ "Xcode": "13.2.1",
64
+ "macOS": "12.0.1"
60
65
  }
61
66
  }
62
67
  }
@@ -1,5 +1,5 @@
1
1
  // main.swift
2
- // Copyright (c) 2021 FastlaneTools
2
+ // Copyright (c) 2022 FastlaneTools
3
3
 
4
4
  //
5
5
  // ** NOTE **
@@ -73,12 +73,17 @@ module FastlaneCore
73
73
  end
74
74
 
75
75
  def self.fetch_info_plist_with_unzip(path)
76
- list, error, = Open3.capture3("unzip", "-Z", "-1", path)
76
+ entry, error, = Open3.capture3("unzip", "-Z", "-1", path, "*Payload/*.app/Info.plist")
77
+
78
+ # unzip can return multiple Info.plist files if is an embedded app bundle (a WatchKit app)
79
+ # - ContainsWatchApp/Payload/Sample.app/Watch/Sample WatchKit App.app/Info.plist
80
+ # - ContainsWatchApp/Payload/Sample.app/Info.plist
81
+ #
82
+ # we can determine the main Info.plist by the shortest path
83
+ entry = entry.lines.map(&:chomp).min_by(&:size)
84
+
77
85
  UI.command_output(error) unless error.empty?
78
- return nil if list.empty?
79
- entry = list.chomp.split("\n").find do |e|
80
- File.fnmatch("**/Payload/*.app/Info.plist", e, File::FNM_PATHNAME)
81
- end
86
+ return nil if entry.nil? || entry.empty?
82
87
  data, error, = Open3.capture3("unzip", "-p", path, entry)
83
88
  UI.command_output(error) unless error.empty?
84
89
  return nil if data.empty?
@@ -1,6 +1,8 @@
1
1
  require 'shellwords'
2
+ require 'tmpdir'
2
3
  require 'fileutils'
3
4
  require 'credentials_manager/account_manager'
5
+ require 'securerandom'
4
6
 
5
7
  require_relative 'features'
6
8
  require_relative 'helper'
@@ -148,6 +150,17 @@ module FastlaneCore
148
150
  end
149
151
  end
150
152
 
153
+ def file_upload_option(source)
154
+ ext = File.extname(source).downcase
155
+ is_asset_file_type = !File.directory?(source) && [".ipa", ".pkg", ".dmg", ".zip"].include?(ext)
156
+
157
+ if is_asset_file_type
158
+ return "-assetFile #{source.shellescape}"
159
+ else
160
+ return "-f #{source.shellescape}"
161
+ end
162
+ end
163
+
151
164
  def additional_upload_parameters
152
165
  # As Apple recommends in Transporter User Guide we shouldn't specify the -t transport parameter
153
166
  # and instead allow Transporter to use automatic transport discovery
@@ -177,7 +190,7 @@ module FastlaneCore
177
190
  ("-u #{username.shellescape}" unless use_jwt),
178
191
  ("-p #{shell_escaped_password(password)}" unless use_jwt),
179
192
  ("-jwt #{jwt}" if use_jwt),
180
- "-f \"#{source}\"",
193
+ file_upload_option(source),
181
194
  additional_upload_parameters, # that's here, because the user might overwrite the -t option
182
195
  "-k 100000",
183
196
  ("-WONoPause true" if Helper.windows?), # Windows only: process instantly returns instead of waiting for key press
@@ -261,7 +274,7 @@ module FastlaneCore
261
274
  ("-u #{username.shellescape}" unless use_jwt),
262
275
  ("-p @env:ITMS_TRANSPORTER_PASSWORD" unless use_jwt),
263
276
  ("-jwt #{jwt}" if use_jwt),
264
- "-f #{source.shellescape}",
277
+ file_upload_option(source),
265
278
  additional_upload_parameters, # that's here, because the user might overwrite the -t option
266
279
  '-k 100000',
267
280
  ("-itc_provider #{provider_short_name}" if jwt.nil? && !provider_short_name.to_s.empty?),
@@ -282,7 +295,7 @@ module FastlaneCore
282
295
  ("-u #{username.shellescape}" unless use_jwt),
283
296
  ("-p #{password.shellescape}" unless use_jwt),
284
297
  ("-jwt #{jwt}" if use_jwt),
285
- "-f #{source.shellescape}",
298
+ file_upload_option(source),
286
299
  additional_upload_parameters, # that's here, because the user might overwrite the -t option
287
300
  '-k 100000',
288
301
  ("-itc_provider #{provider_short_name}" if jwt.nil? && !provider_short_name.to_s.empty?),
@@ -472,12 +485,33 @@ module FastlaneCore
472
485
  # @param app_id [Integer] The unique App ID
473
486
  # @param dir [String] the path in which the package file is located
474
487
  # @param package_path [String] the path to the package file (used instead of app_id and dir)
488
+ # @param asset_path [String] the path to the ipa/dmg/pkg file (used instead of package_path if running on macOS)
475
489
  # @return (Bool) True if everything worked fine
476
490
  # @raise [Deliver::TransporterTransferError] when something went wrong
477
491
  # 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")
492
+ def upload(app_id = nil, dir = nil, package_path: nil, asset_path: nil)
493
+ 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?
494
+
495
+ # Transport can upload .ipa, .dmg, and .pkg files directly with -assetFile
496
+ # However, -assetFile requires -assetDescription if Linux or Windows
497
+ # This will give the asset directly if macOS and asset_path exists
498
+ # otherwise it will use the .itmsp package
499
+
500
+ force_itmsp = FastlaneCore::Env.truthy?("ITMSTRANSPORTER_FORCE_ITMS_PACKAGE_UPLOAD")
501
+ can_use_asset_path = Helper.is_mac? && asset_path
502
+
503
+ actual_dir = if can_use_asset_path && !force_itmsp
504
+ # The asset gets deleted upon completion so copying to a temp directory
505
+ # (with randomized filename, for multibyte-mixed filename upload fails)
506
+ new_file_name = "#{SecureRandom.uuid}#{File.extname(asset_path)}"
507
+ tmp_asset_path = File.join(Dir.tmpdir, new_file_name)
508
+ FileUtils.cp(asset_path, tmp_asset_path)
509
+ tmp_asset_path
510
+ elsif package_path
511
+ package_path
512
+ else
513
+ File.join(dir, "#{app_id}.itmsp")
514
+ end
481
515
 
482
516
  UI.message("Going to upload updated app to App Store Connect")
483
517
  UI.success("This might take a few minutes. Please don't interrupt the script.")
@@ -492,7 +526,7 @@ module FastlaneCore
492
526
  result = @transporter_executor.execute(command, ItunesTransporter.hide_transporter_output?)
493
527
  rescue TransporterRequiresApplicationSpecificPasswordError => ex
494
528
  handle_two_step_failure(ex)
495
- return upload(app_id, dir, package_path: package_path)
529
+ return upload(app_id, dir, package_path: package_path, asset_path: asset_path)
496
530
  end
497
531
 
498
532
  if result
@@ -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
@@ -43,7 +43,7 @@ module Gym
43
43
  options << "-scmProvider system"
44
44
  end
45
45
  options << config[:xcargs] if config[:xcargs]
46
- options << "OTHER_SWIFT_FLAGS=\"-Xfrontend -debug-time-function-bodies\"" if config[:analyze_build_time]
46
+ options << "OTHER_SWIFT_FLAGS=\"\\\$(value) -Xfrontend -debug-time-function-bodies\"" if config[:analyze_build_time]
47
47
 
48
48
  options
49
49
  end
@@ -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])
@@ -86,12 +92,29 @@ module PEM
86
92
  end
87
93
 
88
94
  def certificate
89
- if PEM.config[:development]
90
- Spaceship.certificate.development_push
91
- elsif PEM.config[:website_push]
95
+ if PEM.config[:website_push]
92
96
  Spaceship.certificate.website_push
93
97
  else
94
- 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
+
95
118
  end
96
119
  end
97
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",
@@ -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
@@ -60,7 +60,7 @@ module Scan
60
60
  optional: true,
61
61
  is_string: true,
62
62
  env_name: "SCAN_DEVICE",
63
- description: "The name of the simulator type you want to run tests on (e.g. 'iPhone 6')",
63
+ description: "The name of the simulator type you want to run tests on (e.g. 'iPhone 6' or 'iPhone SE (2nd generation) (14.5)')",
64
64
  conflicting_options: [:devices],
65
65
  conflict_block: proc do |value|
66
66
  UI.user_error!("You can't use 'device' and 'devices' options in one run")
@@ -70,7 +70,7 @@ module Scan
70
70
  is_string: false,
71
71
  env_name: "SCAN_DEVICES",
72
72
  type: Array,
73
- description: "Array of devices to run the tests on (e.g. ['iPhone 6', 'iPad Air'])",
73
+ description: "Array of devices to run the tests on (e.g. ['iPhone 6', 'iPad Air', 'iPhone SE (2nd generation) (14.5)'])",
74
74
  conflicting_options: [:device],
75
75
  conflict_block: proc do |value|
76
76
  UI.user_error!("You can't use 'device' and 'devices' options in one run")
@@ -126,7 +126,7 @@ module Scan
126
126
 
127
127
  test_cases = suite.split(":\n").fetch(1, []).split("\n").each
128
128
  .select { |line| line.match?(/^\s+/) }
129
- .map { |line| line.strip.gsub(".", "/").gsub("()", "") }
129
+ .map { |line| line.strip.gsub(/[\s\.]/, "/").gsub(/[\-\[\]\(\)]/, "") }
130
130
  .map { |line| suite_name + "/" + line }
131
131
 
132
132
  retryable_tests += test_cases
@@ -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
 
@@ -123,7 +123,7 @@ module Snapshot
123
123
  # Simulator could stil be booting with Apple logo
124
124
  # Need to wait "some amount of time" until home screen shows
125
125
  boot_sleep = ENV["SNAPSHOT_SIMULATOR_WAIT_FOR_BOOT_TIMEOUT"].to_i || 10
126
- UI.message("Waiting #{boot_sleep} seconds for device to fully boot before overriding status bar... Set 'SNAPSHOT_SIMULATOR_WAIT_FOR_BOOT_TIMEOUT' environemnt variable to adjust timeout")
126
+ UI.message("Waiting #{boot_sleep} seconds for device to fully boot before overriding status bar... Set 'SNAPSHOT_SIMULATOR_WAIT_FOR_BOOT_TIMEOUT' environment variable to adjust timeout")
127
127
  sleep(boot_sleep) if boot_sleep > 0
128
128
 
129
129
  UI.message("Overriding Status Bar")