fastlane-plugin-amazon_appstore 1.4.0 → 1.5.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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4329f021e36ea416d3dbe494fea656223f7681f01fdaf8c12c067850bd66d042
|
|
4
|
+
data.tar.gz: 5015e8ed07f219d28398b38d4c684db0ddae6342a84270a02cea9c001015041b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4b213a4b4855aa766bb8a5bd789a1c8cfae4ea1a6786d66986828442672b96030b45bc881bb30e8bcd513437396229f004ababe31c6b817b399f4cc23d9eb117
|
|
7
|
+
data.tar.gz: 5bee681d6820d171c9a09c33da5ac3306e3583156748128684c88596d69159a5b4e1858a9a2adf3f90c68a24264cb6f1c06eb56750aaac4fcda4972e8e490fd0
|
data/README.md
CHANGED
|
@@ -30,19 +30,23 @@ upload_to_amazon_appstore(
|
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
### Parameters
|
|
33
|
-
| Key | Description | Default |
|
|
34
|
-
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------- |
|
|
35
|
-
| package_name | The package name of the application to use | * |
|
|
33
|
+
| Key | Description | Default |
|
|
34
|
+
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------- |
|
|
35
|
+
| package_name | The package name of the application to use | * |
|
|
36
36
|
| apk | Path to the APK file to upload (optional if apk_paths is provided) | |
|
|
37
37
|
| apk_paths | An array of paths to APK files to upload (optional if apk is provided) | |
|
|
38
|
-
| client_id | The client ID you saved | |
|
|
39
|
-
| client_secret | The client secret you saved | |
|
|
40
|
-
|
|
|
41
|
-
|
|
|
42
|
-
|
|
|
38
|
+
| client_id | The client ID you saved | |
|
|
39
|
+
| client_secret | The client secret you saved | |
|
|
40
|
+
| skip_upload_apk | Whether to skip uploading APK | false |
|
|
41
|
+
| skip_upload_metadata | Whether to skip uploading metadata (title, descriptions) | false |
|
|
42
|
+
| skip_upload_changelogs | Whether to skip uploading changelogs | false |
|
|
43
|
+
| skip_upload_images | Whether to skip uploading images (icons, promo images) | true |
|
|
44
|
+
| skip_upload_screenshots | Whether to skip uploading screenshots | true |
|
|
45
|
+
| metadata_path | Path to the directory containing the metadata files | ./fastlane/metadata/android |
|
|
46
|
+
| changes_not_sent_for_review | Indicates that the changes in this edit will not be reviewed until they are explicitly sent for review from the Amazon Appstore Console UI | false |
|
|
43
47
|
| overwrite_upload | Whether to allow overwriting an existing upload | false |
|
|
44
48
|
| overwrite_upload_mode | Upload strategy when overwrite_upload is true. Can be 'new' (delete existing edit and create new) or 'reuse' (reuse existing edit) | new |
|
|
45
|
-
| timeout | Timeout for read, open (in seconds) | 300 |
|
|
49
|
+
| timeout | Timeout for read, open (in seconds) | 300 |
|
|
46
50
|
* = default value is dependent on the user's system
|
|
47
51
|
|
|
48
52
|
### Changelogs
|
|
@@ -70,6 +74,74 @@ When uploading multiple APKs with different version codes, the plugin will use t
|
|
|
70
74
|
One difference from Google Play is that the Amazon Appstore always requires release notes to be entered before review.
|
|
71
75
|
For this reason, `-` will be entered by default if the corresponding changelogs file is not found, or if the `skip_upload_changelogs` parameter is used.
|
|
72
76
|
|
|
77
|
+
### Metadata (Title and Descriptions)
|
|
78
|
+
|
|
79
|
+
You can update store listing metadata (title, short description, full description) by adding text files in the metadata directory. The plugin uses the same structure as Google Play's [supply](https://docs.fastlane.tools/actions/upload_to_play_store/).
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
└── fastlane
|
|
83
|
+
└── metadata
|
|
84
|
+
└── android
|
|
85
|
+
├── en-US
|
|
86
|
+
│ ├── title.txt
|
|
87
|
+
│ ├── short_description.txt
|
|
88
|
+
│ └── full_description.txt
|
|
89
|
+
└── ja-JP
|
|
90
|
+
├── title.txt
|
|
91
|
+
├── short_description.txt
|
|
92
|
+
└── full_description.txt
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Images and Screenshots
|
|
96
|
+
|
|
97
|
+
You can upload images (icons, promo images) and screenshots by placing them in the `images/` directory. The plugin supports the Google Play metadata structure and maps it to Amazon Appstore image types.
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
└── fastlane
|
|
101
|
+
└── metadata
|
|
102
|
+
└── android
|
|
103
|
+
└── en-US
|
|
104
|
+
└── images
|
|
105
|
+
├── icon.png → small-icons (114x114)
|
|
106
|
+
├── large_icon.png → large-icons (512x512)
|
|
107
|
+
├── featureGraphic.png → promo-images (1024x500)
|
|
108
|
+
├── phoneScreenshots/ → screenshots
|
|
109
|
+
│ ├── 1.png
|
|
110
|
+
│ └── 2.png
|
|
111
|
+
├── tvBanner.png → firetv-icons
|
|
112
|
+
├── tvBackground.png → firetv-backgrounds
|
|
113
|
+
└── tvScreenshots/ → firetv-screenshots
|
|
114
|
+
├── 1.png
|
|
115
|
+
└── 2.png
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
To enable image uploads, set `skip_upload_images: false` and/or `skip_upload_screenshots: false`:
|
|
119
|
+
|
|
120
|
+
```ruby
|
|
121
|
+
upload_to_amazon_appstore(
|
|
122
|
+
apk: "app/build/outputs/apk/release/app-release.apk",
|
|
123
|
+
client_id: <YOUR_CLIENT_ID>,
|
|
124
|
+
client_secret: <YOUR_CLIENT_SECRET>,
|
|
125
|
+
skip_upload_images: false,
|
|
126
|
+
skip_upload_screenshots: false
|
|
127
|
+
)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Metadata-only Upload
|
|
131
|
+
|
|
132
|
+
You can upload only metadata (without APK) by using `skip_upload_apk: true`:
|
|
133
|
+
|
|
134
|
+
```ruby
|
|
135
|
+
upload_to_amazon_appstore(
|
|
136
|
+
client_id: <YOUR_CLIENT_ID>,
|
|
137
|
+
client_secret: <YOUR_CLIENT_SECRET>,
|
|
138
|
+
skip_upload_apk: true,
|
|
139
|
+
skip_upload_metadata: false,
|
|
140
|
+
skip_upload_images: false,
|
|
141
|
+
skip_upload_screenshots: false
|
|
142
|
+
)
|
|
143
|
+
```
|
|
144
|
+
|
|
73
145
|
## Run tests for this plugin
|
|
74
146
|
|
|
75
147
|
To run both the tests, and code style validation, run
|
|
@@ -62,30 +62,33 @@ module Fastlane
|
|
|
62
62
|
UI.abort_with_message!("Failed to get edit_id") if edit_id.nil?
|
|
63
63
|
end
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
apks << params[:apk] if params[:apk]
|
|
67
|
-
apks += params[:apk_paths] if params[:apk_paths]
|
|
65
|
+
version_codes = []
|
|
68
66
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
67
|
+
unless params[:skip_upload_apk]
|
|
68
|
+
apks = []
|
|
69
|
+
apks << params[:apk] if params[:apk]
|
|
70
|
+
apks += params[:apk_paths] if params[:apk_paths]
|
|
72
71
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
72
|
+
if apks.empty?
|
|
73
|
+
UI.abort_with_message!("No APK files provided. Please provide either 'apk' or 'apk_paths' parameter")
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
UI.message("Replacing APKs with #{apks.length} file(s)...")
|
|
77
|
+
begin
|
|
78
|
+
apk_results = Helper::AmazonAppstoreHelper.replace_apks(
|
|
79
|
+
apk_paths: apks,
|
|
80
|
+
app_id: params[:package_name],
|
|
81
|
+
edit_id: edit_id,
|
|
82
|
+
token: token
|
|
83
|
+
)
|
|
84
|
+
rescue StandardError => e
|
|
85
|
+
UI.error(e.message)
|
|
86
|
+
UI.abort_with_message!("Failed to replace APKs")
|
|
87
|
+
end
|
|
88
|
+
version_codes = apk_results.map { |result| result[:version_code] }
|
|
89
|
+
apk_results.each_with_index do |result, index|
|
|
90
|
+
UI.message("Successfully processed APK #{index + 1} with version code: #{result[:version_code]}")
|
|
91
|
+
end
|
|
89
92
|
end
|
|
90
93
|
|
|
91
94
|
UI.message("Updating release notes...")
|
|
@@ -103,6 +106,10 @@ module Fastlane
|
|
|
103
106
|
UI.abort_with_message!("Failed to update listings")
|
|
104
107
|
end
|
|
105
108
|
|
|
109
|
+
upload_metadata(params, edit_id, token) unless params[:skip_upload_metadata]
|
|
110
|
+
upload_images(params, edit_id, token) unless params[:skip_upload_images]
|
|
111
|
+
upload_screenshots(params, edit_id, token) unless params[:skip_upload_screenshots]
|
|
112
|
+
|
|
106
113
|
if params[:changes_not_sent_for_review]
|
|
107
114
|
UI.success('Successfully finished the upload to Amazon Appstore')
|
|
108
115
|
return
|
|
@@ -123,6 +130,89 @@ module Fastlane
|
|
|
123
130
|
UI.success('Successfully finished the upload to Amazon Appstore')
|
|
124
131
|
end
|
|
125
132
|
|
|
133
|
+
def self.upload_metadata(params, edit_id, token)
|
|
134
|
+
UI.message("Uploading metadata...")
|
|
135
|
+
languages = available_languages(params[:metadata_path])
|
|
136
|
+
languages.each do |language|
|
|
137
|
+
metadata = Helper::AmazonAppstoreHelper.load_metadata_from_files(
|
|
138
|
+
metadata_path: params[:metadata_path],
|
|
139
|
+
language: language
|
|
140
|
+
)
|
|
141
|
+
next if metadata.values.all?(&:nil?)
|
|
142
|
+
|
|
143
|
+
begin
|
|
144
|
+
Helper::AmazonAppstoreHelper.update_listing_metadata(
|
|
145
|
+
app_id: params[:package_name],
|
|
146
|
+
edit_id: edit_id,
|
|
147
|
+
language: language,
|
|
148
|
+
listing_data: metadata,
|
|
149
|
+
token: token
|
|
150
|
+
)
|
|
151
|
+
UI.message("Updated metadata for #{language}")
|
|
152
|
+
rescue StandardError => e
|
|
153
|
+
UI.error("Failed to update metadata for #{language}: #{e.message}")
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def self.upload_images(params, edit_id, token)
|
|
159
|
+
UI.message("Uploading images...")
|
|
160
|
+
upload_image_assets(params, edit_id, token, %w[small-icons large-icons promo-images firetv-icons firetv-backgrounds])
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def self.upload_screenshots(params, edit_id, token)
|
|
164
|
+
UI.message("Uploading screenshots...")
|
|
165
|
+
upload_image_assets(params, edit_id, token, %w[screenshots firetv-screenshots])
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def self.upload_image_assets(params, edit_id, token, image_types)
|
|
169
|
+
languages = available_languages(params[:metadata_path])
|
|
170
|
+
|
|
171
|
+
languages.each do |language|
|
|
172
|
+
image_types.each do |image_type|
|
|
173
|
+
images = Helper::AmazonAppstoreHelper.find_images_for_type(
|
|
174
|
+
metadata_path: params[:metadata_path],
|
|
175
|
+
language: language,
|
|
176
|
+
image_type: image_type
|
|
177
|
+
)
|
|
178
|
+
next if images.empty?
|
|
179
|
+
|
|
180
|
+
begin
|
|
181
|
+
Helper::AmazonAppstoreHelper.delete_all_images(
|
|
182
|
+
app_id: params[:package_name],
|
|
183
|
+
edit_id: edit_id,
|
|
184
|
+
language: language,
|
|
185
|
+
image_type: image_type,
|
|
186
|
+
token: token
|
|
187
|
+
)
|
|
188
|
+
rescue StandardError => e
|
|
189
|
+
UI.message("Failed to delete existing #{image_type} for #{language}: #{e.message}")
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
images.each do |image_path|
|
|
193
|
+
Helper::AmazonAppstoreHelper.upload_image(
|
|
194
|
+
app_id: params[:package_name],
|
|
195
|
+
edit_id: edit_id,
|
|
196
|
+
language: language,
|
|
197
|
+
image_type: image_type,
|
|
198
|
+
image_path: image_path,
|
|
199
|
+
token: token
|
|
200
|
+
)
|
|
201
|
+
UI.message("Uploaded #{image_type} for #{language}: #{File.basename(image_path)}")
|
|
202
|
+
rescue StandardError => e
|
|
203
|
+
UI.error("Failed to upload #{image_type} for #{language}: #{e.message}")
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def self.available_languages(metadata_path)
|
|
210
|
+
return [] unless File.directory?(metadata_path)
|
|
211
|
+
|
|
212
|
+
Dir.entries(metadata_path)
|
|
213
|
+
.select { |entry| File.directory?(File.join(metadata_path, entry)) && !entry.start_with?('.') }
|
|
214
|
+
end
|
|
215
|
+
|
|
126
216
|
def self.description
|
|
127
217
|
"Upload apps to Amazon Appstore"
|
|
128
218
|
end
|
|
@@ -167,12 +257,36 @@ module Fastlane
|
|
|
167
257
|
description: "An array of paths to APK files to upload",
|
|
168
258
|
optional: true,
|
|
169
259
|
type: Array),
|
|
260
|
+
FastlaneCore::ConfigItem.new(key: :skip_upload_apk,
|
|
261
|
+
env_name: "AMAZON_APPSTORE_SKIP_UPLOAD_APK",
|
|
262
|
+
description: "Whether to skip uploading APK",
|
|
263
|
+
default_value: false,
|
|
264
|
+
optional: true,
|
|
265
|
+
type: Boolean),
|
|
266
|
+
FastlaneCore::ConfigItem.new(key: :skip_upload_metadata,
|
|
267
|
+
env_name: "AMAZON_APPSTORE_SKIP_UPLOAD_METADATA",
|
|
268
|
+
description: "Whether to skip uploading metadata (title, descriptions)",
|
|
269
|
+
default_value: false,
|
|
270
|
+
optional: true,
|
|
271
|
+
type: Boolean),
|
|
170
272
|
FastlaneCore::ConfigItem.new(key: :skip_upload_changelogs,
|
|
171
273
|
env_name: "AMAZON_APPSTORE_SKIP_UPLOAD_CHANGELOGS",
|
|
172
274
|
description: "Whether to skip uploading changelogs",
|
|
173
275
|
default_value: false,
|
|
174
276
|
optional: true,
|
|
175
277
|
type: Boolean),
|
|
278
|
+
FastlaneCore::ConfigItem.new(key: :skip_upload_images,
|
|
279
|
+
env_name: "AMAZON_APPSTORE_SKIP_UPLOAD_IMAGES",
|
|
280
|
+
description: "Whether to skip uploading images (icons, promo images)",
|
|
281
|
+
default_value: true,
|
|
282
|
+
optional: true,
|
|
283
|
+
type: Boolean),
|
|
284
|
+
FastlaneCore::ConfigItem.new(key: :skip_upload_screenshots,
|
|
285
|
+
env_name: "AMAZON_APPSTORE_SKIP_UPLOAD_SCREENSHOTS",
|
|
286
|
+
description: "Whether to skip uploading screenshots",
|
|
287
|
+
default_value: true,
|
|
288
|
+
optional: true,
|
|
289
|
+
type: Boolean),
|
|
176
290
|
FastlaneCore::ConfigItem.new(key: :metadata_path,
|
|
177
291
|
env_name: "AMAZON_APPSTORE_METADATA_PATH",
|
|
178
292
|
description: "Path to the directory containing the metadata files",
|
|
@@ -7,7 +7,7 @@ module Fastlane
|
|
|
7
7
|
UI = FastlaneCore::UI unless Fastlane.const_defined?(:UI)
|
|
8
8
|
|
|
9
9
|
module Helper
|
|
10
|
-
class AmazonAppstoreHelper
|
|
10
|
+
class AmazonAppstoreHelper # rubocop:disable Metrics/ClassLength
|
|
11
11
|
BASE_URL = 'https://developer.amazon.com'
|
|
12
12
|
AUTH_URL = 'https://api.amazon.com/auth/o2/token'
|
|
13
13
|
|
|
@@ -186,6 +186,7 @@ module Fastlane
|
|
|
186
186
|
|
|
187
187
|
def self.update_listings_for_multiple_apks(app_id:, edit_id:, token:, version_codes:, skip_upload_changelogs:, metadata_path:)
|
|
188
188
|
return if skip_upload_changelogs
|
|
189
|
+
return if version_codes.empty?
|
|
189
190
|
|
|
190
191
|
UI.message("Updating listings for #{version_codes.length} version codes: #{version_codes.join(', ')}")
|
|
191
192
|
|
|
@@ -260,6 +261,142 @@ module Fastlane
|
|
|
260
261
|
nil
|
|
261
262
|
end
|
|
262
263
|
|
|
264
|
+
def self.upload_image(app_id:, edit_id:, language:, image_type:, image_path:, token:)
|
|
265
|
+
images_path = "api/appstore/v1/applications/#{app_id}/edits/#{edit_id}/listings/#{language}/#{image_type}"
|
|
266
|
+
etag_response = api_client.get(images_path) do |request|
|
|
267
|
+
request.headers['Authorization'] = "Bearer #{token}"
|
|
268
|
+
end
|
|
269
|
+
raise StandardError, etag_response.body unless etag_response.success?
|
|
270
|
+
|
|
271
|
+
etag = etag_response.headers['Etag']
|
|
272
|
+
upload_path = "#{images_path}/upload"
|
|
273
|
+
upload_response = api_client.post(upload_path) do |request|
|
|
274
|
+
request.body = File.binread(image_path)
|
|
275
|
+
request.headers['Content-Length'] = request.body.bytesize.to_s
|
|
276
|
+
request.headers['Content-Type'] = 'application/octet-stream'
|
|
277
|
+
request.headers['Authorization'] = "Bearer #{token}"
|
|
278
|
+
request.headers['If-Match'] = etag
|
|
279
|
+
end
|
|
280
|
+
raise StandardError, upload_response.body unless upload_response.success?
|
|
281
|
+
|
|
282
|
+
upload_response.body[:id]
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
def self.get_images(app_id:, edit_id:, language:, image_type:, token:)
|
|
286
|
+
images_path = "api/appstore/v1/applications/#{app_id}/edits/#{edit_id}/listings/#{language}/#{image_type}"
|
|
287
|
+
images_response = api_client.get(images_path) do |request|
|
|
288
|
+
request.headers['Authorization'] = "Bearer #{token}"
|
|
289
|
+
end
|
|
290
|
+
raise StandardError, images_response.body unless images_response.success?
|
|
291
|
+
|
|
292
|
+
images_response.body
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
def self.delete_all_images(app_id:, edit_id:, language:, image_type:, token:)
|
|
296
|
+
images_path = "api/appstore/v1/applications/#{app_id}/edits/#{edit_id}/listings/#{language}/#{image_type}"
|
|
297
|
+
etag_response = api_client.get(images_path) do |request|
|
|
298
|
+
request.headers['Authorization'] = "Bearer #{token}"
|
|
299
|
+
end
|
|
300
|
+
raise StandardError, etag_response.body unless etag_response.success?
|
|
301
|
+
|
|
302
|
+
etag = etag_response.headers['Etag']
|
|
303
|
+
delete_response = api_client.delete(images_path) do |request|
|
|
304
|
+
request.headers['Authorization'] = "Bearer #{token}"
|
|
305
|
+
request.headers['If-Match'] = etag
|
|
306
|
+
end
|
|
307
|
+
raise StandardError, delete_response.body unless delete_response.success?
|
|
308
|
+
|
|
309
|
+
nil
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
def self.upload_video(app_id:, edit_id:, language:, video_path:, token:)
|
|
313
|
+
videos_path = "api/appstore/v1/applications/#{app_id}/edits/#{edit_id}/listings/#{language}/videos"
|
|
314
|
+
etag_response = api_client.get(videos_path) do |request|
|
|
315
|
+
request.headers['Authorization'] = "Bearer #{token}"
|
|
316
|
+
end
|
|
317
|
+
raise StandardError, etag_response.body unless etag_response.success?
|
|
318
|
+
|
|
319
|
+
etag = etag_response.headers['Etag']
|
|
320
|
+
upload_response = api_client.post(videos_path) do |request|
|
|
321
|
+
request.body = File.binread(video_path)
|
|
322
|
+
request.headers['Content-Length'] = request.body.bytesize.to_s
|
|
323
|
+
request.headers['Content-Type'] = 'application/octet-stream'
|
|
324
|
+
request.headers['Authorization'] = "Bearer #{token}"
|
|
325
|
+
request.headers['If-Match'] = etag
|
|
326
|
+
end
|
|
327
|
+
raise StandardError, upload_response.body unless upload_response.success?
|
|
328
|
+
|
|
329
|
+
upload_response.body[:id]
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
def self.update_listing_metadata(app_id:, edit_id:, language:, listing_data:, token:)
|
|
333
|
+
listings_path = "api/appstore/v1/applications/#{app_id}/edits/#{edit_id}/listings/#{language}"
|
|
334
|
+
etag_response = api_client.get(listings_path) do |request|
|
|
335
|
+
request.headers['Authorization'] = "Bearer #{token}"
|
|
336
|
+
end
|
|
337
|
+
raise StandardError, etag_response.body unless etag_response.success?
|
|
338
|
+
|
|
339
|
+
etag = etag_response.headers['Etag']
|
|
340
|
+
existing_data = etag_response.body
|
|
341
|
+
merged_data = existing_data.merge(listing_data.compact)
|
|
342
|
+
merged_data[:recentChanges] = '-' if merged_data[:recentChanges].nil? || merged_data[:recentChanges].empty?
|
|
343
|
+
|
|
344
|
+
update_response = api_client.put(listings_path) do |request|
|
|
345
|
+
request.body = merged_data.to_json
|
|
346
|
+
request.headers['Content-Type'] = 'application/json'
|
|
347
|
+
request.headers['Authorization'] = "Bearer #{token}"
|
|
348
|
+
request.headers['If-Match'] = etag
|
|
349
|
+
end
|
|
350
|
+
raise StandardError, update_response.body unless update_response.success?
|
|
351
|
+
|
|
352
|
+
nil
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
def self.load_metadata_from_files(metadata_path:, language:)
|
|
356
|
+
lang_path = File.join(metadata_path, language)
|
|
357
|
+
{
|
|
358
|
+
title: read_metadata_file(lang_path, 'title.txt'),
|
|
359
|
+
shortDescription: read_metadata_file(lang_path, 'short_description.txt'),
|
|
360
|
+
fullDescription: read_metadata_file(lang_path, 'full_description.txt')
|
|
361
|
+
}
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
def self.read_metadata_file(lang_path, filename)
|
|
365
|
+
path = File.join(lang_path, filename)
|
|
366
|
+
return nil unless File.exist?(path)
|
|
367
|
+
|
|
368
|
+
File.read(path, encoding: 'UTF-8').strip
|
|
369
|
+
end
|
|
370
|
+
private_class_method :read_metadata_file
|
|
371
|
+
|
|
372
|
+
IMAGE_TYPE_MAPPING = {
|
|
373
|
+
'screenshots' => 'phoneScreenshots',
|
|
374
|
+
'small-icons' => 'icon.png',
|
|
375
|
+
'large-icons' => 'large_icon.png',
|
|
376
|
+
'promo-images' => 'featureGraphic.png',
|
|
377
|
+
'firetv-icons' => 'tvBanner.png',
|
|
378
|
+
'firetv-backgrounds' => 'tvBackground.png',
|
|
379
|
+
'firetv-screenshots' => 'tvScreenshots',
|
|
380
|
+
'firetv-featured-backgrounds' => 'tvFeaturedBackground.png',
|
|
381
|
+
'firetv-featured-logos' => 'tvFeaturedLogo.png'
|
|
382
|
+
}.freeze
|
|
383
|
+
|
|
384
|
+
def self.find_images_for_type(metadata_path:, language:, image_type:)
|
|
385
|
+
images_path = File.join(metadata_path, language, 'images')
|
|
386
|
+
mapping = IMAGE_TYPE_MAPPING[image_type]
|
|
387
|
+
return [] if mapping.nil?
|
|
388
|
+
|
|
389
|
+
target_path = File.join(images_path, mapping)
|
|
390
|
+
|
|
391
|
+
if File.directory?(target_path)
|
|
392
|
+
Dir.glob(File.join(target_path, '*.{png,jpg,jpeg}')).sort
|
|
393
|
+
elsif File.exist?(target_path)
|
|
394
|
+
[target_path]
|
|
395
|
+
else
|
|
396
|
+
[]
|
|
397
|
+
end
|
|
398
|
+
end
|
|
399
|
+
|
|
263
400
|
def self.commit_edits(app_id:, edit_id:, token:)
|
|
264
401
|
get_etag_path = "api/appstore/v1/applications/#{app_id}/edits/#{edit_id}"
|
|
265
402
|
etag_response = api_client.get(get_etag_path) do |request|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fastlane-plugin-amazon_appstore
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- ntsk
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-03-29 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|
|
@@ -215,7 +215,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
215
215
|
requirements:
|
|
216
216
|
- - ">="
|
|
217
217
|
- !ruby/object:Gem::Version
|
|
218
|
-
version: '2.
|
|
218
|
+
version: '2.7'
|
|
219
219
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
220
220
|
requirements:
|
|
221
221
|
- - ">="
|