fastlane 2.209.1 → 2.210.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5010adae3c5b21d54dd16b6247c5955bbe6c415439de68c08fcabe3845f8b6b7
4
- data.tar.gz: '08149ff32ed120e68c970357b564e8dbcec8d9ddbb9d2e2e1dc2b4ef19819d47'
3
+ metadata.gz: 96b025cf8e8588f53bc82b19c432c61649110eeb8ffdf6ee3302007c13b0b531
4
+ data.tar.gz: f022c9464d0223a0ade4069b8a11a23b59d96bc48f68890f6cef29bb8abbab41
5
5
  SHA512:
6
- metadata.gz: 46821e9b86a08c035d3c95da0b4e11d48617a9d2132a28f6e237f7a7e83bc66512d436ae5497de0277509e1331048741e49ae75e2ba78fea1bbc4d5e5b7a3875
7
- data.tar.gz: 4026c9ae374842f26eff1bdea173c0f3eb80168a0dd286be0053ba7bda3368cf331d27e2df85a4473334ca9f8fe0ea94eea7372606aefc84bcb21c26c38531b7
6
+ metadata.gz: 12cdf289ae833312461ccbfe20b8c3e0bb2b0ab0474cab0cf8667b2f5c2223f87fadfdeb319116d8207e2936b147ca0a6ea337a811be342d1404542736662684
7
+ data.tar.gz: 85ec8273275588792cfaeee405554cbc32e66fdedf43f660978f4b51bc3308a62ea0172e981f08253938e6a2ad85ff894a28e6f76ebbf5fa234da2d7781a290c
data/README.md CHANGED
@@ -35,49 +35,49 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
35
35
  <!-- This table is regenerated and resorted on each release -->
36
36
  <table id='team'>
37
37
  <tr>
38
- <td id='jan-piotrowski'>
39
- <a href='https://github.com/janpio'>
40
- <img src='https://github.com/janpio.png' width='140px;'>
38
+ <td id='matthew-ellis'>
39
+ <a href='https://github.com/matthewellis'>
40
+ <img src='https://github.com/matthewellis.png' width='140px;'>
41
41
  </a>
42
- <h4 align='center'><a href='https://twitter.com/Sujan'>Jan Piotrowski</a></h4>
42
+ <h4 align='center'><a href='https://twitter.com/mellis1995'>Matthew Ellis</a></h4>
43
43
  </td>
44
- <td id='kohki-miki'>
45
- <a href='https://github.com/giginet'>
46
- <img src='https://github.com/giginet.png' width='140px;'>
44
+ <td id='joshua-liebowitz'>
45
+ <a href='https://github.com/taquitos'>
46
+ <img src='https://github.com/taquitos.png' width='140px;'>
47
47
  </a>
48
- <h4 align='center'><a href='https://twitter.com/giginet'>Kohki Miki</a></h4>
48
+ <h4 align='center'><a href='https://twitter.com/taquitos'>Joshua Liebowitz</a></h4>
49
49
  </td>
50
- <td id='andrew-mcburney'>
51
- <a href='https://github.com/armcburney'>
52
- <img src='https://github.com/armcburney.png' width='140px;'>
50
+ <td id='helmut-januschka'>
51
+ <a href='https://github.com/hjanuschka'>
52
+ <img src='https://github.com/hjanuschka.png' width='140px;'>
53
53
  </a>
54
- <h4 align='center'><a href='https://twitter.com/armcburney'>Andrew McBurney</a></h4>
54
+ <h4 align='center'><a href='https://twitter.com/hjanuschka'>Helmut Januschka</a></h4>
55
55
  </td>
56
- <td id='matthew-ellis'>
57
- <a href='https://github.com/matthewellis'>
58
- <img src='https://github.com/matthewellis.png' width='140px;'>
56
+ <td id='roger-oba'>
57
+ <a href='https://github.com/rogerluan'>
58
+ <img src='https://github.com/rogerluan.png' width='140px;'>
59
59
  </a>
60
- <h4 align='center'><a href='https://twitter.com/mellis1995'>Matthew Ellis</a></h4>
60
+ <h4 align='center'><a href='https://twitter.com/rogerluan_'>Roger Oba</a></h4>
61
61
  </td>
62
- <td id='josh-holtz'>
63
- <a href='https://github.com/joshdholtz'>
64
- <img src='https://github.com/joshdholtz.png' width='140px;'>
62
+ <td id='iulian-onofrei'>
63
+ <a href='https://github.com/revolter'>
64
+ <img src='https://github.com/revolter.png' width='140px;'>
65
65
  </a>
66
- <h4 align='center'><a href='https://twitter.com/joshdholtz'>Josh Holtz</a></h4>
66
+ <h4 align='center'><a href='https://twitter.com/Revolt666'>Iulian Onofrei</a></h4>
67
67
  </td>
68
68
  </tr>
69
69
  <tr>
70
- <td id='maksym-grebenets'>
71
- <a href='https://github.com/mgrebenets'>
72
- <img src='https://github.com/mgrebenets.png' width='140px;'>
70
+ <td id='felix-krause'>
71
+ <a href='https://github.com/KrauseFx'>
72
+ <img src='https://github.com/KrauseFx.png' width='140px;'>
73
73
  </a>
74
- <h4 align='center'><a href='https://twitter.com/mgrebenets'>Maksym Grebenets</a></h4>
74
+ <h4 align='center'><a href='https://twitter.com/KrauseFx'>Felix Krause</a></h4>
75
75
  </td>
76
- <td id='daniel-jankowski'>
77
- <a href='https://github.com/mollyIV'>
78
- <img src='https://github.com/mollyIV.png' width='140px;'>
76
+ <td id='max-ott'>
77
+ <a href='https://github.com/max-ott'>
78
+ <img src='https://github.com/max-ott.png' width='140px;'>
79
79
  </a>
80
- <h4 align='center'><a href='https://twitter.com/mollyIV'>Daniel Jankowski</a></h4>
80
+ <h4 align='center'><a href='https://twitter.com/ott_max'>Max Ott</a></h4>
81
81
  </td>
82
82
  <td id='manu-wallner'>
83
83
  <a href='https://github.com/milch'>
@@ -85,49 +85,49 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
85
85
  </a>
86
86
  <h4 align='center'><a href='https://twitter.com/acrooow'>Manu Wallner</a></h4>
87
87
  </td>
88
- <td id='jérôme-lacoste'>
89
- <a href='https://github.com/lacostej'>
90
- <img src='https://github.com/lacostej.png' width='140px;'>
88
+ <td id='danielle-tomlinson'>
89
+ <a href='https://github.com/endocrimes'>
90
+ <img src='https://github.com/endocrimes.png' width='140px;'>
91
91
  </a>
92
- <h4 align='center'><a href='https://twitter.com/lacostej'>Jérôme Lacoste</a></h4>
92
+ <h4 align='center'><a href='https://twitter.com/endocrimes'>Danielle Tomlinson</a></h4>
93
93
  </td>
