fastlane 2.155.3 → 2.157.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +78 -78
  3. data/deliver/lib/deliver.rb +1 -0
  4. data/deliver/lib/deliver/app_screenshot_iterator.rb +95 -0
  5. data/deliver/lib/deliver/detect_values.rb +4 -1
  6. data/deliver/lib/deliver/languages.rb +7 -0
  7. data/deliver/lib/deliver/loader.rb +4 -5
  8. data/deliver/lib/deliver/queue_worker.rb +64 -0
  9. data/deliver/lib/deliver/runner.rb +7 -5
  10. data/deliver/lib/deliver/upload_screenshots.rb +143 -128
  11. data/fastlane/lib/fastlane/actions/app_store_connect_api_key.rb +120 -0
  12. data/fastlane/lib/fastlane/actions/commit_version_bump.rb +1 -1
  13. data/fastlane/lib/fastlane/actions/docs/upload_to_play_store.md +2 -0
  14. data/fastlane/lib/fastlane/actions/docs/upload_to_testflight.md +17 -1
  15. data/fastlane/lib/fastlane/actions/set_changelog.rb +2 -2
  16. data/fastlane/lib/fastlane/actions/sonar.rb +5 -0
  17. data/fastlane/lib/fastlane/actions/spaceship_stats.rb +73 -0
  18. data/fastlane/lib/fastlane/actions/upload_to_testflight.rb +4 -0
  19. data/fastlane/lib/fastlane/version.rb +1 -1
  20. data/fastlane/swift/Deliverfile.swift +1 -1
  21. data/fastlane/swift/DeliverfileProtocol.swift +1 -1
  22. data/fastlane/swift/Fastlane.swift +67 -7
  23. data/fastlane/swift/Gymfile.swift +1 -1
  24. data/fastlane/swift/GymfileProtocol.swift +1 -1
  25. data/fastlane/swift/Matchfile.swift +1 -1
  26. data/fastlane/swift/MatchfileProtocol.swift +1 -1
  27. data/fastlane/swift/Precheckfile.swift +1 -1
  28. data/fastlane/swift/PrecheckfileProtocol.swift +1 -1
  29. data/fastlane/swift/Scanfile.swift +1 -1
  30. data/fastlane/swift/ScanfileProtocol.swift +1 -1
  31. data/fastlane/swift/Screengrabfile.swift +1 -1
  32. data/fastlane/swift/ScreengrabfileProtocol.swift +1 -1
  33. data/fastlane/swift/Snapshotfile.swift +1 -1
  34. data/fastlane/swift/SnapshotfileProtocol.swift +1 -1
  35. data/fastlane_core/lib/fastlane_core/command_executor.rb +1 -0
  36. data/fastlane_core/lib/fastlane_core/itunes_transporter.rb +71 -42
  37. data/fastlane_core/lib/fastlane_core/project.rb +1 -0
  38. data/gym/lib/gym/error_handler.rb +1 -1
  39. data/gym/lib/gym/generators/build_command_generator.rb +0 -1
  40. data/pilot/lib/pilot/build_manager.rb +18 -4
  41. data/pilot/lib/pilot/manager.rb +16 -5
  42. data/pilot/lib/pilot/options.rb +16 -0
  43. data/produce/lib/produce/itunes_connect.rb +2 -2
  44. data/scan/lib/scan/test_command_generator.rb +3 -1
  45. data/screengrab/lib/screengrab/runner.rb +36 -17
  46. data/sigh/lib/sigh/runner.rb +4 -4
  47. data/snapshot/lib/snapshot/test_command_generator_base.rb +3 -1
  48. data/spaceship/lib/spaceship.rb +4 -0
  49. data/spaceship/lib/spaceship/client.rb +2 -0
  50. data/spaceship/lib/spaceship/connect_api.rb +0 -15
  51. data/spaceship/lib/spaceship/connect_api/api_client.rb +270 -0
  52. data/spaceship/lib/spaceship/connect_api/client.rb +144 -213
  53. data/spaceship/lib/spaceship/connect_api/provisioning/client.rb +8 -17
  54. data/spaceship/lib/spaceship/connect_api/provisioning/provisioning.rb +75 -64
  55. data/spaceship/lib/spaceship/connect_api/spaceship.rb +98 -0
  56. data/spaceship/lib/spaceship/connect_api/testflight/client.rb +8 -17
  57. data/spaceship/lib/spaceship/connect_api/testflight/testflight.rb +288 -277
  58. data/spaceship/lib/spaceship/connect_api/token.rb +46 -5
  59. data/spaceship/lib/spaceship/connect_api/token_refresh_middleware.rb +24 -0
  60. data/spaceship/lib/spaceship/connect_api/tunes/client.rb +8 -17
  61. data/spaceship/lib/spaceship/connect_api/tunes/tunes.rb +717 -706
  62. data/spaceship/lib/spaceship/connect_api/users/client.rb +8 -17
  63. data/spaceship/lib/spaceship/connect_api/users/users.rb +28 -17
  64. data/spaceship/lib/spaceship/stats_middleware.rb +65 -0
  65. metadata +26 -23
  66. data/match/lib/match/.options.rb.swp +0 -0
  67. data/match/lib/match/.runner.rb.swp +0 -0
  68. data/sigh/lib/sigh/.options.rb.swp +0 -0
  69. data/sigh/lib/sigh/.runner.rb.swp +0 -0
  70. data/spaceship/lib/spaceship/connect_api/models/.profile.rb.swp +0 -0
  71. data/spaceship/lib/spaceship/connect_api/provisioning/.provisioning.rb.swp +0 -0
