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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bf52f7fe8ae95ead1055561f0b7416d8c646a8cb5bc67ffbf040a3512970d5d8
4
- data.tar.gz: a2be421d18a3b9ae4c3952f47bfdf088846497df9e1028425cee71c8fc55a814
3
+ metadata.gz: '094df9f916199c588e3d991874d996cbcde91fe1318c3ed59745ceeaab381b07'
4
+ data.tar.gz: fb5dd2f76921dee9a2d144519c534d629927d8e8be3e21bfacb6c09420ba7635
5
5
  SHA512:
6
- metadata.gz: 9543c016c7b1c73835fd826b80b5c935e946e458785fac9b60809c77f665fed2167f6f2cefc36a72e9eac0246b20ff289aab0d7b31d27c6e81feda3391a0eced
7
- data.tar.gz: bce77eff8312ea9a8260f8fbaec83446431d87934f4c4e6a23b6d21912e44fc95f5e85ad1b6b933657cd1e8d15485a77fe35fb4123759d5d1f5f3215cd41289a
6
+ metadata.gz: 1e39a53958627bb1ba620320ef996ec2ef3cbc9fa9daa3048f2f80c5851495b92c8756b2db59bad512f375250596c0faf51a5066c19dc8e68a9f6effa54319bc
7
+ data.tar.gz: 643294ce82684f55c3c82978b07273d9f0156de55bfee73284b597b2e4d5a48b9ee167633904672d657aefe9301315d504a05176f240b357a93f516bcaaf3d3a
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Zealot plugin
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
- | zealot Options |
22
- +-----------------+-------------------------------------------------+------------------------+----------+
23
- | Key | Description | Env Var | Default |
24
- +-----------------+-------------------------------------------------+------------------------+----------+
25
- | endpoint | The endpoint of zealot | ZEALOT_ENDPOINT | |
26
- | token | The token of user | ZEALOT_TOKEN | |
27
- | channel_key | The key of app's channel | ZEALOT_CHANNEL_KEY | |
28
- | file | The path of app file. Optional if you use the | ZEALOT_FILE | |
29
- | | `gym`, `ipa`, `xcodebuild` or `gradle` action. | | |
30
- | name | The name of app to display on zealot | ZEALOT_NAME | |
31
- | changelog | The changelog of app | ZEALOT_CHANGELOG | |
32
- | slug | The slug of app | ZEALOT_SLUG | |
33
- | release_type | The release type of app | ZEALOT_RELEASE_TYPE | |
34
- | branch | The name of git branch | ZEALOT_BRANCH | |
35
- | git_commit | The hash of git commit | ZEALOT_GIT_COMMIT | |
36
- | password | The password of app to download | ZEALOT_PASSWORD | |
37
- | source | The name of upload source | ZEALOT_SOURCE | fastlane |
38
- | timeout | Request timeout in seconds | ZEALOT_TIMEOUT | |
39
- | hide_user_token | replase user token to *** to keep secret | ZEALOT_HIDE_USER_TOKEN | true |
40
- | fail_on_error | Should an error uploading app cause a failure? | ZEALOT_FAIL_ON_ERROR | false |
41
- | | (true/false) | | |
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
- 检查[范例 `Fastfile` 文件](fastlane/Fastfile) 来看看如何使用插件吧(其实啥都没有写)
187
+ # Android
188
+ gradle
48
189
 
49
- ## Issues and Feedback
190
+ # 根据 CI 系统自动获取提交日志
191
+ ci_changelog
50
192
 
51
- For any other issues and feedback about this plugin, please submit it to this repository.
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
- ## Troubleshooting
302
+ ## 更多例子
54
303
 
55
- If you have trouble using plugins, check out the [Plugins Troubleshooting](https://docs.fastlane.tools/plugins/plugins-troubleshooting/) guide.
304
+ 检查[范例 `Fastfile` 文件](fastlane/Fastfile) 来看看如何使用插件吧
56
305
 
57
- ## Using _fastlane_ Plugins
306
+ ## 问题和反馈
58
307
 
59
- For more information about how the `fastlane` plugin system works, check out the [Plugins documentation](https://docs.fastlane.tools/plugins/create-plugin/).
308
+ 使用本插件过程中遇到的任何问题和反馈请提交问题。
60
309
 
61
- ## About _fastlane_
310
+ ## 疑惑解答
62
311
 
63
- _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).
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 show_error("Error uploading to Zealot: empty response", fail_on_error) unless response
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 new build to Zealot'
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 compress debug file" unless file
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
- case platform
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: #{value}, avaiable value are #{PLATFORM.join(',')}.")
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, path)
44
- params[:archive_path] = if 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, path)
55
- params[:app_path] = path if path && !path.empty?
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 show_error("Error uploading to Zealot: empty response", fail_on_error) unless response
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 new build to Zealot'
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: 'The key of app\'s channel',
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
- verify_block: proc do |value|
104
- UI.user_error!("No match value of platform: #{value}") unless PLATFORM.include?(value)
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 Apphost timed out ⏳', params[:fail_on_error])
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
- source git_commit password custom_fields
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
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module Zealot
3
- VERSION = "0.2.4"
3
+ VERSION = "0.7.1"
4
4
  end
5
5
  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.2.4
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-05-21 00:00:00.000000000 Z
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.1.1
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.1.1
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.0.3
201
- signing_key:
201
+ rubygems_version: 3.1.2
202
+ signing_key:
202
203
  specification_version: 4
203
- summary: Upload a new build to Zealot
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: []