fastlane-plugin-zealot 0.2.4 → 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +284 -35
- data/lib/fastlane/plugin/zealot/actions/zealot_action.rb +7 -3
- data/lib/fastlane/plugin/zealot/actions/zealot_debug_file.rb +82 -28
- data/lib/fastlane/plugin/zealot/actions/zealot_sync_devices.rb +146 -0
- data/lib/fastlane/plugin/zealot/actions/zealot_version_check.rb +25 -0
- data/lib/fastlane/plugin/zealot/helper/zealot_helper.rb +62 -3
- data/lib/fastlane/plugin/zealot/version.rb +1 -1
- metadata +14 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '094df9f916199c588e3d991874d996cbcde91fe1318c3ed59745ceeaab381b07'
|
4
|
+
data.tar.gz: fb5dd2f76921dee9a2d144519c534d629927d8e8be3e21bfacb6c09420ba7635
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1e39a53958627bb1ba620320ef996ec2ef3cbc9fa9daa3048f2f80c5851495b92c8756b2db59bad512f375250596c0faf51a5066c19dc8e68a9f6effa54319bc
|
7
|
+
data.tar.gz: 643294ce82684f55c3c82978b07273d9f0156de55bfee73284b597b2e4d5a48b9ee167633904672d657aefe9301315d504a05176f240b357a93f516bcaaf3d3a
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# fastlane-plugin-zealot
|
2
2
|
|
3
3
|
[![fastlane Plugin Badge](https://rawcdn.githack.com/fastlane/fastlane/master/fastlane/assets/plugin-badge.svg)](https://rubygems.org/gems/fastlane-plugin-zealot)
|
4
4
|
|
@@ -14,50 +14,299 @@
|
|
14
14
|
$ fastlane add_plugin zealot
|
15
15
|
```
|
16
16
|
|
17
|
-
##
|
17
|
+
## 功能列表
|
18
|
+
|
19
|
+
插件包含多个 actions 提供大家使用:
|
20
|
+
|
21
|
+
### zealot
|
22
|
+
|
23
|
+
上传 iOS/Android App 至 Zealot 系统,插件会通过参数和 CI 系统自动获取很多辅助信息。包括但不仅限于:
|
24
|
+
|
25
|
+
- 使用 gym 或 gradle 打包生成的 app 文件路径
|
26
|
+
- 解析应用获取的应用名称、打包类型
|
27
|
+
- Git 提交日志
|
28
|
+
- Git 分支名
|
29
|
+
- Git 最后一次提交的 Commit Hash
|
30
|
+
- CI 系统的名称
|
31
|
+
- CI 系统本次构建的 URL
|
32
|
+
|
33
|
+
#### 参数和返回值
|
18
34
|
|
19
35
|
```
|
20
|
-
|
21
|
-
|
|
22
|
-
|
23
|
-
| Key | Description
|
24
|
-
|
25
|
-
| endpoint | The endpoint of zealot
|
26
|
-
| token | The token of user
|
27
|
-
| channel_key | The key of app's channel
|
28
|
-
| file | The path of app file. Optional
|
29
|
-
| | `gym`, `ipa`,
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
36
|
+
+-----------------+-----------------------------------+------------------------+----------+
|
37
|
+
| zealot Options |
|
38
|
+
+-----------------+-----------------------------------+------------------------+----------+
|
39
|
+
| Key | Description | Env Var | Default |
|
40
|
+
+-----------------+-----------------------------------+------------------------+----------+
|
41
|
+
| endpoint | The endpoint of zealot | ZEALOT_ENDPOINT | |
|
42
|
+
| token | The token of user | ZEALOT_TOKEN | |
|
43
|
+
| channel_key | The key of app's channel | ZEALOT_CHANNEL_KEY | |
|
44
|
+
| file | The path of app file. Optional | ZEALOT_FILE | |
|
45
|
+
| | if you use the `gym`, `ipa`, | | |
|
46
|
+
| | `xcodebuild` or `gradle` action. | | |
|
47
|
+
| name | The name of app to display on | ZEALOT_NAME | |
|
48
|
+
| | zealot | | |
|
49
|
+
| changelog | The changelog of app | ZEALOT_CHANGELOG | |
|
50
|
+
| slug | The slug of app | ZEALOT_SLUG | |
|
51
|
+
| release_type | The release type of app | ZEALOT_RELEASE_TYPE | |
|
52
|
+
| branch | The name of git branch | ZEALOT_BRANCH | |
|
53
|
+
| git_commit | The hash of git commit | ZEALOT_GIT_COMMIT | |
|
54
|
+
| custom_fields | The key-value hash of custom | ZEALOT_CUSTOM_FIELDS | |
|
55
|
+
| | fields | | |
|
56
|
+
| password | The password of app to download | ZEALOT_PASSWORD | |
|
57
|
+
| source | The name of upload source | ZEALOT_SOURCE | fastlane |
|
58
|
+
| ci_url | The name of upload source | ZEALOT_CI_CURL | |
|
59
|
+
| timeout | Request timeout in seconds | ZEALOT_TIMEOUT | |
|
60
|
+
| hide_user_token | replase user token to *** to | ZEALOT_HIDE_USER_TOKEN | true |
|
61
|
+
| | keep secret | | |
|
62
|
+
| verify_ssl | Should verify SSL of zealot | ZEALOT_VERIFY_SSL | true |
|
63
|
+
| | service | | |
|
64
|
+
| fail_on_error | Should an error uploading app | ZEALOT_FAIL_ON_ERROR | false |
|
65
|
+
| | cause a failure | | |
|
66
|
+
+-----------------+-----------------------------------+------------------------+----------+
|
67
|
+
* = default value is dependent on the user's system
|
68
|
+
|
69
|
+
+-----------------------+---------------------------------------------+
|
70
|
+
| zealot Output Variables |
|
71
|
+
+-----------------------+---------------------------------------------+
|
72
|
+
| Key | Description |
|
73
|
+
+-----------------------+---------------------------------------------+
|
74
|
+
| ZEALOT_APP_ID | The id of app |
|
75
|
+
| ZEALOT_RELEASE_ID | The id of app's release |
|
76
|
+
| ZEALOT_RELEASE_URL | The release URL of the newly uploaded build |
|
77
|
+
| ZEALOT_INSTALL_URL | The install URL of the newly uploaded build |
|
78
|
+
| ZEALOT_QRCODE_URL | The QRCode URL of the newly uploaded build |
|
79
|
+
| ZEAALOT_ERROR_MESSAGE | The error message during upload process |
|
80
|
+
+-----------------------+---------------------------------------------+
|
43
81
|
```
|
44
82
|
|
45
|
-
|
83
|
+
#### 样例
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
# 自动根据上面结果来获取信息上传
|
87
|
+
lane :automatic_upload do
|
88
|
+
# iOS
|
89
|
+
gym
|
90
|
+
|
91
|
+
# Android
|
92
|
+
gradle
|
93
|
+
|
94
|
+
# 根据 CI 系统自动获取提交日志
|
95
|
+
ci_changelog
|
96
|
+
|
97
|
+
zealot(
|
98
|
+
endpoint: 'http://localhost:3000',
|
99
|
+
token: '...',
|
100
|
+
channel_key: '...'
|
101
|
+
)
|
102
|
+
|
103
|
+
# 或者通过环境变量配置参数
|
104
|
+
ENV['ZEALOT_ENDPOINT'] = 'http://localhost:3000'
|
105
|
+
ENV['ZEALOT_TOKEN'] = '...'
|
106
|
+
ENV['ZEALOT_CHANNEL_KEY'] = '...'
|
107
|
+
|
108
|
+
# 这里就无需再配置参数
|
109
|
+
zealot
|
110
|
+
end
|
111
|
+
|
112
|
+
# 上传指定文件
|
113
|
+
lane :upload_file do
|
114
|
+
zealot(
|
115
|
+
endpoint: 'http://localhost:3000',
|
116
|
+
token: '...',
|
117
|
+
channel_key: '...',
|
118
|
+
file: '.ipa_or_apk',
|
119
|
+
custom_fields: {
|
120
|
+
api_env: '测试环境'
|
121
|
+
}
|
122
|
+
)
|
123
|
+
end
|
124
|
+
```
|
125
|
+
|
126
|
+
### zealot_debug_file
|
127
|
+
|
128
|
+
上传 iOS 的 dSYM 或 Android 的 Proguard 调试文件到 Zealot
|
129
|
+
|
130
|
+
#### 参数和返回值
|
131
|
+
|
132
|
+
```
|
133
|
+
+--------------------+-----------------------------------+---------------------------+---------+
|
134
|
+
| zealot_debug_file Options |
|
135
|
+
+--------------------+-----------------------------------+---------------------------+---------+
|
136
|
+
| Key | Description | Env Var | Default |
|
137
|
+
+--------------------+-----------------------------------+---------------------------+---------+
|
138
|
+
| endpoint | The endpoint of zealot | ZEALOT_ENDPOINT | |
|
139
|
+
| token | The token of user | ZEALOT_TOKEN | |
|
140
|
+
| channel_key | Any channel key of app | ZEALOT_CHANNEL_KEY | |
|
141
|
+
| zip_file | Using given the path of zip file | DF_DSYM_ZIP_FILE | |
|
142
|
+
| | to direct upload | | |
|
143
|
+
| platform | The name of platfrom, avaiable | ZEALOT_PLATFORM | |
|
144
|
+
| | value are | | |
|
145
|
+
| | ios,mac,macos,osx,android | | |
|
146
|
+
| path | The path of debug file | ZEALOT_PATH | |
|
147
|
+
| | (iOS/macOS is archive path for | | |
|
148
|
+
| | Xcode, Android is path for app | | |
|
149
|
+
| | project) | | |
|
150
|
+
| xcode_scheme | The scheme name of app | ZEALOT_XCODE_SCHEME | |
|
151
|
+
| android_build_type | The build type of app | ZEALOT_ANDROID_BUILD_TYPE | release |
|
152
|
+
| android_flavor | The product flavor of app | ZEALOT_ANDROID_FLAVOR | |
|
153
|
+
| extra_files | A set file names | ZEALOT_EXTRA_FILES | [] |
|
154
|
+
| output_path | The output path of compressed | DF_DSYM_OUTPUT_PATH | . |
|
155
|
+
| | dSYM file | | |
|
156
|
+
| release_version | The release version of app | ZEALOT_RELEASE_VERSION | |
|
157
|
+
| | (Android needs) | | |
|
158
|
+
| build_version | The build version of app | ZEALOT_BUILD_VERSION | |
|
159
|
+
| | (Android needs) | | |
|
160
|
+
| overwrite | Overwrite output compressed file | DF_DSYM_OVERWRITE | false |
|
161
|
+
| | if it existed | | |
|
162
|
+
| timeout | Request timeout in seconds | ZEALOT_TIMEOUT | |
|
163
|
+
| verify_ssl | Should verify SSL of zealot | ZEALOT_VERIFY_SSL | true |
|
164
|
+
| | service | | |
|
165
|
+
| fail_on_error | Should an error uploading app | ZEALOT_FAIL_ON_ERROR | false |
|
166
|
+
| | cause a failure? (true/false) | | |
|
167
|
+
+--------------------+-----------------------------------+---------------------------+---------+
|
168
|
+
* = default value is dependent on the user's system
|
169
|
+
|
170
|
+
+-----------------------+-----------------------------------------+
|
171
|
+
| zealot_debug_file Output Variables |
|
172
|
+
+-----------------------+-----------------------------------------+
|
173
|
+
| Key | Description |
|
174
|
+
+-----------------------+-----------------------------------------+
|
175
|
+
| ZEAALOT_ERROR_MESSAGE | The error message during upload process |
|
176
|
+
+-----------------------+-----------------------------------------+
|
177
|
+
```
|
178
|
+
|
179
|
+
#### 样例
|
180
|
+
|
181
|
+
```ruby
|
182
|
+
# 自动根据上面结果来获取信息上传
|
183
|
+
lane :automatic_upload do
|
184
|
+
# iOS
|
185
|
+
gym
|
46
186
|
|
47
|
-
|
187
|
+
# Android
|
188
|
+
gradle
|
48
189
|
|
49
|
-
|
190
|
+
# 根据 CI 系统自动获取提交日志
|
191
|
+
ci_changelog
|
50
192
|
|
51
|
-
|
193
|
+
ENV['ZEALOT_ENDPOINT'] = 'http://localhost:3000'
|
194
|
+
ENV['ZEALOT_TOKEN'] = '...'
|
195
|
+
ENV['ZEALOT_CHANNEL_KEY'] = '...'
|
196
|
+
|
197
|
+
# 自动上传 App 和调试文件
|
198
|
+
zealot
|
199
|
+
zealot_debug_file
|
200
|
+
end
|
201
|
+
```
|
202
|
+
|
203
|
+
### zealot_sync_device
|
204
|
+
|
205
|
+
同步指定 Apple 开发者账号的设备列表信息到 Zealot,主要是为了让使用者更清晰看到每个设备 udid 记录的名称
|
206
|
+
|
207
|
+
#### 参数和返回值
|
208
|
+
|
209
|
+
```
|
210
|
+
+---------------+-----------------------------------+------------------------+---------+
|
211
|
+
| zealot_sync_devices Options |
|
212
|
+
+---------------+-----------------------------------+------------------------+---------+
|
213
|
+
| Key | Description | Env Var | Default |
|
214
|
+
+---------------+-----------------------------------+------------------------+---------+
|
215
|
+
| endpoint | The endpoint of zealot | ZEALOT_ENDPOINT | |
|
216
|
+
| token | The token of user | ZEALOT_TOKEN | |
|
217
|
+
| username | The apple id (username) of Apple | DELIVER_USER | * |
|
218
|
+
| | Developer Portal | | |
|
219
|
+
| team_id | The ID of your Developer Portal | ZEALOT_APPLE_TEAM_ID | * |
|
220
|
+
| | team if you're in multiple teams | | |
|
221
|
+
| team_name | The name of your Developer | ZEALOT_APPLE_TEAM_NAME | * |
|
222
|
+
| | Portal team if you're in | | |
|
223
|
+
| | multiple teams | | |
|
224
|
+
| platform | The platform to use (optional) | ZEALOT_APPLE_PLATFORM | ios |
|
225
|
+
| verify_ssl | Should verify SSL of zealot | ZEALOT_VERIFY_SSL | true |
|
226
|
+
| | service | | |
|
227
|
+
| timeout | Request timeout in seconds | ZEALOT_TIMEOUT | |
|
228
|
+
| fail_on_error | Should an error http request | ZEALOT_FAIL_ON_ERROR | false |
|
229
|
+
| | cause a failure? (true/false) | | |
|
230
|
+
+---------------+-----------------------------------+------------------------+---------+
|
231
|
+
```
|
232
|
+
|
233
|
+
#### 样例
|
234
|
+
|
235
|
+
```ruby
|
236
|
+
lane :sync do
|
237
|
+
zealot_sync_devices(
|
238
|
+
endpoint: "...",
|
239
|
+
token: "...",
|
240
|
+
username: "...",
|
241
|
+
team_id: "..."
|
242
|
+
)
|
243
|
+
end
|
244
|
+
```
|
245
|
+
|
246
|
+
### zealot_version_check
|
247
|
+
|
248
|
+
检查应用版本是否已经上传,避免重复打包、上传已经上传的应用,目前支持两种方式检查:
|
249
|
+
|
250
|
+
- bundle_id + git commit
|
251
|
+
- bundle_id+ release_version + build_version
|
252
|
+
|
253
|
+
参数和各平台实际值对应关系
|
254
|
+
|
255
|
+
参数 | iOS | Android
|
256
|
+
---|---|---
|
257
|
+
bundle_id | bundle_id | package_name
|
258
|
+
release_version | CFBundleShortVersionString | versionName
|
259
|
+
build_version | CFBundleVersion | versionCode
|
260
|
+
|
261
|
+
#### 参数和返回值
|
262
|
+
|
263
|
+
```
|
264
|
+
+-----------------+---------------------------------+------------------------+---------+
|
265
|
+
| zealot_version_check Options |
|
266
|
+
+-----------------+---------------------------------+------------------------+---------+
|
267
|
+
| Key | Description | Env Var | Default |
|
268
|
+
+-----------------+---------------------------------+------------------------+---------+
|
269
|
+
| endpoint | The endpoint of zealot | ZEALOT_ENDPOINT | |
|
270
|
+
| token | The token of user | ZEALOT_TOKEN | |
|
271
|
+
| channel_key | The key of app's channel | ZEALOT_CHANNEL_KEY | |
|
272
|
+
| bundle_id | The bundle id(package name) of | ZEALOT_BUNDLE_ID | |
|
273
|
+
| | app | | |
|
274
|
+
| release_version | The release version of app | ZEALOT_RELEASE_VERSION | |
|
275
|
+
| build_version | The build version of app | ZEALOT_BUILD_VERSION | |
|
276
|
+
| git_commit | The latest git commit of app | ZEALOT_GIT_COMMIT | |
|
277
|
+
| verify_ssl | Should verify SSL of zealot | ZEALOT_VERIFY_SSL | true |
|
278
|
+
| | service | | |
|
279
|
+
| hide_user_token | replase user token to *** to | ZEALOT_HIDE_USER_TOKEN | true |
|
280
|
+
| | keep secret | | |
|
281
|
+
| fail_on_error | Should an error http request | ZEALOT_FAIL_ON_ERROR | false |
|
282
|
+
| | cause a failure? (true/false) | | |
|
283
|
+
+-----------------+---------------------------------+------------------------+---------+
|
284
|
+
* = default value is dependent on the user's system
|
285
|
+
|
286
|
+
+------------------------+---------------------------------------------+
|
287
|
+
| zealot_version_check Output Variables |
|
288
|
+
+------------------------+---------------------------------------------+
|
289
|
+
| Key | Description |
|
290
|
+
+------------------------+---------------------------------------------+
|
291
|
+
| ZEALOT_VERSION_EXISTED | The result of app verison existed (Boolean) |
|
292
|
+
| ZEAALOT_ERROR_MESSAGE | The error message during upload process |
|
293
|
+
+------------------------+---------------------------------------------+
|
294
|
+
Access the output values using `lane_context[SharedValues::VARIABLE_NAME]`
|
295
|
+
|
296
|
+
+-----------------------------------+
|
297
|
+
| zealot_version_check Return Value |
|
298
|
+
+-----------------------------------+
|
299
|
+
| Fastlane::Boolean |
|
300
|
+
```
|
52
301
|
|
53
|
-
##
|
302
|
+
## 更多例子
|
54
303
|
|
55
|
-
|
304
|
+
检查[范例 `Fastfile` 文件](fastlane/Fastfile) 来看看如何使用插件吧
|
56
305
|
|
57
|
-
##
|
306
|
+
## 问题和反馈
|
58
307
|
|
59
|
-
|
308
|
+
使用本插件过程中遇到的任何问题和反馈请提交问题。
|
60
309
|
|
61
|
-
##
|
310
|
+
## 疑惑解答
|
62
311
|
|
63
|
-
|
312
|
+
如果你对 fastlane 不了解建议现看看[本教程](https://icyleaf.com/tags/fastlane/),再看看使用插件的[疑惑解答](https://docs.fastlane.tools/plugins/plugins-troubleshooting/)
|
@@ -31,10 +31,9 @@ module Fastlane
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def self.parse_response(response, upload_url, fail_on_error)
|
34
|
-
return
|
34
|
+
return unless response
|
35
35
|
|
36
36
|
UI.verbose response.body.to_s
|
37
|
-
|
38
37
|
if response.status != 201
|
39
38
|
return show_error("Error uploading to Zealot [#{response.status}]: #{response.body}", fail_on_error)
|
40
39
|
end
|
@@ -58,7 +57,7 @@ module Fastlane
|
|
58
57
|
#####################################################
|
59
58
|
|
60
59
|
def self.description
|
61
|
-
'Upload a
|
60
|
+
'Upload IPA/APK files to Zealot which it provides a self-host Over The Air Server for deployment of Android and iOS apps.'
|
62
61
|
end
|
63
62
|
|
64
63
|
def self.available_options
|
@@ -137,6 +136,11 @@ module Fastlane
|
|
137
136
|
optional: true,
|
138
137
|
default_value: 'fastlane',
|
139
138
|
type: String),
|
139
|
+
FastlaneCore::ConfigItem.new(key: :ci_url,
|
140
|
+
env_name: 'ZEALOT_CI_CURL',
|
141
|
+
description: 'The name of upload source',
|
142
|
+
optional: true,
|
143
|
+
type: String),
|
140
144
|
FastlaneCore::ConfigItem.new(key: :timeout,
|
141
145
|
env_name: 'ZEALOT_TIMEOUT',
|
142
146
|
description: 'Request timeout in seconds',
|
@@ -14,7 +14,7 @@ module Fastlane
|
|
14
14
|
|
15
15
|
def self.run(params)
|
16
16
|
file = generate_zip_file(params)
|
17
|
-
UI.user_error! "Something wrong with
|
17
|
+
UI.user_error! "Something wrong with compressed debug file" unless file
|
18
18
|
|
19
19
|
response = upload_debug_file(params, file)
|
20
20
|
if parse_response(response, params[:endpoint], params[:fail_on_error])
|
@@ -27,56 +27,81 @@ module Fastlane
|
|
27
27
|
next unless value = params[key]
|
28
28
|
obj[key] = value
|
29
29
|
end
|
30
|
-
path = new_params.delete(:path)
|
31
|
-
platform = new_params[:platform]
|
32
30
|
|
33
|
-
|
31
|
+
if (zip_file = params[:zip_file]) && File.file?(zip_file)
|
32
|
+
UI.user_error! "The zip file can not be readable: #{zip_file}" unless File.readable?(zip_file)
|
33
|
+
|
34
|
+
UI.verbose "Using given zip file: #{zip_file}"
|
35
|
+
return zip_file
|
36
|
+
end
|
37
|
+
|
38
|
+
platform = new_params.delete(:platform)
|
39
|
+
if !platform && Fastlane::Actions.lane_context[SharedValues::XCODEBUILD_ARCHIVE]
|
40
|
+
return generate_dsym_zip(new_params, nil)
|
41
|
+
end
|
42
|
+
|
43
|
+
path = new_params.delete(:path)
|
44
|
+
case platform.downcase.to_sym
|
34
45
|
when :ios, :mac, :macos, :osx
|
35
46
|
generate_dsym_zip(new_params, path)
|
36
47
|
when :android
|
37
48
|
generate_proguard_zip(new_params, path)
|
38
49
|
else
|
39
|
-
UI.user_error!("No match value of platform: #{
|
50
|
+
UI.user_error!("No match value of platform: #{platform}, avaiable value are #{PLATFORM.join(',')}.")
|
40
51
|
end
|
41
52
|
end
|
42
53
|
|
43
|
-
def self.generate_dsym_zip(params,
|
44
|
-
params[:archive_path] =
|
45
|
-
path
|
46
|
-
else
|
47
|
-
Actions.lane_context[SharedValues::XCODEBUILD_ARCHIVE] || Fastlane::Actions::DsymAction::ARCHIVE_PATH
|
48
|
-
end
|
49
|
-
|
54
|
+
def self.generate_dsym_zip(params, archive_path)
|
55
|
+
params[:archive_path] = archive_path || Actions.lane_context[SharedValues::XCODEBUILD_ARCHIVE] || Fastlane::Actions::DsymAction::ARCHIVE_PATH
|
50
56
|
params[:scheme] = params.delete(:xcode_scheme)
|
51
57
|
Fastlane::Actions::DsymAction.run(params)
|
52
58
|
end
|
53
59
|
|
54
|
-
def self.generate_proguard_zip(params,
|
55
|
-
params[:app_path] =
|
60
|
+
def self.generate_proguard_zip(params, app_path)
|
61
|
+
params[:app_path] = app_path unless app_path.to_s.empty?
|
56
62
|
params[:build_type] = params.delete(:android_build_type)
|
57
63
|
params[:flavor] = params.delete(:android_flavor)
|
58
64
|
Fastlane::Actions::ProguardAction.run(params)
|
59
65
|
end
|
60
66
|
|
61
67
|
def self.parse_response(response, upload_url, fail_on_error)
|
62
|
-
return
|
68
|
+
return unless response
|
63
69
|
|
64
70
|
UI.verbose response.body.to_s
|
65
|
-
|
66
71
|
if (body = response.body) && (error = body['error'])
|
67
|
-
return show_error("Error uploading to Zealot: #{response.body}", fail_on_error)
|
72
|
+
return show_error("Error uploading to Zealot[#{response.status}]: #{response.body}", fail_on_error)
|
68
73
|
end
|
69
74
|
|
75
|
+
print_uploaded_data(body)
|
76
|
+
|
70
77
|
true
|
71
78
|
end
|
72
79
|
private_class_method :parse_response
|
73
80
|
|
81
|
+
def self.print_uploaded_data(data)
|
82
|
+
rows = data.each_with_object({}) do |(key, value), obj|
|
83
|
+
if key == 'metadata'
|
84
|
+
obj["#{key} (#{value.size})"] = value.each_with_object([]) do |item, obj|
|
85
|
+
obj << item.map {|k, v| "#{k}: #{v}" }.join("\n")
|
86
|
+
end.join("\n-------------------------\n")
|
87
|
+
else
|
88
|
+
obj[key] = value.to_s
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
puts Terminal::Table.new(
|
93
|
+
title: 'Uploaded debug file information'.green,
|
94
|
+
rows: rows
|
95
|
+
)
|
96
|
+
end
|
97
|
+
private_class_method :print_uploaded_data
|
98
|
+
|
74
99
|
#####################################################
|
75
100
|
# @!group Documentation
|
76
101
|
#####################################################
|
77
102
|
|
78
103
|
def self.description
|
79
|
-
'Upload a
|
104
|
+
'Upload dSYM/Proguard files to Zealot which it provides a self-host Over The Air Server for deployment of Android and iOS apps.'
|
80
105
|
end
|
81
106
|
|
82
107
|
def self.available_options
|
@@ -95,15 +120,21 @@ module Fastlane
|
|
95
120
|
type: String),
|
96
121
|
FastlaneCore::ConfigItem.new(key: :channel_key,
|
97
122
|
env_name: 'ZEALOT_CHANNEL_KEY',
|
98
|
-
description: '
|
123
|
+
description: 'Any channel key of app',
|
124
|
+
verify_block: proc do |value|
|
125
|
+
UI.user_error!("No channel key of app, pass using `channel_key: 'channel_key'`") if value.nil? || value.empty?
|
126
|
+
end,
|
127
|
+
type: String),
|
128
|
+
FastlaneCore::ConfigItem.new(key: :zip_file,
|
129
|
+
env_name: 'DF_DSYM_ZIP_FILE',
|
130
|
+
description: "Using given the path of zip file to direct upload",
|
131
|
+
optional: true,
|
99
132
|
type: String),
|
100
133
|
FastlaneCore::ConfigItem.new(key: :platform,
|
101
134
|
env_name: 'ZEALOT_PLATFORM',
|
102
135
|
description: "The name of platfrom, avaiable value are #{PLATFORM.join(',')}",
|
103
|
-
|
104
|
-
|
105
|
-
end,
|
106
|
-
type: :Symbol),
|
136
|
+
optional: true,
|
137
|
+
type: String),
|
107
138
|
FastlaneCore::ConfigItem.new(key: :path,
|
108
139
|
env_name: 'ZEALOT_PATH',
|
109
140
|
description: 'The path of debug file (iOS/macOS is archive path for Xcode, Android is path for app project)',
|
@@ -139,12 +170,12 @@ module Fastlane
|
|
139
170
|
type: String),
|
140
171
|
FastlaneCore::ConfigItem.new(key: :release_version,
|
141
172
|
env_name: 'ZEALOT_RELEASE_VERSION',
|
142
|
-
description: 'The release version of app',
|
173
|
+
description: 'The release version of app (Android needs)',
|
143
174
|
optional: true,
|
144
175
|
type: String),
|
145
176
|
FastlaneCore::ConfigItem.new(key: :build_version,
|
146
177
|
env_name: 'ZEALOT_BUILD_VERSION',
|
147
|
-
description: 'The build version of app',
|
178
|
+
description: 'The build version of app (Android needs)',
|
148
179
|
optional: true,
|
149
180
|
type: String),
|
150
181
|
FastlaneCore::ConfigItem.new(key: :overwrite,
|
@@ -174,14 +205,37 @@ module Fastlane
|
|
174
205
|
|
175
206
|
def self.example_code
|
176
207
|
[
|
208
|
+
'zealot_debug_file(
|
209
|
+
endpoint: "...",
|
210
|
+
token: "...",
|
211
|
+
channel_key: "...",
|
212
|
+
platform: :ios
|
213
|
+
)',
|
214
|
+
'zealot_debug_file(
|
215
|
+
endpoint: "...",
|
216
|
+
token: "...",
|
217
|
+
channel_key: "...",
|
218
|
+
platform: :ios,
|
219
|
+
xcode_scheme: "AppName"
|
220
|
+
)',
|
221
|
+
'zealot_debug_file(
|
222
|
+
endpoint: "...",
|
223
|
+
token: "...",
|
224
|
+
channel_key: "...",
|
225
|
+
platform: :android,
|
226
|
+
android_build_type: "release",
|
227
|
+
android_flavor: "google_play",
|
228
|
+
release_version: "1.1.0",
|
229
|
+
build_version: "1",
|
230
|
+
)',
|
177
231
|
'zealot_debug_file(
|
178
232
|
endpoint: "...",
|
179
233
|
token: "...",
|
180
234
|
channel_key: "...",
|
181
235
|
zip_file: "...",
|
182
|
-
release_version: "
|
183
|
-
build_version: "
|
184
|
-
)'
|
236
|
+
release_version: "1.1.0",
|
237
|
+
build_version: "1",
|
238
|
+
)',
|
185
239
|
]
|
186
240
|
end
|
187
241
|
|
@@ -0,0 +1,146 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'credentials_manager'
|
4
|
+
require 'fastlane/action'
|
5
|
+
require_relative '../helper/zealot_helper'
|
6
|
+
|
7
|
+
module Fastlane
|
8
|
+
module Actions
|
9
|
+
|
10
|
+
class ZealotSyncDevicesAction < Action
|
11
|
+
extend Fastlane::Helper::ZealotHelper
|
12
|
+
|
13
|
+
def self.run(params)
|
14
|
+
require 'spaceship'
|
15
|
+
|
16
|
+
credentials = CredentialsManager::AccountManager.new(user: params[:username])
|
17
|
+
Spaceship.login(credentials.user, credentials.password)
|
18
|
+
Spaceship.select_team
|
19
|
+
|
20
|
+
UI.message('Fetching list of currently registered devices...')
|
21
|
+
all_platforms = Set[params[:platform]]
|
22
|
+
supported_platforms = all_platforms.select { |platform| self.is_supported?(platform.to_sym) }
|
23
|
+
|
24
|
+
devices = supported_platforms.flat_map { |platform| Spaceship::Device.all(mac: platform == "mac") }
|
25
|
+
|
26
|
+
print_table(build_table_data(params, devices), title: 'zealot_sync_devices')
|
27
|
+
|
28
|
+
UI.verbose("Syncing devices to #{params[:endpoint]} ...")
|
29
|
+
failed_devices = []
|
30
|
+
devices.each do |device|
|
31
|
+
begin
|
32
|
+
sync_deivce(params, device)
|
33
|
+
rescue Faraday::ConnectionFailed
|
34
|
+
failed_devices << {udid: device.udid, error: 'Can not connecting to Zealot'}
|
35
|
+
rescue Faraday::TimeoutError
|
36
|
+
failed_devices << {udid: device.udid, error: 'Timed out to Zealot'}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
failed = failed_devices.size
|
41
|
+
successed = devices.size - failed
|
42
|
+
UI.success "Successful Synced devices. success: #{successed}, failed: #{failed}"
|
43
|
+
UI.verbose "Failed devices: #{failed_devices}"
|
44
|
+
end
|
45
|
+
|
46
|
+
#####################################################
|
47
|
+
# @!group Documentation
|
48
|
+
#####################################################
|
49
|
+
|
50
|
+
def self.description
|
51
|
+
'Check app version exists from Zealot'
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.available_options
|
55
|
+
[
|
56
|
+
FastlaneCore::ConfigItem.new(key: :endpoint,
|
57
|
+
env_name: 'ZEALOT_ENDPOINT',
|
58
|
+
description: 'The endpoint of zealot',
|
59
|
+
type: String),
|
60
|
+
FastlaneCore::ConfigItem.new(key: :token,
|
61
|
+
env_name: 'ZEALOT_TOKEN',
|
62
|
+
description: 'The token of user',
|
63
|
+
sensitive: true,
|
64
|
+
verify_block: proc do |value|
|
65
|
+
UI.user_error!("No user token for Zealot given, pass using `token: 'token'`") if value.nil? || value.empty?
|
66
|
+
end,
|
67
|
+
type: String),
|
68
|
+
FastlaneCore::ConfigItem.new(key: :username,
|
69
|
+
env_name: 'DELIVER_USER',
|
70
|
+
description: 'The apple id (username) of Apple Developer Portal',
|
71
|
+
default_value_dynamic: true,
|
72
|
+
optional: true,
|
73
|
+
type: String),
|
74
|
+
FastlaneCore::ConfigItem.new(key: :team_id,
|
75
|
+
env_name: 'ZEALOT_APPLE_TEAM_ID',
|
76
|
+
description: 'The ID of your Developer Portal team if you\'re in multiple teams',
|
77
|
+
default_value: CredentialsManager::AppfileConfig.try_fetch_value(:team_id),
|
78
|
+
default_value_dynamic: true,
|
79
|
+
optional: true,
|
80
|
+
type: String,
|
81
|
+
verify_block: proc do |value|
|
82
|
+
ENV["FASTLANE_TEAM_ID"] = value.to_s
|
83
|
+
end),
|
84
|
+
FastlaneCore::ConfigItem.new(key: :team_name,
|
85
|
+
env_name: 'ZEALOT_APPLE_TEAM_NAME',
|
86
|
+
description: 'The name of your Developer Portal team if you\'re in multiple teams',
|
87
|
+
default_value: CredentialsManager::AppfileConfig.try_fetch_value(:team_id),
|
88
|
+
default_value_dynamic: true,
|
89
|
+
optional: true,
|
90
|
+
type: String,
|
91
|
+
verify_block: proc do |value|
|
92
|
+
ENV["FASTLANE_TEAM_NAME"] = value.to_s
|
93
|
+
end),
|
94
|
+
FastlaneCore::ConfigItem.new(key: :platform,
|
95
|
+
env_name: 'ZEALOT_APPLE_PLATFORM',
|
96
|
+
description: 'The platform to use (optional)',
|
97
|
+
optional: true,
|
98
|
+
default_value: 'ios',
|
99
|
+
verify_block: proc do |value|
|
100
|
+
UI.user_error!('The platform can only be ios or mac') unless %('ios', 'mac').include?(value)
|
101
|
+
end),
|
102
|
+
FastlaneCore::ConfigItem.new(key: :verify_ssl,
|
103
|
+
env_name: 'ZEALOT_VERIFY_SSL',
|
104
|
+
description: 'Should verify SSL of zealot service',
|
105
|
+
optional: true,
|
106
|
+
default_value: true,
|
107
|
+
type: Boolean),
|
108
|
+
FastlaneCore::ConfigItem.new(key: :timeout,
|
109
|
+
env_name: 'ZEALOT_TIMEOUT',
|
110
|
+
description: 'Request timeout in seconds',
|
111
|
+
type: Integer,
|
112
|
+
optional: true),
|
113
|
+
FastlaneCore::ConfigItem.new(key: :fail_on_error,
|
114
|
+
env_name: 'ZEALOT_FAIL_ON_ERROR',
|
115
|
+
description: 'Should an error http request cause a failure? (true/false)',
|
116
|
+
optional: true,
|
117
|
+
default_value: false,
|
118
|
+
type: Boolean)
|
119
|
+
]
|
120
|
+
end
|
121
|
+
|
122
|
+
def self.example_code
|
123
|
+
[
|
124
|
+
'zealot_sync_devices(
|
125
|
+
endpoint: "...",
|
126
|
+
token: "...",
|
127
|
+
username: "...",
|
128
|
+
team_id: "..."
|
129
|
+
)'
|
130
|
+
]
|
131
|
+
end
|
132
|
+
|
133
|
+
def self.category
|
134
|
+
:beta
|
135
|
+
end
|
136
|
+
|
137
|
+
def self.authors
|
138
|
+
['icyleaf']
|
139
|
+
end
|
140
|
+
|
141
|
+
def self.is_supported?(_)
|
142
|
+
true
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -7,6 +7,14 @@ module Fastlane
|
|
7
7
|
module Actions
|
8
8
|
module SharedValues
|
9
9
|
ZEALOT_VERSION_EXISTED = :ZEALOT_VERSION_EXISTED
|
10
|
+
ZEALOT_LATEST_RELEASE_ID = :ZEALOT_LATEST_RELEASE_ID
|
11
|
+
ZEALOT_LATEST_RELEASE_VERSION = :ZEALOT_LATEST_RELEASE_VERSION
|
12
|
+
ZEALOT_LATEST_BUILD_VERSION = :ZEALOT_LATEST_VERSION
|
13
|
+
ZEALOT_LATEST_VERSION = :ZEALOT_LATEST_VERSION
|
14
|
+
ZEALOT_LATEST_RELEASE_URL = :ZEALOT_LATEST_RELEASE_URL
|
15
|
+
ZEALOT_LATEST_QRCODE_URL = :ZEALOT_LATEST_QRCODE_URL
|
16
|
+
ZEALOT_LATEST_INSTALL_URL = :ZEALOT_LATEST_INSTALL_URL
|
17
|
+
ZEALOT_LATEST_CONTEXT = :ZEALOT_LATEST_CONTEXT
|
10
18
|
end
|
11
19
|
|
12
20
|
class ZealotVersionCheckAction < Action
|
@@ -31,6 +39,17 @@ module Fastlane
|
|
31
39
|
Actions.lane_context[SharedValues::ZEALOT_VERSION_EXISTED] = is_existed
|
32
40
|
|
33
41
|
if is_existed
|
42
|
+
context = response.body
|
43
|
+
|
44
|
+
Actions.lane_context[SharedValues::ZEALOT_LATEST_RELEASE_ID] = context['id']
|
45
|
+
Actions.lane_context[SharedValues::ZEALOT_LATEST_RELEASE_VERSION] = context['release_version']
|
46
|
+
Actions.lane_context[SharedValues::ZEALOT_LATEST_BUILD_VERSION] = context['build_version']
|
47
|
+
Actions.lane_context[SharedValues::ZEALOT_LATEST_VERSION] = context['version']
|
48
|
+
Actions.lane_context[SharedValues::ZEALOT_LATEST_RELEASE_URL] = context['release_url']
|
49
|
+
Actions.lane_context[SharedValues::ZEALOT_LATEST_INSTALL_URL] = context['install_url']
|
50
|
+
Actions.lane_context[SharedValues::ZEALOT_LATEST_QRCODE_URL] = context['qrcode_url']
|
51
|
+
Actions.lane_context[SharedValues::ZEALOT_LATEST_CONTEXT] = context
|
52
|
+
|
34
53
|
UI.important 'Found app version, you can skip upload it'
|
35
54
|
else
|
36
55
|
UI.success 'Not found app version, you can upload it'
|
@@ -92,6 +111,12 @@ module Fastlane
|
|
92
111
|
optional: true,
|
93
112
|
default_value: true,
|
94
113
|
type: Boolean),
|
114
|
+
FastlaneCore::ConfigItem.new(key: :hide_user_token,
|
115
|
+
env_name: 'ZEALOT_HIDE_USER_TOKEN',
|
116
|
+
description: 'replase user token to *** to keep secret',
|
117
|
+
optional: true,
|
118
|
+
default_value: true,
|
119
|
+
type: Boolean),
|
95
120
|
FastlaneCore::ConfigItem.new(key: :fail_on_error,
|
96
121
|
env_name: 'ZEALOT_FAIL_ON_ERROR',
|
97
122
|
description: 'Should an error http request cause a failure? (true/false)',
|
@@ -57,7 +57,7 @@ module Fastlane
|
|
57
57
|
rescue Faraday::ConnectionFailed
|
58
58
|
show_error('Can not connecting to Zealot', params[:fail_on_error])
|
59
59
|
rescue Faraday::TimeoutError
|
60
|
-
show_error('Uploading build to
|
60
|
+
show_error('Uploading build to Zealot timed out ⏳', params[:fail_on_error])
|
61
61
|
end
|
62
62
|
|
63
63
|
def upload_app_params(params)
|
@@ -71,14 +71,16 @@ module Fastlane
|
|
71
71
|
end
|
72
72
|
|
73
73
|
UPLOAD_APP_PARAMS_KEYS = %w[
|
74
|
-
name changelog release_type slug branch
|
75
|
-
|
74
|
+
name changelog release_type slug branch password
|
75
|
+
git_commit custom_fields source ci_url
|
76
76
|
].freeze
|
77
77
|
|
78
78
|
def avialable_upload_app_params(params)
|
79
79
|
UPLOAD_APP_PARAMS_KEYS.each_with_object({}) do |key, obj|
|
80
80
|
value = params.fetch(key.to_sym, ask: false)
|
81
81
|
value = JSON.dump(value) if key == 'custom_fields' && value
|
82
|
+
value = detect_ci_url(params) if key == 'ci_url'
|
83
|
+
value = detect_source(params) if key == 'source'
|
82
84
|
obj[key.to_sym] = value if value && !value.empty?
|
83
85
|
end
|
84
86
|
end
|
@@ -133,8 +135,30 @@ module Fastlane
|
|
133
135
|
end
|
134
136
|
end
|
135
137
|
|
138
|
+
#######################################
|
139
|
+
|
140
|
+
def sync_deivce(params, device)
|
141
|
+
body = { token: params[:token], name: device.name, model: device.model }
|
142
|
+
http_request(:put, "/api/devices/#{device.udid}", body, params)
|
143
|
+
end
|
144
|
+
|
145
|
+
def build_table_data(params, devices)
|
146
|
+
data = {
|
147
|
+
'Endpoint' => params[:endpoint],
|
148
|
+
'Token' => params[:token],
|
149
|
+
"Devices (#{devices.size})" => devices.map {|d| "#{d.name}: #{d.udid}"}.join("\n")
|
150
|
+
}
|
151
|
+
end
|
152
|
+
|
136
153
|
#####################################
|
137
154
|
|
155
|
+
def http_request(method, uri, body, params)
|
156
|
+
connection = make_connection(params[:endpoint], params[:verify_ssl])
|
157
|
+
connection.run_request(method, uri, body, nil) do |req|
|
158
|
+
req.options.timeout = params[:timeout] if params[:timeout]
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
138
162
|
def make_connection(endpoint, verify_ssl = true)
|
139
163
|
require 'faraday'
|
140
164
|
require 'faraday_middleware'
|
@@ -155,6 +179,7 @@ module Fastlane
|
|
155
179
|
rows.delete(k) if hidden_keys.include?(k.to_sym)
|
156
180
|
rows[k] = rows[k].path if rows[k].is_a?(UploadIO)
|
157
181
|
end
|
182
|
+
|
158
183
|
puts Terminal::Table.new(
|
159
184
|
title: "Summary for #{title} #{Fastlane::Zealot::VERSION}".green,
|
160
185
|
rows: rows
|
@@ -178,6 +203,40 @@ module Fastlane
|
|
178
203
|
|
179
204
|
[:token]
|
180
205
|
end
|
206
|
+
|
207
|
+
def detect_source(params)
|
208
|
+
return 'jenkins' if jenkins?
|
209
|
+
return 'gitlab-ci' if gitlab?
|
210
|
+
|
211
|
+
params[:source]
|
212
|
+
end
|
213
|
+
|
214
|
+
def detect_ci_url(params)
|
215
|
+
return params[:ci_url] if params[:ci_url]
|
216
|
+
|
217
|
+
if ENV['BUILD_URL']
|
218
|
+
# Jenkins
|
219
|
+
return ENV['BUILD_URL']
|
220
|
+
elsif ENV['CI_JOB_URL']
|
221
|
+
# Gitlab >= 11.1, Runner 0.5
|
222
|
+
return ENV['CI_JOB_URL']
|
223
|
+
elsif ENV['CI_PROJECT_URL']
|
224
|
+
# Gitlab >= 8.10, Runner 0.5
|
225
|
+
return "#{ENV['CI_PROJECT_URL']}/-/jobs/#{ENV['CI_BUILD_ID']}"
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
def jenkins?
|
230
|
+
%w(JENKINS_URL JENKINS_HOME).each do |current|
|
231
|
+
return true if ENV.key?(current)
|
232
|
+
end
|
233
|
+
|
234
|
+
return false
|
235
|
+
end
|
236
|
+
|
237
|
+
def gitlab?
|
238
|
+
ENV.key?('GITLAB_CI')
|
239
|
+
end
|
181
240
|
end
|
182
241
|
end
|
183
242
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fastlane-plugin-zealot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- icyleaf
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-12-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -28,16 +28,16 @@ dependencies:
|
|
28
28
|
name: fastlane-plugin-debug_file
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: 0.3.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.
|
40
|
+
version: 0.3.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: pry
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -164,7 +164,7 @@ dependencies:
|
|
164
164
|
- - ">="
|
165
165
|
- !ruby/object:Gem::Version
|
166
166
|
version: 2.137.0
|
167
|
-
description:
|
167
|
+
description:
|
168
168
|
email: icyleaf.cn@gmail.com
|
169
169
|
executables: []
|
170
170
|
extensions: []
|
@@ -175,6 +175,7 @@ files:
|
|
175
175
|
- lib/fastlane/plugin/zealot.rb
|
176
176
|
- lib/fastlane/plugin/zealot/actions/zealot_action.rb
|
177
177
|
- lib/fastlane/plugin/zealot/actions/zealot_debug_file.rb
|
178
|
+
- lib/fastlane/plugin/zealot/actions/zealot_sync_devices.rb
|
178
179
|
- lib/fastlane/plugin/zealot/actions/zealot_version_check.rb
|
179
180
|
- lib/fastlane/plugin/zealot/helper/zealot_helper.rb
|
180
181
|
- lib/fastlane/plugin/zealot/version.rb
|
@@ -182,7 +183,7 @@ homepage: https://github.com/getzealot/fastlane-plugin-zealot
|
|
182
183
|
licenses:
|
183
184
|
- MIT
|
184
185
|
metadata: {}
|
185
|
-
post_install_message:
|
186
|
+
post_install_message:
|
186
187
|
rdoc_options: []
|
187
188
|
require_paths:
|
188
189
|
- lib
|
@@ -197,8 +198,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
197
198
|
- !ruby/object:Gem::Version
|
198
199
|
version: '0'
|
199
200
|
requirements: []
|
200
|
-
rubygems_version: 3.
|
201
|
-
signing_key:
|
201
|
+
rubygems_version: 3.1.2
|
202
|
+
signing_key:
|
202
203
|
specification_version: 4
|
203
|
-
summary: Upload
|
204
|
+
summary: Upload IPA/APK/dSYM/Proguard files to Zealot which it provides a self-host
|
205
|
+
Over The Air Server for deployment of Android and iOS apps.
|
204
206
|
test_files: []
|