fastlane-plugin-appcenter 1.8.0 → 1.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d80a48da7efa15bbdfb68ed3af18b8ed57bac5ecca51d0725b428520a0912608
4
- data.tar.gz: 651ed034f616868690bcf677453cb6c8646c9d02692d831284b54f5fe061d4f0
3
+ metadata.gz: f3383c94635e8212980d620bf95d5e61eca5a3bbacfeea4875e8128884670d66
4
+ data.tar.gz: 12d16a1669fb1f2c0239d3d0e5feba0e7a076d48c109047ba474b7e59672be5f
5
5
  SHA512:
6
- metadata.gz: 68027e3171f663771bc1030396874f14c95f118050b8b881a6d61c2a0a9569876f7fe27a8841c32cfcb00c7a8e536fed5c26f47a64f15df78aed5b9683681cc6
7
- data.tar.gz: 8d4584eea5879862b0f08a7e074fbee368636de399dd55f76f3e585f4b44717b72f8c2d4dae3da6cbab32b6d19eb6b319a1cb7761850d3399866d167b3972993
6
+ metadata.gz: 1b8e7acb6b7dc353a0aa443e9d0737b08a634f88e8f311cd78be834d38ceb23d15e81038d8cfba88aca7e09be3f83431fb2681829b969c3f074fe21601b67fdb
7
+ data.tar.gz: 0f143cb13db8034eca974c0c7a4a6c773c1a9faa3b11c29cf9419397957124f331bfa642ecaad475c4fa6cd41d5d11a53145035de16157b10e239c39573683bd
data/README.md CHANGED
@@ -31,7 +31,6 @@ To get started, first, [obtain an API token](https://appcenter.ms/settings/apito
31
31
  appcenter_fetch_devices(
32
32
  api_token: "<appcenter token>",
33
33
  owner_name: "<appcenter account name of the owner of the app (username or organization URL name)>",
34
- owner_type: "user", # Default is user - set to organization for appcenter organizations
35
34
  app_name: "<appcenter app name>",
36
35
  destinations: "*", # Default is 'Collaborators', use '*' for all distribution groups
37
36
  devices_file: "devices.txt" # Default. If you customize, the extension must be .txt
@@ -90,7 +89,6 @@ Here is the list of all existing parameters:
90
89
  | Key & Env Var | Description |
91
90
  |-----------------|--------------------|
92
91
  | `api_token` <br/> `APPCENTER_API_TOKEN` | API Token for App Center |
93
- | `owner_type` <br/> `APPCENTER_OWNER_TYPE` | Owner type, either 'user' or 'organization' (default: `user`) |
94
92
  | `owner_name` <br/> `APPCENTER_OWNER_NAME` | Owner name, as found in the App's URL in App Center |
95
93
  | `destinations` <br/> `APPCENTER_DISTRIBUTE_DESTINATIONS` | Comma separated list of distribution group names. Default is 'Collaborators', use '*' for all distribution groups |
96
94
  | `devices_file` <br/> `FL_REGISTER_DEVICES_FILE` | File to save the devices list to. Same environment variable as _fastlane_'s `register_devices` action |
@@ -104,7 +102,7 @@ Here is the list of all existing parameters:
104
102
  | `owner_name` <br/> `APPCENTER_OWNER_NAME` | Owner name as found in the App's URL in App Center |
105
103
  | `app_name` <br/> `APPCENTER_APP_NAME` | App name as found in the App's URL in App Center. If there is no app with such name, you will be prompted to create one |
106
104
  | `app_display_name` <br/> `APPCENTER_APP_DISPLAY_NAME` | App display name to use when creating a new app |
107
- | `app_os` <br/> `APPCENTER_APP_OS` | App OS. Used for new app creation, if app 'app_name' was not found |
105
+ | `app_os` <br/> `APPCENTER_APP_OS` | App OS can be Android, iOS, macOS, Windows, Custom. Used for new app creation, if app 'app_name' was not found |
108
106
  | `app_platform` <br/> `APPCENTER_APP_PLATFORM` | App Platform. Used for new app creation, if app 'app_name' was not found |
109
107
  | `file` <br/> `APPCENTER_DISTRIBUTE_FILE` | File path to the release build to publish |
110
108
  | `upload_build_only` <br/> `APPCENTER_DISTRIBUTE_UPLOAD_BUILD_ONLY` | Flag to upload only the build to App Center. Skips uploading symbols or mapping (default: `false`) |
@@ -116,7 +114,7 @@ Here is the list of all existing parameters:
116
114
  | `destination_type` <br/> `APPCENTER_DISTRIBUTE_DESTINATION_TYPE` | Destination type of distribution destination. 'group' and 'store' are supported (default: `group`) |
117
115
  | `mandatory_update` <br/> `APPCENTER_DISTRIBUTE_MANDATORY_UPDATE` | Require users to update to this release. Ignored if destination type is 'store' (default: `false`) |
118
116
  | `notify_testers` <br/> `APPCENTER_DISTRIBUTE_NOTIFY_TESTERS` | Send email notification about release. Ignored if destination type is 'store' (default: `false`) |
119
- | `release_notes` <br/> `APPCENTER_DISTRIBUTE_RELEASE_NOTES` | Release notes (default: `No changelog given`) |
117
+ | `release_notes` <br/> `APPCENTER_DISTRIBUTE_RELEASE_NOTES` | Release notes (default: `No changelog given`) |
120
118
  | `should_clip` <br/> `APPCENTER_DISTRIBUTE_RELEASE_NOTES_CLIPPING` | Clip release notes if its length is more then 5000, true by default (default: `true`) |
121
119
  | `release_notes_link` <br/> `APPCENTER_DISTRIBUTE_RELEASE_NOTES_LINK` | Additional release notes link |
122
120
  | `build_number` <br/> `APPCENTER_DISTRIBUTE_BUILD_NUMBER` | The build number, required for macOS .pkg and .dmg builds, as well as Android ProGuard `mapping.txt` when using `upload_mapping_only` |
@@ -185,4 +183,4 @@ Check out [SECURITY.md](SECURITY.md) for any security concern with this project.
185
183
 
186
184
  ## Contact
187
185
 
188
- We're on Twitter as [@vsappcenter](https://www.twitter.com/vsappcenter). Additionally you can reach out to us on the [App Center](https://appcenter.ms/apps) portal by using the blue Intercom button on the bottom right to start a conversation.
186
+ We're on Twitter as [@vsappcenter](https://www.twitter.com/vsappcenter). Additionally you can reach out to us on the [App Center](https://appcenter.ms/apps) portal. Open the "?" menu on the top right corner of screen, then use "Contact support" to file a support ticket. Our support team is there to answer your questions and help you solve your problems.
@@ -180,7 +180,7 @@ module Fastlane
180
180
  File.delete zip_file
181
181
  end
182
182
  UI.message("Creating zip archive: #{zip_file}")
183
- file = Actions::ZipAction.run(path: file, output_path: zip_file)
183
+ file = Actions::ZipAction.run(path: file, output_path: zip_file, symlinks: true)
184
184
  end
185
185
 
186
186
  UI.message("Starting release upload...")
@@ -252,10 +252,11 @@ module Fastlane
252
252
  app_platform = params[:app_platform]
253
253
 
254
254
  platforms = {
255
- Android: %w[Java React-Native Xamarin],
256
- iOS: %w[Objective-C-Swift React-Native Xamarin],
255
+ Android: %w[Java React-Native Xamarin Unity],
256
+ iOS: %w[Objective-C-Swift React-Native Xamarin Unity],
257
257
  macOS: %w[Objective-C-Swift],
258
- Windows: %w[UWP WPF WinForms Unity]
258
+ Windows: %w[UWP WPF WinForms Unity],
259
+ Custom: %w[Custom]
259
260
  }
260
261
 
261
262
  begin
@@ -284,6 +285,30 @@ module Fastlane
284
285
  end
285
286
  end
286
287
 
288
+ def self.add_app_to_distribution_group_if_needed(params)
289
+ return unless params[:destination_type] == 'group' && params[:owner_type] == 'organization' && params[:destinations] != '*'
290
+
291
+ app_distribution_groups = Helper::AppcenterHelper.fetch_distribution_groups(
292
+ api_token: params[:api_token],
293
+ owner_name: params[:owner_name],
294
+ app_name: params[:app_name]
295
+ )
296
+
297
+ group_names = app_distribution_groups.map { |g| g['name'] }
298
+ destination_names = params[:destinations].split(',').map(&:strip)
299
+
300
+ destination_names.each do |destination_name|
301
+ unless group_names.include? destination_name
302
+ Helper::AppcenterHelper.add_new_app_to_distribution_group(
303
+ api_token: params[:api_token],
304
+ owner_name: params[:owner_name],
305
+ app_name: params[:app_name],
306
+ destination_name: destination_name
307
+ )
308
+ end
309
+ end
310
+ end
311
+
287
312
  def self.run(params)
288
313
  values = params.values
289
314
  upload_build_only = params[:upload_build_only]
@@ -294,6 +319,7 @@ module Fastlane
294
319
 
295
320
  # if app found or successfully created
296
321
  if self.get_or_create_app(params)
322
+ self.add_app_to_distribution_group_if_needed(params)
297
323
  release = self.run_release_upload(params) unless upload_dsym_only || upload_mapping_only
298
324
  params[:version] = release['short_version'] if release
299
325
  params[:build_number] = release['version'] if release
@@ -368,7 +394,7 @@ module Fastlane
368
394
 
369
395
  FastlaneCore::ConfigItem.new(key: :app_os,
370
396
  env_name: "APPCENTER_APP_OS",
371
- description: "App OS. Used for new app creation, if app 'app_name' was not found",
397
+ description: "App OS can be Android, iOS, macOS, Windows, Custom. Used for new app creation, if app 'app_name' was not found",
372
398
  optional: true,
373
399
  type: String),
374
400
 
@@ -18,10 +18,17 @@ module Fastlane
18
18
  require 'faraday'
19
19
  require 'faraday_middleware'
20
20
 
21
+ default_api_url = "https://api.appcenter.ms"
22
+ if ENV['APPCENTER_ENV']&.upcase == 'INT'
23
+ default_api_url = "https://api-gateway-core-integration.dev.avalanch.es"
24
+ end
25
+
21
26
  options = {
22
- url: upload_url || ENV.fetch('APPCENTER_UPLOAD_URL', "https://api.appcenter.ms")
27
+ url: upload_url || default_api_url
23
28
  }
24
29
 
30
+ UI.message("DEBUG: BASE URL #{options[:url]}") if ENV['DEBUG']
31
+
25
32
  Faraday.new(options) do |builder|
26
33
  if upload_url
27
34
  builder.request :multipart unless dsym
@@ -42,15 +49,22 @@ module Fastlane
42
49
  def self.create_release_upload(api_token, owner_name, app_name, body)
43
50
  connection = self.connection
44
51
 
45
- response = connection.post("v0.1/apps/#{owner_name}/#{app_name}/release_uploads") do |req|
52
+ url = "v0.1/apps/#{owner_name}/#{app_name}/release_uploads"
53
+ body ||= {}
54
+
55
+ UI.message("DEBUG: POST #{url}") if ENV['DEBUG']
56
+ UI.message("DEBUG: POST body: #{JSON.pretty_generate(body)}\n") if ENV['DEBUG']
57
+
58
+ response = connection.post(url) do |req|
46
59
  req.headers['X-API-Token'] = api_token
47
60
  req.headers['internal-request-source'] = "fastlane"
48
- req.body = body.nil? && {} || body
61
+ req.body = body
49
62
  end
50
63
 
64
+ UI.message("DEBUG: #{response.status} #{JSON.pretty_generate(response.body)}\n") if ENV['DEBUG']
65
+
51
66
  case response.status
52
67
  when 200...300
53
- UI.message("DEBUG: #{JSON.pretty_generate(response.body)}\n") if ENV['DEBUG']
54
68
  response.body
55
69
  when 401
56
70
  UI.user_error!("Auth Error, provided invalid token")
@@ -59,7 +73,7 @@ module Fastlane
59
73
  UI.error("Not found, invalid owner or application name")
60
74
  false
61
75
  when 500...600
62
- UI.crash!("Internal Service Error, please try again later")
76
+ UI.abort_with_message!("Internal Service Error, please try again later")
63
77
  else
64
78
  UI.error("Error #{response.status}: #{response.body}")
65
79
  false
@@ -74,20 +88,27 @@ module Fastlane
74
88
  def self.create_mapping_upload(api_token, owner_name, app_name, file_name, build_number, version)
75
89
  connection = self.connection
76
90
 
77
- response = connection.post("v0.1/apps/#{owner_name}/#{app_name}/symbol_uploads") do |req|
91
+ url = "v0.1/apps/#{owner_name}/#{app_name}/symbol_uploads"
92
+ body = {
93
+ symbol_type: "AndroidProguard",
94
+ file_name: file_name,
95
+ build: build_number,
96
+ version: version,
97
+ }
98
+
99
+ UI.message("DEBUG: POST #{url}") if ENV['DEBUG']
100
+ UI.message("DEBUG: POST body #{JSON.pretty_generate(body)}\n") if ENV['DEBUG']
101
+
102
+ response = connection.post(url) do |req|
78
103
  req.headers['X-API-Token'] = api_token
79
104
  req.headers['internal-request-source'] = "fastlane"
80
- req.body = {
81
- symbol_type: "AndroidProguard",
82
- file_name: file_name,
83
- build: build_number,
84
- version: version,
85
- }
105
+ req.body = body
86
106
  end
87
107
 
108
+ UI.message("DEBUG: #{response.status} #{JSON.pretty_generate(response.body)}\n") if ENV['DEBUG']
109
+
88
110
  case response.status
89
111
  when 200...300
90
- UI.message("DEBUG: #{JSON.pretty_generate(response.body)}\n") if ENV['DEBUG']
91
112
  response.body
92
113
  when 401
93
114
  UI.user_error!("Auth Error, provided invalid token")
@@ -109,17 +130,24 @@ module Fastlane
109
130
  def self.create_dsym_upload(api_token, owner_name, app_name)
110
131
  connection = self.connection
111
132
 
112
- response = connection.post("v0.1/apps/#{owner_name}/#{app_name}/symbol_uploads") do |req|
133
+ url = "v0.1/apps/#{owner_name}/#{app_name}/symbol_uploads"
134
+ body = {
135
+ symbol_type: 'Apple'
136
+ }
137
+
138
+ UI.message("DEBUG: POST #{url}") if ENV['DEBUG']
139
+ UI.message("DEBUG: POST body #{JSON.pretty_generate(body)}\n") if ENV['DEBUG']
140
+
141
+ response = connection.post(url) do |req|
113
142
  req.headers['X-API-Token'] = api_token
114
143
  req.headers['internal-request-source'] = "fastlane"
115
- req.body = {
116
- symbol_type: 'Apple'
117
- }
144
+ req.body = body
118
145
  end
119
146
 
147
+ UI.message("DEBUG: #{response.status} #{JSON.pretty_generate(response.body)}\n") if ENV['DEBUG']
148
+
120
149
  case response.status
121
150
  when 200...300
122
- UI.message("DEBUG: #{JSON.pretty_generate(response.body)}\n") if ENV['DEBUG']
123
151
  response.body
124
152
  when 401
125
153
  UI.user_error!("Auth Error, provided invalid token")
@@ -137,17 +165,24 @@ module Fastlane
137
165
  def self.update_symbol_upload(api_token, owner_name, app_name, symbol_upload_id, status)
138
166
  connection = self.connection
139
167
 
140
- response = connection.patch("v0.1/apps/#{owner_name}/#{app_name}/symbol_uploads/#{symbol_upload_id}") do |req|
168
+ url = "v0.1/apps/#{owner_name}/#{app_name}/symbol_uploads/#{symbol_upload_id}"
169
+ body = {
170
+ status: status
171
+ }
172
+
173
+ UI.message("DEBUG: PATCH #{url}") if ENV['DEBUG']
174
+ UI.message("DEBUG: PATCH body #{JSON.pretty_generate(body)}\n") if ENV['DEBUG']
175
+
176
+ response = connection.patch(url) do |req|
141
177
  req.headers['X-API-Token'] = api_token
142
178
  req.headers['internal-request-source'] = "fastlane"
143
- req.body = {
144
- "status" => status
145
- }
179
+ req.body = body
146
180
  end
147
181
 
182
+ UI.message("DEBUG: #{response.status} #{JSON.pretty_generate(response.body)}\n") if ENV['DEBUG']
183
+
148
184
  case response.status
149
185
  when 200...300
150
- UI.message("DEBUG: #{JSON.pretty_generate(response.body)}\n") if ENV['DEBUG']
151
186
  response.body
152
187
  when 401
153
188
  UI.user_error!("Auth Error, provided invalid token")
@@ -164,6 +199,9 @@ module Fastlane
164
199
  def self.upload_symbol(api_token, owner_name, app_name, symbol, symbol_type, symbol_upload_id, upload_url)
165
200
  connection = self.connection(upload_url, true)
166
201
 
202
+ UI.message("DEBUG: PUT #{upload_url}") if ENV['DEBUG']
203
+ UI.message("DEBUG: PUT body <data>\n") if ENV['DEBUG']
204
+
167
205
  response = connection.put do |req|
168
206
  req.headers['x-ms-blob-type'] = "BlockBlob"
169
207
  req.headers['Content-Length'] = File.size(symbol).to_s
@@ -171,20 +209,22 @@ module Fastlane
171
209
  req.body = Faraday::UploadIO.new(symbol, 'application/octet-stream') if symbol && File.exist?(symbol)
172
210
  end
173
211
 
174
- logType = "dSYM" if (symbol_type == "Apple")
175
- logType = "mapping" if (symbol_type == "Android")
212
+ UI.message("DEBUG: #{response.status} #{JSON.pretty_generate(response.body)}\n") if ENV['DEBUG']
213
+
214
+ log_type = "dSYM" if symbol_type == "Apple"
215
+ log_type = "mapping" if symbol_type == "Android"
176
216
 
177
217
  case response.status
178
218
  when 200...300
179
219
  self.update_symbol_upload(api_token, owner_name, app_name, symbol_upload_id, 'committed')
180
- UI.success("#{logType} uploaded")
220
+ UI.success("#{log_type} uploaded")
181
221
  when 401
182
222
  UI.user_error!("Auth Error, provided invalid token")
183
223
  false
184
224
  else
185
- UI.error("Error uploading #{logType} #{response.status}: #{response.body}")
225
+ UI.error("Error uploading #{log_type} #{response.status}: #{response.body}")
186
226
  self.update_symbol_upload(api_token, owner_name, app_name, symbol_upload_id, 'aborted')
187
- UI.error("#{logType} upload aborted")
227
+ UI.error("#{log_type} upload aborted")
188
228
  false
189
229
  end
190
230
  end
@@ -200,12 +240,17 @@ module Fastlane
200
240
  # ipa field is used for .apk, .aab and .ipa files
201
241
  options[:ipa] = Faraday::UploadIO.new(file, 'application/octet-stream') if file && File.exist?(file)
202
242
 
243
+ UI.message("DEBUG: POST #{upload_url}") if ENV['DEBUG']
244
+ UI.message("DEBUG: POST body <data>\n") if ENV['DEBUG']
245
+
203
246
  response = connection.post do |req|
204
247
  req.options.timeout = timeout
205
248
  req.headers['internal-request-source'] = "fastlane"
206
249
  req.body = options
207
250
  end
208
251
 
252
+ UI.message("DEBUG: #{response.status} #{JSON.pretty_generate(response.body)}\n") if ENV['DEBUG']
253
+
209
254
  case response.status
210
255
  when 200...300
211
256
  UI.message("Binary uploaded")
@@ -225,23 +270,30 @@ module Fastlane
225
270
  def self.update_release_upload(api_token, owner_name, app_name, upload_id, status)
226
271
  connection = self.connection
227
272
 
228
- response = connection.patch("v0.1/apps/#{owner_name}/#{app_name}/release_uploads/#{upload_id}") do |req|
273
+ url = "v0.1/apps/#{owner_name}/#{app_name}/release_uploads/#{upload_id}"
274
+ body = {
275
+ status: status
276
+ }
277
+
278
+ UI.message("DEBUG: PATCH #{url}") if ENV['DEBUG']
279
+ UI.message("DEBUG: PATCH body #{JSON.pretty_generate(body)}\n") if ENV['DEBUG']
280
+
281
+ response = connection.patch(url) do |req|
229
282
  req.headers['X-API-Token'] = api_token
230
283
  req.headers['internal-request-source'] = "fastlane"
231
- req.body = {
232
- "status" => status
233
- }
284
+ req.body = body
234
285
  end
235
286
 
287
+ UI.message("DEBUG: #{response.status} #{JSON.pretty_generate(response.body)}\n") if ENV['DEBUG']
288
+
236
289
  case response.status
237
290
  when 200...300
238
- UI.message("DEBUG: #{JSON.pretty_generate(response.body)}\n") if ENV['DEBUG']
239
291
  response.body
240
292
  when 401
241
293
  UI.user_error!("Auth Error, provided invalid token")
242
294
  false
243
295
  when 500...600
244
- UI.crash!("Internal Service Error, please try again later")
296
+ UI.abort_with_message!("Internal Service Error, please try again later")
245
297
  else
246
298
  UI.error("Error #{response.status}: #{response.body}")
247
299
  false
@@ -251,15 +303,21 @@ module Fastlane
251
303
  # get existing release
252
304
  def self.get_release(api_token, owner_name, app_name, release_id)
253
305
  connection = self.connection
254
- response = connection.get("v0.1/apps/#{owner_name}/#{app_name}/releases/#{release_id}") do |req|
306
+
307
+ url = "v0.1/apps/#{owner_name}/#{app_name}/releases/#{release_id}"
308
+
309
+ UI.message("DEBUG: GET #{url}") if ENV['DEBUG']
310
+
311
+ response = connection.get(url) do |req|
255
312
  req.headers['X-API-Token'] = api_token
256
313
  req.headers['internal-request-source'] = "fastlane"
257
314
  end
258
315
 
316
+ UI.message("DEBUG: #{response.status} #{JSON.pretty_generate(response.body)}\n") if ENV['DEBUG']
317
+
259
318
  case response.status
260
319
  when 200...300
261
320
  release = response.body
262
- UI.message("DEBUG: #{JSON.pretty_generate(release)}") if ENV['DEBUG']
263
321
  release
264
322
  when 404
265
323
  UI.error("Not found, invalid release url")
@@ -277,15 +335,20 @@ module Fastlane
277
335
  def self.get_destination(api_token, owner_name, app_name, destination_type, destination_name)
278
336
  connection = self.connection
279
337
 
280
- response = connection.get("v0.1/apps/#{owner_name}/#{app_name}/distribution_#{destination_type}s/#{ERB::Util.url_encode(destination_name)}") do |req|
338
+ url = "v0.1/apps/#{owner_name}/#{app_name}/distribution_#{destination_type}s/#{ERB::Util.url_encode(destination_name)}"
339
+
340
+ UI.message("DEBUG: GET #{url}") if ENV['DEBUG']
341
+
342
+ response = connection.get(url) do |req|
281
343
  req.headers['X-API-Token'] = api_token
282
344
  req.headers['internal-request-source'] = "fastlane"
283
345
  end
284
346
 
347
+ UI.message("DEBUG: #{response.status} #{JSON.pretty_generate(response.body)}\n") if ENV['DEBUG']
348
+
285
349
  case response.status
286
350
  when 200...300
287
351
  destination = response.body
288
- UI.message("DEBUG: received #{destination_type} #{JSON.pretty_generate(destination)}") if ENV['DEBUG']
289
352
  destination
290
353
  when 404
291
354
  UI.error("Not found, invalid distribution #{destination_type} name")
@@ -303,14 +366,22 @@ module Fastlane
303
366
  def self.update_release(api_token, owner_name, app_name, release_id, release_notes = '')
304
367
  connection = self.connection
305
368
 
306
- response = connection.put("v0.1/apps/#{owner_name}/#{app_name}/releases/#{release_id}") do |req|
369
+ url = "v0.1/apps/#{owner_name}/#{app_name}/releases/#{release_id}"
370
+ body = {
371
+ release_notes: release_notes
372
+ }
373
+
374
+ UI.message("DEBUG: PUT #{url}") if ENV['DEBUG']
375
+ UI.message("DEBUG: PUT body #{JSON.pretty_generate(body)}\n") if ENV['DEBUG']
376
+
377
+ response = connection.put(url) do |req|
307
378
  req.headers['X-API-Token'] = api_token
308
379
  req.headers['internal-request-source'] = "fastlane"
309
- req.body = {
310
- release_notes: release_notes
311
- }
380
+ req.body = body
312
381
  end
313
382
 
383
+ UI.message("DEBUG: #{response.status} #{JSON.pretty_generate(response.body)}\n") if ENV['DEBUG']
384
+
314
385
  case response.status
315
386
  when 200...300
316
387
  # get full release info
@@ -319,8 +390,6 @@ module Fastlane
319
390
 
320
391
  download_url = release['download_url']
321
392
 
322
- UI.message("DEBUG: #{JSON.pretty_generate(release)}") if ENV['DEBUG']
323
-
324
393
  Actions.lane_context[Fastlane::Actions::SharedValues::APPCENTER_DOWNLOAD_LINK] = download_url
325
394
  Actions.lane_context[Fastlane::Actions::SharedValues::APPCENTER_BUILD_INFORMATION] = release
326
395
 
@@ -343,19 +412,25 @@ module Fastlane
343
412
  def self.update_release_metadata(api_token, owner_name, app_name, release_id, dsa_signature)
344
413
  return if dsa_signature.to_s == ''
345
414
 
346
- release_metadata = {
347
- dsa_signature: dsa_signature
415
+ url = "v0.1/apps/#{owner_name}/#{app_name}/releases/#{release_id}"
416
+ body = {
417
+ metadata: {
418
+ dsa_signature: dsa_signature
419
+ }
348
420
  }
349
421
 
422
+ UI.message("DEBUG: PATCH #{url}") if ENV['DEBUG']
423
+ UI.message("DEBUG: PATCH body #{JSON.pretty_generate(body)}\n") if ENV['DEBUG']
424
+
350
425
  connection = self.connection
351
- response = connection.patch("v0.1/apps/#{owner_name}/#{app_name}/releases/#{release_id}") do |req|
426
+ response = connection.patch(url) do |req|
352
427
  req.headers['X-API-Token'] = api_token
353
428
  req.headers['internal-request-source'] = "fastlane"
354
- req.body = {
355
- metadata: release_metadata
356
- }
429
+ req.body = body
357
430
  end
358
431
 
432
+ UI.message("DEBUG: #{response.status} #{JSON.pretty_generate(response.body)}\n") if ENV['DEBUG']
433
+
359
434
  case response.status
360
435
  when 200...300
361
436
  UI.message("Release Metadata was successfully updated for release '#{release_id}'")
@@ -375,20 +450,27 @@ module Fastlane
375
450
  def self.add_to_destination(api_token, owner_name, app_name, release_id, destination_type, destination_id, mandatory_update = false, notify_testers = false)
376
451
  connection = self.connection
377
452
 
378
- UI.message("DEBUG: getting #{release_id}") if ENV['DEBUG']
453
+ url = "v0.1/apps/#{owner_name}/#{app_name}/releases/#{release_id}/#{destination_type}s"
454
+ body = {
455
+ id: destination_id
456
+ }
379
457
 
380
- body = { "id" => destination_id }
381
458
  if destination_type == "group"
382
459
  body["mandatory_update"] = mandatory_update
383
460
  body["notify_testers"] = notify_testers
384
461
  end
385
462
 
386
- response = connection.post("v0.1/apps/#{owner_name}/#{app_name}/releases/#{release_id}/#{destination_type}s") do |req|
463
+ UI.message("DEBUG: POST #{url}") if ENV['DEBUG']
464
+ UI.message("DEBUG: POST body #{JSON.pretty_generate(body)}\n") if ENV['DEBUG']
465
+
466
+ response = connection.post(url) do |req|
387
467
  req.headers['X-API-Token'] = api_token
388
468
  req.headers['internal-request-source'] = "fastlane"
389
469
  req.body = body
390
470
  end
391
471
 
472
+ UI.message("DEBUG: #{response.status} #{JSON.pretty_generate(response.body)}\n") if ENV['DEBUG']
473
+
392
474
  case response.status
393
475
  when 200...300
394
476
  # get full release info
@@ -397,8 +479,6 @@ module Fastlane
397
479
 
398
480
  download_url = release['download_url']
399
481
 
400
- UI.message("DEBUG: received release #{JSON.pretty_generate(release)}") if ENV['DEBUG']
401
-
402
482
  Actions.lane_context[Fastlane::Actions::SharedValues::APPCENTER_DOWNLOAD_LINK] = download_url
403
483
  Actions.lane_context[Fastlane::Actions::SharedValues::APPCENTER_BUILD_INFORMATION] = release
404
484
 
@@ -421,11 +501,17 @@ module Fastlane
421
501
  def self.get_app(api_token, owner_name, app_name)
422
502
  connection = self.connection
423
503
 
424
- response = connection.get("v0.1/apps/#{owner_name}/#{app_name}") do |req|
504
+ url = "v0.1/apps/#{owner_name}/#{app_name}"
505
+
506
+ UI.message("DEBUG: GET #{url}") if ENV['DEBUG']
507
+
508
+ response = connection.get(url) do |req|
425
509
  req.headers['X-API-Token'] = api_token
426
510
  req.headers['internal-request-source'] = "fastlane"
427
511
  end
428
512
 
513
+ UI.message("DEBUG: #{response.status} #{JSON.pretty_generate(response.body)}\n") if ENV['DEBUG']
514
+
429
515
  case response.status
430
516
  when 200...300
431
517
  UI.message("DEBUG: #{JSON.pretty_generate(response.body)}\n") if ENV['DEBUG']
@@ -446,23 +532,28 @@ module Fastlane
446
532
  def self.create_app(api_token, owner_type, owner_name, app_name, app_display_name, os, platform)
447
533
  connection = self.connection
448
534
 
449
- endpoint = owner_type == "user" ? "v0.1/apps" : "v0.1/orgs/#{owner_name}/apps"
535
+ url = owner_type == "user" ? "v0.1/apps" : "v0.1/orgs/#{owner_name}/apps"
536
+ body = {
537
+ display_name: app_display_name,
538
+ name: app_name,
539
+ os: os,
540
+ platform: platform
541
+ }
542
+
543
+ UI.message("DEBUG: POST #{url}") if ENV['DEBUG']
544
+ UI.message("DEBUG: POST body #{JSON.pretty_generate(body)}\n") if ENV['DEBUG']
450
545
 
451
- response = connection.post(endpoint) do |req|
546
+ response = connection.post(url) do |req|
452
547
  req.headers['X-API-Token'] = api_token
453
548
  req.headers['internal-request-source'] = "fastlane"
454
- req.body = {
455
- "display_name" => app_display_name,
456
- "name" => app_name,
457
- "os" => os,
458
- "platform" => platform
459
- }
549
+ req.body = body
460
550
  end
461
551
 
552
+ UI.message("DEBUG: #{response.status} #{JSON.pretty_generate(response.body)}\n") if ENV['DEBUG']
553
+
462
554
  case response.status
463
555
  when 200...300
464
556
  created = response.body
465
- UI.message("DEBUG: #{JSON.pretty_generate(created)}") if ENV['DEBUG']
466
557
  UI.success("Created #{os}/#{platform} app with name \"#{created['name']}\" and display name \"#{created['display_name']}\" for #{owner_type} \"#{owner_name}\"")
467
558
  true
468
559
  when 401
@@ -477,16 +568,19 @@ module Fastlane
477
568
  def self.fetch_distribution_groups(api_token:, owner_name:, app_name:)
478
569
  connection = self.connection
479
570
 
480
- endpoint = "/v0.1/apps/#{owner_name}/#{app_name}/distribution_groups"
571
+ url = "/v0.1/apps/#{owner_name}/#{app_name}/distribution_groups"
572
+
573
+ UI.message("DEBUG: GET #{url}") if ENV['DEBUG']
481
574
 
482
- response = connection.get(endpoint) do |req|
575
+ response = connection.get(url) do |req|
483
576
  req.headers['X-API-Token'] = api_token
484
577
  req.headers['internal-request-source'] = "fastlane"
485
578
  end
486
579
 
580
+ UI.message("DEBUG: #{response.status} #{JSON.pretty_generate(response.body)}\n") if ENV['DEBUG']
581
+
487
582
  case response.status
488
583
  when 200...300
489
- UI.message("DEBUG: #{JSON.pretty_generate(response.body)}\n") if ENV['DEBUG']
490
584
  response.body
491
585
  when 401
492
586
  UI.user_error!("Auth Error, provided invalid token")
@@ -503,16 +597,19 @@ module Fastlane
503
597
  def self.fetch_devices(api_token:, owner_name:, app_name:, distribution_group:)
504
598
  connection = self.connection(nil, false, true)
505
599
 
506
- endpoint = "/v0.1/apps/#{owner_name}/#{app_name}/distribution_groups/#{ERB::Util.url_encode(distribution_group)}/devices/download_devices_list"
600
+ url = "/v0.1/apps/#{owner_name}/#{app_name}/distribution_groups/#{ERB::Util.url_encode(distribution_group)}/devices/download_devices_list"
601
+
602
+ UI.message("DEBUG: GET #{url}") if ENV['DEBUG']
507
603
 
508
- response = connection.get(endpoint) do |req|
604
+ response = connection.get(url) do |req|
509
605
  req.headers['X-API-Token'] = api_token
510
606
  req.headers['internal-request-source'] = "fastlane"
511
607
  end
512
608
 
609
+ UI.message("DEBUG: #{response.status} #{JSON.pretty_generate(response.body)}\n") if ENV['DEBUG']
610
+
513
611
  case response.status
514
612
  when 200...300
515
- UI.message("DEBUG: #{response.body.inspect}") if ENV['DEBUG']
516
613
  response.body
517
614
  when 401
518
615
  UI.user_error!("Auth Error, provided invalid token")
@@ -529,16 +626,19 @@ module Fastlane
529
626
  def self.fetch_releases(api_token:, owner_name:, app_name:)
530
627
  connection = self.connection(nil, false, true)
531
628
 
532
- endpoint = "/v0.1/apps/#{owner_name}/#{app_name}/releases"
629
+ url = "/v0.1/apps/#{owner_name}/#{app_name}/releases"
533
630
 
534
- response = connection.get(endpoint) do |req|
631
+ UI.message("DEBUG: GET #{url}") if ENV['DEBUG']
632
+
633
+ response = connection.get(url) do |req|
535
634
  req.headers['X-API-Token'] = api_token
536
635
  req.headers['internal-request-source'] = "fastlane"
537
636
  end
538
637
 
638
+ UI.message("DEBUG: #{response.status} #{JSON.pretty_generate(response.body)}\n") if ENV['DEBUG']
639
+
539
640
  case response.status
540
641
  when 200...300
541
- UI.message("DEBUG: #{response.body.inspect}") if ENV['DEBUG']
542
642
  JSON.parse(response.body)
543
643
  when 401
544
644
  UI.user_error!("Auth Error, provided invalid token")
@@ -552,17 +652,58 @@ module Fastlane
552
652
  end
553
653
  end
554
654
 
555
- # Note: This does not support testing environment (INT)
556
655
  def self.get_release_url(owner_type, owner_name, app_name, release_id)
557
656
  owner_path = owner_type == "user" ? "users/#{owner_name}" : "orgs/#{owner_name}"
657
+ if ENV['APPCENTER_ENV']&.upcase == 'INT'
658
+ return "https://portal-server-core-integration.dev.avalanch.es/#{owner_path}/apps/#{app_name}/distribute/releases/#{release_id}"
659
+ end
660
+
558
661
  return "https://appcenter.ms/#{owner_path}/apps/#{app_name}/distribute/releases/#{release_id}"
559
662
  end
560
663
 
561
- # Note: This does not support testing environment (INT)
562
664
  def self.get_install_url(owner_type, owner_name, app_name)
563
665
  owner_path = owner_type == "user" ? "users/#{owner_name}" : "orgs/#{owner_name}"
666
+ if ENV['APPCENTER_ENV']&.upcase == 'INT'
667
+ return "https://install.portal-server-core-integration.dev.avalanch.es/#{owner_path}/apps/#{app_name}"
668
+ end
669
+
564
670
  return "https://install.appcenter.ms/#{owner_path}/apps/#{app_name}"
565
671
  end
672
+
673
+ # add new created app to existing distribution group
674
+ def self.add_new_app_to_distribution_group(api_token:, owner_name:, app_name:, destination_name:)
675
+ url = URI.escape("/v0.1/orgs/#{owner_name}/distribution_groups/#{destination_name}/apps")
676
+ body = {
677
+ apps: [
678
+ { name: app_name }
679
+ ]
680
+ }
681
+
682
+ UI.message("DEBUG: POST #{url}") if ENV['DEBUG']
683
+ UI.message("DEBUG: POST body #{JSON.pretty_generate(body)}\n") if ENV['DEBUG']
684
+
685
+ response = connection.post(url) do |req|
686
+ req.headers['X-API-Token'] = api_token
687
+ req.headers['internal-request-source'] = "fastlane"
688
+ req.body = body
689
+ end
690
+
691
+ UI.message("DEBUG: #{response.status} #{JSON.pretty_generate(response.body)}\n") if ENV['DEBUG']
692
+
693
+ case response.status
694
+ when 200...300
695
+ created = response.body
696
+ UI.success("Added new app #{app_name} to distribution group #{destination_name}")
697
+ when 401
698
+ UI.user_error!("Auth Error, provided invalid token")
699
+ when 404
700
+ UI.error("Not found, invalid distribution group name #{destination_name}")
701
+ when 409
702
+ UI.success("App already added to distribution group #{destination_name}")
703
+ else
704
+ UI.error("Error adding app to distribution group #{response.status}: #{response.body}")
705
+ end
706
+ end
566
707
  end
567
708
  end
568
709
  end
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module Appcenter
3
- VERSION = "1.8.0"
3
+ VERSION = "1.8.1"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane-plugin-appcenter
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.0
4
+ version: 1.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Microsoft Corporation
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-03 00:00:00.000000000 Z
11
+ date: 2020-06-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: 0.77.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: webmock
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
111
125
  description:
112
126
  email:
113
127
  executables: []
@@ -141,7 +155,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
141
155
  - !ruby/object:Gem::Version
142
156
  version: '0'
143
157
  requirements: []
144
- rubygems_version: 3.0.4
158
+ rubygems_version: 3.0.8
145
159
  signing_key:
146
160
  specification_version: 4
147
161
  summary: Fastlane plugin for App Center