fastlane-plugin-diawi 0.1.3 → 1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/fastlane/plugin/diawi/actions/diawi_action.rb +198 -202
- data/lib/fastlane/plugin/diawi/version.rb +1 -1
- metadata +18 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 04d3075ca4844afc66a5901c747809bcf7587a51
|
4
|
+
data.tar.gz: d87a0bc99bfbd37912e9912f9bc03044b327e393
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 076d74d84511627a8a3f07f8f447b6243ea5c3ff0095258e37c47018c26d1fdbafc4fe0ac2f1661d7fa88a426ee1da7184463579e4c260f0e9dc90d0c8b83164
|
7
|
+
data.tar.gz: 97afd011057504c7ffc43ada2a673621149c0d6be21ddeebfd5561d0adc0d76c35be2a195c296b2ded77a54f47c64aa87390b8edab9b46240593462cd99fa69f
|
@@ -1,217 +1,213 @@
|
|
1
1
|
# based on https://dashboard.diawi.com/docs/apis/upload
|
2
2
|
|
3
3
|
module Fastlane
|
4
|
-
|
4
|
+
module Actions
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
end
|
9
|
-
|
10
|
-
class DiawiAction < Action
|
11
|
-
|
12
|
-
ENDPOINT = "https://upload.diawi.com/"
|
13
|
-
|
14
|
-
#####################################################
|
15
|
-
# @!group Connection
|
16
|
-
#####################################################
|
17
|
-
|
18
|
-
def self.status_connection(token, job)
|
19
|
-
require 'faraday'
|
20
|
-
require 'faraday_middleware'
|
21
|
-
|
22
|
-
connection = Faraday.new(:url => ENDPOINT) do |builder|
|
23
|
-
builder.request :url_encoded
|
24
|
-
builder.response :json, content_type: /\bjson$/
|
25
|
-
builder.use FaradayMiddleware::FollowRedirects
|
26
|
-
builder.adapter :net_http
|
27
|
-
end
|
28
|
-
connection.get "/status", { :token => token, :job => job }
|
29
|
-
end
|
30
|
-
|
31
|
-
def self.upload_connection
|
32
|
-
require 'faraday'
|
33
|
-
require 'faraday_middleware'
|
34
|
-
|
35
|
-
Faraday.new(url: ENDPOINT) do |builder|
|
36
|
-
builder.request :multipart
|
37
|
-
builder.request :url_encoded
|
38
|
-
builder.request :retry
|
39
|
-
builder.response :json, content_type: /\bjson$/
|
40
|
-
builder.use FaradayMiddleware::FollowRedirects
|
41
|
-
builder.adapter :net_http
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
#####################################################
|
46
|
-
# @!group Data logic
|
47
|
-
#####################################################
|
48
|
-
|
49
|
-
def self.check_status_for_upload(file, token, job)
|
50
|
-
# from diawi's documendation:
|
51
|
-
# Polling frequence
|
52
|
-
# Usually, processing of an upload will take from 0.5 to 5 seconds, so the best polling frequence would be every 1 second for up to 10 times.
|
53
|
-
# If the status is still 2001 after 10 seconds, there probably is a problem, let us know.
|
54
|
-
availableRequestCount = 5 # 2 sec * 5 times = 10 sec for status check request else raise an error
|
55
|
-
requestCount = 0
|
56
|
-
|
57
|
-
status_ok = 2000
|
58
|
-
status_in_progress = 2001
|
59
|
-
status_error = 4000
|
60
|
-
|
61
|
-
while availableRequestCount > requestCount do
|
62
|
-
response = self.status_connection(token, job)
|
63
|
-
|
64
|
-
case response.body["status"]
|
65
|
-
when status_ok
|
66
|
-
link = "https://i.diawi.com/#{response.body['hash']}"
|
67
|
-
UI.success("File successfully uploaded to diawi. Link: #{link}")
|
68
|
-
Actions.lane_context[SharedValues::UPLOADED_FILE_LINK_TO_DIAWI] = link
|
69
|
-
return
|
70
|
-
when status_in_progress
|
71
|
-
UI.message("Uploading...")
|
72
|
-
when status_error
|
73
|
-
UI.warning("Error uploading file to diawi. Message: #{response.body['message']}")
|
74
|
-
UI.warning("Try to upload file by yourself: #{file}")
|
75
|
-
return
|
76
|
-
else
|
77
|
-
UI.warning("Unknown error uploading file to diawi.")
|
78
|
-
UI.warning("Try to upload file by yourself: #{file}")
|
79
|
-
return
|
80
|
-
end
|
81
|
-
|
82
|
-
requestCount += 1
|
83
|
-
sleep(2)
|
84
|
-
end
|
85
|
-
|
86
|
-
UI.warning("`In progress` status took more than 10 sec, so raise error. Check out the https://dashboard.diawi.com/. Maybe your file has been uploaded successfully.")
|
87
|
-
UI.warning("If not, try to upload file by yourself: #{file}")
|
88
|
-
end
|
89
|
-
|
90
|
-
def self.upload(file, token, options)
|
91
|
-
connection = self.upload_connection
|
92
|
-
|
93
|
-
options.update({
|
94
|
-
token: token,
|
95
|
-
file: Faraday::UploadIO.new(file, "application/octet-stream")
|
96
|
-
})
|
97
|
-
|
98
|
-
post_request = connection.post do |request|
|
99
|
-
request.body = options
|
6
|
+
module SharedValues
|
7
|
+
UPLOADED_FILE_LINK_TO_DIAWI = :UPLOADED_FILE_LINK_TO_DIAWI
|
100
8
|
end
|
101
9
|
|
102
|
-
|
103
|
-
if response.body && response.body.key?("job")
|
104
|
-
return response.body["job"]
|
105
|
-
else
|
106
|
-
UI.warning("Error uploading file to diawi: #{response.body['message']}")
|
107
|
-
return
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
10
|
+
class Diawi < Action
|
111
11
|
|
112
|
-
|
113
|
-
|
114
|
-
|
12
|
+
UPLOAD_URL = "https://upload.diawi.com/"
|
13
|
+
STATUS_CHECK_URL = "https://upload.diawi.com/status"
|
14
|
+
DIAWI_FILE_LINK = "https://i.diawi.com"
|
115
15
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
16
|
+
def self.run(options)
|
17
|
+
Actions.verify_gem!('rest-client')
|
18
|
+
require 'rest-client'
|
19
|
+
require 'json'
|
20
|
+
|
21
|
+
if options[:file].nil?
|
22
|
+
UI.important("File didn't come to diawi_plugin. Uploading is unavailable.")
|
23
|
+
return
|
24
|
+
end
|
25
|
+
|
26
|
+
if options[:token].nil?
|
27
|
+
UI.important("Diawi token is nil - uploading is unavailable.")
|
28
|
+
UI.important("Try to upload file by yourself. Path: #{options[:file]}")
|
29
|
+
return
|
30
|
+
end
|
129
31
|
|
130
|
-
|
32
|
+
upload_options = options.values.select do |key, value|
|
33
|
+
[:password, :comment, :callback_url, :callback_emails].include? key unless value.nil?
|
34
|
+
end
|
131
35
|
|
132
|
-
|
36
|
+
options.values.each do |key, value|
|
37
|
+
if [:find_by_udid, :wall_of_apps, :installation_notifications].include? key
|
38
|
+
upload_options[key] = value ? 1 : 0 unless value.nil?
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
upload_options[:token] = options[:token]
|
43
|
+
upload_options[:file] = File.new(options[:file], 'rb')
|
44
|
+
|
45
|
+
UI.success("Start uploading file to diawi. Please, be patient. This could take some time.")
|
46
|
+
|
47
|
+
response = RestClient.post(UPLOAD_URL, upload_options)
|
48
|
+
|
49
|
+
begin
|
50
|
+
response
|
51
|
+
rescue RestClient::ExceptionWithResponse => error
|
52
|
+
UI.important("Faild to upload file to diawi, because of:")
|
53
|
+
UI.important(error)
|
54
|
+
UI.important("Try to upload file by yourself. Path: #{options[:file]}")
|
55
|
+
return
|
56
|
+
end
|
57
|
+
|
58
|
+
job = JSON.parse(response.body)['job']
|
59
|
+
|
60
|
+
if job
|
61
|
+
return self.check_status(options[:token], options[:file], job, options[:last_hope_attempts_count])
|
62
|
+
end
|
63
|
+
|
64
|
+
UI.important("Something went wrong and `job` value didn't come from uploading request. Check out your dashboard: https://dashboard.diawi.com/. Maybe your file already has been uploaded successfully.")
|
65
|
+
UI.important("If not, try to upload file by yourself. Path: #{options[:file]}")
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.check_status(token, file, job, last_hope_attempts_count)
|
69
|
+
# From documendation:
|
70
|
+
|
71
|
+
# Polling frequence
|
72
|
+
# Usually, processing of an upload will take a few seconds:
|
73
|
+
# so, a base rule would be to poll every 2 seconds for up to 5 times and should match most simple use-cases.
|
74
|
+
|
75
|
+
# For larger apps, a longer processing might be needed on our side.
|
76
|
+
# A rule of thumb would be to wait up to 1 second for each 10 MB of the app.
|
77
|
+
# In other words, up to 10 seconds for a 100 MB app, 50 seconds for a 500 MB app, and so on…
|
78
|
+
|
79
|
+
# ^ Based on this here we calculate polling_count
|
80
|
+
|
81
|
+
file_size = (File.size(file).to_i) / 2**20
|
82
|
+
additional_polling_count = last_hope_attempts_count.between?(1, 5) ? last_hope_attempts_count : 1
|
83
|
+
polling_count = file_size / 10 + additional_polling_count # also add "last hope" attempts
|
84
|
+
|
85
|
+
polling_attempts = 0
|
86
|
+
|
87
|
+
status_ok = 2000
|
88
|
+
status_in_progress = 2001
|
89
|
+
status_error = 4000
|
90
|
+
|
91
|
+
while polling_count > polling_attempts do
|
92
|
+
response = RestClient.get STATUS_CHECK_URL, {params: {token: token, job: job}}
|
93
|
+
|
94
|
+
begin
|
95
|
+
response
|
96
|
+
rescue RestClient::ExceptionWithResponse => error
|
97
|
+
UI.important("Check file status request error:")
|
98
|
+
UI.important(error)
|
99
|
+
polling_attempts += 1
|
100
|
+
sleep(2)
|
101
|
+
next
|
102
|
+
end
|
103
|
+
|
104
|
+
json = JSON.parse(response.body)
|
105
|
+
|
106
|
+
case json['status']
|
107
|
+
when status_ok
|
108
|
+
link = "#{DIAWI_FILE_LINK}/#{json['hash']}"
|
109
|
+
UI.success("File successfully uploaded to diawi. Link: #{link}")
|
110
|
+
Actions.lane_context[SharedValues::UPLOADED_FILE_LINK_TO_DIAWI] = link
|
111
|
+
return
|
112
|
+
|
113
|
+
when status_in_progress
|
114
|
+
UI.message("Processing file...")
|
115
|
+
|
116
|
+
when status_error
|
117
|
+
UI.important("Error uploading file to diawi.")
|
118
|
+
UI.important(json['message'])
|
119
|
+
else
|
120
|
+
UI.important("Unknown error uploading file to diawi.")
|
121
|
+
end
|
122
|
+
|
123
|
+
polling_attempts += 1
|
124
|
+
sleep(2)
|
125
|
+
end
|
126
|
+
|
127
|
+
UI.important("File is not processed.")
|
128
|
+
UI.important("Try to upload file by yourself: #{file}")
|
129
|
+
end
|
130
|
+
|
131
|
+
#####################################################
|
132
|
+
# @!group Documentation
|
133
|
+
#####################################################
|
134
|
+
|
135
|
+
def self.available_options
|
136
|
+
[
|
137
|
+
FastlaneCore::ConfigItem.new(key: :token,
|
138
|
+
env_name: "DIAWI_TOKEN",
|
139
|
+
description: "API access token",
|
140
|
+
optional: false),
|
141
|
+
FastlaneCore::ConfigItem.new(key: :file,
|
142
|
+
env_name: "DIAWI_FILE",
|
143
|
+
description: "Path to .ipa or .apk file",
|
144
|
+
optional: false),
|
145
|
+
FastlaneCore::ConfigItem.new(key: :find_by_udid,
|
146
|
+
env_name: "DIAWI_FIND_BY_UDID",
|
147
|
+
description: "Allow your testers to find the app on diawi's mobile web app using their UDID (iOS only)",
|
148
|
+
is_string: false,
|
149
|
+
optional: true),
|
150
|
+
FastlaneCore::ConfigItem.new(key: :wall_of_apps,
|
151
|
+
env_name: "DIAWI_WALL_OF_APPS",
|
152
|
+
description: "Allow diawi to display the app's icon on the wall of apps",
|
153
|
+
is_string: false,
|
154
|
+
optional: true),
|
155
|
+
FastlaneCore::ConfigItem.new(key: :password,
|
156
|
+
env_name: "DIAWI_PASSWORD",
|
157
|
+
description: "Protect your app with a password: it will be required to access the installation page",
|
158
|
+
optional: true),
|
159
|
+
FastlaneCore::ConfigItem.new(key: :comment,
|
160
|
+
env_name: "DIAWI_COMMENT",
|
161
|
+
description: "Additional information to your users on this build: the comment will be displayed on the installation page",
|
162
|
+
optional: true),
|
163
|
+
FastlaneCore::ConfigItem.new(key: :callback_url,
|
164
|
+
env_name: "DIAWI_CALLBACK_URL",
|
165
|
+
description: "The URL diawi should call with the result",
|
166
|
+
optional: true,
|
167
|
+
verify_block: proc do |value|
|
168
|
+
UI.user_error!("The `callback_url` not valid.") if value =~ URI::regexp
|
169
|
+
end),
|
170
|
+
FastlaneCore::ConfigItem.new(key: :callback_emails,
|
171
|
+
env_name: "DIAWI_CALLBACK_EMAILS",
|
172
|
+
description: "The email addresses diawi will send the result to (up to 5 separated by commas for starter/premium/enterprise accounts, 1 for free accounts). Emails should be a string. Ex: \"example@test.com,example1@test.com\"",
|
173
|
+
optional: true),
|
174
|
+
FastlaneCore::ConfigItem.new(key: :installation_notifications,
|
175
|
+
env_name: "DIAWI_INSTALLATION_NOTIFICATIONS",
|
176
|
+
description: "Receive notifications each time someone installs the app (only starter/premium/enterprise accounts)",
|
177
|
+
is_string: false,
|
178
|
+
optional: true),
|
179
|
+
FastlaneCore::ConfigItem.new(key: :last_hope_attempts_count,
|
180
|
+
env_name: "DIAWI_LAST_HOPE_ATTEMPTS_COUNT",
|
181
|
+
description: "Number of attempts to check status after last attempt. Default - 1, max - 5. (See more at `self.check_status` func comment)",
|
182
|
+
is_string: false,
|
183
|
+
optional: true,
|
184
|
+
default_value: 1)
|
185
|
+
]
|
186
|
+
end
|
187
|
+
|
188
|
+
def self.output
|
189
|
+
[
|
190
|
+
['UPLOADED_FILE_LINK_TO_DIAWI', 'URL to uploaded .ipa or .apk file to diawi.']
|
191
|
+
]
|
192
|
+
end
|
193
|
+
|
194
|
+
def self.description
|
195
|
+
"Upload .ipa/.apk file to diawi.com"
|
196
|
+
end
|
197
|
+
|
198
|
+
def self.authors
|
199
|
+
["pacification"]
|
200
|
+
end
|
201
|
+
|
202
|
+
def self.details
|
203
|
+
"This action upload .ipa/.apk file to https://www.diawi.com and return link to uploaded file."
|
204
|
+
end
|
205
|
+
|
206
|
+
def self.is_supported?(platform)
|
207
|
+
[:ios, :android].include?(platform)
|
208
|
+
end
|
133
209
|
|
134
|
-
if job
|
135
|
-
self.check_status_for_upload(file, token, job)
|
136
210
|
end
|
137
|
-
end
|
138
|
-
|
139
|
-
#####################################################
|
140
|
-
# @!group Documentation
|
141
|
-
#####################################################
|
142
|
-
|
143
|
-
def self.available_options
|
144
|
-
[
|
145
|
-
FastlaneCore::ConfigItem.new(key: :token,
|
146
|
-
env_name: "DIAWI_TOKEN",
|
147
|
-
description: "API access token",
|
148
|
-
optional: false),
|
149
|
-
FastlaneCore::ConfigItem.new(key: :file,
|
150
|
-
env_name: "DIAWI_FILE",
|
151
|
-
description: "Path to .ipa or .apk file",
|
152
|
-
optional: false,
|
153
|
-
verify_block: proc do |value|
|
154
|
-
UI.user_error!("Couldn't find file at path '#{value}'") unless File.exist?(value)
|
155
|
-
end),
|
156
|
-
FastlaneCore::ConfigItem.new(key: :find_by_udid,
|
157
|
-
env_name: "DIAWI_FIND_BY_UDID",
|
158
|
-
description: "Allow your testers to find the app on diawi's mobile web app using their UDID (iOS only)",
|
159
|
-
is_string: false,
|
160
|
-
optional: true),
|
161
|
-
FastlaneCore::ConfigItem.new(key: :wall_of_apps,
|
162
|
-
env_name: "DIAWI_WALL_OF_APPS",
|
163
|
-
description: "Allow diawi to display the app's icon on the wall of apps",
|
164
|
-
is_string: false,
|
165
|
-
optional: true),
|
166
|
-
FastlaneCore::ConfigItem.new(key: :password,
|
167
|
-
env_name: "DIAWI_PASSWORD",
|
168
|
-
description: "Protect your app with a password: it will be required to access the installation page",
|
169
|
-
optional: true),
|
170
|
-
FastlaneCore::ConfigItem.new(key: :comment,
|
171
|
-
env_name: "DIAWI_COMMENT",
|
172
|
-
description: "Additional information to your users on this build: the comment will be displayed on the installation page",
|
173
|
-
optional: true),
|
174
|
-
FastlaneCore::ConfigItem.new(key: :callback_url,
|
175
|
-
env_name: "DIAWI_CALLBACK_URL",
|
176
|
-
description: "The URL diawi should call with the result",
|
177
|
-
optional: true,
|
178
|
-
verify_block: proc do |value|
|
179
|
-
UI.user_error!("The `callback_url` not valid.") if value =~ URI::regexp
|
180
|
-
end),
|
181
|
-
FastlaneCore::ConfigItem.new(key: :callback_emails,
|
182
|
-
env_name: "DIAWI_CALLBACK_EMAILS",
|
183
|
-
description: "The email addresses diawi will send the result to (up to 5 separated by commas for starter/premium/enterprise accounts, 1 for free accounts). Emails should be a string. Ex: \"example@test.com,example1@test.com\"",
|
184
|
-
optional: true),
|
185
|
-
FastlaneCore::ConfigItem.new(key: :installation_notifications,
|
186
|
-
env_name: "DIAWI_INSTALLATION_NOTIFICATIONS",
|
187
|
-
description: "Receive notifications each time someone installs the app (only starter/premium/enterprise accounts)",
|
188
|
-
is_string: false,
|
189
|
-
optional: true)
|
190
|
-
]
|
191
|
-
end
|
192
|
-
|
193
|
-
def self.output
|
194
|
-
[
|
195
|
-
['UPLOADED_FILE_LINK_TO_DIAWI', 'URL to uploaded .ipa or .apk file to diawi.']
|
196
|
-
]
|
197
|
-
end
|
198
|
-
|
199
|
-
def self.description
|
200
|
-
"Upload .ipa/.apk file to diawi.com"
|
201
|
-
end
|
202
|
-
|
203
|
-
def self.authors
|
204
|
-
["pacification"]
|
205
|
-
end
|
206
|
-
|
207
|
-
def self.details
|
208
|
-
"This action upload .ipa/.apk file to https://www.diawi.com and return link to uploaded file."
|
209
|
-
end
|
210
|
-
|
211
|
-
def self.is_supported?(platform)
|
212
|
-
[:ios, :android].include?(platform)
|
213
|
-
end
|
214
211
|
|
215
212
|
end
|
216
|
-
end
|
217
213
|
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fastlane-plugin-diawi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: '1.0'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- pacification
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-03-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rest-client
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.0.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.0.0
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: pry
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,14 +100,14 @@ dependencies:
|
|
86
100
|
requirements:
|
87
101
|
- - ">="
|
88
102
|
- !ruby/object:Gem::Version
|
89
|
-
version:
|
103
|
+
version: 1.93.0
|
90
104
|
type: :development
|
91
105
|
prerelease: false
|
92
106
|
version_requirements: !ruby/object:Gem::Requirement
|
93
107
|
requirements:
|
94
108
|
- - ">="
|
95
109
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
110
|
+
version: 1.93.0
|
97
111
|
description:
|
98
112
|
email: dmitry.lyaschuck@gmail.com
|
99
113
|
executables: []
|