fastlane-plugin-amazon_app_submission 0.1.0 → 0.3.0

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: a0973749b49a3b53f7cfde27b869f789befd6909ce53d7de52329b501d42ab3f
4
- data.tar.gz: 9b6ca51c1f57dcfbebb2086bfe2a8780d78c710b107c75f55257b2ceed978057
3
+ metadata.gz: f52eed564ae7f2ef5d42738c00c3f45a71e0438cb63b6bcad67b53f0c646562b
4
+ data.tar.gz: 623727ff4a80c261d9ff34c28b012b2c2f067295eabdb3cf40ee2dbbc1f0e40c
5
5
  SHA512:
6
- metadata.gz: f38478b00c63058c819306b62f9fdbe332f1d833ea45d9de4217e64e60b7d7210f855c3fa8c6c72382457f35ab077b7249c00598eb923e7ea4e68577056f5214
7
- data.tar.gz: 4edba88cce969fd122755d5c9821fc90ad25147291b3ed54a2b0d6cd249e8406326de014ea2033b0d0d19d947029e953ab59592c04bdba154cec2ace9e4fb796
6
+ metadata.gz: c9e84b1862121a03660d78b7fdcd5c0a45290982f5e5e8fd1a5b76bdfc37dfa199c9f03c9c7262cf262e6fdb7a0ac6b3cf6633244f93e937acde4494d8ccdfa9
7
+ data.tar.gz: d345f6b63c462c4510edc2df6e9aa3957711abf93e83f58f022c8742117fe9bc6db8ebd920a94568dcbd3c9c7c461eb9e25a57ac3b5fa698cae8b5d2bf479140
data/README.md CHANGED
@@ -1 +1,68 @@
1
- # amazon-app-store-submission
1
+ # fastlane-plugin-amazon-app-submission
2
+
3
+ ## Getting Started
4
+
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
+
7
+ ```bash
8
+ fastlane add_plugin amazon_app_submission
9
+ ```
10
+
11
+ ## About amazon_app_submission
12
+
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).
15
+ * App Submission API Reference is [App Submission RESTFUL API](https://developer.amazon.com/docs/app-submission-api/appsub-api-ref.html).
16
+
17
+ ## Usage
18
+
19
+ Following the [guide](https://developer.amazon.com/docs/app-submission-api/auth.html), you will need to generate `client_id` and `client_secret` to access the console in advance.
20
+
21
+ For `app_id` you can get it from Amazon app dashboard
22
+ Please set the apk path to `apk_path` field
23
+
24
+ Call `amazon_app_submission` in your Fastfile.
25
+
26
+ ```ruby
27
+ amazon_app_submission(
28
+ client_id: "<CLIENT_ID>",
29
+ client_secret: "<CLIENT_SECRET>",
30
+ app_id: "<APP_ID>",
31
+ apk_path: "<APK_PATH>",
32
+ # Optional
33
+ changelogs_folder_path: "<CHANGELOG_PATH>",
34
+ upload_changelogs: false,
35
+ submit_for_review: false
36
+ )
37
+ ```
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
+
63
+ ## Testing
64
+
65
+ For testing the plugin locally you have to get `client_id`, `client_secret`, `app_id` and `apk_path` in fastlane/Fastfile
66
+ please check Usage step to see how you can get them.
67
+
68
+ Then call `bundle exec fastlane test` in your terminal
@@ -1,4 +1,4 @@
1
- require 'fastlane/action'
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
- replace_apk_response_code = Helper::AmazonAppSubmissionHelper.replaceExistingApk(token, params[:app_id], current_edit_id, current_apk_id, current_apk_eTag, params[:apk_path])
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
- "test"
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
- "test"
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.get_current_apk_etag(token, app_id, edit_id, apk_id)
70
+ def self.get_current_apk_id(token, app_id, edit_id)
78
71
 
79
- get_apks_etag = "/v1/applications/#{app_id}/edits/#{edit_id}/apks/#{apk_id}"
80
- get_apks_etag_url = BASE_URL + get_apks_etag
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(get_apks_etag_url)
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
- return res.header['ETag']
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.get_current_apk_id(token, app_id, edit_id)
93
+ def self.get_current_apk_etag(token, app_id, edit_id, apk_id)
96
94
 
97
- get_apks_path = "/v1/applications/#{app_id}/edits/#{edit_id}/apks"
98
- get_apks_url = BASE_URL + get_apks_path
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(get_apks_url)
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
- if !res.body.nil?
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 = 10000
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
- return res.code
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 = 10000
171
- http.read_timeout = 10000
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
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module AmazonAppSubmission
3
- VERSION = "0.1.0"
3
+ VERSION = "0.3.0"
4
4
  end
5
5
  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.1.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-08 00:00:00.000000000 Z
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: {}