fastlane-plugin-mobile_center 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 658f351985d0f8f3958fb121e99949e346f65029
4
+ data.tar.gz: 8ec5929738adbb7d2c219029ea580cc633b70bfb
5
+ SHA512:
6
+ metadata.gz: 1d5b9afc23e560e849b73926a1dd43c63bff9be52809c09c0cc52225e15c698716eede20531a8364d9d8f8bc97f657cedf15ecdfc66211d396cac35d60a83551
7
+ data.tar.gz: 4a9dcc774dd40042d99451ec7d1b5a1f598c291e414aed61d206ad7c984cf1badc7c44fade4ae777e5421c8f8a96f33727516ba68485e6feba53ea4dd6744a46
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Microsoft Corporation. All rights reserved.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE
data/README.md ADDED
@@ -0,0 +1,82 @@
1
+ # mobile_center plugin
2
+
3
+ [![fastlane Plugin Badge](https://rawcdn.githack.com/fastlane/fastlane/master/fastlane/assets/plugin-badge.svg)](https://rubygems.org/gems/fastlane-plugin-mobile_center)
4
+
5
+ ## Getting Started
6
+
7
+ This project is a [_fastlane_](https://github.com/fastlane/fastlane) plugin. To get started with `fastlane-plugin-mobile_center`, add it to your project by running:
8
+
9
+ ```bash
10
+ fastlane add_plugin mobile_center
11
+ ```
12
+
13
+ ## About mobile_center
14
+
15
+ Plugin for [Mobile Center](https://mobile.azure.com). Provides `mobile_center_upload` action for [release distribution](https://docs.microsoft.com/en-us/mobile-center/distribution/uploading) and [dSYM uploads](https://docs.microsoft.com/en-us/mobile-center/crashes/ios)
16
+
17
+ ## Usage
18
+
19
+ Obtain an [API token](https://docs.microsoft.com/en-us/mobile-center/api-docs/). API Token is used for authentication for all Mobile Center API calls.
20
+
21
+ ```
22
+ mobile_center_upload(
23
+ api_token: <mobile center token>,
24
+ owner_name: <your mobile center account name>,
25
+ app_name: <your app name>,
26
+ apk: <path to android build binary>
27
+ )
28
+ ```
29
+
30
+ ## Example
31
+
32
+ Check out the [example `Fastfile`](fastlane/Fastfile) to see how to use this plugin. Try it by cloning the repo, running `fastlane install_plugins` and `bundle exec fastlane test`.
33
+
34
+ Sample uses `.env` for setting private variables like API token, owner name, .etc. You need to replace it in `Fastfile` by your own values.
35
+
36
+ There are three examples in `test` lane:
37
+ - upload release for android with minimum required parameters
38
+ - upload release for ios with all set parameters
39
+ - upload only dSYM file for ios
40
+
41
+ ## Run tests for this plugin
42
+
43
+ To run both the tests, and code style validation, run
44
+
45
+ ```
46
+ rake
47
+ ```
48
+
49
+ To automatically fix many of the styling issues, use
50
+ ```
51
+ rubocop -a
52
+ ```
53
+
54
+ ## Issues and Feedback
55
+
56
+ For any other issues and feedback about this plugin, please submit it to this repository.
57
+
58
+ ## Troubleshooting
59
+
60
+ If you have trouble using plugins, check out the [Plugins Troubleshooting](https://docs.fastlane.tools/plugins/plugins-troubleshooting/) guide.
61
+
62
+ ## Using _fastlane_ Plugins
63
+
64
+ For more information about how the `fastlane` plugin system works, check out the [Plugins documentation](https://docs.fastlane.tools/plugins/create-plugin/).
65
+
66
+ ## About _fastlane_
67
+
68
+ _fastlane_ is the easiest way to automate beta deployments and releases for your iOS and Android apps. To learn more, check out [fastlane.tools](https://fastlane.tools).
69
+
70
+ ## Contributing
71
+
72
+ This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
73
+
74
+ ## Contact
75
+
76
+ ### Intercom
77
+
78
+ If you have further questions, want to provide feedback or you are running into issues, log in to the [Mobile Center](https://mobile.azure.com) portal and use the blue Intercom button on the bottom right to start a conversation with us.
79
+
80
+ ### Twitter
81
+
82
+ We're on Twitter as [@mobilecenter](https://www.twitter.com/mobilecenter).
@@ -0,0 +1,16 @@
1
+ require 'fastlane/plugin/mobile_center/version'
2
+
3
+ module Fastlane
4
+ module MobileCenter
5
+ # Return all .rb files inside the "actions" and "helper" directory
6
+ def self.all_classes
7
+ Dir[File.expand_path('**/{actions,helper}/*.rb', File.dirname(__FILE__))]
8
+ end
9
+ end
10
+ end
11
+
12
+ # By default we want to import all available actions and helpers
13
+ # A plugin can contain any number of actions and plugins
14
+ Fastlane::MobileCenter.all_classes.each do |current|
15
+ require current
16
+ end
@@ -0,0 +1,472 @@
1
+ # rubocop:disable Metrics/ClassLength
2
+ module Fastlane
3
+ module Actions
4
+ module SharedValues
5
+ MOBILE_CENTER_DOWNLOAD_LINK = :MOBILE_CENTER_DOWNLOAD_LINK
6
+ MOBILE_CENTER_BUILD_INFORMATION = :MOBILE_CENTER_BUILD_INFORMATION
7
+ end
8
+
9
+ class MobileCenterUploadAction < Action
10
+ # create request
11
+ def self.connection(upload_url = false, dsym = false)
12
+ require 'faraday'
13
+ require 'faraday_middleware'
14
+
15
+ options = {
16
+ url: upload_url ? upload_url : "https://api.mobile.azure.com"
17
+ }
18
+
19
+ Faraday.new(options) do |builder|
20
+ if upload_url
21
+ builder.request :multipart unless dsym
22
+ builder.request :url_encoded unless dsym
23
+ else
24
+ builder.request :json
25
+ end
26
+ builder.response :json, content_type: /\bjson$/
27
+ builder.use FaradayMiddleware::FollowRedirects
28
+ builder.adapter :net_http
29
+ end
30
+ end
31
+
32
+ # creates new release upload
33
+ # returns:
34
+ # upload_id
35
+ # upload_url
36
+ def self.create_release_upload(api_token, owner_name, app_name)
37
+ connection = self.connection
38
+
39
+ response = connection.post do |req|
40
+ req.url("/v0.1/apps/#{owner_name}/#{app_name}/release_uploads")
41
+ req.headers['X-API-Token'] = api_token
42
+ req.headers['internal-request-source'] = "fastlane"
43
+ req.body = {}
44
+ end
45
+
46
+ case response.status
47
+ when 200...300
48
+ if ENV['DEBUG']
49
+ UI.message("DEBUG: #{JSON.pretty_generate(response.body)}\n")
50
+ end
51
+ response.body
52
+ when 401
53
+ UI.user_error!("Auth Error, provided invalid token")
54
+ false
55
+ when 404
56
+ UI.error("Not found, invalid owner or application name")
57
+ false
58
+ else
59
+ UI.error("Error #{response.status}: #{response.body}")
60
+ false
61
+ end
62
+ end
63
+
64
+ # creates new dSYM upload in mobile center
65
+ # returns:
66
+ # symbol_upload_id
67
+ # upload_url
68
+ # expiration_date
69
+ def self.create_dsym_upload(api_token, owner_name, app_name)
70
+ connection = self.connection
71
+
72
+ response = connection.post do |req|
73
+ req.url("/v0.1/apps/#{owner_name}/#{app_name}/symbol_uploads")
74
+ req.headers['X-API-Token'] = api_token
75
+ req.headers['internal-request-source'] = "fastlane"
76
+ req.body = {
77
+ symbol_type: 'Apple'
78
+ }
79
+ end
80
+
81
+ case response.status
82
+ when 200...300
83
+ if ENV['DEBUG']
84
+ UI.message("DEBUG: #{JSON.pretty_generate(response.body)}\n")
85
+ end
86
+ response.body
87
+ when 401
88
+ UI.user_error!("Auth Error, provided invalid token")
89
+ false
90
+ when 404
91
+ UI.error("Not found, invalid owner or application name")
92
+ false
93
+ else
94
+ UI.error("Error #{response.status}: #{response.body}")
95
+ false
96
+ end
97
+ end
98
+
99
+ # committs or aborts dsym upload
100
+ def self.update_dsym_upload(api_token, owner_name, app_name, symbol_upload_id, status)
101
+ connection = self.connection
102
+
103
+ response = connection.patch do |req|
104
+ req.url("/v0.1/apps/#{owner_name}/#{app_name}/symbol_uploads/#{symbol_upload_id}")
105
+ req.headers['X-API-Token'] = api_token
106
+ req.headers['internal-request-source'] = "fastlane"
107
+ req.body = {
108
+ "status" => status
109
+ }
110
+ end
111
+
112
+ case response.status
113
+ when 200...300
114
+ if ENV['DEBUG']
115
+ UI.message("DEBUG: #{JSON.pretty_generate(response.body)}\n")
116
+ end
117
+ response.body
118
+ else
119
+ UI.error("Error #{response.status}: #{response.body}")
120
+ false
121
+ end
122
+ end
123
+
124
+ # upload dSYM files to specified upload url
125
+ # if succeed, then commits the upload
126
+ # otherwise aborts
127
+ def self.upload_dsym(api_token, owner_name, app_name, dsym, symbol_upload_id, upload_url)
128
+ connection = self.connection(upload_url, true)
129
+
130
+ response = connection.put do |req|
131
+ req.headers['x-ms-blob-type'] = "BlockBlob"
132
+ req.headers['Content-Length'] = File.size(dsym).to_s
133
+ req.headers['internal-request-source'] = "fastlane"
134
+ req.body = Faraday::UploadIO.new(dsym, 'application/octet-stream') if dsym and File.exist?(dsym)
135
+ end
136
+
137
+ case response.status
138
+ when 200...300
139
+ self.update_dsym_upload(api_token, owner_name, app_name, symbol_upload_id, 'committed')
140
+ UI.success("dSYM uploaded")
141
+ else
142
+ UI.error("Error uploading dSYM #{response.status}: #{response.body}")
143
+ self.update_dsym_upload(api_token, owner_name, app_name, symbol_upload_id, 'aborted')
144
+ UI.error("dSYM upload aborted")
145
+ false
146
+ end
147
+ end
148
+
149
+ # upload binary for specified upload_url
150
+ # if succeed, then commits the release
151
+ # otherwise aborts
152
+ def self.upload_build(api_token, owner_name, app_name, file, upload_id, upload_url)
153
+ connection = self.connection(upload_url)
154
+
155
+ options = {}
156
+ options[:upload_id] = upload_id
157
+ # ipa field is used both for .apk and .ipa files
158
+ options[:ipa] = Faraday::UploadIO.new(file, 'application/octet-stream') if file and File.exist?(file)
159
+
160
+ response = connection.post do |req|
161
+ req.headers['internal-request-source'] = "fastlane"
162
+ req.body = options
163
+ end
164
+
165
+ case response.status
166
+ when 200...300
167
+ UI.message("Binary uploaded")
168
+ self.update_release_upload(api_token, owner_name, app_name, upload_id, 'committed')
169
+ else
170
+ UI.error("Error uploading binary #{response.status}: #{response.body}")
171
+ self.update_release_upload(api_token, owner_name, app_name, upload_id, 'aborted')
172
+ UI.error("Release aborted")
173
+ false
174
+ end
175
+ end
176
+
177
+ # Commits or aborts the upload process for a release
178
+ def self.update_release_upload(api_token, owner_name, app_name, upload_id, status)
179
+ connection = self.connection
180
+
181
+ response = connection.patch do |req|
182
+ req.url("/v0.1/apps/#{owner_name}/#{app_name}/release_uploads/#{upload_id}")
183
+ req.headers['X-API-Token'] = api_token
184
+ req.headers['internal-request-source'] = "fastlane"
185
+ req.body = {
186
+ "status" => status
187
+ }
188
+ end
189
+
190
+ case response.status
191
+ when 200...300
192
+ if ENV['DEBUG']
193
+ UI.message("DEBUG: #{JSON.pretty_generate(response.body)}\n")
194
+ end
195
+ response.body
196
+ else
197
+ UI.error("Error #{response.status}: #{response.body}")
198
+ false
199
+ end
200
+ end
201
+
202
+ # add release to distribution group
203
+ def self.add_to_group(api_token, release_url, group_name, release_notes = '')
204
+ connection = self.connection
205
+
206
+ response = connection.patch do |req|
207
+ req.url("/#{release_url}")
208
+ req.headers['X-API-Token'] = api_token
209
+ req.headers['internal-request-source'] = "fastlane"
210
+ req.body = {
211
+ "distribution_group_name" => group_name,
212
+ "release_notes" => release_notes
213
+ }
214
+ end
215
+
216
+ case response.status
217
+ when 200...300
218
+ release = response.body
219
+ download_url = release['download_url']
220
+
221
+ if ENV['DEBUG']
222
+ UI.message("DEBUG: #{JSON.pretty_generate(release)}")
223
+ end
224
+
225
+ Actions.lane_context[SharedValues::MOBILE_CENTER_DOWNLOAD_LINK] = download_url
226
+ Actions.lane_context[SharedValues::MOBILE_CENTER_BUILD_INFORMATION] = release
227
+
228
+ UI.message("Public Download URL: #{download_url}") if download_url
229
+ UI.success("Release #{release['short_version']} was successfully distributed")
230
+
231
+ release
232
+ when 404
233
+ UI.error("Not found, invalid distribution group name")
234
+ false
235
+ else
236
+ UI.error("Error adding to group #{response.status}: #{response.body}")
237
+ false
238
+ end
239
+ end
240
+
241
+ # run whole upload process for dSYM files
242
+ def self.run_dsym_upload(params)
243
+ values = params.values
244
+ api_token = params[:api_token]
245
+ owner_name = params[:owner_name]
246
+ app_name = params[:app_name]
247
+ file = params[:ipa]
248
+ dsym = params[:dsym]
249
+
250
+ dsym_path = nil
251
+ if dsym
252
+ # we can use dsym parameter only if build file is ipa
253
+ if !file or File.extname(file) == '.ipa'
254
+ dsym_path = dsym
255
+ end
256
+ else
257
+ # if dsym is note set, but build is ipa - check default path
258
+ if file and File.exist?(file) and File.extname(file) == '.ipa'
259
+ dsym_path = file.to_s.gsub('.ipa', '.dSYM.zip')
260
+ UI.message("dSYM is found")
261
+ end
262
+ end
263
+
264
+ # if we provided valid dsym path, or <ipa_path>.dSYM.zip was found, start dSYM upload
265
+ if dsym_path and File.exist?(dsym_path)
266
+ if File.directory?(dsym_path)
267
+ UI.message("dSYM path is folder, zipping...")
268
+ dsym_path = Actions::ZipAction.run(path: dsym, output_path: dsym + ".zip")
269
+ UI.message("dSYM files zipped")
270
+ end
271
+
272
+ values[:dsym_path] = dsym_path
273
+
274
+ UI.message("Starting dSYM upload...")
275
+ dsym_upload_details = self.create_dsym_upload(api_token, owner_name, app_name)
276
+
277
+ if dsym_upload_details
278
+ symbol_upload_id = dsym_upload_details['symbol_upload_id']
279
+ upload_url = dsym_upload_details['upload_url']
280
+
281
+ UI.message("Uploading dSYM...")
282
+ self.upload_dsym(api_token, owner_name, app_name, dsym_path, symbol_upload_id, upload_url)
283
+ end
284
+ end
285
+ end
286
+
287
+ # run whole upload process for release
288
+ def self.run_release_upload(params)
289
+ api_token = params[:api_token]
290
+ owner_name = params[:owner_name]
291
+ app_name = params[:app_name]
292
+ group = params[:group]
293
+
294
+ file = [
295
+ params[:ipa],
296
+ params[:apk]
297
+ ].detect { |e| !e.to_s.empty? }
298
+
299
+ UI.user_error!("Couldn't find build file at path '#{file}'") unless file and File.exist?(file)
300
+ UI.user_error!("No Distribute Group given, pass using `group: 'group name'`") unless group and !group.empty?
301
+
302
+ UI.message("Starting release upload...")
303
+ upload_details = self.create_release_upload(api_token, owner_name, app_name)
304
+ if upload_details
305
+ upload_id = upload_details['upload_id']
306
+ upload_url = upload_details['upload_url']
307
+
308
+ UI.message("Uploading release binary...")
309
+ uploaded = self.upload_build(api_token, owner_name, app_name, file, upload_id, upload_url)
310
+
311
+ if uploaded
312
+ release_url = uploaded['release_url']
313
+ UI.message("Release committed")
314
+ self.add_to_group(api_token, release_url, group, params[:release_notes])
315
+ end
316
+ end
317
+ end
318
+
319
+ def self.run(params)
320
+ values = params.values
321
+ upload_dsym_only = params[:upload_dsym_only]
322
+
323
+ self.run_release_upload(params) unless upload_dsym_only
324
+ self.run_dsym_upload(params)
325
+
326
+ return values if Helper.test?
327
+ end
328
+
329
+ def self.description
330
+ "Distribute new release to Mobile Center"
331
+ end
332
+
333
+ def self.authors
334
+ ["Microsoft"]
335
+ end
336
+
337
+ def self.details
338
+ [
339
+ "Symbols will also be uploaded automatically if a `app.dSYM.zip` file is found next to `app.ipa`. In case it is located in a different place you can specify the path explicitly in `:dsym` parameter."
340
+ ]
341
+ end
342
+
343
+ def self.available_options
344
+ [
345
+ FastlaneCore::ConfigItem.new(key: :api_token,
346
+ env_name: "MOBILE_CENTER_API_TOKEN",
347
+ description: "API Token for Mobile Center",
348
+ optional: false,
349
+ type: String,
350
+ verify_block: proc do |value|
351
+ UI.user_error!("No API token for Mobile Center given, pass using `api_token: 'token'`") unless value and !value.empty?
352
+ end),
353
+
354
+ FastlaneCore::ConfigItem.new(key: :owner_name,
355
+ env_name: "MOBILE_CENTER_OWNER_NAME",
356
+ description: "Owner name",
357
+ optional: false,
358
+ type: String,
359
+ verify_block: proc do |value|
360
+ UI.user_error!("No Owner name for Mobile Center given, pass using `owner_name: 'name'`") unless value and !value.empty?
361
+ end),
362
+
363
+ FastlaneCore::ConfigItem.new(key: :app_name,
364
+ env_name: "MOBILE_CENTER_APP_NAME",
365
+ description: "App name",
366
+ optional: false,
367
+ type: String,
368
+ verify_block: proc do |value|
369
+ UI.user_error!("No App name given, pass using `app_name: 'app name'`") unless value and !value.empty?
370
+ end),
371
+
372
+ FastlaneCore::ConfigItem.new(key: :apk,
373
+ env_name: "MOBILE_CENTER_DISTRIBUTE_APK",
374
+ description: "Build release path for android build",
375
+ default_value: Actions.lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH],
376
+ optional: true,
377
+ type: String,
378
+ conflicting_options: [:ipa],
379
+ conflict_block: proc do |value|
380
+ UI.user_error!("You can't use 'apk' and '#{value.key}' options in one run")
381
+ end,
382
+ verify_block: proc do |value|
383
+ accepted_formats = [".apk"]
384
+ UI.user_error!("Only \".apk\" formats are allowed, you provided \"#{File.extname(value)}\"") unless accepted_formats.include? File.extname(value)
385
+ end),
386
+
387
+ FastlaneCore::ConfigItem.new(key: :ipa,
388
+ env_name: "MOBILE_CENTER_DISTRIBUTE_IPA",
389
+ description: "Build release path for ios build",
390
+ default_value: Actions.lane_context[SharedValues::IPA_OUTPUT_PATH],
391
+ optional: true,
392
+ type: String,
393
+ conflicting_options: [:apk],
394
+ conflict_block: proc do |value|
395
+ UI.user_error!("You can't use 'ipa' and '#{value.key}' options in one run")
396
+ end,
397
+ verify_block: proc do |value|
398
+ accepted_formats = [".ipa"]
399
+ UI.user_error!("Only \".ipa\" formats are allowed, you provided \"#{File.extname(value)}\"") unless accepted_formats.include? File.extname(value)
400
+ end),
401
+
402
+ FastlaneCore::ConfigItem.new(key: :dsym,
403
+ env_name: "MOBILE_CENTER_DISTRIBUTE_DSYM",
404
+ description: "Path to your symbols file. For iOS provide path to app.dSYM.zip",
405
+ default_value: Actions.lane_context[SharedValues::DSYM_OUTPUT_PATH],
406
+ optional: true,
407
+ type: String,
408
+ verify_block: proc do |value|
409
+ if value
410
+ UI.user_error!("Couldn't find dSYM file at path '#{value}'") unless File.exist?(value)
411
+ end
412
+ end),
413
+
414
+ FastlaneCore::ConfigItem.new(key: :upload_dsym_only,
415
+ env_name: "MOBILE_CENTER_DISTRIBUTE_UPLOAD_DSYM_ONLY",
416
+ description: "Flag to upload only the dSYM file to Mobile Center",
417
+ optional: true,
418
+ is_string: false,
419
+ default_value: false),
420
+
421
+ FastlaneCore::ConfigItem.new(key: :group,
422
+ env_name: "MOBILE_CENTER_DISTRIBUTE_GROUP",
423
+ description: "Distribute group name",
424
+ default_value: "Collaborators",
425
+ optional: true,
426
+ type: String),
427
+
428
+ FastlaneCore::ConfigItem.new(key: :release_notes,
429
+ env_name: "MOBILE_CENTER_DISTRIBUTE_RELEASE_NOTES",
430
+ description: "Release notes",
431
+ default_value: Actions.lane_context[SharedValues::FL_CHANGELOG] || "No changelog given",
432
+ optional: true,
433
+ type: String)
434
+ ]
435
+ end
436
+
437
+ def self.output
438
+ [
439
+ ['MOBILE_CENTER_DOWNLOAD_LINK', 'The newly generated download link for this build'],
440
+ ['MOBILE_CENTER_BUILD_INFORMATION', 'contains all keys/values from the Mobile CEnter API']
441
+ ]
442
+ end
443
+
444
+ def self.is_supported?(platform)
445
+ true
446
+ end
447
+
448
+ def self.example_code
449
+ [
450
+ 'mobile_center_upload(
451
+ api_token: "...",
452
+ owner_name: "mobile_center_owner",
453
+ app_name: "testing_app",
454
+ apk: "./app-release.apk",
455
+ group: "Testers",
456
+ release_notes: "release notes"
457
+ )',
458
+ 'mobile_center_upload(
459
+ api_token: "...",
460
+ owner_name: "mobile_center_owner",
461
+ app_name: "testing_app",
462
+ apk: "./app-release.ipa",
463
+ group: "Testers",
464
+ dsym: "./app.dSYM.zip",
465
+ release_notes: "release notes"
466
+ )'
467
+ ]
468
+ end
469
+ end
470
+ end
471
+ end
472
+ # rubocop:enable Metrics/ClassLength
@@ -0,0 +1,12 @@
1
+ module Fastlane
2
+ module Helper
3
+ class MobileCenterHelper
4
+ # class methods that you define here become available in your action
5
+ # as `Helper::MobileCenterHelper.your_method`
6
+ #
7
+ def self.show_message
8
+ UI.message("Hello from the mobile_center plugin helper!")
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,5 @@
1
+ module Fastlane
2
+ module MobileCenter
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fastlane-plugin-mobile_center
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Microsoft Corporation
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-05-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: pry
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: fastlane
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: 2.28.9
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: 2.28.9
97
+ description:
98
+ email:
99
+ executables: []
100
+ extensions: []
101
+ extra_rdoc_files: []
102
+ files:
103
+ - LICENSE
104
+ - README.md
105
+ - lib/fastlane/plugin/mobile_center.rb
106
+ - lib/fastlane/plugin/mobile_center/actions/mobile_center_upload_action.rb
107
+ - lib/fastlane/plugin/mobile_center/helper/mobile_center_helper.rb
108
+ - lib/fastlane/plugin/mobile_center/version.rb
109
+ homepage:
110
+ licenses:
111
+ - MIT
112
+ metadata: {}
113
+ post_install_message:
114
+ rdoc_options: []
115
+ require_paths:
116
+ - lib
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ requirements: []
128
+ rubyforge_project:
129
+ rubygems_version: 2.6.8
130
+ signing_key:
131
+ specification_version: 4
132
+ summary: Fastlane plugin for Mobile Center
133
+ test_files: []