94
- <td id='felix-krause'>
95
- <a href='https://github.com/KrauseFx'>
96
- <img src='https://github.com/KrauseFx.png' width='140px;'>
94
+ <td id='satoshi-namai'>
95
+ <a href='https://github.com/ainame'>
96
+ <img src='https://github.com/ainame.png' width='140px;'>
97
97
  </a>
98
- <h4 align='center'><a href='https://twitter.com/KrauseFx'>Felix Krause</a></h4>
98
+ <h4 align='center'><a href='https://twitter.com/ainame'>Satoshi Namai</a></h4>
99
99
  </td>
100
100
  </tr>
101
101
  <tr>
102
- <td id='olivier-halligon'>
103
- <a href='https://github.com/AliSoftware'>
104
- <img src='https://github.com/AliSoftware.png' width='140px;'>
102
+ <td id='jan-piotrowski'>
103
+ <a href='https://github.com/janpio'>
104
+ <img src='https://github.com/janpio.png' width='140px;'>
105
105
  </a>
106
- <h4 align='center'><a href='https://twitter.com/aligatr'>Olivier Halligon</a></h4>
106
+ <h4 align='center'><a href='https://twitter.com/Sujan'>Jan Piotrowski</a></h4>
107
107
  </td>
108
- <td id='jorge-revuelta-h'>
109
- <a href='https://github.com/minuscorp'>
110
- <img src='https://github.com/minuscorp.png' width='140px;'>
108
+ <td id='maksym-grebenets'>
109
+ <a href='https://github.com/mgrebenets'>
110
+ <img src='https://github.com/mgrebenets.png' width='140px;'>
111
111
  </a>
112
- <h4 align='center'><a href='https://twitter.com/minuscorp'>Jorge Revuelta H</a></h4>
112
+ <h4 align='center'><a href='https://twitter.com/mgrebenets'>Maksym Grebenets</a></h4>
113
113
  </td>
114
- <td id='satoshi-namai'>
115
- <a href='https://github.com/ainame'>
116
- <img src='https://github.com/ainame.png' width='140px;'>
114
+ <td id='josh-holtz'>
115
+ <a href='https://github.com/joshdholtz'>
116
+ <img src='https://github.com/joshdholtz.png' width='140px;'>
117
117
  </a>
118
- <h4 align='center'><a href='https://twitter.com/ainame'>Satoshi Namai</a></h4>
118
+ <h4 align='center'><a href='https://twitter.com/joshdholtz'>Josh Holtz</a></h4>
119
119
  </td>
120
- <td id='roger-oba'>
121
- <a href='https://github.com/rogerluan'>
122
- <img src='https://github.com/rogerluan.png' width='140px;'>
120
+ <td id='jorge-revuelta-h'>
121
+ <a href='https://github.com/minuscorp'>
122
+ <img src='https://github.com/minuscorp.png' width='140px;'>
123
123
  </a>
124
- <h4 align='center'><a href='https://twitter.com/rogerluan_'>Roger Oba</a></h4>
124
+ <h4 align='center'><a href='https://twitter.com/minuscorp'>Jorge Revuelta H</a></h4>
125
125
  </td>
126
- <td id='iulian-onofrei'>
127
- <a href='https://github.com/revolter'>
128
- <img src='https://github.com/revolter.png' width='140px;'>
126
+ <td id='fumiya-nakamura'>
127
+ <a href='https://github.com/nafu'>
128
+ <img src='https://github.com/nafu.png' width='140px;'>
129
129
  </a>
130
- <h4 align='center'><a href='https://twitter.com/Revolt666'>Iulian Onofrei</a></h4>
130
+ <h4 align='center'><a href='https://twitter.com/nafu003'>Fumiya Nakamura</a></h4>
131
131
  </td>
132
132
  </tr>
133
133
  <tr>
@@ -137,11 +137,17 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
137
137
  </a>
138
138
  <h4 align='center'>Jimmy Dee</h4>
139
139
  </td>
140
- <td id='helmut-januschka'>
141
- <a href='https://github.com/hjanuschka'>
142
- <img src='https://github.com/hjanuschka.png' width='140px;'>
140
+ <td id='kohki-miki'>
141
+ <a href='https://github.com/giginet'>
142
+ <img src='https://github.com/giginet.png' width='140px;'>
143
143
  </a>
144
- <h4 align='center'><a href='https://twitter.com/hjanuschka'>Helmut Januschka</a></h4>
144
+ <h4 align='center'><a href='https://twitter.com/giginet'>Kohki Miki</a></h4>
145
+ </td>
146
+ <td id='łukasz-grabowski'>
147
+ <a href='https://github.com/lucgrabowski'>
148
+ <img src='https://github.com/lucgrabowski.png' width='140px;'>
149
+ </a>
150
+ <h4 align='center'>Łukasz Grabowski</h4>
145
151
  </td>
146
152
  <td id='stefan-natchev'>
147
153
  <a href='https://github.com/snatchev'>
@@ -149,57 +155,51 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
149
155
  </a>
150
156
  <h4 align='center'><a href='https://twitter.com/snatchev'>Stefan Natchev</a></h4>
151
157
  </td>
152
- <td id='fumiya-nakamura'>
153
- <a href='https://github.com/nafu'>
154
- <img src='https://github.com/nafu.png' width='140px;'>
155
- </a>
156
- <h4 align='center'><a href='https://twitter.com/nafu003'>Fumiya Nakamura</a></h4>
157
- </td>
158
- <td id='aaron-brager'>
159
- <a href='https://github.com/getaaron'>
160
- <img src='https://github.com/getaaron.png' width='140px;'>
158
+ <td id='olivier-halligon'>
159
+ <a href='https://github.com/AliSoftware'>
160
+ <img src='https://github.com/AliSoftware.png' width='140px;'>
161
161
  </a>
162
- <h4 align='center'><a href='https://twitter.com/getaaron'>Aaron Brager</a></h4>
162
+ <h4 align='center'><a href='https://twitter.com/aligatr'>Olivier Halligon</a></h4>
163
163
  </td>
164
164
  </tr>
165
165
  <tr>
166
- <td id='manish-rathi'>
167
- <a href='https://github.com/crazymanish'>
168
- <img src='https://github.com/crazymanish.png' width='140px;'>
169
- </a>
170
- <h4 align='center'><a href='https://twitter.com/iammanishrathi'>Manish Rathi</a></h4>
171
- </td>
172
166
  <td id='luka-mirosevic'>
173
167
  <a href='https://github.com/lmirosevic'>
174
168
  <img src='https://github.com/lmirosevic.png' width='140px;'>
175
169
  </a>
176
170
  <h4 align='center'><a href='https://twitter.com/lmirosevic'>Luka Mirosevic</a></h4>
177
171
  </td>
178
- <td id='łukasz-grabowski'>
179
- <a href='https://github.com/lucgrabowski'>
180
- <img src='https://github.com/lucgrabowski.png' width='140px;'>
172
+ <td id='jérôme-lacoste'>
173
+ <a href='https://github.com/lacostej'>
174
+ <img src='https://github.com/lacostej.png' width='140px;'>
181
175
  </a>
