fastlane-plugin-amazon_app_submission 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +35 -6
- data/lib/fastlane/plugin/amazon_app_submission/actions/amazon_app_submission_action.rb +47 -12
- data/lib/fastlane/plugin/amazon_app_submission/helper/amazon_app_submission_helper.rb +112 -34
- data/lib/fastlane/plugin/amazon_app_submission/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f52eed564ae7f2ef5d42738c00c3f45a71e0438cb63b6bcad67b53f0c646562b
|
4
|
+
data.tar.gz: 623727ff4a80c261d9ff34c28b012b2c2f067295eabdb3cf40ee2dbbc1f0e40c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c9e84b1862121a03660d78b7fdcd5c0a45290982f5e5e8fd1a5b76bdfc37dfa199c9f03c9c7262cf262e6fdb7a0ac6b3cf6633244f93e937acde4494d8ccdfa9
|
7
|
+
data.tar.gz: d345f6b63c462c4510edc2df6e9aa3957711abf93e83f58f022c8742117fe9bc6db8ebd920a94568dcbd3c9c7c461eb9e25a57ac3b5fa698cae8b5d2bf479140
|
data/README.md
CHANGED
@@ -1,16 +1,17 @@
|
|
1
|
-
# amazon-app-
|
1
|
+
# fastlane-plugin-amazon-app-submission
|
2
2
|
|
3
3
|
## Getting Started
|
4
4
|
|
5
|
-
This project is a [_fastlane_](https://github.com/fastlane/fastlane) plugin. To get started with `
|
5
|
+
This project is a [_fastlane_](https://github.com/fastlane/fastlane) plugin. To get started with `amazon_app_submission`, add it to your project by running:
|
6
6
|
|
7
7
|
```bash
|
8
|
-
fastlane add_plugin
|
8
|
+
fastlane add_plugin amazon_app_submission
|
9
9
|
```
|
10
10
|
|
11
|
-
## About
|
11
|
+
## About amazon_app_submission
|
12
12
|
|
13
|
-
|
13
|
+
* Project link on rubygems [fastlane-plugin-amazon_app_submission](https://rubygems.org/gems/fastlane-plugin-amazon_app_submission)
|
14
|
+
* Upload the apk to the Amazon Appstore using the [App Submission API](https://developer.amazon.com/docs/app-submission-api/overview.html).
|
14
15
|
* App Submission API Reference is [App Submission RESTFUL API](https://developer.amazon.com/docs/app-submission-api/appsub-api-ref.html).
|
15
16
|
|
16
17
|
## Usage
|
@@ -27,10 +28,38 @@ Call `amazon_app_submission` in your Fastfile.
|
|
27
28
|
client_id: "<CLIENT_ID>",
|
28
29
|
client_secret: "<CLIENT_SECRET>",
|
29
30
|
app_id: "<APP_ID>",
|
30
|
-
apk_path: "<APK_PATH>"
|
31
|
+
apk_path: "<APK_PATH>",
|
32
|
+
# Optional
|
33
|
+
changelogs_folder_path: "<CHANGELOG_PATH>",
|
34
|
+
upload_changelogs: false,
|
35
|
+
submit_for_review: false
|
31
36
|
)
|
32
37
|
```
|
33
38
|
|
39
|
+
| param | default value | optional | description
|
40
|
+
|:----------|:-----------:|:-----------:|:-----------:|
|
41
|
+
client_id | - | false | getting client id from Amazon developer console dashboard
|
42
|
+
client_secret | - | false | getting client secret from Amazon developer console dashboard
|
43
|
+
app_id | - | false | getting app id from Amazon developer console dashboard
|
44
|
+
apk_path | - | false | link where you storing the release apk
|
45
|
+
changelogs_folder_path | "" | true | setting the folder path where you have the change logs with different file for each language, if language file not found it will use default.txt
|
46
|
+
upload_changelogs | false | true | updating the change logs for the upcoming version
|
47
|
+
submit_for_review | false | true | submit the uploaded APK to the store
|
48
|
+
|
49
|
+
* changelogs folder files name should be:
|
50
|
+
|
51
|
+
| Language | File name
|
52
|
+
|:----------|:-----------:|
|
53
|
+
English-US | en-US.txt
|
54
|
+
English-British | en-GB.txt
|
55
|
+
English-Australia | en-AU.txt
|
56
|
+
English-India | en-IN.txt
|
57
|
+
Italian |it-IT.txt
|
58
|
+
French | fr-FR.txt
|
59
|
+
Spanish | es-ES.txt
|
60
|
+
Spanish-Mexican | es-MX.txt
|
61
|
+
Other | default.txt
|
62
|
+
|
34
63
|
## Testing
|
35
64
|
|
36
65
|
For testing the plugin locally you have to get `client_id`, `client_secret`, `app_id` and `apk_path` in fastlane/Fastfile
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require 'fastlane/action'
|
2
2
|
require_relative '../helper/amazon_app_submission_helper'
|
3
3
|
|
4
4
|
module Fastlane
|
@@ -11,31 +11,45 @@ module Fastlane
|
|
11
11
|
|
12
12
|
if token.nil?
|
13
13
|
UI.message("Cannot retrieve token, please check your client ID and client secret")
|
14
|
-
else
|
15
|
-
UI.message("the token is #{token}")
|
16
14
|
end
|
17
15
|
|
16
|
+
UI.message("Getting current edit")
|
18
17
|
current_edit_id, edit_eTag = Helper::AmazonAppSubmissionHelper.open_edit(token, params[:app_id])
|
19
18
|
|
20
19
|
if current_edit_id.nil?
|
20
|
+
UI.message("Current edit not found, creating a new edit")
|
21
21
|
Helper::AmazonAppSubmissionHelper.create_new_edit(token, params[:app_id])
|
22
22
|
current_edit_id, edit_eTag = Helper::AmazonAppSubmissionHelper.open_edit(token, params[:app_id])
|
23
23
|
end
|
24
24
|
|
25
|
+
UI.message("Get current apk id")
|
25
26
|
current_apk_id = Helper::AmazonAppSubmissionHelper.get_current_apk_id(token, params[:app_id], current_edit_id)
|
26
27
|
|
28
|
+
UI.message("Get current apk ETag")
|
27
29
|
current_apk_eTag = Helper::AmazonAppSubmissionHelper.get_current_apk_etag(token, params[:app_id], current_edit_id, current_apk_id)
|
28
30
|
|
29
|
-
|
30
|
-
|
31
|
-
if replace_apk_response_code === 200
|
32
|
-
Helper::AmazonAppSubmissionHelper.commit_edit(token, params[:app_id], current_edit_id, edit_eTag)
|
33
|
-
end
|
31
|
+
UI.message("Replacing the apk with ETag #{current_apk_eTag}")
|
32
|
+
replace_apk_response_code, replace_apk_response = Helper::AmazonAppSubmissionHelper.replaceExistingApk(token, params[:app_id], current_edit_id, current_apk_id, current_apk_eTag, params[:apk_path])
|
34
33
|
|
34
|
+
if params[:upload_changelogs]
|
35
|
+
UI.message("Updating the changelogs")
|
36
|
+
Helper::AmazonAppSubmissionHelper.update_listings( token, params[:app_id],current_edit_id, params[:changelogs_path], params[:changelogs_path])
|
37
|
+
end
|
38
|
+
|
39
|
+
if replace_apk_response_code == '200'
|
40
|
+
if params[:submit_for_review]
|
41
|
+
UI.message("Submitting to Amazon app store")
|
42
|
+
Helper::AmazonAppSubmissionHelper.commit_edit(token, params[:app_id], current_edit_id, edit_eTag)
|
43
|
+
end
|
44
|
+
else
|
45
|
+
UI.message("Amazon app submission failed at replacing the apk error code #{replace_apk_response_code} and error respones #{replace_apk_response}")
|
46
|
+
return
|
47
|
+
end
|
48
|
+
UI.message("Amazon app submission finished successfully!")
|
35
49
|
end
|
36
50
|
|
37
51
|
def self.description
|
38
|
-
"
|
52
|
+
"fast-lane plugin for Amazon App Submissions"
|
39
53
|
end
|
40
54
|
|
41
55
|
def self.authors
|
@@ -48,7 +62,7 @@ module Fastlane
|
|
48
62
|
|
49
63
|
def self.details
|
50
64
|
# Optional:
|
51
|
-
"
|
65
|
+
"fast-lane plugin for Amazon App Submissions"
|
52
66
|
end
|
53
67
|
|
54
68
|
def self.available_options
|
@@ -75,8 +89,29 @@ module Fastlane
|
|
75
89
|
env_name: "AMAZON_APP_SUBMISSION_APK_PATH",
|
76
90
|
description: "Amazon App Submission APK Path",
|
77
91
|
optional: false,
|
78
|
-
type: String)
|
79
|
-
|
92
|
+
type: String),
|
93
|
+
|
94
|
+
FastlaneCore::ConfigItem.new(key: :changelogs_path,
|
95
|
+
env_name: "AMAZON_APP_SUBMISSION_CHANGELOGS_PATH",
|
96
|
+
description: "Amazon App Submission changelogs path",
|
97
|
+
default_value: "",
|
98
|
+
optional: true,
|
99
|
+
type: String),
|
100
|
+
|
101
|
+
FastlaneCore::ConfigItem.new(key: :upload_changelogs,
|
102
|
+
env_name: "AMAZON_APP_SUBMISSION_SKIP_UPLOAD_CHANGELOGS",
|
103
|
+
description: "Amazon App Submission skip upload changelogs",
|
104
|
+
default_value: false,
|
105
|
+
optional: true,
|
106
|
+
type: Boolean),
|
107
|
+
|
108
|
+
FastlaneCore::ConfigItem.new(key: :submit_for_review,
|
109
|
+
env_name: "AMAZON_APP_SUBMISSION_SUBMIT_FOR_REVIEW",
|
110
|
+
description: "Amazon App Submission submit for review",
|
111
|
+
default_value: false,
|
112
|
+
optional: true,
|
113
|
+
type: Boolean)
|
114
|
+
|
80
115
|
# FastlaneCore::ConfigItem.new(key: :your_option,
|
81
116
|
# env_name: "AMAZON_APP_SUBMISSION_YOUR_OPTION",
|
82
117
|
# description: "A description of your option",
|
@@ -13,10 +13,6 @@ module Fastlane
|
|
13
13
|
|
14
14
|
def self.get_token(client_id, client_secret)
|
15
15
|
UI.important("Fetching app access token")
|
16
|
-
|
17
|
-
UI.important("client_id #{client_id}")
|
18
|
-
UI.important("client_secret #{client_secret}")
|
19
|
-
|
20
16
|
uri = URI('https://api.amazon.com/auth/o2/token')
|
21
17
|
http = Net::HTTP.new(uri.host, uri.port)
|
22
18
|
http.use_ssl = true
|
@@ -26,9 +22,8 @@ module Fastlane
|
|
26
22
|
|
27
23
|
res = http.request(req)
|
28
24
|
result_json = JSON.parse(res.body)
|
29
|
-
|
30
25
|
auth_token = "Bearer #{result_json['access_token']}"
|
31
|
-
|
26
|
+
|
32
27
|
return auth_token
|
33
28
|
end
|
34
29
|
|
@@ -69,17 +64,15 @@ module Fastlane
|
|
69
64
|
res = http.request(req)
|
70
65
|
current_edit = JSON.parse(res.body)
|
71
66
|
|
72
|
-
UI.message("eTag #{res.header['ETag']}")
|
73
|
-
|
74
67
|
return current_edit['id'], res.header['ETag']
|
75
68
|
end
|
76
69
|
|
77
|
-
def self.
|
70
|
+
def self.get_current_apk_id(token, app_id, edit_id)
|
78
71
|
|
79
|
-
|
80
|
-
|
72
|
+
get_apks_path = "/v1/applications/#{app_id}/edits/#{edit_id}/apks"
|
73
|
+
get_apks_url = BASE_URL + get_apks_path
|
81
74
|
|
82
|
-
uri = URI(
|
75
|
+
uri = URI(get_apks_url)
|
83
76
|
http = Net::HTTP.new(uri.host, uri.port)
|
84
77
|
http.use_ssl = true
|
85
78
|
req = Net::HTTP::Get.new(
|
@@ -89,15 +82,20 @@ module Fastlane
|
|
89
82
|
)
|
90
83
|
|
91
84
|
res = http.request(req)
|
92
|
-
|
85
|
+
if !res.body.nil?
|
86
|
+
apks = JSON.parse(res.body)
|
87
|
+
firstAPK = apks[0]
|
88
|
+
apk_id = firstAPK['id']
|
89
|
+
return apk_id
|
90
|
+
end
|
93
91
|
end
|
94
92
|
|
95
|
-
def self.
|
93
|
+
def self.get_current_apk_etag(token, app_id, edit_id, apk_id)
|
96
94
|
|
97
|
-
|
98
|
-
|
95
|
+
get_apks_etag = "/v1/applications/#{app_id}/edits/#{edit_id}/apks/#{apk_id}"
|
96
|
+
get_apks_etag_url = BASE_URL + get_apks_etag
|
99
97
|
|
100
|
-
uri = URI(
|
98
|
+
uri = URI(get_apks_etag_url)
|
101
99
|
http = Net::HTTP.new(uri.host, uri.port)
|
102
100
|
http.use_ssl = true
|
103
101
|
req = Net::HTTP::Get.new(
|
@@ -107,34 +105,40 @@ module Fastlane
|
|
107
105
|
)
|
108
106
|
|
109
107
|
res = http.request(req)
|
110
|
-
|
111
|
-
apks = JSON.parse(res.body)
|
112
|
-
firstAPK = apks[0]
|
113
|
-
apk_id = firstAPK['id']
|
114
|
-
return apk_id
|
115
|
-
end
|
108
|
+
return res.header['ETag']
|
116
109
|
end
|
117
110
|
|
118
|
-
def self.replaceExistingApk(token, app_id, edit_id, apk_id, eTag, apk_path)
|
111
|
+
def self.replaceExistingApk(token, app_id, edit_id, apk_id, eTag, apk_path, should_retry = true)
|
119
112
|
|
120
113
|
replace_apk_path = "/v1/applications/#{app_id}/edits/#{edit_id}/apks/#{apk_id}/replace"
|
121
114
|
local_apk = File.open(apk_path, "r").read
|
122
115
|
|
116
|
+
apk_uri = URI.parse(apk_path)
|
117
|
+
apk_name = apk_uri.path.split('/').last
|
118
|
+
|
123
119
|
replace_apk_url = BASE_URL + replace_apk_path
|
124
120
|
uri = URI(replace_apk_url)
|
125
121
|
http = Net::HTTP.new(uri.host, uri.port)
|
126
122
|
http.use_ssl = true
|
127
|
-
http.write_timeout =
|
123
|
+
http.write_timeout = 1000
|
128
124
|
req = Net::HTTP::Put.new(
|
129
125
|
uri.path,
|
130
126
|
'Authorization' => token,
|
131
127
|
'Content-Type' => 'application/vnd.android.package-archive',
|
128
|
+
'fileName' => apk_name,
|
132
129
|
'If-Match' => eTag
|
133
130
|
)
|
134
131
|
|
135
132
|
req.body = local_apk
|
136
133
|
res = http.request(req)
|
137
|
-
|
134
|
+
replace_apk_response = JSON.parse(res.body)
|
135
|
+
# Retry again if replace failed
|
136
|
+
if res.code == '412' && should_retry
|
137
|
+
UI.message("replacing the apk failed, retrying uploading it again...")
|
138
|
+
replaceExistingApk(token, app_id, edit_id, apk_id, eTag, apk_path, false)
|
139
|
+
return
|
140
|
+
end
|
141
|
+
return res.code, replace_apk_response
|
138
142
|
end
|
139
143
|
|
140
144
|
def self.delete_apk(token, app_id, edit_id, apk_id, eTag)
|
@@ -142,8 +146,6 @@ module Fastlane
|
|
142
146
|
delete_apk_path = "/v1/applications/#{app_id}/edits/#{edit_id}/apks/#{apk_id}"
|
143
147
|
delete_apk_url = BASE_URL + delete_apk_path
|
144
148
|
|
145
|
-
UI.message("delete_apk_url #{delete_apk_url}")
|
146
|
-
|
147
149
|
uri = URI(delete_apk_url)
|
148
150
|
http = Net::HTTP.new(uri.host, uri.port)
|
149
151
|
http.use_ssl = true
|
@@ -167,8 +169,8 @@ module Fastlane
|
|
167
169
|
uri = URI(add_apk_url)
|
168
170
|
http = Net::HTTP.new(uri.host, uri.port)
|
169
171
|
http.use_ssl = true
|
170
|
-
http.write_timeout =
|
171
|
-
http.read_timeout =
|
172
|
+
http.write_timeout = 1000
|
173
|
+
http.read_timeout = 1000
|
172
174
|
req = Net::HTTP::Post.new(
|
173
175
|
uri.path,
|
174
176
|
'Authorization' => token,
|
@@ -180,6 +182,86 @@ module Fastlane
|
|
180
182
|
result_json = JSON.parse(res.body)
|
181
183
|
end
|
182
184
|
|
185
|
+
def self.update_listings(token, app_id, edit_id, changelogs_path, upload_changelogs)
|
186
|
+
|
187
|
+
listings_path = "/v1/applications/#{app_id}/edits/#{edit_id}/listings"
|
188
|
+
listings_url = BASE_URL + listings_path
|
189
|
+
|
190
|
+
uri = URI(listings_url)
|
191
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
192
|
+
http.use_ssl = true
|
193
|
+
req = Net::HTTP::Get.new(
|
194
|
+
uri.path,
|
195
|
+
'Authorization' => token,
|
196
|
+
'Content-Type' => 'application/json'
|
197
|
+
)
|
198
|
+
|
199
|
+
res = http.request(req)
|
200
|
+
listings_response = JSON.parse(res.body)
|
201
|
+
|
202
|
+
# Iterating over the languages for getting the ETag.
|
203
|
+
listings_response['listings'].each do |lang, listing|
|
204
|
+
lang_path = "/v1/applications/#{app_id}/edits/#{edit_id}/listings/#{lang}"
|
205
|
+
lang_url = BASE_URL + lang_path
|
206
|
+
|
207
|
+
uri = URI(lang_url)
|
208
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
209
|
+
http.use_ssl = true
|
210
|
+
req = Net::HTTP::Get.new(
|
211
|
+
uri.path,
|
212
|
+
'Authorization' => token,
|
213
|
+
'Content-Type' => 'application/json'
|
214
|
+
)
|
215
|
+
etag_response = http.request(req)
|
216
|
+
etag = etag_response.header['Etag']
|
217
|
+
|
218
|
+
recent_changes = find_changelog(
|
219
|
+
changelogs_path,
|
220
|
+
lang,
|
221
|
+
upload_changelogs,
|
222
|
+
)
|
223
|
+
|
224
|
+
listing[:recentChanges] = recent_changes
|
225
|
+
|
226
|
+
update_listings_path = "/v1/applications/#{app_id}/edits/#{edit_id}/listings/#{lang}"
|
227
|
+
update_listings_url = BASE_URL + update_listings_path
|
228
|
+
|
229
|
+
uri = URI(update_listings_url)
|
230
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
231
|
+
http.use_ssl = true
|
232
|
+
req = Net::HTTP::Put.new(
|
233
|
+
uri.path,
|
234
|
+
'Authorization' => token,
|
235
|
+
'Content-Type' => 'application/json',
|
236
|
+
'If-Match' => etag
|
237
|
+
)
|
238
|
+
|
239
|
+
req.body = listing.to_json
|
240
|
+
res = http.request(req)
|
241
|
+
listings_response = JSON.parse(res.body)
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
def self.find_changelog(changelogs_path, language, upload_changelogs)
|
246
|
+
# The Amazon appstore requires you to enter changelogs before reviewing.
|
247
|
+
# Therefore, if there is no metadata, hyphen text is returned.
|
248
|
+
changelog_text = '-'
|
249
|
+
return changelog_text if !upload_changelogs
|
250
|
+
|
251
|
+
path = File.join(changelogs_path, "#{language}.txt")
|
252
|
+
if File.exist?(path) && !File.zero?(path)
|
253
|
+
changelog_text = File.read(path, encoding: 'UTF-8')
|
254
|
+
else
|
255
|
+
defalut_changelog_path = File.join(changelogs_path, 'default.txt')
|
256
|
+
if File.exist?(defalut_changelog_path) && !File.zero?(defalut_changelog_path)
|
257
|
+
changelog_text = File.read(defalut_changelog_path, encoding: 'UTF-8')
|
258
|
+
else
|
259
|
+
UI.message("Could not find changelog for language '#{language}' at path #{path}...")
|
260
|
+
end
|
261
|
+
end
|
262
|
+
changelog_text
|
263
|
+
end
|
264
|
+
|
183
265
|
def self.commit_edit(token, app_id, edit_id, eTag)
|
184
266
|
|
185
267
|
commit_edit_path = "/v1/applications/#{app_id}/edits/#{edit_id}/commit"
|
@@ -197,10 +279,6 @@ module Fastlane
|
|
197
279
|
res = http.request(req)
|
198
280
|
result_json = JSON.parse(res.body)
|
199
281
|
end
|
200
|
-
|
201
|
-
def self.show_message
|
202
|
-
UI.message("Hello from the amazon_app_submission plugin helper!")
|
203
|
-
end
|
204
282
|
end
|
205
283
|
end
|
206
284
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fastlane-plugin-amazon_app_submission
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- mohammedhemaid
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-06-
|
11
|
+
date: 2022-06-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -162,7 +162,7 @@ files:
|
|
162
162
|
- lib/fastlane/plugin/amazon_app_submission/actions/amazon_app_submission_action.rb
|
163
163
|
- lib/fastlane/plugin/amazon_app_submission/helper/amazon_app_submission_helper.rb
|
164
164
|
- lib/fastlane/plugin/amazon_app_submission/version.rb
|
165
|
-
homepage:
|
165
|
+
homepage: https://github.com/ugroupmedia/fastlane-plugin-amazon-app-store-submission
|
166
166
|
licenses:
|
167
167
|
- MIT
|
168
168
|
metadata: {}
|