@@ -220,7 +220,7 @@ module Fastlane
220
220
  'commit_version_bump',
221
221
  'commit_version_bump(
222
222
  message: "Version Bump", # create a commit with a custom message
223
- xcodeproj: "./path/to/MyProject.xcodeproj", # optional, if you have multiple Xcode project files, you must specify your main project here
223
+ xcodeproj: "./path/to/MyProject.xcodeproj" # optional, if you have multiple Xcode project files, you must specify your main project here
224
224
  )',
225
225
  'commit_version_bump(
226
226
  settings: true # Include Settings.bundle/Root.plist
@@ -49,6 +49,8 @@ The previous p12 configuration is still currently supported.
49
49
 
50
50
  ## Quick Start
51
51
 
52
+ > Before using _supply_ to connect to Google Play Store, you'll need to set up your app manually first by uploading at least one build to Google Play Store. See [fastane/fastlane#14686](https://github.com/fastlane/fastlane/issues/14686) for more info.
53
+
52
54
  - `cd [your_project_folder]`
53
55
  - `fastlane supply init`
54
56
  - Make changes to the downloaded metadata, add images, screenshots and/or an APK
@@ -26,7 +26,23 @@ _pilot_ uses [spaceship.airforce](https://spaceship.airforce) to interact with A
26
26
 
27
27
  # Usage
28
28
 
29
- For all commands you can specify the Apple ID to use using `-u felix@krausefx.com`. If you execute _pilot_ in a project already using [_fastlane_](https://fastlane.tools) the username and app identifier will automatically be determined.
29
+ For all commands, you can either use an [API Key](#app-store-connect-api-key) or your [Apple ID](#apple-id).
30
+
31
+ ### App Store Connect API Key
32
+
33
+ The App Store Connect API Key is the preferred authentication method (if you are able to use it).
34
+
35
+ - Uses offial App Store Connect API
36
+ - No need for 2FA
37
+ - Better performance over Apple ID
38
+
39
+ Specify the API key using `--api_key_path ./path/to/api_key_info.json` or `--api_key "{\"key_id\": \"D83848D23\", \"issuer_id\": \"227b0bbf-ada8-458c-9d62-3d8022b7d07f\", \"key_filepath\": \"D83848D23.p8\"}"`
40
+
41
+ Go to [Using App Store Connect API](/app-store-connect-api) for information on obtaining an API key, the _fastlane_ `api_key_info.json` format, and other API key usage.
42
+
43
+ ### Apple ID
44
+
45
+ Specify the Apple ID to use using `-u felix@krausefx.com`. If you execute _pilot_ in a project already using [_fastlane_](https://fastlane.tools) the username and app identifier will automatically be determined.
30
46
 
31
47
  ## Uploading builds
32
48
 
@@ -5,8 +5,8 @@ module Fastlane
5
5
  require 'spaceship'
6
6
 
7
7
  UI.message("Login to App Store Connect (#{params[:username]})")
8
- Spaceship::Tunes.login(params[:username])
9
- Spaceship::Tunes.select_team
8
+ Spaceship::ConnectAPI.login(params[:username], use_portal: false, use_tunes: true)
9
+ Spaceship::ConnectAPI.select_team
10
10
  UI.message("Login successful")
11
11
 
12
12
  app = Spaceship::ConnectAPI::App.find(params[:app_identifier])
@@ -16,6 +16,7 @@ module Fastlane
16
16
  sonar_scanner_args << "-Dsonar.projectName=\"#{params[:project_name]}\"" if params[:project_name]
17
17
  sonar_scanner_args << "-Dsonar.projectVersion=\"#{params[:project_version]}\"" if params[:project_version]
18
18
  sonar_scanner_args << "-Dsonar.sources=\"#{params[:sources_path]}\"" if params[:sources_path]
19
+ sonar_scanner_args << "-Dsonar.exclusions=\"#{params[:exclusions]}\"" if params[:exclusions]
19
20
  sonar_scanner_args << "-Dsonar.language=\"#{params[:project_language]}\"" if params[:project_language]
20
21
  sonar_scanner_args << "-Dsonar.sourceEncoding=\"#{params[:source_encoding]}\"" if params[:source_encoding]
21
22
  sonar_scanner_args << "-Dsonar.login=\"#{params[:sonar_login]}\"" if params[:sonar_login]
@@ -81,6 +82,10 @@ module Fastlane
81
82
  env_name: "FL_SONAR_RUNNER_SOURCES_PATH",
82
83
  description: "Comma-separated paths to directories containing source files. Must either be specified here or inside the sonar project configuration file",
83
84
  optional: true),
85
+ FastlaneCore::ConfigItem.new(key: :exclusions,
86
+ env_name: "FL_SONAR_RUNNER_EXCLUSIONS",
87
+ description: "Comma-separated paths to directories to be excluded from the analysis",
88
+ optional: true),
84
89
  FastlaneCore::ConfigItem.new(key: :project_language,
85
90
  env_name: "FL_SONAR_RUNNER_PROJECT_LANGUAGE",
86
91
  description: "Language key, e.g. objc",
@@ -0,0 +1,73 @@
1
+ module Fastlane
2
+ module Actions
3
+ class SpaceshipStatsAction < Action
4
+ def self.run(params)
5
+ require 'fastlane_core/print_table'
6
+ require 'spaceship'
7
+
8
+ rows = []
9
+ Spaceship::StatsMiddleware.service_stats.each do |service, count|
10
+ rows << [service.name, service.auth_type, service.url, count]
11
+ end
12
+
13
+ puts("")
14
+ puts(Terminal::Table.new(
15
+ title: "Spaceship Stats",
16
+ headings: ["Service", "Auth Type", "URL", "Number of requests"],
17
+ rows: FastlaneCore::PrintTable.transform_output(rows)
18
+ ))
19
+ puts("")
20
+
21
+ if params[:print_request_logs]
22
+ log_rows = []
23
+ Spaceship::StatsMiddleware.request_logs.each do |request_log|
24
+ log_rows << [request_log.auth_type, request_log.url]
25
+ end
26
+
27
+ puts("")
28
+ puts(Terminal::Table.new(
29
+ title: "Spaceship Request Log",
30
+ headings: ["Auth Type", "URL"],
31
+ rows: FastlaneCore::PrintTable.transform_output(log_rows)
32
+ ))
33
+ puts("")
34
+ end
35
+ end
36
+
37
+ def self.url_name(url_prefix)
38
+ Spaceship::StatsMiddleware::URL_PREFIXES[url_prefix]
39
+ end
40
+
41
+ def self.description
42
+ "Print out Spaceship stats from this session (number of request to each domain)"
43
+ end
44
+
45
+ def self.is_supported?(platform)
46
+ true
47
+ end
48
+
49
+ def self.available_options
50
+ [
51
+ FastlaneCore::ConfigItem.new(key: :print_request_logs,
52
+ description: "Print all URLs requested",
53
+ type: Boolean,
54
+ default_value: false)
55
+ ]
56
+ end
57
+
58
+ def self.example_code
59
+ [
60
+ 'spaceship_stats'
61
+ ]
62
+ end
63
+
64
+ def self.category
65
+ :misc
66
+ end
67
+
68
+ def self.author
69
+ "joshdholtz"
70
+ end
71
+ end
72
+ end
73
+ end
@@ -15,6 +15,10 @@ module Fastlane
15
15
  values[:ipa] = File.expand_path(values[:ipa]) if values[:ipa]
16
16
  end
17
17
 
18
+ if values[:api_key_path].nil?
19
+ values[:api_key] ||= Actions.lane_context[SharedValues::APP_STORE_CONNECT_API_KEY]
20
+ end
21
+
18
22
  return values if Helper.test?
19
23
 
20
24
  if distribute_only
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
- VERSION = '2.155.3'.freeze
2
+ VERSION = '2.157.2'.freeze
3
3
  DESCRIPTION = "The easiest way to automate beta deployments and releases for your iOS and Android apps".freeze
4
4
  MINIMUM_XCODE_RELEASE = "7.0".freeze
5
5
  RUBOCOP_REQUIREMENT = '0.49.1'.freeze
@@ -14,4 +14,4 @@ class Deliverfile: DeliverfileProtocol {
14
14
  // during the `init` process, and you won't see this message
15
15
  }
16
16
 
17
- // Generated with fastlane 2.155.3
17
+ // Generated with fastlane 2.157.2
@@ -245,4 +245,4 @@ extension DeliverfileProtocol {
245
245
 
246
246
  // Please don't remove the lines below
247
247
  // They are used to detect outdated files
248
- // FastlaneRunnerAPIVersion [0.9.32]
248
+ // FastlaneRunnerAPIVersion [0.9.37]
@@ -127,6 +127,35 @@ func appStoreBuildNumber(initialBuildNumber: Any,
127
127
  _ = runner.executeCommand(command)
128
128
  }
129
129
 
130
+ /**
131
+ Load the App Store Connect API token to use in other fastlane tools and actions
132
+
133
+ - parameters:
134
+ - keyId: The key ID
135
+ - issuerId: The issuer ID
136
+ - keyFilepath: The path to the key p8 file
137
+ - keyContent: The content of the key p8 file
138
+ - duration: The token session duration
139
+ - inHouse: Is App Store or Enterprise (in house) team? App Store Connect API cannot not determine this on its own (yet)
140
+
141
+ Load the App Store Connect API token to use in other fastlane tools and actions
142
+ */
143
+ func appStoreConnectApiKey(keyId: String,
144
+ issuerId: String,
145
+ keyFilepath: String? = nil,
146
+ keyContent: String? = nil,
147
+ duration: Int? = nil,
148
+ inHouse: Bool? = nil)
149
+ {
150
+ let command = RubyCommand(commandID: "", methodName: "app_store_connect_api_key", className: nil, args: [RubyCommand.Argument(name: "key_id", value: keyId),
151
+ RubyCommand.Argument(name: "issuer_id", value: issuerId),
152
+ RubyCommand.Argument(name: "key_filepath", value: keyFilepath),
153
+ RubyCommand.Argument(name: "key_content", value: keyContent),
154
+ RubyCommand.Argument(name: "duration", value: duration),
155
+ RubyCommand.Argument(name: "in_house", value: inHouse)])
156
+ _ = runner.executeCommand(command)
157
+ }
158
+
130
159
  /**
131
160
  Upload your app to [Appaloosa Store](https://www.appaloosa-store.com/)
132
161
 
@@ -5149,6 +5178,8 @@ func pem(development: Bool = false,
5149
5178
  Alias for the `upload_to_testflight` action
5150
5179
 
5151
5180
  - parameters:
5181
+ - apiKeyPath: Path to your App Store Connect API key JSON file
5182
+ - apiKey: Path to your App Store Connect API key JSON file
5152
5183
  - username: Your Apple ID Username
5153
5184
  - appIdentifier: The bundle identifier of the app to upload or manage testers (optional)
5154
5185
  - appPlatform: The platform to use (optional)
@@ -5187,7 +5218,9 @@ func pem(development: Bool = false,
5187
5218
  More details can be found on https://docs.fastlane.tools/actions/pilot/.
5188
5219
  This integration will only do the TestFlight upload.
5189
5220
  */
5190
- func pilot(username: String,
5221
+ func pilot(apiKeyPath: String? = nil,
5222
+ apiKey: [String: Any]? = nil,
5223
+ username: String,
5191
5224
  appIdentifier: String? = nil,
5192
5225
  appPlatform: String = "ios",
5193
5226
  appleId: String? = nil,
@@ -5222,7 +5255,9 @@ func pilot(username: String,
5222
5255
  waitForUploadedBuild: Bool = false,
5223
5256
  rejectBuildWaitingForReview: Bool = false)
5224
5257
  {
5225
- let command = RubyCommand(commandID: "", methodName: "pilot", className: nil, args: [RubyCommand.Argument(name: "username", value: username),
5258
+ let command = RubyCommand(commandID: "", methodName: "pilot", className: nil, args: [RubyCommand.Argument(name: "api_key_path", value: apiKeyPath),
5259
+ RubyCommand.Argument(name: "api_key", value: apiKey),
5260
+ RubyCommand.Argument(name: "username", value: username),
5226
5261
  RubyCommand.Argument(name: "app_identifier", value: appIdentifier),
5227
5262
  RubyCommand.Argument(name: "app_platform", value: appPlatform),
5228
5263
  RubyCommand.Argument(name: "apple_id", value: appleId),
@@ -7157,6 +7192,7 @@ func snapshot(workspace: Any? = snapshotfile.workspace,
7157
7192
  - projectName: The name of the project that gets displayed on the sonar report page. Must either be specified here or inside the sonar project configuration file
7158
7193
  - projectVersion: The project's version that gets displayed on the sonar report page. Must either be specified here or inside the sonar project configuration file
7159
7194
  - sourcesPath: Comma-separated paths to directories containing source files. Must either be specified here or inside the sonar project configuration file
7195
+ - exclusions: Comma-separated paths to directories to be excluded from the analysis
7160
7196
  - projectLanguage: Language key, e.g. objc
7161
7197
  - sourceEncoding: Used encoding of source files, e.g., UTF-8
7162
7198
  - sonarRunnerArgs: Pass additional arguments to sonar-scanner. Be sure to provide the arguments with a leading `-D` e.g. FL_SONAR_RUNNER_ARGS="-Dsonar.verbose=true"
@@ -7178,6 +7214,7 @@ func sonar(projectConfigurationPath: String? = nil,
7178
7214
  projectName: String? = nil,
7179
7215
  projectVersion: String? = nil,
7180
7216
  sourcesPath: String? = nil,
7217
+ exclusions: String? = nil,
7181
7218
  projectLanguage: String? = nil,
7182
7219
  sourceEncoding: String? = nil,
7183
7220
  sonarRunnerArgs: String? = nil,
@@ -7194,6 +7231,7 @@ func sonar(projectConfigurationPath: String? = nil,
7194
7231
  RubyCommand.Argument(name: "project_name", value: projectName),
7195
7232
  RubyCommand.Argument(name: "project_version", value: projectVersion),
7196
7233
  RubyCommand.Argument(name: "sources_path", value: sourcesPath),
7234
+ RubyCommand.Argument(name: "exclusions", value: exclusions),
7197
7235
  RubyCommand.Argument(name: "project_language", value: projectLanguage),
7198
7236
  RubyCommand.Argument(name: "source_encoding", value: sourceEncoding),
7199
7237
  RubyCommand.Argument(name: "sonar_runner_args", value: sonarRunnerArgs),
@@ -7233,6 +7271,16 @@ func spaceshipLogs(latest: Bool = true,
7233
7271
  _ = runner.executeCommand(command)
7234
7272
  }
7235
7273
 
7274
+ /**
7275
+ Print out Spaceship stats from this session (number of request to each domain)
7276
+
7277
+ - parameter printRequestLogs: Print all URLs requested
7278
+ */
7279
+ func spaceshipStats(printRequestLogs: Bool = false) {
7280
+ let command = RubyCommand(commandID: "", methodName: "spaceship_stats", className: nil, args: [RubyCommand.Argument(name: "print_request_logs", value: printRequestLogs)])
7281
+ _ = runner.executeCommand(command)
7282
+ }
7283
+
7236
7284
  /**
7237
7285
  Upload dSYM file to [Splunk MINT](https://mint.splunk.com/)
7238
7286
 
@@ -7705,6 +7753,8 @@ func testfairy(apiKey: String,
7705
7753
  Alias for the `upload_to_testflight` action
7706
7754
 
7707
7755
  - parameters:
7756
+ - apiKeyPath: Path to your App Store Connect API key JSON file
7757
+ - apiKey: Path to your App Store Connect API key JSON file
7708
7758
  - username: Your Apple ID Username
7709
7759
  - appIdentifier: The bundle identifier of the app to upload or manage testers (optional)
7710
7760
  - appPlatform: The platform to use (optional)
@@ -7743,7 +7793,9 @@ func testfairy(apiKey: String,
7743
7793
  More details can be found on https://docs.fastlane.tools/actions/pilot/.
7744
7794
  This integration will only do the TestFlight upload.
7745
7795
  */
7746
- func testflight(username: String,
7796
+ func testflight(apiKeyPath: String? = nil,
7797
+ apiKey: [String: Any]? = nil,
7798
+ username: String,
7747
7799
  appIdentifier: String? = nil,
7748
7800
  appPlatform: String = "ios",
7749
7801
  appleId: String? = nil,
@@ -7778,7 +7830,9 @@ func testflight(username: String,
7778
7830
  waitForUploadedBuild: Bool = false,
7779
7831
  rejectBuildWaitingForReview: Bool = false)
7780
7832
  {
7781
- let command = RubyCommand(commandID: "", methodName: "testflight", className: nil, args: [RubyCommand.Argument(name: "username", value: username),
7833
+ let command = RubyCommand(commandID: "", methodName: "testflight", className: nil, args: [RubyCommand.Argument(name: "api_key_path", value: apiKeyPath),
7834
+ RubyCommand.Argument(name: "api_key", value: apiKey),
7835
+ RubyCommand.Argument(name: "username", value: username),
7782
7836
  RubyCommand.Argument(name: "app_identifier", value: appIdentifier),
7783
7837
  RubyCommand.Argument(name: "app_platform", value: appPlatform),
7784
7838
  RubyCommand.Argument(name: "apple_id", value: appleId),
@@ -8648,6 +8702,8 @@ func uploadToPlayStoreInternalAppSharing(packageName: String,
8648
8702
  Upload new binary to App Store Connect for TestFlight beta testing (via _pilot_)
8649
8703
 
8650
8704
  - parameters:
8705
+ - apiKeyPath: Path to your App Store Connect API key JSON file
8706
+ - apiKey: Path to your App Store Connect API key JSON file
8651
8707
  - username: Your Apple ID Username
8652
8708
  - appIdentifier: The bundle identifier of the app to upload or manage testers (optional)
8653
8709
  - appPlatform: The platform to use (optional)
@@ -8686,7 +8742,9 @@ func uploadToPlayStoreInternalAppSharing(packageName: String,
8686
8742
  More details can be found on https://docs.fastlane.tools/actions/pilot/.
8687
8743
  This integration will only do the TestFlight upload.
8688
8744
  */
8689
- func uploadToTestflight(username: String,
8745
+ func uploadToTestflight(apiKeyPath: String? = nil,
8746
+ apiKey: [String: Any]? = nil,
8747
+ username: String,
8690
8748
  appIdentifier: String? = nil,
8691
8749
  appPlatform: String = "ios",
8692
8750
  appleId: String? = nil,
@@ -8721,7 +8779,9 @@ func uploadToTestflight(username: String,
8721
8779
  waitForUploadedBuild: Bool = false,
8722
8780
  rejectBuildWaitingForReview: Bool = false)
8723
8781
  {
8724
- let command = RubyCommand(commandID: "", methodName: "upload_to_testflight", className: nil, args: [RubyCommand.Argument(name: "username", value: username),
8782
+ let command = RubyCommand(commandID: "", methodName: "upload_to_testflight", className: nil, args: [RubyCommand.Argument(name: "api_key_path", value: apiKeyPath),
8783
+ RubyCommand.Argument(name: "api_key", value: apiKey),
8784
+ RubyCommand.Argument(name: "username", value: username),
8725
8785
  RubyCommand.Argument(name: "app_identifier", value: appIdentifier),
8726
8786
  RubyCommand.Argument(name: "app_platform", value: appPlatform),
8727
8787
  RubyCommand.Argument(name: "apple_id", value: appleId),
@@ -9204,4 +9264,4 @@ let snapshotfile: Snapshotfile = Snapshotfile()
9204
9264
 
9205
9265
  // Please don't remove the lines below
9206
9266
  // They are used to detect outdated files
9207
- // FastlaneRunnerAPIVersion [0.9.85]
9267
+ // FastlaneRunnerAPIVersion [0.9.90]
@@ -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.155.3
17
+ // Generated with fastlane 2.157.2
@@ -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.35]
184
+ // FastlaneRunnerAPIVersion [0.9.40]
@@ -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.155.3
17
+ // Generated with fastlane 2.157.2
@@ -165,4 +165,4 @@ extension MatchfileProtocol {
165
165
 
166
166
  // Please don't remove the lines below
167
167
  // They are used to detect outdated files
168
- // FastlaneRunnerAPIVersion [0.9.29]
168
+ // FastlaneRunnerAPIVersion [0.9.34]
@@ -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.155.3
17
+ // Generated with fastlane 2.157.2
@@ -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.28]
36
+ // FastlaneRunnerAPIVersion [0.9.33]
@@ -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.155.3
17
+ // Generated with fastlane 2.157.2
@@ -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.40]
260
+ // FastlaneRunnerAPIVersion [0.9.45]
@@ -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.155.3
17
+ // Generated with fastlane 2.157.2
@@ -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.30]
96
+ // FastlaneRunnerAPIVersion [0.9.35]
@@ -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.155.3
17
+ // Generated with fastlane 2.157.2
@@ -181,4 +181,4 @@ extension SnapshotfileProtocol {
181
181
 
182
182
  // Please don't remove the lines below
183
183
  // They are used to detect outdated files
184
- // FastlaneRunnerAPIVersion [0.9.24]
184
+ // FastlaneRunnerAPIVersion [0.9.29]
@@ -52,6 +52,7 @@ module FastlaneCore
52
52
  status = FastlaneCore::FastlanePty.spawn(command) do |command_stdout, command_stdin, pid|
53
53
  command_stdout.each do |l|
54
54
  line = l.chomp
55
+ line = line[1..-1] if line[0] == "\r"
55
56
  output << line
56
57
 
57
58
  next unless print_all
@@ -170,38 +170,44 @@ module FastlaneCore
170
170
 
171
171
  # Generates commands and executes the iTMSTransporter through the shell script it provides by the same name
172
172
  class ShellScriptTransporterExecutor < TransporterExecutor
173
- def build_upload_command(username, password, source = "/tmp", provider_short_name = "")
173
+ def build_upload_command(username, password, source = "/tmp", provider_short_name = "", jwt = nil)
174
+ use_jwt = !jwt.to_s.empty?
174
175
  [
175
176
  '"' + Helper.transporter_path + '"',
176
177
  "-m upload",
177
- "-u #{username.shellescape}",
178
- "-p #{shell_escaped_password(password)}",
178
+ ("-u #{username.shellescape}" unless use_jwt),
179
+ ("-p #{shell_escaped_password(password)}" unless use_jwt),
180
+ ("-jwt #{jwt}" if use_jwt),
179
181
  "-f \"#{source}\"",
180
182
  additional_upload_parameters, # that's here, because the user might overwrite the -t option
181
183
  "-k 100000",
182
184
  ("-WONoPause true" if Helper.windows?), # Windows only: process instantly returns instead of waiting for key press
183
- ("-itc_provider #{provider_short_name}" unless provider_short_name.to_s.empty?)
185
+ ("-itc_provider #{provider_short_name}" if jwt.nil? && !provider_short_name.to_s.empty?)
184
186
  ].compact.join(' ')
185
187
  end
186
188
 
187
- def build_download_command(username, password, apple_id, destination = "/tmp", provider_short_name = "")
189
+ def build_download_command(username, password, apple_id, destination = "/tmp", provider_short_name = "", jwt = nil)
190
+ use_jwt = !jwt.to_s.empty?
188
191
  [
189
192
  '"' + Helper.transporter_path + '"',
190
193
  "-m lookupMetadata",
191
- "-u #{username.shellescape}",
192
- "-p #{shell_escaped_password(password)}",
194
+ ("-u #{username.shellescape}" unless use_jwt),
195
+ ("-p #{shell_escaped_password(password)}" unless use_jwt),
196
+ ("-jwt #{jwt}" if use_jwt),
193
197
  "-apple_id #{apple_id}",
194
198
  "-destination '#{destination}'",
195
- ("-itc_provider #{provider_short_name}" unless provider_short_name.to_s.empty?)
199
+ ("-itc_provider #{provider_short_name}" if jwt.nil? && !provider_short_name.to_s.empty?)
196
200
  ].compact.join(' ')
197
201
  end
198
202
 
199
- def build_provider_ids_command(username, password)
203
+ def build_provider_ids_command(username, password, jwt = nil)
204
+ use_jwt = !jwt.to_s.empty?
200
205
  [
201
206
  '"' + Helper.transporter_path + '"',
202
207
  '-m provider',
203
- "-u \"#{username}\"",
204
- "-p #{shell_escaped_password(password)}"
208
+ ("-u \"#{username.shellescape}\"" unless use_jwt),
209
+ ("-p #{shell_escaped_password(password)}" unless use_jwt),
210
+ ("-jwt #{jwt}" if use_jwt)
205
211
  ].compact.join(' ')
206
212
  end
207
213
 
@@ -246,18 +252,20 @@ module FastlaneCore
246
252
  # Generates commands and executes the iTMSTransporter by invoking its Java app directly, to avoid the crazy parameter
247
253
  # escaping problems in its accompanying shell script.
248
254
  class JavaTransporterExecutor < TransporterExecutor
249
- def build_upload_command(username, password, source = "/tmp", provider_short_name = "")
255
+ def build_upload_command(username, password, source = "/tmp", provider_short_name = "", jwt = nil)
256
+ use_jwt = !jwt.to_s.empty?
250
257
  if Helper.mac? && Helper.xcode_at_least?(11)
251
258
  [
252
- "ITMS_TRANSPORTER_PASSWORD=#{password.shellescape}",
259
+ ("ITMS_TRANSPORTER_PASSWORD=#{password.shellescape}" unless use_jwt),
253
260
  'xcrun iTMSTransporter',
254
261
  '-m upload',
255
- "-u #{username.shellescape}",
256
- "-p @env:ITMS_TRANSPORTER_PASSWORD",
262
+ ("-u #{username.shellescape}" unless use_jwt),
263
+ ("-p @env:ITMS_TRANSPORTER_PASSWORD" unless use_jwt),
264
+ ("-jwt #{jwt}" if use_jwt),
257
265
  "-f #{source.shellescape}",
258
266
  additional_upload_parameters, # that's here, because the user might overwrite the -t option
259
267
  '-k 100000',
260
- ("-itc_provider #{provider_short_name}" unless provider_short_name.to_s.empty?),
268
+ ("-itc_provider #{provider_short_name}" if jwt.nil? && !provider_short_name.to_s.empty?),
261
269
  '2>&1' # cause stderr to be written to stdout
262
270
  ].compact.join(' ') # compact gets rid of the possibly nil ENV value
263
271
  else
@@ -272,28 +280,31 @@ module FastlaneCore
272
280
  '-Dsun.net.http.retryPost=false',
273
281
  java_code_option,
274
282
  '-m upload',
275
- "-u #{username.shellescape}",
276
- "-p #{password.shellescape}",
283
+ ("-u #{username.shellescape}" unless use_jwt),
284
+ ("-p #{password.shellescape}" unless use_jwt),
285
+ ("-jwt #{jwt}" if use_jwt),
277
286
  "-f #{source.shellescape}",
278
287
  additional_upload_parameters, # that's here, because the user might overwrite the -t option
279
288
  '-k 100000',
280
- ("-itc_provider #{provider_short_name}" unless provider_short_name.to_s.empty?),
289
+ ("-itc_provider #{provider_short_name}" if jwt.nil? && !provider_short_name.to_s.empty?),
281
290
  '2>&1' # cause stderr to be written to stdout
282
291
  ].compact.join(' ') # compact gets rid of the possibly nil ENV value
283
292
  end
284
293
  end
285
294
 
286
- def build_download_command(username, password, apple_id, destination = "/tmp", provider_short_name = "")
295
+ def build_download_command(username, password, apple_id, destination = "/tmp", provider_short_name = "", jwt = nil)
296
+ use_jwt = !jwt.to_s.empty?
287
297
  if Helper.mac? && Helper.xcode_at_least?(11)
288
298
  [
289
- "ITMS_TRANSPORTER_PASSWORD=#{password.shellescape}",
299
+ ("ITMS_TRANSPORTER_PASSWORD=#{password.shellescape}" unless use_jwt),
290
300
  'xcrun iTMSTransporter',
291
301
  '-m lookupMetadata',
292
- "-u #{username.shellescape}",
293
- "-p @env:ITMS_TRANSPORTER_PASSWORD",
302
+ ("-u #{username.shellescape}" unless use_jwt),
303
+ ("-p @env:ITMS_TRANSPORTER_PASSWORD" unless use_jwt),
304
+ ("-jwt #{jwt}" if use_jwt),
294
305
  "-apple_id #{apple_id.shellescape}",
295
306
  "-destination #{destination.shellescape}",
296
- ("-itc_provider #{provider_short_name}" unless provider_short_name.to_s.empty?),
307
+ ("-itc_provider #{provider_short_name}" if jwt.nil? && !provider_short_name.to_s.empty?),
297
308
  '2>&1' # cause stderr to be written to stdout
298
309
  ].compact.join(' ')
299
310
  else
@@ -308,24 +319,27 @@ module FastlaneCore
308
319
  '-Dsun.net.http.retryPost=false',
309
320
  java_code_option,
310
321
  '-m lookupMetadata',
311
- "-u #{username.shellescape}",
312
- "-p #{password.shellescape}",
322
+ ("-u #{username.shellescape}" unless use_jwt),
323
+ ("-p #{password.shellescape}" unless use_jwt),
324
+ ("-jwt #{jwt}" if use_jwt),
313
325
  "-apple_id #{apple_id.shellescape}",
314
326
  "-destination #{destination.shellescape}",
315
- ("-itc_provider #{provider_short_name}" unless provider_short_name.to_s.empty?),
327
+ ("-itc_provider #{provider_short_name}" if jwt.nil? && !provider_short_name.to_s.empty?),
316
328
  '2>&1' # cause stderr to be written to stdout
317
329
  ].compact.join(' ')
318
330
  end
319
331
  end
320
332
 
321
- def build_provider_ids_command(username, password)
333
+ def build_provider_ids_command(username, password, jwt = nil)
334
+ use_jwt = !jwt.to_s.empty?
322
335
  if Helper.mac? && Helper.xcode_at_least?(11)
323
336
  [
324
- "ITMS_TRANSPORTER_PASSWORD=#{password.shellescape}",
337
+ ("ITMS_TRANSPORTER_PASSWORD=#{password.shellescape}" unless use_jwt),
325
338
  'xcrun iTMSTransporter',
326
339
  '-m provider',
327
- "-u #{username.shellescape}",
328
- "-p @env:ITMS_TRANSPORTER_PASSWORD",
340
+ ("-u #{username.shellescape}" unless use_jwt),
341
+ ("-p @env:ITMS_TRANSPORTER_PASSWORD" unless use_jwt),
342
+ ("-jwt #{jwt}" if use_jwt),
329
343
  '2>&1' # cause stderr to be written to stdout
330
344
  ].compact.join(' ')
331
345
  else
@@ -340,8 +354,9 @@ module FastlaneCore
340
354
  '-Dsun.net.http.retryPost=false',
341
355
  java_code_option,
342
356
  '-m provider',
343
- "-u #{username.shellescape}",
344
- "-p #{password.shellescape}",
357
+ ("-u #{username.shellescape}" unless use_jwt),
358
+ ("-p #{password.shellescape}" unless use_jwt),
359
+ ("-jwt #{jwt}" if use_jwt),
345
360
  '2>&1' # cause stderr to be written to stdout
346
361
  ].compact.join(' ')
347
362
  end
@@ -399,15 +414,19 @@ module FastlaneCore
399
414
  # see: https://github.com/fastlane/fastlane/issues/1524#issuecomment-196370628
400
415
  # for more information about how to use the iTMSTransporter to list your provider
401
416
  # short names
402
- def initialize(user = nil, password = nil, use_shell_script = false, provider_short_name = nil)
417
+ def initialize(user = nil, password = nil, use_shell_script = false, provider_short_name = nil, jwt = nil)
403
418
  # Xcode 6.x doesn't have the same iTMSTransporter Java setup as later Xcode versions, so
404
419
  # we can't default to using the newer direct Java invocation strategy for those versions.
405
420
  use_shell_script ||= Helper.is_mac? && Helper.xcode_version.start_with?('6.')
406
421
  use_shell_script ||= Helper.windows?
407
422
  use_shell_script ||= Feature.enabled?('FASTLANE_ITUNES_TRANSPORTER_USE_SHELL_SCRIPT')
408
423
 
409
- @user = user
410
- @password = password || load_password_for_transporter
424
+ if jwt.to_s.empty?
425
+ @user = user
426
+ @password = password || load_password_for_transporter
427
+ end
428
+
429
+ @jwt = jwt
411
430
 
412
431
  @transporter_executor = use_shell_script ? ShellScriptTransporterExecutor.new : JavaTransporterExecutor.new
413
432
  @provider_short_name = provider_short_name
@@ -422,9 +441,12 @@ module FastlaneCore
422
441
  def download(app_id, dir = nil)
423
442
  dir ||= "/tmp"
424
443
 
444
+ password_placeholder = @jwt.nil? ? 'YourPassword' : nil
445
+ jwt_placeholder = @jwt.nil? ? nil : 'YourJWT'
446
+
425
447
  UI.message("Going to download app metadata from App Store Connect")
426
- command = @transporter_executor.build_download_command(@user, @password, app_id, dir, @provider_short_name)
427
- UI.verbose(@transporter_executor.build_download_command(@user, 'YourPassword', app_id, dir, @provider_short_name))
448
+ command = @transporter_executor.build_download_command(@user, @password, app_id, dir, @provider_short_name, @jwt)
449
+ UI.verbose(@transporter_executor.build_download_command(@user, password_placeholder, app_id, dir, @provider_short_name, jwt_placeholder))
428
450
 
429
451
  begin
430
452
  result = @transporter_executor.execute(command, ItunesTransporter.hide_transporter_output?)
@@ -459,8 +481,11 @@ module FastlaneCore
459
481
  UI.message("Going to upload updated app to App Store Connect")
460
482
  UI.success("This might take a few minutes. Please don't interrupt the script.")
461
483
 
462
- command = @transporter_executor.build_upload_command(@user, @password, actual_dir, @provider_short_name)
463
- UI.verbose(@transporter_executor.build_upload_command(@user, 'YourPassword', actual_dir, @provider_short_name))
484
+ password_placeholder = @jwt.nil? ? 'YourPassword' : nil
485
+ jwt_placeholder = @jwt.nil? ? nil : 'YourJWT'
486
+
487
+ command = @transporter_executor.build_upload_command(@user, @password, actual_dir, @provider_short_name, @jwt)
488
+ UI.verbose(@transporter_executor.build_upload_command(@user, password_placeholder, actual_dir, @provider_short_name, jwt_placeholder))
464
489
 
465
490
  begin
466
491
  result = @transporter_executor.execute(command, ItunesTransporter.hide_transporter_output?)
@@ -481,8 +506,12 @@ module FastlaneCore
481
506
  end
482
507
 
483
508
  def provider_ids
484
- command = @transporter_executor.build_provider_ids_command(@user, @password)
485
- UI.verbose(@transporter_executor.build_provider_ids_command(@user, 'YourPassword'))
509
+ password_placeholder = @jwt.nil? ? 'YourPassword' : nil
510
+ jwt_placeholder = @jwt.nil? ? nil : 'YourJWT'
511
+
512
+ command = @transporter_executor.build_provider_ids_command(@user, @password, @jwt)
513
+ UI.verbose(@transporter_executor.build_provider_ids_command(@user, password_placeholder, jwt_placeholder))
514
+
486
515
  lines = []
487
516
  begin
488
517
  result = @transporter_executor.execute(command, ItunesTransporter.hide_transporter_output?) { |xs| lines = xs }