182
- <h4 align='center'>Łukasz Grabowski</h4>
176
+ <h4 align='center'><a href='https://twitter.com/lacostej'>Jérôme Lacoste</a></h4>
183
177
  </td>
184
- <td id='danielle-tomlinson'>
185
- <a href='https://github.com/endocrimes'>
186
- <img src='https://github.com/endocrimes.png' width='140px;'>
178
+ <td id='manish-rathi'>
179
+ <a href='https://github.com/crazymanish'>
180
+ <img src='https://github.com/crazymanish.png' width='140px;'>
187
181
  </a>
188
- <h4 align='center'><a href='https://twitter.com/endocrimes'>Danielle Tomlinson</a></h4>
182
+ <h4 align='center'><a href='https://twitter.com/iammanishrathi'>Manish Rathi</a></h4>
189
183
  </td>
190
- <td id='max-ott'>
191
- <a href='https://github.com/max-ott'>
192
- <img src='https://github.com/max-ott.png' width='140px;'>
184
+ <td id='daniel-jankowski'>
185
+ <a href='https://github.com/mollyIV'>
186
+ <img src='https://github.com/mollyIV.png' width='140px;'>
193
187
  </a>
194
- <h4 align='center'><a href='https://twitter.com/ott_max'>Max Ott</a></h4>
188
+ <h4 align='center'><a href='https://twitter.com/mollyIV'>Daniel Jankowski</a></h4>
189
+ </td>
190
+ <td id='aaron-brager'>
191
+ <a href='https://github.com/getaaron'>
192
+ <img src='https://github.com/getaaron.png' width='140px;'>
193
+ </a>
194
+ <h4 align='center'><a href='https://twitter.com/getaaron'>Aaron Brager</a></h4>
195
195
  </td>
196
196
  </tr>
197
197
  <tr>
198
- <td id='joshua-liebowitz'>
199
- <a href='https://github.com/taquitos'>
200
- <img src='https://github.com/taquitos.png' width='140px;'>
198
+ <td id='andrew-mcburney'>
199
+ <a href='https://github.com/armcburney'>
200
+ <img src='https://github.com/armcburney.png' width='140px;'>
201
201
  </a>
202
- <h4 align='center'><a href='https://twitter.com/taquitos'>Joshua Liebowitz</a></h4>
202
+ <h4 align='center'><a href='https://twitter.com/armcburney'>Andrew McBurney</a></h4>
203
203
  </td>
204
204
  </table>
205
205
 
@@ -206,7 +206,7 @@ module Deliver
206
206
  pkg_path = options[:pkg]
207
207
 
208
208
  platform = options[:platform]
209
- transporter = transporter_for_selected_team
209
+ transporter = transporter_for_selected_team(upload: true)
210
210
 
211
211
  case platform
212
212
  when "ios", "appletvos"
@@ -216,7 +216,7 @@ module Deliver
216
216
  package_path: "/tmp",
217
217
  platform: platform
218
218
  )
219
- result = transporter.upload(package_path: package_path, asset_path: ipa_path)
219
+ result = transporter.upload(package_path: package_path, asset_path: ipa_path, platform: platform)
220
220
  when "osx"
221
221
  package_path = FastlaneCore::PkgUploadPackageBuilder.new.generate(
222
222
  app_id: Deliver.cache[:app].id,
@@ -224,7 +224,7 @@ module Deliver
224
224
  package_path: "/tmp",
225
225
  platform: platform
226
226
  )
227
- result = transporter.upload(package_path: package_path, asset_path: pkg_path)
227
+ result = transporter.upload(package_path: package_path, asset_path: pkg_path, platform: platform)
228
228
  else
229
229
  UI.user_error!("No suitable file found for upload for platform: #{options[:platform]}")
230
230
  end
@@ -270,17 +270,24 @@ module Deliver
270
270
  # If itc_provider was explicitly specified, use it.
271
271
  # If there are multiple teams, infer the provider from the selected team name.
272
272
  # If there are fewer than two teams, don't infer the provider.
273
- def transporter_for_selected_team
273
+ def transporter_for_selected_team(upload: false)
274
274
  # Use JWT auth
275
275
  api_token = Spaceship::ConnectAPI.token
276
+ api_key = if options[:api_key].nil? && !api_token.nil?
277
+ # Load api key info if user set api_key_path, not api_key
278
+ { key_id: api_token.key_id, issuer_id: api_token.issuer_id, key: api_token.key_raw, is_key_content_base64: api_token.is_key_content_base64 }
279
+ elsif !options[:api_key].nil?
280
+ options[:api_key].transform_keys(&:to_sym)
281
+ end
282
+
276
283
  unless api_token.nil?
277
284
  api_token.refresh! if api_token.expired?
278
- return FastlaneCore::ItunesTransporter.new(nil, nil, false, nil, api_token.text)
285
+ return FastlaneCore::ItunesTransporter.new(nil, nil, false, nil, api_token.text, upload: upload, api_key: api_key)
279
286
  end
280
287
 
281
288
  tunes_client = Spaceship::ConnectAPI.client.tunes_client
282
289
 
283
- generic_transporter = FastlaneCore::ItunesTransporter.new(options[:username], nil, false, options[:itc_provider])
290
+ generic_transporter = FastlaneCore::ItunesTransporter.new(options[:username], nil, false, options[:itc_provider], upload: upload, api_key: api_key)
284
291
  return generic_transporter unless options[:itc_provider].nil? && tunes_client.teams.count > 1
285
292
 
286
293
  begin
@@ -288,7 +295,7 @@ module Deliver
288
295
  name = team['name']
289
296
  provider_id = generic_transporter.provider_ids[name]
290
297
  UI.verbose("Inferred provider id #{provider_id} for team #{name}.")
291
- return FastlaneCore::ItunesTransporter.new(options[:username], nil, false, provider_id)
298
+ return FastlaneCore::ItunesTransporter.new(options[:username], nil, false, provider_id, upload: upload, api_key: api_key)
292
299
  rescue => ex
293
300
  UI.verbose("Couldn't infer a provider short name for team with id #{tunes_client.team_id} automatically: #{ex}. Proceeding without provider short name.")
294
301
  return generic_transporter
@@ -57,7 +57,7 @@ module Fastlane
57
57
  end
58
58
 
59
59
  def self.return_value
60
- 'Outputs has of results with :number_of_tests, :number_of_failures, :number_of_retries, :number_of_tests_excluding_retries, :number_of_failures_excluding_retries'
60
+ 'Outputs hash of results with the following keys: :number_of_tests, :number_of_failures, :number_of_retries, :number_of_tests_excluding_retries, :number_of_failures_excluding_retries'
61
61
  end
62
62
 
63
63
  def self.return_type
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
- VERSION = '2.209.1'.freeze
2
+ VERSION = '2.210.0'.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 = '1.12.1'.freeze
@@ -17,4 +17,4 @@ public class Deliverfile: DeliverfileProtocol {
17
17
  // during the `init` process, and you won't see this message
18
18
  }
