fastlane-plugin-mad 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 +7 -0
- data/LICENSE +21 -0
- data/README.md +44 -0
- data/lib/fastlane/plugin/mad/actions/mad_action.rb +317 -0
- data/lib/fastlane/plugin/mad/helper/mad_helper.rb +13 -0
- data/lib/fastlane/plugin/mad/mad.rb +13 -0
- data/lib/fastlane/plugin/mad/version.rb +5 -0
- data/lib/fastlane/plugin/mad.rb +1 -0
- metadata +161 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: e77f27ccff773cb7dcbd32ecc90cd8fe29ea0c31a9d22126e1ecdcc4132ea64c
|
|
4
|
+
data.tar.gz: 8f1c2bd9747a9cfe80b54d9fad59be8f10471e3ee0102b7e6c533db3edf677bd
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 3045c80d042167fd4e6775c4f1e02a7f30e8c812401c6ae3efd5d40a200a92bbec851f7fbf711c26413f2750f5281c6c58f3f4182e74816d987427d5dcc40f2a
|
|
7
|
+
data.tar.gz: 8c70d232302c478a2ac9f196af0a499f54c286407b1c04bfe4cc885ebf6d3de901b118f127e4d9a87469cf312d4ea90b3d67b6b37eeed93ec1ed97d2408e8377
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Simon Sarrafi
|
|
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,44 @@
|
|
|
1
|
+
# fastlane-plugin-mad
|
|
2
|
+
|
|
3
|
+
Upload builds to MAD (TestFairy-compatible upload endpoint).
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Add the plugin to your project's `Pluginfile`:
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
gem 'fastlane-plugin-mad', path: '/path/to/fastlane-plugin-mad'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
mad(
|
|
17
|
+
api_key: "your_api_key",
|
|
18
|
+
ipa: "./path/to/app.ipa",
|
|
19
|
+
comment: "Build #{lane_context[SharedValues::BUILD_NUMBER]}"
|
|
20
|
+
)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Parameters
|
|
24
|
+
|
|
25
|
+
| Key | Description | Default |
|
|
26
|
+
|-----|-------------|---------|
|
|
27
|
+
| `api_key` | API Key for MAD | — |
|
|
28
|
+
| `ipa` | Path to your IPA file (iOS) | — |
|
|
29
|
+
| `apk` | Path to your APK file (Android) | — |
|
|
30
|
+
| `symbols_file` | Symbols mapping file | — |
|
|
31
|
+
| `upload_url` | API URL for MAD | `https://app.testfairy.com` |
|
|
32
|
+
| `testers_groups` | Array of tester groups | `[]` |
|
|
33
|
+
| `metrics` | Array of metrics to record | `[]` |
|
|
34
|
+
| `comment` | Additional release notes | `No comment provided` |
|
|
35
|
+
| `auto_update` | Auto-upgrade users (`on`/`off`) | `off` |
|
|
36
|
+
| `notify` | Send email to testers (`on`/`off`) | `off` |
|
|
37
|
+
| `options` | Array of options | `[]` |
|
|
38
|
+
| `custom` | Custom options string | `""` |
|
|
39
|
+
| `timeout` | Request timeout in seconds | — |
|
|
40
|
+
| `tags` | Custom tags for builds | `[]` |
|
|
41
|
+
| `folder_name` | Dashboard folder name | `""` |
|
|
42
|
+
| `landing_page_mode` | Landing page visibility (`open`/`closed`) | `open` |
|
|
43
|
+
| `upload_to_saucelabs` | Upload to Sauce Labs (`on`/`off`) | `off` |
|
|
44
|
+
| `platform` | Platform override | `""` |
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
module Fastlane
|
|
2
|
+
module Actions
|
|
3
|
+
module SharedValues
|
|
4
|
+
MAD_BUILD_URL = :MAD_BUILD_URL
|
|
5
|
+
MAD_DOWNLOAD_URL = :MAD_DOWNLOAD_URL
|
|
6
|
+
MAD_LANDING_PAGE = :MAD_LANDING_PAGE
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
class MadAction < Action
|
|
10
|
+
def self.upload_build(upload_url, ipa, options, timeout)
|
|
11
|
+
require 'faraday'
|
|
12
|
+
require 'faraday_middleware'
|
|
13
|
+
|
|
14
|
+
UI.success("Uploading to #{upload_url}...")
|
|
15
|
+
|
|
16
|
+
connection = Faraday.new(url: upload_url) do |builder|
|
|
17
|
+
builder.request(:multipart)
|
|
18
|
+
builder.request(:url_encoded)
|
|
19
|
+
builder.request(:retry, max: 3, interval: 5)
|
|
20
|
+
builder.response(:json, content_type: /\bjson$/)
|
|
21
|
+
builder.use(FaradayMiddleware::FollowRedirects)
|
|
22
|
+
builder.adapter(:net_http)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
options[:file] = Faraday::UploadIO.new(ipa, 'application/octet-stream') if ipa && File.exist?(ipa)
|
|
26
|
+
|
|
27
|
+
symbols_file = options.delete(:symbols_file)
|
|
28
|
+
if symbols_file
|
|
29
|
+
options[:symbols_file] = Faraday::UploadIO.new(symbols_file, 'application/octet-stream')
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
begin
|
|
33
|
+
connection.post do |req|
|
|
34
|
+
req.options.timeout = timeout
|
|
35
|
+
req.url("/api/upload/")
|
|
36
|
+
req.body = options
|
|
37
|
+
end
|
|
38
|
+
rescue Faraday::TimeoutError
|
|
39
|
+
UI.crash!("Uploading build to MAD timed out ⏳")
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def self.run(params)
|
|
44
|
+
UI.success('Starting with ipa upload to MAD...')
|
|
45
|
+
|
|
46
|
+
metrics_to_client = lambda do |metrics|
|
|
47
|
+
metrics.map do |metric|
|
|
48
|
+
case metric
|
|
49
|
+
when :cpu, :memory, :network, :gps, :battery, :mic, :wifi
|
|
50
|
+
metric.to_s
|
|
51
|
+
when :phone_signal
|
|
52
|
+
'phone-signal'
|
|
53
|
+
else
|
|
54
|
+
UI.user_error!("Unknown metric: #{metric}")
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
options_to_client = lambda do |options|
|
|
60
|
+
options.map do |option|
|
|
61
|
+
case option.to_sym
|
|
62
|
+
when :shake, :anonymous
|
|
63
|
+
option.to_s
|
|
64
|
+
when :video_only_wifi
|
|
65
|
+
'video-only-wifi'
|
|
66
|
+
else
|
|
67
|
+
UI.user_error!("Unknown option: #{option}")
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Rejecting key `upload_url` and `timeout` as we don't need it in options
|
|
73
|
+
client_options = Hash[params.values.reject do |key, value|
|
|
74
|
+
[:upload_url, :timeout].include?(key)
|
|
75
|
+
end.map do |key, value|
|
|
76
|
+
case key
|
|
77
|
+
when :api_key
|
|
78
|
+
[key, value]
|
|
79
|
+
when :ipa
|
|
80
|
+
[key, value]
|
|
81
|
+
when :apk
|
|
82
|
+
[key, value]
|
|
83
|
+
when :symbols_file
|
|
84
|
+
[key, value]
|
|
85
|
+
when :testers_groups
|
|
86
|
+
[key, value.join(',')]
|
|
87
|
+
when :metrics
|
|
88
|
+
[key, metrics_to_client.call(value).join(',')]
|
|
89
|
+
when :comment
|
|
90
|
+
[key, value]
|
|
91
|
+
when :auto_update
|
|
92
|
+
['auto-update', value]
|
|
93
|
+
when :notify
|
|
94
|
+
[key, value]
|
|
95
|
+
when :options
|
|
96
|
+
[key, options_to_client.call(value).join(',')]
|
|
97
|
+
when :custom
|
|
98
|
+
[key, value]
|
|
99
|
+
when :tags
|
|
100
|
+
[key, value.join(',')]
|
|
101
|
+
when :folder_name
|
|
102
|
+
[key, value]
|
|
103
|
+
when :landing_page_mode
|
|
104
|
+
[key, value]
|
|
105
|
+
when :upload_to_saucelabs
|
|
106
|
+
[key, value]
|
|
107
|
+
when :platform
|
|
108
|
+
[key, value]
|
|
109
|
+
else
|
|
110
|
+
UI.user_error!("Unknown parameter: #{key}")
|
|
111
|
+
end
|
|
112
|
+
end]
|
|
113
|
+
|
|
114
|
+
path = params[:ipa] || params[:apk]
|
|
115
|
+
UI.user_error!("No ipa or apk were given") unless path
|
|
116
|
+
|
|
117
|
+
return path if Helper.test?
|
|
118
|
+
|
|
119
|
+
response = self.upload_build(params[:upload_url], path, client_options, params[:timeout])
|
|
120
|
+
if parse_response(response)
|
|
121
|
+
UI.success("Build URL: #{Actions.lane_context[SharedValues::MAD_BUILD_URL]}")
|
|
122
|
+
UI.success("Download URL: #{Actions.lane_context[SharedValues::MAD_DOWNLOAD_URL]}")
|
|
123
|
+
UI.success("Landing Page URL: #{Actions.lane_context[SharedValues::MAD_LANDING_PAGE]}")
|
|
124
|
+
UI.success("Build successfully uploaded to MAD.")
|
|
125
|
+
else
|
|
126
|
+
UI.user_error!("Error when trying to upload ipa to MAD")
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def self.parse_response(response)
|
|
131
|
+
if response.body && response.body.key?('status') && response.body['status'] == 'ok'
|
|
132
|
+
build_url = response.body['build_url']
|
|
133
|
+
app_url = response.body['app_url']
|
|
134
|
+
landing_page_url = response.body['landing_page_url']
|
|
135
|
+
|
|
136
|
+
Actions.lane_context[SharedValues::MAD_BUILD_URL] = build_url
|
|
137
|
+
Actions.lane_context[SharedValues::MAD_DOWNLOAD_URL] = app_url
|
|
138
|
+
Actions.lane_context[SharedValues::MAD_LANDING_PAGE] = landing_page_url
|
|
139
|
+
|
|
140
|
+
return true
|
|
141
|
+
else
|
|
142
|
+
UI.error("Error uploading to MAD: #{response.body}")
|
|
143
|
+
|
|
144
|
+
return false
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
private_class_method :parse_response
|
|
148
|
+
|
|
149
|
+
def self.description
|
|
150
|
+
'Upload a new build to MAD'
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def self.details
|
|
154
|
+
'Upload a new build to MAD (TestFairy-compatible upload endpoint).'
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def self.available_options
|
|
158
|
+
[
|
|
159
|
+
# required
|
|
160
|
+
FastlaneCore::ConfigItem.new(key: :api_key,
|
|
161
|
+
env_name: "FL_MAD_API_KEY",
|
|
162
|
+
description: "API Key for MAD",
|
|
163
|
+
sensitive: true,
|
|
164
|
+
verify_block: proc do |value|
|
|
165
|
+
UI.user_error!("No API key for MAD given, pass using `api_key: 'key'`") unless value.to_s.length > 0
|
|
166
|
+
end),
|
|
167
|
+
FastlaneCore::ConfigItem.new(key: :ipa,
|
|
168
|
+
env_name: 'MAD_IPA_PATH',
|
|
169
|
+
description: 'Path to your IPA file for iOS',
|
|
170
|
+
default_value: Actions.lane_context[SharedValues::IPA_OUTPUT_PATH],
|
|
171
|
+
default_value_dynamic: true,
|
|
172
|
+
optional: true,
|
|
173
|
+
conflicting_options: [:apk],
|
|
174
|
+
verify_block: proc do |value|
|
|
175
|
+
UI.user_error!("Couldn't find ipa file at path '#{value}'") unless File.exist?(value)
|
|
176
|
+
end),
|
|
177
|
+
FastlaneCore::ConfigItem.new(key: :apk,
|
|
178
|
+
env_name: 'MAD_APK_PATH',
|
|
179
|
+
description: 'Path to your APK file for Android',
|
|
180
|
+
default_value: Actions.lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH],
|
|
181
|
+
default_value_dynamic: true,
|
|
182
|
+
optional: true,
|
|
183
|
+
conflicting_options: [:ipa],
|
|
184
|
+
verify_block: proc do |value|
|
|
185
|
+
UI.user_error!("Couldn't find apk file at path '#{value}'") unless File.exist?(value)
|
|
186
|
+
end),
|
|
187
|
+
# optional
|
|
188
|
+
FastlaneCore::ConfigItem.new(key: :symbols_file,
|
|
189
|
+
optional: true,
|
|
190
|
+
env_name: "FL_MAD_SYMBOLS_FILE",
|
|
191
|
+
description: "Symbols mapping file",
|
|
192
|
+
default_value: Actions.lane_context[SharedValues::DSYM_OUTPUT_PATH],
|
|
193
|
+
default_value_dynamic: true,
|
|
194
|
+
verify_block: proc do |value|
|
|
195
|
+
UI.user_error!("Couldn't find dSYM file at path '#{value}'") unless File.exist?(value)
|
|
196
|
+
end),
|
|
197
|
+
FastlaneCore::ConfigItem.new(key: :upload_url,
|
|
198
|
+
env_name: "FL_MAD_UPLOAD_URL",
|
|
199
|
+
description: "API URL for MAD",
|
|
200
|
+
default_value: "https://app.testfairy.com",
|
|
201
|
+
optional: true),
|
|
202
|
+
FastlaneCore::ConfigItem.new(key: :testers_groups,
|
|
203
|
+
optional: true,
|
|
204
|
+
type: Array,
|
|
205
|
+
short_option: '-g',
|
|
206
|
+
env_name: "FL_MAD_TESTERS_GROUPS",
|
|
207
|
+
description: "Array of tester groups to be notified",
|
|
208
|
+
default_value: []),
|
|
209
|
+
FastlaneCore::ConfigItem.new(key: :metrics,
|
|
210
|
+
optional: true,
|
|
211
|
+
type: Array,
|
|
212
|
+
env_name: "FL_MAD_METRICS",
|
|
213
|
+
description: "Array of metrics to record (cpu,memory,network,phone_signal,gps,battery,mic,wifi)",
|
|
214
|
+
default_value: []),
|
|
215
|
+
FastlaneCore::ConfigItem.new(key: :comment,
|
|
216
|
+
optional: true,
|
|
217
|
+
env_name: "FL_MAD_COMMENT",
|
|
218
|
+
description: "Additional release notes for this upload. This text will be added to email notifications",
|
|
219
|
+
default_value: 'No comment provided'),
|
|
220
|
+
FastlaneCore::ConfigItem.new(key: :auto_update,
|
|
221
|
+
optional: true,
|
|
222
|
+
env_name: "FL_MAD_AUTO_UPDATE",
|
|
223
|
+
description: "Allows an easy upgrade of all users to the current version. To enable set to 'on'",
|
|
224
|
+
default_value: 'off'),
|
|
225
|
+
FastlaneCore::ConfigItem.new(key: :notify,
|
|
226
|
+
optional: true,
|
|
227
|
+
env_name: "FL_MAD_NOTIFY",
|
|
228
|
+
description: "Send email to testers",
|
|
229
|
+
default_value: 'off'),
|
|
230
|
+
FastlaneCore::ConfigItem.new(key: :options,
|
|
231
|
+
optional: true,
|
|
232
|
+
type: Array,
|
|
233
|
+
env_name: "FL_MAD_OPTIONS",
|
|
234
|
+
description: "Array of options (shake,video_only_wifi,anonymous)",
|
|
235
|
+
default_value: []),
|
|
236
|
+
FastlaneCore::ConfigItem.new(key: :custom,
|
|
237
|
+
optional: true,
|
|
238
|
+
env_name: "FL_MAD_CUSTOM",
|
|
239
|
+
description: "Array of custom options. Contact support for more information",
|
|
240
|
+
default_value: ''),
|
|
241
|
+
FastlaneCore::ConfigItem.new(key: :timeout,
|
|
242
|
+
env_name: "FL_MAD_TIMEOUT",
|
|
243
|
+
description: "Request timeout in seconds",
|
|
244
|
+
type: Integer,
|
|
245
|
+
optional: true),
|
|
246
|
+
FastlaneCore::ConfigItem.new(key: :tags,
|
|
247
|
+
optional: true,
|
|
248
|
+
env_name: "FL_MAD_TAGS",
|
|
249
|
+
description: "Custom tags that can be used to organize your builds",
|
|
250
|
+
type: Array,
|
|
251
|
+
default_value: []),
|
|
252
|
+
FastlaneCore::ConfigItem.new(key: :folder_name,
|
|
253
|
+
optional: true,
|
|
254
|
+
env_name: "FL_MAD_FOLDER_NAME",
|
|
255
|
+
description: "Name of the dashboard folder that contains this app",
|
|
256
|
+
default_value: ''),
|
|
257
|
+
FastlaneCore::ConfigItem.new(key: :landing_page_mode,
|
|
258
|
+
optional: true,
|
|
259
|
+
env_name: "FL_MAD_LANDING_PAGE_MODE",
|
|
260
|
+
description: "Visibility of build landing after upload. Can be 'open' or 'closed'",
|
|
261
|
+
default_value: 'open',
|
|
262
|
+
verify_block: proc do |value|
|
|
263
|
+
UI.user_error!("The landing page mode can only be open or closed") unless %w(open closed).include?(value)
|
|
264
|
+
end),
|
|
265
|
+
FastlaneCore::ConfigItem.new(key: :upload_to_saucelabs,
|
|
266
|
+
optional: true,
|
|
267
|
+
env_name: "FL_MAD_UPLOAD_TO_SAUCELABS",
|
|
268
|
+
description: "Upload file directly to Sauce Labs. It can be 'on' or 'off'",
|
|
269
|
+
default_value: 'off',
|
|
270
|
+
verify_block: proc do |value|
|
|
271
|
+
UI.user_error!("The upload to Sauce Labs can only be on or off") unless %w(on off).include?(value)
|
|
272
|
+
end),
|
|
273
|
+
FastlaneCore::ConfigItem.new(key: :platform,
|
|
274
|
+
optional: true,
|
|
275
|
+
env_name: "FL_MAD_PLATFORM",
|
|
276
|
+
description: "Use if upload build is not iOS or Android. Contact support for more information",
|
|
277
|
+
default_value: '')
|
|
278
|
+
]
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
def self.example_code
|
|
282
|
+
[
|
|
283
|
+
'mad(
|
|
284
|
+
api_key: "...",
|
|
285
|
+
ipa: "./ipa_file.ipa",
|
|
286
|
+
comment: "Build #{lane_context[SharedValues::BUILD_NUMBER]}",
|
|
287
|
+
)',
|
|
288
|
+
'mad(
|
|
289
|
+
api_key: "...",
|
|
290
|
+
apk: "../build/app/outputs/apk/qa/release/app-qa-release.apk",
|
|
291
|
+
comment: "Build #{lane_context[SharedValues::BUILD_NUMBER]}",
|
|
292
|
+
)'
|
|
293
|
+
]
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
def self.category
|
|
297
|
+
:beta
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
def self.output
|
|
301
|
+
[
|
|
302
|
+
['MAD_BUILD_URL', 'URL for the sessions of the newly uploaded build'],
|
|
303
|
+
['MAD_DOWNLOAD_URL', 'URL directly to the newly uploaded build'],
|
|
304
|
+
['MAD_LANDING_PAGE', "URL of the build's landing page"]
|
|
305
|
+
]
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
def self.authors
|
|
309
|
+
["mad"]
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
def self.is_supported?(platform)
|
|
313
|
+
[:ios, :android].include?(platform)
|
|
314
|
+
end
|
|
315
|
+
end
|
|
316
|
+
end
|
|
317
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require 'fastlane/plugin/mad/version'
|
|
2
|
+
|
|
3
|
+
module Fastlane
|
|
4
|
+
module Mad
|
|
5
|
+
def self.all_classes
|
|
6
|
+
Dir[File.expand_path('**/{actions,helper}/*.rb', File.dirname(__FILE__))]
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
Fastlane::Mad.all_classes.each do |current|
|
|
12
|
+
require current
|
|
13
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require 'fastlane/plugin/mad/mad'
|
metadata
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: fastlane-plugin-mad
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Sauce Labs
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-02-18 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: faraday
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '1.0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '1.0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: faraday_middleware
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '1.0'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '1.0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: bundler
|
|
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: fastlane
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ">="
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '2.0'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '2.0'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: pry
|
|
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: rake
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - ">="
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ">="
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: rspec
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - ">="
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '0'
|
|
104
|
+
type: :development
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - ">="
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '0'
|
|
111
|
+
- !ruby/object:Gem::Dependency
|
|
112
|
+
name: rubocop
|
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
|
114
|
+
requirements:
|
|
115
|
+
- - '='
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: 1.50.2
|
|
118
|
+
type: :development
|
|
119
|
+
prerelease: false
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - '='
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: 1.50.2
|
|
125
|
+
description:
|
|
126
|
+
email: mobileappdistribution@saucelabs.com
|
|
127
|
+
executables: []
|
|
128
|
+
extensions: []
|
|
129
|
+
extra_rdoc_files: []
|
|
130
|
+
files:
|
|
131
|
+
- LICENSE
|
|
132
|
+
- README.md
|
|
133
|
+
- lib/fastlane/plugin/mad.rb
|
|
134
|
+
- lib/fastlane/plugin/mad/actions/mad_action.rb
|
|
135
|
+
- lib/fastlane/plugin/mad/helper/mad_helper.rb
|
|
136
|
+
- lib/fastlane/plugin/mad/mad.rb
|
|
137
|
+
- lib/fastlane/plugin/mad/version.rb
|
|
138
|
+
homepage: https://saucelabs.com/products/mobile-testing/app-betas
|
|
139
|
+
licenses:
|
|
140
|
+
- MIT
|
|
141
|
+
metadata: {}
|
|
142
|
+
post_install_message:
|
|
143
|
+
rdoc_options: []
|
|
144
|
+
require_paths:
|
|
145
|
+
- lib
|
|
146
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
147
|
+
requirements:
|
|
148
|
+
- - ">="
|
|
149
|
+
- !ruby/object:Gem::Version
|
|
150
|
+
version: '2.6'
|
|
151
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
152
|
+
requirements:
|
|
153
|
+
- - ">="
|
|
154
|
+
- !ruby/object:Gem::Version
|
|
155
|
+
version: '0'
|
|
156
|
+
requirements: []
|
|
157
|
+
rubygems_version: 3.4.1
|
|
158
|
+
signing_key:
|
|
159
|
+
specification_version: 4
|
|
160
|
+
summary: Upload builds to MAD (TestFairy-compatible)
|
|
161
|
+
test_files: []
|