19
19
 
20
- // Generated with fastlane 2.209.1
20
+ // Generated with fastlane 2.210.0
@@ -264,4 +264,4 @@ public extension DeliverfileProtocol {
264
264
 
265
265
  // Please don't remove the lines below
266
266
  // They are used to detect outdated files
267
- // FastlaneRunnerAPIVersion [0.9.109]
267
+ // FastlaneRunnerAPIVersion [0.9.110]
@@ -8685,7 +8685,7 @@ public func rubyVersion() {
8685
8685
  - numberOfRetries: The number of times a test can fail
8686
8686
  - failBuild: Should this step stop the build if the tests fail? Set this to false if you're using trainer
8687
8687
 
8688
- - returns: Outputs has of results with :number_of_tests, :number_of_failures, :number_of_retries, :number_of_tests_excluding_retries, :number_of_failures_excluding_retries
8688
+ - returns: Outputs hash of results with the following keys: :number_of_tests, :number_of_failures, :number_of_retries, :number_of_tests_excluding_retries, :number_of_failures_excluding_retries
8689
8689
 
8690
8690
  More information: https://docs.fastlane.tools/actions/scan/
8691
8691
  */
@@ -9108,7 +9108,7 @@ public func say(text: [String],
9108
9108
  - numberOfRetries: The number of times a test can fail
9109
9109
  - failBuild: Should this step stop the build if the tests fail? Set this to false if you're using trainer
9110
9110
 
9111
- - returns: Outputs has of results with :number_of_tests, :number_of_failures, :number_of_retries, :number_of_tests_excluding_retries, :number_of_failures_excluding_retries
9111
+ - returns: Outputs hash of results with the following keys: :number_of_tests, :number_of_failures, :number_of_retries, :number_of_tests_excluding_retries, :number_of_failures_excluding_retries
9112
9112
 
9113
9113
  More information: https://docs.fastlane.tools/actions/scan/
9114
9114
  */
@@ -13486,4 +13486,4 @@ public let snapshotfile: Snapshotfile = .init()
13486
13486
 
13487
13487
  // Please don't remove the lines below
13488
13488
  // They are used to detect outdated files
13489
- // FastlaneRunnerAPIVersion [0.9.162]
13489
+ // FastlaneRunnerAPIVersion [0.9.163]
@@ -17,4 +17,4 @@ public class Gymfile: GymfileProtocol {
17
17
  // during the `init` process, and you won't see this message
18
18
  }
19
19
 
20
- // Generated with fastlane 2.209.1
20
+ // Generated with fastlane 2.210.0
@@ -204,4 +204,4 @@ public extension GymfileProtocol {
204
204
 
205
205
  // Please don't remove the lines below
206
206
  // They are used to detect outdated files
207
- // FastlaneRunnerAPIVersion [0.9.112]
207
+ // FastlaneRunnerAPIVersion [0.9.113]
@@ -17,4 +17,4 @@ public class Matchfile: MatchfileProtocol {
17
17
  // during the `init` process, and you won't see this message
18
18
  }
19
19
 
20
- // Generated with fastlane 2.209.1
20
+ // Generated with fastlane 2.210.0
@@ -204,4 +204,4 @@ public extension MatchfileProtocol {
204
204
 
205
205
  // Please don't remove the lines below
206
206
  // They are used to detect outdated files
207
- // FastlaneRunnerAPIVersion [0.9.106]
207
+ // FastlaneRunnerAPIVersion [0.9.107]
@@ -17,4 +17,4 @@ public class Precheckfile: PrecheckfileProtocol {
17
17
  // during the `init` process, and you won't see this message
18
18
  }
19
19
 
20
- // Generated with fastlane 2.209.1
20
+ // Generated with fastlane 2.210.0
@@ -52,4 +52,4 @@ public extension PrecheckfileProtocol {
52
52
 
53
53
  // Please don't remove the lines below
54
54
  // They are used to detect outdated files
55
- // FastlaneRunnerAPIVersion [0.9.105]
55
+ // FastlaneRunnerAPIVersion [0.9.106]
@@ -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.209.1
20
+ // Generated with fastlane 2.210.0
@@ -312,4 +312,4 @@ public extension ScanfileProtocol {
312
312
 
313
313
  // Please don't remove the lines below
314
314
  // They are used to detect outdated files
315
- // FastlaneRunnerAPIVersion [0.9.117]
315
+ // FastlaneRunnerAPIVersion [0.9.118]
@@ -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.209.1
20
+ // Generated with fastlane 2.210.0
@@ -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.107]
99
+ // FastlaneRunnerAPIVersion [0.9.108]
@@ -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.209.1
20
+ // Generated with fastlane 2.210.0
@@ -204,4 +204,4 @@ public extension SnapshotfileProtocol {
204
204
 
205
205
  // Please don't remove the lines below
206
206
  // They are used to detect outdated files
207
- // FastlaneRunnerAPIVersion [0.9.101]
207
+ // FastlaneRunnerAPIVersion [0.9.102]
@@ -2,40 +2,40 @@
2
2
  "entries": {
3
3
  "brew": {
4
4
  "swiftformat": {
5
- "version": "0.49.17",
5
+ "version": "0.49.18",
6
6
  "bottle": {
7
7
  "rebuild": 0,
8
8
  "root_url": "https://ghcr.io/v2/homebrew/core",
9
9
  "files": {
10
10
  "arm64_monterey": {
11
11
  "cellar": ":any_skip_relocation",
12
- "url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:4b7f2dbc6e2d69c55e556339fd37bcb9b5085ffb26e18ece57f6614f68f71d9a",
13
- "sha256": "4b7f2dbc6e2d69c55e556339fd37bcb9b5085ffb26e18ece57f6614f68f71d9a"
12
+ "url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:6362f6087bc3821f4271c3d17b3a4f180b1e1326646ddfb60f6d27bfb5a2a357",
13
+ "sha256": "6362f6087bc3821f4271c3d17b3a4f180b1e1326646ddfb60f6d27bfb5a2a357"
14
14
  },
15
15
  "arm64_big_sur": {
16
16
  "cellar": ":any_skip_relocation",
17
- "url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:6762a1f50c474ace807cbe505c40ec83e07d95f3a709b862b55a4aee358bcbc2",
18
- "sha256": "6762a1f50c474ace807cbe505c40ec83e07d95f3a709b862b55a4aee358bcbc2"
17
+ "url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:e94cf1b66df0d712bbfbf509b98efaf31d39a61b82999314e1f3c0e45195c51a",
18
+ "sha256": "e94cf1b66df0d712bbfbf509b98efaf31d39a61b82999314e1f3c0e45195c51a"
19
19
  },
20
20
  "monterey": {
21
21
  "cellar": ":any_skip_relocation",
22
- "url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:46ab8382cc299980caf2aa48ca4e08cf3b3052432959e2bd02ca190f168f563b",
23
- "sha256": "46ab8382cc299980caf2aa48ca4e08cf3b3052432959e2bd02ca190f168f563b"
22
+ "url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:456e0c95a565adbb45a29747abfadf41c838a7f09fae052a874e59429a94ef14",
23
+ "sha256": "456e0c95a565adbb45a29747abfadf41c838a7f09fae052a874e59429a94ef14"
24
24
  },
25
25
  "big_sur": {
26
26
  "cellar": ":any_skip_relocation",
27
- "url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:0145b1f25c402c6d3f4b022a1ec3fc1469b3d61428bc9f47405e2124cffda100",
28
- "sha256": "0145b1f25c402c6d3f4b022a1ec3fc1469b3d61428bc9f47405e2124cffda100"
27
+ "url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:d00204be714789fa8b35d4c6f6eea5813604aa09f3911635059973aa827d2e8c",
28
+ "sha256": "d00204be714789fa8b35d4c6f6eea5813604aa09f3911635059973aa827d2e8c"
29
29
  },
30
30
  "catalina": {
31
31
  "cellar": ":any_skip_relocation",
32
- "url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:bc210385a7a34bd8babd475927d698e38feb6d9b6bc267f159acd67e90542380",
33
- "sha256": "bc210385a7a34bd8babd475927d698e38feb6d9b6bc267f159acd67e90542380"
32
+ "url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:b07f7221f3c5225ad0037293cecb95bde4f0dba4fa19797d84a3376dd1ad02ea",
33
+ "sha256": "b07f7221f3c5225ad0037293cecb95bde4f0dba4fa19797d84a3376dd1ad02ea"
34
34
  },
35
35
  "x86_64_linux": {
36
36
  "cellar": "/home/linuxbrew/.linuxbrew/Cellar",
37
- "url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:326c9a8cedeeb429315d94638a5c03a764194b346a2781fe858d5cb83d93662d",
38
- "sha256": "326c9a8cedeeb429315d94638a5c03a764194b346a2781fe858d5cb83d93662d"
37
+ "url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:c4a4ebd2f3f54b8f399551efaf47b3e419db2c729ffaf18a09e64bbf62d82f38",
38
+ "sha256": "c4a4ebd2f3f54b8f399551efaf47b3e419db2c729ffaf18a09e64bbf62d82f38"
39
39
  }
40
40
  }
41
41
  }
@@ -61,9 +61,9 @@
61
61
  "macOS": "11.0.1"
62
62
  },
63
63
  "monterey": {
64
- "HOMEBREW_VERSION": "3.5.9",
64
+ "HOMEBREW_VERSION": "3.6.1-50-g6eaa510",
65
65
  "HOMEBREW_PREFIX": "/opt/homebrew",
66
- "Homebrew/homebrew-core": "191ec7ef868ea58e6d7305d756516e5d69c2568c",
66
+ "Homebrew/homebrew-core": "4d6529affa1851ffb992a33fe5641b0cd739c895",
67
67
  "CLT": "13.4.0.0.1.1651278267",
68
68
  "Xcode": "13.4.1",
69
69
  "macOS": "12.5"
@@ -28,10 +28,29 @@ module FastlaneCore
28
28
  OUTPUT_REGEX = />\s+(.+)/
29
29
  RETURN_VALUE_REGEX = />\sDBG-X:\sReturning\s+(\d+)/
30
30
 
31
+ # Matches a line in the iTMSTransporter provider table: "12 Initech Systems Inc LG89CQY559"
32
+ ITMS_PROVIDER_REGEX = /^\d+\s{2,}.+\s{2,}[^\s]+$/
33
+
31
34
  SKIP_ERRORS = ["ERROR: An exception has occurred: Scheduling automatic restart in 1 minute"]
32
35
 
33
36
  private_constant :ERROR_REGEX, :WARNING_REGEX, :OUTPUT_REGEX, :RETURN_VALUE_REGEX, :SKIP_ERRORS
34
37
 
38
+ def build_download_command(username, password, apple_id, destination = "/tmp", provider_short_name = "", jwt = nil)
39
+ not_implemented(__method__)
40
+ end
41
+
42
+ def build_provider_ids_command(username, password, jwt = nil, api_key = nil)
43
+ not_implemented(__method__)
44
+ end
45
+
46
+ def build_upload_command(username, password, source = "/tmp", provider_short_name = "", jwt = nil, platform = nil, api_key = nil)
47
+ not_implemented(__method__)
48
+ end
49
+
50
+ def build_verify_command(username, password, source = "/tmp", provider_short_name = "", jwt = nil)
51
+ not_implemented(__method__)
52
+ end
53
+
35
54
  def execute(command, hide_output)
36
55
  if Helper.test?
37
56
  yield(nil) if block_given?
@@ -100,8 +119,18 @@ module FastlaneCore
100
119
  @errors.map { |error| "[Transporter Error Output]: #{error}" }.join("\n").gsub!(/"/, "")
101
120
  end
102
121
 
122
+ def parse_provider_info(lines)
123
+ lines.map { |line| itms_provider_pair(line) }.compact.to_h
124
+ end
125
+
103
126
  private
104
127
 
128
+ def itms_provider_pair(line)
129
+ line = line.strip
130
+ return nil unless line =~ ITMS_PROVIDER_REGEX
131
+ line.split(/\s{2,}/).drop(1)
132
+ end
133
+
105
134
  def parse_line(line, hide_output)
106
135
  # Taken from https://github.com/sshaw/itunes_store_transporter/blob/master/lib/itunes/store/transporter/output_parser.rb
107
136
 
@@ -180,9 +209,166 @@ module FastlaneCore
180
209
  end
181
210
  end
182
211
 
212
+ # Generates commands and executes the altool.
213
+ class AltoolTransporterExecutor < TransporterExecutor
214
+ ERROR_REGEX = /\*\*\* Error:\s+(.+)/
215
+
216
+ private_constant :ERROR_REGEX
217
+
218
+ def execute(command, hide_output)
219
+ if Helper.test?
220
+ yield(nil) if block_given?
221
+ return command
222
+ end
223
+
224
+ @errors = []
225
+ @all_lines = []
226
+
227
+ if hide_output
228
+ # Show a one time message instead
229
+ UI.success("Waiting for App Store Connect transporter to be finished.")
230
+ UI.success("Application Loader progress... this might take a few minutes...")
231
+ end
232
+
233
+ begin
234
+ exit_status = FastlaneCore::FastlanePty.spawn(command) do |command_stdout, command_stdin, pid|
235
+ command_stdout.each do |line|
236
+ @all_lines << line
237
+ parse_line(line, hide_output) # this is where the parsing happens
238
+ end
239
+ end
240
+ rescue => ex
241
+ # FastlanePty adds exit_status on to StandardError so every error will have a status code
242
+ exit_status = ex.exit_status
243
+ @errors << ex.to_s
244
+ end
245
+
246
+ @errors << "The call to the altool completed with a non-zero exit status: #{exit_status}. This indicates a failure." unless exit_status.zero?
247
+
248
+ unless @errors.empty? || @all_lines.empty?
249
+ # Print the last lines that appear after the last error from the logs
250
+ # If error text is not detected, it will be 20 lines
251
+ # This is key for non-verbose mode
252
+
253
+ # The format of altool's result with error is like below
254
+ # > *** Error: Error uploading '...'.
255
+ # > *** Error: ...
256
+ # > {
257
+ # > NSLocalizedDescription = "...",
258
+ # > ...
259
+ # > }
260
+ # So this line tries to find the line which has "*** Error:" prefix from bottom of log
261
+ error_line_index = @all_lines.rindex { |line| ERROR_REGEX.match?(line) }
262
+
263
+ @all_lines[(error_line_index || -20)..-1].each do |line|
264
+ UI.important("[altool] #{line}")
265
+ end
266
+ UI.message("Application Loader output above ^")
267
+ @errors.each { |error| UI.error(error) }
268
+ end
269
+
270
+ yield(@all_lines) if block_given?
271
+ exit_status.zero?
272
+ end
273
+
274
+ def build_upload_command(username, password, source = "/tmp", provider_short_name = "", jwt = nil, platform = nil, api_key = nil)
275
+ use_api_key = !api_key.nil?
276
+ [
277
+ ("API_PRIVATE_KEYS_DIR=#{api_key[:key_dir]}" if use_api_key),
278
+ "xcrun altool",
279
+ "--upload-app",
280
+ ("-u #{username.shellescape}" unless use_api_key),
281
+ ("-p #{password.shellescape}" unless use_api_key),
282
+ ("--apiKey #{api_key[:key_id]}" if use_api_key),
283
+ ("--apiIssuer #{api_key[:issuer_id]}" if use_api_key),
284
+ ("--asc-provider #{provider_short_name}" unless use_api_key || provider_short_name.to_s.empty?),
285
+ platform_option(platform),
286
+ file_upload_option(source),
287
+ additional_upload_parameters,
288
+ "-k 100000"
289
+ ].compact.join(' ')
290
+ end
291
+
292
+ def build_provider_ids_command(username, password, jwt = nil, api_key = nil)
293
+ use_api_key = !api_key.nil?
294
+ [
295
+ ("API_PRIVATE_KEYS_DIR=#{api_key[:key_dir]}" if use_api_key),
296
+ "xcrun altool",
297
+ "--list-providers",
298
+ ("-u #{username.shellescape}" unless use_api_key),
299
+ ("-p #{password.shellescape}" unless use_api_key),
300
+ ("--apiKey #{api_key[:key_id]}" if use_api_key),
301
+ ("--apiIssuer #{api_key[:issuer_id]}" if use_api_key),
302
+ "--output-format json"
303
+ ].compact.join(' ')
304
+ end
305
+
306
+ def build_download_command(username, password, apple_id, destination = "/tmp", provider_short_name = "", jwt = nil)
307
+ raise "This feature has not been implemented yet with altool for Xcode 14"
308
+ end
309
+
310
+ def build_verify_command(username, password, source = "/tmp", provider_short_name = "", jwt = nil)
311
+ raise "This feature has not been implemented yet with altool for Xcode 14"
312
+ end
313
+
314
+ def additional_upload_parameters
315
+ env_deliver_additional_params = ENV["DELIVER_ALTOOL_ADDITIONAL_UPLOAD_PARAMETERS"]
316
+ return nil if env_deliver_additional_params.to_s.strip.empty?
317
+
318
+ env_deliver_additional_params.to_s.strip
319
+ end
320
+
321
+ def handle_error(password)
322
+ UI.error("Could not download/upload from App Store Connect!")
323
+ end
324
+
325
+ def displayable_errors
326
+ @errors.map { |error| "[Application Loader Error Output]: #{error}" }.join("\n")
327
+ end
328
+
329
+ def parse_provider_info(lines)
330
+ # This tries parsing the provider id from altool output to detect provider list
331
+ provider_info = {}
332
+ json_body = lines[-2] # altool outputs result in second line from last
333
+ return provider_info if json_body.nil?
334
+ providers = JSON.parse(json_body)["providers"]
335
+ return provider_info if providers.nil?
336
+ providers.each do |provider|
337
+ provider_info[provider["ProviderName"]] = provider["ProviderShortname"]
338
+ end
339
+ provider_info
340
+ end
341
+
342
+ private
343
+
344
+ def file_upload_option(source)
345
+ "-f #{source.shellescape}"
346
+ end
347
+
348
+ def platform_option(platform)
349
+ "-t #{platform == 'osx' ? 'macos' : platform}"
350
+ end
351
+
352
+ def parse_line(line, hide_output)
353
+ output_done = false
354
+
355
+ if line =~ ERROR_REGEX
356
+ @errors << $1
357
+ output_done = true
358
+ end
359
+
360
+ unless hide_output
361
+ # General logging for debug purposes
362
+ unless output_done
363
+ UI.verbose("[altool]: #{line}")
364
+ end
365
+ end
366
+ end
367
+ end
368
+
183
369
  # Generates commands and executes the iTMSTransporter through the shell script it provides by the same name
184
370
  class ShellScriptTransporterExecutor < TransporterExecutor
185
- def build_upload_command(username, password, source = "/tmp", provider_short_name = "", jwt = nil)
371
+ def build_upload_command(username, password, source = "/tmp", provider_short_name = "", jwt = nil, platform = nil, api_key = nil)
186
372
  use_jwt = !jwt.to_s.empty?
187
373
  [
188
374
  '"' + Helper.transporter_path + '"',
@@ -212,7 +398,7 @@ module FastlaneCore
212
398
  ].compact.join(' ')
213
399
  end
214
400
 
215
- def build_provider_ids_command(username, password, jwt = nil)
401
+ def build_provider_ids_command(username, password, jwt = nil, api_key = nil)
216
402
  use_jwt = !jwt.to_s.empty?
217
403
  [
218
404
  '"' + Helper.transporter_path + '"',
@@ -278,7 +464,7 @@ module FastlaneCore
278
464
  # Generates commands and executes the iTMSTransporter by invoking its Java app directly, to avoid the crazy parameter
279
465
  # escaping problems in its accompanying shell script.
280
466
  class JavaTransporterExecutor < TransporterExecutor
281
- def build_upload_command(username, password, source = "/tmp", provider_short_name = "", jwt = nil)
467
+ def build_upload_command(username, password, source = "/tmp", provider_short_name = "", jwt = nil, platform = nil, api_key = nil)
282
468
  use_jwt = !jwt.to_s.empty?
283
469
  if !Helper.user_defined_itms_path? && Helper.mac? && Helper.xcode_at_least?(11)
284
470
  [
@@ -392,7 +578,7 @@ module FastlaneCore
392
578
  end
393
579
  end
394
580
 
395
- def build_provider_ids_command(username, password, jwt = nil)
581
+ def build_provider_ids_command(username, password, jwt = nil, api_key = nil)
396
582
  use_jwt = !jwt.to_s.empty?
397
583
  if !Helper.user_defined_itms_path? && Helper.mac? && Helper.xcode_at_least?(11)
398
584
  [
@@ -451,8 +637,6 @@ module FastlaneCore
451
637
  end
452
638
 
453
639
  class ItunesTransporter
454
- # Matches a line in the provider table: "12 Initech Systems Inc LG89CQY559"
455
- PROVIDER_REGEX = /^\d+\s{2,}.+\s{2,}[^\s]+$/
456
640
  TWO_STEP_HOST_PREFIX = "deliver.appspecific"
457
641
 
458
642
  # This will be called from the Deliverfile, and disables the logging of the transporter output
@@ -476,7 +660,7 @@ module FastlaneCore
476
660
  # see: https://github.com/fastlane/fastlane/issues/1524#issuecomment-196370628
477
661
  # for more information about how to use the iTMSTransporter to list your provider
478
662
  # short names
479
- def initialize(user = nil, password = nil, use_shell_script = false, provider_short_name = nil, jwt = nil)
663
+ def initialize(user = nil, password = nil, use_shell_script = false, provider_short_name = nil, jwt = nil, upload: false, api_key: nil)
480
664
  # Xcode 6.x doesn't have the same iTMSTransporter Java setup as later Xcode versions, so
481
665
  # we can't default to using the newer direct Java invocation strategy for those versions.
482
666
  use_shell_script ||= Helper.is_mac? && Helper.xcode_version.start_with?('6.')
@@ -489,8 +673,16 @@ module FastlaneCore
489
673
  end
490
674
 
491
675
  @jwt = jwt
676
+ @api_key = api_key
677
+
678
+ if should_use_altool?(upload, use_shell_script)
679
+ UI.verbose("Using altool as transporter.")
680
+ @transporter_executor = AltoolTransporterExecutor.new
681
+ else
682
+ UI.verbose("Using iTMSTransporter as transporter.")
683
+ @transporter_executor = use_shell_script ? ShellScriptTransporterExecutor.new : JavaTransporterExecutor.new
684
+ end
492
685
 
493
- @transporter_executor = use_shell_script ? ShellScriptTransporterExecutor.new : JavaTransporterExecutor.new
494
686
  @provider_short_name = provider_short_name
495
687
  end
496
688
 
@@ -539,7 +731,7 @@ module FastlaneCore
539
731
  # @return (Bool) True if everything worked fine
540
732
  # @raise [Deliver::TransporterTransferError] when something went wrong
541
733
  # when transferring
542
- def upload(app_id = nil, dir = nil, package_path: nil, asset_path: nil)
734
+ def upload(app_id = nil, dir = nil, package_path: nil, asset_path: nil, platform: nil)
543
735
  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?
544
736
 
545
737
  # Transport can upload .ipa, .dmg, and .pkg files directly with -assetFile
@@ -569,14 +761,25 @@ module FastlaneCore
569
761
  password_placeholder = @jwt.nil? ? 'YourPassword' : nil
570
762
  jwt_placeholder = @jwt.nil? ? nil : 'YourJWT'
571
763
 
572
- command = @transporter_executor.build_upload_command(@user, @password, actual_dir, @provider_short_name, @jwt)
573
- UI.verbose(@transporter_executor.build_upload_command(@user, password_placeholder, actual_dir, @provider_short_name, jwt_placeholder))
764
+ # Handle AppStore Connect API
765
+ use_api_key = !@api_key.nil?
766
+ api_key_placeholder = use_api_key ? { key_id: "YourKeyID", issuer_id: "YourIssuerID", key_dir: "YourTmpP8KeyDir" } : nil
767
+
768
+ api_key = nil
769
+ api_key = api_key_with_p8_file_path(@api_key) if use_api_key
770
+
771
+ command = @transporter_executor.build_upload_command(@user, @password, actual_dir, @provider_short_name, @jwt, platform, api_key)
772
+ UI.verbose(@transporter_executor.build_upload_command(@user, password_placeholder, actual_dir, @provider_short_name, jwt_placeholder, platform, api_key_placeholder))
574
773
 
575
774
  begin
576
775
  result = @transporter_executor.execute(command, ItunesTransporter.hide_transporter_output?)
577
776
  rescue TransporterRequiresApplicationSpecificPasswordError => ex
578
777
  handle_two_step_failure(ex)
579
778
  return upload(app_id, dir, package_path: package_path, asset_path: asset_path)
779
+ ensure
780
+ if use_api_key
781
+ FileUtils.rm_rf(api_key[:key_dir]) unless api_key.nil?
782
+ end
580
783
  end
581
784
 
582
785
  if result
@@ -638,8 +841,15 @@ module FastlaneCore
638
841
  password_placeholder = @jwt.nil? ? 'YourPassword' : nil
639
842
  jwt_placeholder = @jwt.nil? ? nil : 'YourJWT'
640
843
 
641
- command = @transporter_executor.build_provider_ids_command(@user, @password, @jwt)
642
- UI.verbose(@transporter_executor.build_provider_ids_command(@user, password_placeholder, jwt_placeholder))
844
+ # Handle AppStore Connect API
845
+ use_api_key = !@api_key.nil?
846
+ api_key_placeholder = use_api_key ? { key_id: "YourKeyID", issuer_id: "YourIssuerID", key_dir: "YourTmpP8KeyDir" } : nil
847
+
848
+ api_key = nil
849
+ api_key = api_key_with_p8_file_path(@api_key) if use_api_key
850
+
851
+ command = @transporter_executor.build_provider_ids_command(@user, @password, @jwt, api_key)
852
+ UI.verbose(@transporter_executor.build_provider_ids_command(@user, password_placeholder, jwt_placeholder, api_key_placeholder))
643
853
 
644
854
  lines = []
645
855
  begin
@@ -648,15 +858,37 @@ module FastlaneCore
648
858
  rescue TransporterRequiresApplicationSpecificPasswordError => ex
649
859
  handle_two_step_failure(ex)
650
860
  return provider_ids
861
+ ensure
862
+ if use_api_key
863
+ FileUtils.rm_rf(api_key[:key_dir]) unless api_key.nil?
864
+ end
651
865
  end
652
866
 
653
- lines.map { |line| provider_pair(line) }.compact.to_h
867
+ @transporter_executor.parse_provider_info(lines)
654
868
  end
655
869
 
656
870
  private
657
871
 
658
872
  TWO_FACTOR_ENV_VARIABLE = "FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD"
659
873
 
874
+ # Create .p8 file from api_key and provide api key info which contains .p8 file path
875
+ def api_key_with_p8_file_path(original_api_key)
876
+ api_key = original_api_key.clone
877
+ api_key[:key_dir] = Dir.mktmpdir("deliver-")
878
+ # Specified p8 needs to be generated to call altool
879
+ File.open(File.join(api_key[:key_dir], "AuthKey_#{api_key[:key_id]}.p8"), "wb") do |p8|
880
+ key_content = api_key[:is_key_content_base64] ? Base64.decode64(api_key[:key]) : api_key[:key]
881
+ p8.write(key_content)
882
+ end
883
+ api_key
884
+ end
885
+
886
+ # Returns whether altool should be used or ItunesTransporter should be used
887
+ def should_use_altool?(upload, use_shell_script)
888
+ # Xcode 14 no longer supports iTMSTransporter. Use altool instead
889
+ !use_shell_script && upload && !Helper.user_defined_itms_path? && Helper.mac? && Helper.xcode_at_least?(14)
890
+ end
891
+
660
892
  # Returns the password to be used with the transporter
661
893
  def load_password_for_transporter
662
894
  # 3 different sources for the password
@@ -714,11 +946,5 @@ module FastlaneCore
714
946
  def handle_error(password)
715
947
  @transporter_executor.handle_error(password)
716
948
  end
717
-
718
- def provider_pair(line)
719
- line = line.strip
720
- return nil unless line =~ PROVIDER_REGEX
721
- line.split(/\s{2,}/).drop(1)
722
- end
723
949
  end
724
950
  end
@@ -47,7 +47,7 @@ module Pilot
47
47
  end
48
48
 
49
49
  transporter = transporter_for_selected_team(options)
50
- result = transporter.upload(package_path: package_path, asset_path: asset_path)
50
+ result = transporter.upload(package_path: package_path, asset_path: asset_path, platform: platform)
51
51
 
52
52
  unless result
53
53
  transporter_errors = transporter.displayable_errors
@@ -389,15 +389,22 @@ module Pilot
389
389
  def transporter_for_selected_team(options)
390
390
  # Use JWT auth
391
391
  api_token = Spaceship::ConnectAPI.token
392
+ api_key = if options[:api_key].nil? && !api_token.nil?
393
+ # Load api key info if user set api_key_path, not api_key
394
+ { key_id: api_token.key_id, issuer_id: api_token.issuer_id, key: api_token.key_raw, is_key_content_base64: api_token.is_key_content_base64 }
395
+ elsif !options[:api_key].nil?
396
+ options[:api_key].transform_keys(&:to_sym)
397
+ end
398
+
392
399
  unless api_token.nil?
393
400
  api_token.refresh! if api_token.expired?
394
- return FastlaneCore::ItunesTransporter.new(nil, nil, false, nil, api_token.text)
401
+ return FastlaneCore::ItunesTransporter.new(nil, nil, false, nil, api_token.text, upload: true, api_key: api_key)
395
402
  end
396
403
 
397
404
  # Otherwise use username and password
398
405
  tunes_client = Spaceship::ConnectAPI.client ? Spaceship::ConnectAPI.client.tunes_client : nil
399
406
 
400
- generic_transporter = FastlaneCore::ItunesTransporter.new(options[:username], nil, false, options[:itc_provider])
407
+ generic_transporter = FastlaneCore::ItunesTransporter.new(options[:username], nil, false, options[:itc_provider], upload: true, api_key: api_key)
401
408
  return generic_transporter if options[:itc_provider] || tunes_client.nil?
402
409
  return generic_transporter unless tunes_client.teams.count > 1
403
410
 
@@ -406,7 +413,7 @@ module Pilot
406
413
  name = team['name']
407
414
  provider_id = generic_transporter.provider_ids[name]
408
415
  UI.verbose("Inferred provider id #{provider_id} for team #{name}.")
409
- return FastlaneCore::ItunesTransporter.new(options[:username], nil, false, provider_id)
416
+ return FastlaneCore::ItunesTransporter.new(options[:username], nil, false, provider_id, upload: true, api_key: api_key)
410
417
  rescue => ex
411
418
  STDERR.puts(ex.to_s)
412
419
  UI.verbose("Couldn't infer a provider short name for team with id #{tunes_client.team_id} automatically: #{ex}. Proceeding without provider short name.")
@@ -22,6 +22,7 @@ module Spaceship
22
22
  attr_reader :expiration
23
23
 
24
24
  attr_reader :key_raw
25
+ attr_reader :is_key_content_base64
25
26
 
26
27
  # Temporary attribute not needed to create the JWT text
27
28
  # There is no way to determine if the team associated with this
@@ -71,17 +72,19 @@ module Spaceship
71
72
  key: OpenSSL::PKey::EC.new(key),
72
73
  key_raw: key,
73
74
  duration: duration,
74
- in_house: in_house
75
+ in_house: in_house,
76
+ is_key_content_base64: is_key_content_base64
75
77
  )
76
78
  end
77
79
 
78
- def initialize(key_id: nil, issuer_id: nil, key: nil, key_raw: nil, duration: nil, in_house: nil)
80
+ def initialize(key_id: nil, issuer_id: nil, key: nil, key_raw: nil, duration: nil, in_house: nil, is_key_content_base64: nil)
79
81
  @key_id = key_id
80
82
  @key = key
81
83
  @key_raw = key_raw
82
84
  @issuer_id = issuer_id
83
85
  @duration = duration
84
86
  @in_house = in_house
87
+ @is_key_content_base64 = is_key_content_base64
85
88
 
86
89
  @duration ||= DEFAULT_TOKEN_DURATION
87
90
  @duration = @duration.to_i if @duration
metadata CHANGED
@@ -1,39 +1,39 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.209.1
4
+ version: 2.210.0
5
5
  platform: ruby
6
6
  authors:
7
- - Luka Mirosevic
7
+ - Kohki Miki
8
+ - Stefan Natchev
9
+ - Maksym Grebenets
10
+ - Joshua Liebowitz
8
11
  - Łukasz Grabowski
9
- - Manish Rathi
12
+ - Jimmy Dee
13
+ - Jorge Revuelta H
14
+ - Danielle Tomlinson
15
+ - Helmut Januschka
16
+ - Luka Mirosevic
17
+ - Iulian Onofrei
18
+ - Manu Wallner
19
+ - Jérôme Lacoste
10
20
  - Aaron Brager
11
- - Daniel Jankowski
12
- - Max Ott
13
- - Joshua Liebowitz
21
+ - Satoshi Namai
14
22
  - Matthew Ellis
15
- - Jérôme Lacoste
16
- - Olivier Halligon
17
23
  - Josh Holtz
18
- - Stefan Natchev
19
- - Jorge Revuelta H
20
- - Jan Piotrowski
21
24
  - Felix Krause
22
- - Roger Oba
23
- - Danielle Tomlinson
24
- - Kohki Miki
25
- - Iulian Onofrei
26
- - Jimmy Dee
27
- - Helmut Januschka
28
25
  - Andrew McBurney
29
- - Satoshi Namai
30
- - Manu Wallner
26
+ - Jan Piotrowski
27
+ - Daniel Jankowski
28
+ - Max Ott
29
+ - Manish Rathi
31
30
  - Fumiya Nakamura
32
- - Maksym Grebenets
31
+ - Roger Oba
32
+ - Olivier Halligon
33
33
  autorequire:
34
34
  bindir: bin
35
35
  cert_chain: []
36
- date: 2022-08-22 00:00:00.000000000 Z
36
+ date: 2022-09-15 00:00:00.000000000 Z
37
37
  dependencies:
38
38
  - !ruby/object:Gem::Dependency
39
39
  name: xcodeproj