deliver 1.9.0 → 1.10.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 +52 -0
- data/lib/deliver/app_screenshot.rb +3 -3
- data/lib/deliver/commands_generator.rb +16 -7
- data/lib/deliver/detect_values.rb +2 -2
- data/lib/deliver/download_screenshots.rb +5 -5
- data/lib/deliver/html_generator.rb +9 -11
- data/lib/deliver/loader.rb +3 -2
- data/lib/deliver/options.rb +9 -0
- data/lib/deliver/runner.rb +10 -9
- data/lib/deliver/setup.rb +4 -4
- data/lib/deliver/submit_for_review.rb +21 -14
- data/lib/deliver/upload_assets.rb +3 -3
- data/lib/deliver/upload_metadata.rb +52 -10
- data/lib/deliver/upload_price_tier.rb +2 -2
- data/lib/deliver/upload_screenshots.rb +7 -7
- data/lib/deliver/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 85b232e72ca3d072534da39681bd5f123cf56e62
|
4
|
+
data.tar.gz: 72f32e4ebc39f9d7307b321eebb9316510947f5f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1e2c105d24aabc6d9d26da5864136928af30501d41a4866bf99266a05fa11f296d3b39e71da9d44755051316af6299a9b1a1d8c03b9c4bdfb8b5790d1fd40c77
|
7
|
+
data.tar.gz: 6d62b64ea08247a6f49b2cefd814b58001da85c4e1d8e439e0b4724c7079123481f12e9e08a1f462f7761280d783457405d0dde246a1380c01800c74052a8202
|
data/README.md
CHANGED
@@ -132,6 +132,13 @@ To get a list of available options run
|
|
132
132
|
deliver --help
|
133
133
|
```
|
134
134
|
|
135
|
+
|
136
|
+
Select a previously uploaded build and submit it for review.
|
137
|
+
|
138
|
+
```
|
139
|
+
deliver submit_build --build_number 830
|
140
|
+
```
|
141
|
+
|
135
142
|
Check out [Deliverfile.md](https://github.com/fastlane/deliver/blob/master/Deliverfile.md) for more options.
|
136
143
|
|
137
144
|
Already using `deliver` and just updated to 1.0? Check out the [Migration Guide](https://github.com/fastlane/deliver/blob/master/MigrationGuide.md).
|
@@ -176,6 +183,51 @@ Before actually uploading anything to iTunes, ```deliver``` will generate a HTML
|
|
176
183
|
no, en-US, en-CA, fi, ru, zh-Hans, nl-NL, zh-Hant, en-AU, id, de-DE, sv, ko, ms, pt-BR, el, es-ES, it, fr-CA, es-MX, pt-PT, vi, th, ja, fr-FR, da, tr, en-GB
|
177
184
|
```
|
178
185
|
|
186
|
+
## Default values
|
187
|
+
|
188
|
+
Deliver has a special `default` language code which allows you to provide values that are not localised, and which will be used as defaults when you don’t provide a specific localised value.
|
189
|
+
|
190
|
+
You can use this either in json within your deliverfile, or as a folder in your metadata file.
|
191
|
+
|
192
|
+
Imagine that you have localised data for the following language codes: ```en-US, de-DE, el, it```
|
193
|
+
|
194
|
+
You can set the following in your deliverfile
|
195
|
+
|
196
|
+
```
|
197
|
+
release_notes({
|
198
|
+
'default' => "Shiny and new”,
|
199
|
+
'de-DE' => "glänzend und neu"
|
200
|
+
})
|
201
|
+
```
|
202
|
+
|
203
|
+
Deliver will use "Shiny and new" for en-US, el and it.
|
204
|
+
|
205
|
+
It will use "glänzend und neu" for de-DE.
|
206
|
+
|
207
|
+
You can do the same with folders
|
208
|
+
|
209
|
+
```
|
210
|
+
default
|
211
|
+
keywords.txt
|
212
|
+
marketing_url.txt
|
213
|
+
name.txt
|
214
|
+
privacy_url.txt
|
215
|
+
support_url.txt
|
216
|
+
release_notes.txt
|
217
|
+
en-US
|
218
|
+
description.txt
|
219
|
+
de-DE
|
220
|
+
description.txt
|
221
|
+
el
|
222
|
+
description.txt
|
223
|
+
it
|
224
|
+
description.txt
|
225
|
+
```
|
226
|
+
|
227
|
+
In this case, default values for keywords, urls, name and release notes are used in all localisations, but each language has a fully localised description
|
228
|
+
|
229
|
+
|
230
|
+
|
179
231
|
## Automatically create screenshots
|
180
232
|
|
181
233
|
If you want to integrate `deliver` with [snapshot](https://github.com/fastlane/snapshot), check out [fastlane](https://fastlane.tools)!
|
@@ -44,7 +44,7 @@ module Deliver
|
|
44
44
|
|
45
45
|
self.screen_size = screen_size
|
46
46
|
|
47
|
-
|
47
|
+
UI.error("Looks like the screenshot given (#{path}) does not match the requirements of #{screen_size}") unless self.is_valid?
|
48
48
|
end
|
49
49
|
|
50
50
|
# The iTC API requires a different notation for the device
|
@@ -139,7 +139,7 @@ module Deliver
|
|
139
139
|
def self.calculate_screen_size(path)
|
140
140
|
size = FastImage.size(path)
|
141
141
|
|
142
|
-
|
142
|
+
UI.user_error!("Could not find or parse file at path '#{path}'") if size.nil? or size.count == 0
|
143
143
|
|
144
144
|
# Walk up two directories and test if we need to handle a platform that doesn't support landscape
|
145
145
|
path_component = Pathname.new(path).each_filename.to_a[-3]
|
@@ -162,7 +162,7 @@ module Deliver
|
|
162
162
|
end
|
163
163
|
end
|
164
164
|
|
165
|
-
|
165
|
+
UI.user_error!("Unsupported screen size #{size} for path '#{path}'")
|
166
166
|
end
|
167
167
|
end
|
168
168
|
|
@@ -6,7 +6,6 @@ HighLine.track_eof = false
|
|
6
6
|
module Deliver
|
7
7
|
class CommandsGenerator
|
8
8
|
include Commander::Methods
|
9
|
-
UI = FastlaneCore::UI
|
10
9
|
|
11
10
|
def self.start
|
12
11
|
FastlaneCore::UpdateChecker.start_looking_for_update('deliver')
|
@@ -39,7 +38,7 @@ module Deliver
|
|
39
38
|
loaded = options.load_configuration_file("Deliverfile")
|
40
39
|
loaded = true if options[:description] || options[:ipa] || options[:pkg] # do we have *anything* here?
|
41
40
|
unless loaded
|
42
|
-
if
|
41
|
+
if UI.confirm("No deliver configuration found in the current directory. Do you want to setup deliver?")
|
43
42
|
require 'deliver/setup'
|
44
43
|
Deliver::Runner.new(options) # to login...
|
45
44
|
Deliver::Setup.new.run(options)
|
@@ -50,13 +49,23 @@ module Deliver
|
|
50
49
|
Deliver::Runner.new(options).run
|
51
50
|
end
|
52
51
|
end
|
53
|
-
|
52
|
+
command :submit_build do |c|
|
53
|
+
c.syntax = 'deliver submit_build'
|
54
|
+
c.description = 'Submit a specific build-nr for review, use latest for the latest build'
|
55
|
+
c.action do |args, options|
|
56
|
+
options = FastlaneCore::Configuration.create(Deliver::Options.available_options, options.__hash__)
|
57
|
+
options.load_configuration_file("Deliverfile")
|
58
|
+
options[:submit_for_review] = true
|
59
|
+
options[:build_number] = "latest" unless options[:build_number]
|
60
|
+
Deliver::Runner.new(options).run
|
61
|
+
end
|
62
|
+
end
|
54
63
|
command :init do |c|
|
55
64
|
c.syntax = 'deliver init'
|
56
65
|
c.description = 'Create the initial `deliver` configuration based on an existing app'
|
57
66
|
c.action do |args, options|
|
58
67
|
if File.exist?("Deliverfile") or File.exist?("fastlane/Deliverfile")
|
59
|
-
|
68
|
+
Ui.important("You already got a running deliver setup in this directory")
|
60
69
|
return 0
|
61
70
|
end
|
62
71
|
|
@@ -88,7 +97,7 @@ module Deliver
|
|
88
97
|
options = FastlaneCore::Configuration.create(Deliver::Options.available_options, options.__hash__)
|
89
98
|
options.load_configuration_file("Deliverfile")
|
90
99
|
Deliver::Runner.new(options) # to login...
|
91
|
-
path = (FastlaneCore::Helper.fastlane_enabled? ? './fastlane' : '.')
|
100
|
+
path = options[:screenshots_path] || (FastlaneCore::Helper.fastlane_enabled? ? './fastlane' : '.')
|
92
101
|
Deliver::DownloadScreenshots.run(options, path)
|
93
102
|
end
|
94
103
|
end
|
@@ -101,9 +110,9 @@ module Deliver
|
|
101
110
|
options = FastlaneCore::Configuration.create(Deliver::Options.available_options, options.__hash__)
|
102
111
|
options.load_configuration_file("Deliverfile")
|
103
112
|
Deliver::Runner.new(options) # to login...
|
104
|
-
path = (FastlaneCore::Helper.fastlane_enabled? ? './fastlane' : '.')
|
113
|
+
path = options[:metadata_path] || (FastlaneCore::Helper.fastlane_enabled? ? './fastlane' : '.')
|
105
114
|
res = ENV["DELIVER_FORCE_OVERWRITE"]
|
106
|
-
res ||=
|
115
|
+
res ||= UI.confirm("Do you want to overwrite existing metadata on path '#{File.expand_path(path)}/metadata'?")
|
107
116
|
if res
|
108
117
|
require 'deliver/setup'
|
109
118
|
v = options[:app].latest_version
|
@@ -17,7 +17,7 @@ module Deliver
|
|
17
17
|
end
|
18
18
|
|
19
19
|
options[:app_identifier] = identifier if identifier.to_s.length > 0
|
20
|
-
options[:app_identifier] ||=
|
20
|
+
options[:app_identifier] ||= UI.input("The Bundle Identifier of your App: ")
|
21
21
|
end
|
22
22
|
|
23
23
|
def find_app(options)
|
@@ -27,7 +27,7 @@ module Deliver
|
|
27
27
|
if app
|
28
28
|
options[:app] = app
|
29
29
|
else
|
30
|
-
|
30
|
+
UI.user_error!("Could not find app with app identifier '#{options[:app_identifier]}' in your iTunes Connect account (#{options[:username]} - Team: #{Spaceship::Tunes.client.team_id})")
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
@@ -1,12 +1,12 @@
|
|
1
1
|
module Deliver
|
2
2
|
class DownloadScreenshots
|
3
3
|
def self.run(options, path)
|
4
|
-
|
4
|
+
UI.message("Downloading all existing screenshots...")
|
5
5
|
download(options, path)
|
6
|
-
|
6
|
+
UI.success("Successfully downloaded all existing screenshots")
|
7
7
|
rescue => ex
|
8
|
-
|
9
|
-
|
8
|
+
UI.error(ex)
|
9
|
+
UI.error("Couldn't download already existing screenshots from iTunes Connect.")
|
10
10
|
end
|
11
11
|
|
12
12
|
def self.download(options, folder_path)
|
@@ -18,7 +18,7 @@ module Deliver
|
|
18
18
|
original_file_extension = File.basename(screenshot.original_file_name)
|
19
19
|
file_name += "." + original_file_extension
|
20
20
|
|
21
|
-
|
21
|
+
UI.message("Downloading existing screenshot '#{file_name}'")
|
22
22
|
|
23
23
|
# If the screen shot is for an appleTV we need to store it in a way that we'll know it's an appleTV
|
24
24
|
# screen shot later as the screen size is the same as an iPhone 6 Plus in landscape.
|
@@ -4,24 +4,22 @@ module Deliver
|
|
4
4
|
begin
|
5
5
|
html_path = self.render(options, screenshots, '.')
|
6
6
|
rescue => ex
|
7
|
-
|
8
|
-
|
9
|
-
okay =
|
7
|
+
UI.error(ex.inspect)
|
8
|
+
UI.error(ex.backtrace.join("\n"))
|
9
|
+
okay = UI.input("Could not render HTML preview. Do you still want to continue?")
|
10
10
|
return if okay
|
11
|
-
|
11
|
+
UI.crash!("Could not render HTML page")
|
12
12
|
end
|
13
|
-
|
14
|
-
|
15
|
-
puts "`force true` to your Deliverfile or using `deliver --force`"
|
16
|
-
puts "----------------------------------------------------------------------------"
|
13
|
+
UI.important("Verifying the upload via the HTML file can be disabled by either adding")
|
14
|
+
UI.important("`force true` to your Deliverfile or using `deliver --force`")
|
17
15
|
|
18
16
|
system("open '#{html_path}'")
|
19
|
-
okay =
|
17
|
+
okay = UI.confirm("Does the Preview on path '#{html_path}' look okay for you?")
|
20
18
|
|
21
19
|
if okay
|
22
|
-
|
20
|
+
UI.success("HTML file confirmed...") # print this to give feedback to the user immediately
|
23
21
|
else
|
24
|
-
|
22
|
+
UI.user_error!("Did not upload the metadata, because the HTML file was rejected by the user")
|
25
23
|
end
|
26
24
|
end
|
27
25
|
|
data/lib/deliver/loader.rb
CHANGED
@@ -4,8 +4,9 @@ module Deliver
|
|
4
4
|
module Loader
|
5
5
|
# The directory 'appleTV' is a special folder that will cause our screenshot gathering code to iterate
|
6
6
|
# through it as well searching for language folders.
|
7
|
-
APPLE_TV_DIR_NAME = "appleTV"
|
8
|
-
|
7
|
+
APPLE_TV_DIR_NAME = "appleTV".freeze
|
8
|
+
DEFAULT_DIR_NAME = "default".freeze
|
9
|
+
ALL_LANGUAGES = (FastlaneCore::Languages::ALL_LANGUAGES + [APPLE_TV_DIR_NAME, APPLE_TV_DIR_NAME]).map(&:downcase).freeze
|
9
10
|
|
10
11
|
def self.language_folders(root)
|
11
12
|
Dir.glob(File.join(root, '*')).select do |path|
|
data/lib/deliver/options.rb
CHANGED
@@ -94,6 +94,15 @@ module Deliver
|
|
94
94
|
description: "The price tier of this application",
|
95
95
|
is_string: false,
|
96
96
|
optional: true),
|
97
|
+
FastlaneCore::ConfigItem.new(key: :build_number,
|
98
|
+
short_option: "-n",
|
99
|
+
description: "If set the given build number (already uploaded to iTC) will be used instead of the current built one",
|
100
|
+
default_value: "latest",
|
101
|
+
optional: true,
|
102
|
+
conflicting_options: [:ipa, :pkg],
|
103
|
+
conflict_block: proc do |value|
|
104
|
+
raise "You can't use 'build_number' and '#{value.key}' options in one run.".red
|
105
|
+
end),
|
97
106
|
FastlaneCore::ConfigItem.new(key: :app_rating_config_path,
|
98
107
|
short_option: "-g",
|
99
108
|
description: "Path to the app rating's config",
|
data/lib/deliver/runner.rb
CHANGED
@@ -10,22 +10,22 @@ module Deliver
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def login
|
13
|
-
|
13
|
+
UI.message("Login to iTunes Connect (#{options[:username]})")
|
14
14
|
Spaceship::Tunes.login(options[:username])
|
15
15
|
Spaceship::Tunes.select_team
|
16
|
-
|
16
|
+
UI.message("Login successful")
|
17
17
|
end
|
18
18
|
|
19
19
|
def run
|
20
20
|
verify_version if options[:app_version].to_s.length > 0
|
21
21
|
upload_metadata
|
22
22
|
|
23
|
-
has_binary = options[:ipa] || options[:pkg]
|
24
|
-
if !options[:skip_binary_upload] && has_binary
|
23
|
+
has_binary = (options[:ipa] || options[:pkg])
|
24
|
+
if !options[:skip_binary_upload] && !options[:build_number] && has_binary
|
25
25
|
upload_binary
|
26
26
|
end
|
27
27
|
|
28
|
-
|
28
|
+
UI.success("Finished the upload to iTunes Connect")
|
29
29
|
|
30
30
|
submit_for_review if options[:submit_for_review]
|
31
31
|
end
|
@@ -34,13 +34,13 @@ module Deliver
|
|
34
34
|
# If not, the new version will automatically be created
|
35
35
|
def verify_version
|
36
36
|
app_version = options[:app_version]
|
37
|
-
|
37
|
+
UI.message("Making sure the latest version on iTunes Connect matches '#{app_version}' from the ipa file...")
|
38
38
|
|
39
39
|
changed = options[:app].ensure_version!(app_version)
|
40
40
|
if changed
|
41
|
-
|
41
|
+
UI.success("Successfully set the version to '#{app_version}'")
|
42
42
|
else
|
43
|
-
|
43
|
+
UI.success("'#{app_version}' is the latest version on iTunes Connect")
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
@@ -49,6 +49,7 @@ module Deliver
|
|
49
49
|
# First, collect all the things for the HTML Report
|
50
50
|
screenshots = UploadScreenshots.new.collect_screenshots(options)
|
51
51
|
UploadMetadata.new.load_from_filesystem(options)
|
52
|
+
UploadMetadata.new.assign_defaults(options)
|
52
53
|
|
53
54
|
# Validate
|
54
55
|
validate_html(screenshots)
|
@@ -62,7 +63,7 @@ module Deliver
|
|
62
63
|
|
63
64
|
# Upload the binary to iTunes Connect
|
64
65
|
def upload_binary
|
65
|
-
|
66
|
+
UI.message("Uploading binary to iTunes Connect")
|
66
67
|
if options[:ipa]
|
67
68
|
package_path = FastlaneCore::IpaUploadPackageBuilder.new.generate(
|
68
69
|
app_id: options[:app].apple_id,
|
data/lib/deliver/setup.rb
CHANGED
@@ -16,7 +16,7 @@ module Deliver
|
|
16
16
|
FileUtils.mkdir_p File.join(deliver_path, 'screenshots') # just in case the fetching didn't work
|
17
17
|
File.write(File.join(deliver_path, 'screenshots', 'README.txt'), File.read("#{Helper.gem_path('deliver')}/lib/assets/ScreenshotsHelp"))
|
18
18
|
|
19
|
-
|
19
|
+
UI.success("Successfully created new Deliverfile at path '#{file_path}'")
|
20
20
|
end
|
21
21
|
|
22
22
|
# This method takes care of creating a new 'deliver' folder, containg the app metadata
|
@@ -49,7 +49,7 @@ module Deliver
|
|
49
49
|
resulting_path = File.join(containing, language, "#{key}.txt")
|
50
50
|
FileUtils.mkdir_p(File.expand_path('..', resulting_path))
|
51
51
|
File.write(resulting_path, content)
|
52
|
-
|
52
|
+
UI.message("Writing to '#{resulting_path}'")
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
@@ -63,10 +63,10 @@ module Deliver
|
|
63
63
|
|
64
64
|
resulting_path = File.join(containing, "#{key}.txt")
|
65
65
|
File.write(resulting_path, content)
|
66
|
-
|
66
|
+
UI.message("Writing to '#{resulting_path}'")
|
67
67
|
end
|
68
68
|
|
69
|
-
|
69
|
+
UI.success("Successfully created new configuration files.")
|
70
70
|
end
|
71
71
|
|
72
72
|
def download_screenshots(deliver_path, options)
|
@@ -4,7 +4,7 @@ module Deliver
|
|
4
4
|
app = options[:app]
|
5
5
|
select_build(options)
|
6
6
|
|
7
|
-
|
7
|
+
UI.message("Submitting the app for review...")
|
8
8
|
submission = app.create_submission
|
9
9
|
|
10
10
|
# Set app submission information
|
@@ -15,9 +15,8 @@ module Deliver
|
|
15
15
|
|
16
16
|
# User Values
|
17
17
|
if options[:submission_information]
|
18
|
-
raise "`submission_information` must be a hash" unless options[:submission_information].kind_of?(Hash)
|
19
18
|
options[:submission_information].each do |key, value|
|
20
|
-
|
19
|
+
UI.message("Setting '#{key}' to '#{value}'...")
|
21
20
|
submission.send("#{key}=", value)
|
22
21
|
end
|
23
22
|
end
|
@@ -25,25 +24,33 @@ module Deliver
|
|
25
24
|
# Finalize app submission
|
26
25
|
submission.complete!
|
27
26
|
|
28
|
-
|
27
|
+
UI.success("Successfully submitted the app for review!")
|
29
28
|
end
|
30
29
|
|
31
30
|
def select_build(options)
|
32
|
-
Helper.log.info "Selecting the latest build..."
|
33
31
|
app = options[:app]
|
34
32
|
v = app.edit_version
|
35
|
-
build = wait_for_build(app)
|
36
33
|
|
37
|
-
|
34
|
+
if options[:build_number] and options[:build_number] != "latest"
|
35
|
+
UI.message("Selecting existing build-number: #{options[:build_number]}")
|
36
|
+
build = v.candidate_builds.detect { |a| a.build_version == options[:build_number] }
|
37
|
+
unless build
|
38
|
+
UI.user_error!("Build number: #{options[:build_number]} does not exist")
|
39
|
+
end
|
40
|
+
else
|
41
|
+
UI.message("Selecting the latest build...")
|
42
|
+
build = wait_for_build(app)
|
43
|
+
end
|
44
|
+
UI.message("Selecting build #{build.train_version} (#{build.build_version})...")
|
38
45
|
|
39
46
|
v.select_build(build)
|
40
47
|
v.save!
|
41
48
|
|
42
|
-
|
49
|
+
UI.success("Successfully selected build")
|
43
50
|
end
|
44
51
|
|
45
52
|
def wait_for_build(app)
|
46
|
-
|
53
|
+
UI.user_error!("Could not find app with app identifier #{WatchBuild.config[:app_identifier]}") unless app
|
47
54
|
|
48
55
|
start = Time.now
|
49
56
|
|
@@ -51,10 +58,10 @@ module Deliver
|
|
51
58
|
build = find_build(app)
|
52
59
|
return build if build.processing == false
|
53
60
|
|
54
|
-
|
61
|
+
UI.message("Waiting iTunes Connect processing for build #{build.train_version} (#{build.build_version})... this might take a while...")
|
55
62
|
if (Time.now - start) > (60 * 5)
|
56
|
-
|
57
|
-
|
63
|
+
UI.message("")
|
64
|
+
UI.message("You can tweet: \"iTunes Connect #iosprocessingtime #{((Time.now - start) / 60).round} minutes\"")
|
58
65
|
end
|
59
66
|
sleep 30
|
60
67
|
end
|
@@ -70,8 +77,8 @@ module Deliver
|
|
70
77
|
end
|
71
78
|
|
72
79
|
unless build
|
73
|
-
|
74
|
-
|
80
|
+
UI.error(app.latest_version.candidate_builds)
|
81
|
+
UI.crash!("Could not find build")
|
75
82
|
end
|
76
83
|
|
77
84
|
return build
|
@@ -4,15 +4,15 @@ module Deliver
|
|
4
4
|
app = options[:app]
|
5
5
|
|
6
6
|
v = app.edit_version
|
7
|
-
|
7
|
+
UI.user_error!("Could not find a version to edit for app '#{app.name}'") unless v
|
8
8
|
|
9
9
|
if options[:app_icon]
|
10
|
-
|
10
|
+
UI.message("Uploading app icon...")
|
11
11
|
v.upload_large_icon!(options[:app_icon])
|
12
12
|
end
|
13
13
|
|
14
14
|
if options[:apple_watch_app_icon]
|
15
|
-
|
15
|
+
UI.message("Uploading apple watchapp icon...")
|
16
16
|
v.upload_watch_icon!(options[:apple_watch_app_icon])
|
17
17
|
end
|
18
18
|
|
@@ -31,7 +31,7 @@ module Deliver
|
|
31
31
|
next unless current
|
32
32
|
|
33
33
|
unless current.kind_of?(Hash)
|
34
|
-
|
34
|
+
UI.error("Error with provided '#{key}'. Must be a hash, the key being the language.")
|
35
35
|
next
|
36
36
|
end
|
37
37
|
|
@@ -55,10 +55,52 @@ module Deliver
|
|
55
55
|
set_review_information(v, options)
|
56
56
|
set_app_rating(v, options)
|
57
57
|
|
58
|
-
|
58
|
+
UI.message("Uploading metadata to iTunes Connect")
|
59
59
|
v.save!
|
60
60
|
details.save!
|
61
|
-
|
61
|
+
UI.success("Successfully uploaded initial set of metadata to iTunes Connect")
|
62
|
+
end
|
63
|
+
|
64
|
+
# If the user is using the 'default' language, then assign values where they are needed
|
65
|
+
def assign_defaults(options)
|
66
|
+
# Build a complete list of the required languages
|
67
|
+
enabled_languages = []
|
68
|
+
|
69
|
+
# Get all languages used in existing settings
|
70
|
+
(LOCALISED_VERSION_VALUES + LOCALISED_APP_VALUES).each do |key|
|
71
|
+
current = options[key]
|
72
|
+
next unless current && current.kind_of?(Hash)
|
73
|
+
current.each do |language, value|
|
74
|
+
enabled_languages << language unless enabled_languages.include?(language)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Check folder list (an empty folder signifies a language is required)
|
79
|
+
Dir.glob(File.join(options[:metadata_path], "*")).each do |lng_folder|
|
80
|
+
next unless File.directory?(lng_folder) # We don't want to read txt as they are non localised
|
81
|
+
|
82
|
+
language = File.basename(lng_folder)
|
83
|
+
enabled_languages << language unless enabled_languages.include?(language)
|
84
|
+
end
|
85
|
+
|
86
|
+
return unless enabled_languages.include?("default")
|
87
|
+
UI.message("Detected languages: " + enabled_languages.to_s)
|
88
|
+
|
89
|
+
(LOCALISED_VERSION_VALUES + LOCALISED_APP_VALUES).each do |key|
|
90
|
+
current = options[key]
|
91
|
+
next unless current && current.kind_of?(Hash)
|
92
|
+
|
93
|
+
default = current["default"]
|
94
|
+
next if default.nil?
|
95
|
+
|
96
|
+
enabled_languages.each do |language|
|
97
|
+
value = current[language]
|
98
|
+
next unless value.nil?
|
99
|
+
|
100
|
+
current[language] = default
|
101
|
+
end
|
102
|
+
current.delete("default")
|
103
|
+
end
|
62
104
|
end
|
63
105
|
|
64
106
|
# Makes sure all languages we need are actually created
|
@@ -69,7 +111,7 @@ module Deliver
|
|
69
111
|
# We only care about languages from user provided values
|
70
112
|
# as the other languages are on iTC already anyway
|
71
113
|
v = options[:app].edit_version
|
72
|
-
|
114
|
+
UI.user_error!("Could not find a version to edit for app '#{options[:app].name}', the app metadata is read-only currently") unless v
|
73
115
|
|
74
116
|
enabled_languages = []
|
75
117
|
LOCALISED_VERSION_VALUES.each do |key|
|
@@ -84,7 +126,7 @@ module Deliver
|
|
84
126
|
v.create_languages(enabled_languages)
|
85
127
|
lng_text = "language"
|
86
128
|
lng_text += "s" if enabled_languages.count != 1
|
87
|
-
|
129
|
+
UI.message("Activating #{lng_text} #{enabled_languages.join(', ')}...")
|
88
130
|
v.save!
|
89
131
|
end
|
90
132
|
true
|
@@ -101,7 +143,7 @@ module Deliver
|
|
101
143
|
path = File.join(lng_folder, "#{key}.txt")
|
102
144
|
next unless File.exist?(path)
|
103
145
|
|
104
|
-
|
146
|
+
UI.message("Loading '#{path}'...")
|
105
147
|
options[key] ||= {}
|
106
148
|
options[key][language] ||= File.read(path)
|
107
149
|
end
|
@@ -112,7 +154,7 @@ module Deliver
|
|
112
154
|
path = File.join(options[:metadata_path], "#{key}.txt")
|
113
155
|
next unless File.exist?(path)
|
114
156
|
|
115
|
-
|
157
|
+
UI.message("Loading '#{path}'...")
|
116
158
|
options[key] ||= File.read(path)
|
117
159
|
end
|
118
160
|
end
|
@@ -122,7 +164,7 @@ module Deliver
|
|
122
164
|
def set_review_information(v, options)
|
123
165
|
return unless options[:app_review_information]
|
124
166
|
info = options[:app_review_information]
|
125
|
-
|
167
|
+
UI.user_error!("`app_review_information` must be a hash") unless info.kind_of?(Hash)
|
126
168
|
|
127
169
|
v.review_first_name = info[:first_name] if info[:first_name]
|
128
170
|
v.review_last_name = info[:last_name] if info[:last_name]
|
@@ -140,8 +182,8 @@ module Deliver
|
|
140
182
|
begin
|
141
183
|
json = JSON.parse(File.read(options[:app_rating_config_path]))
|
142
184
|
rescue => ex
|
143
|
-
|
144
|
-
|
185
|
+
UI.error(ex.to_s)
|
186
|
+
UI.user_error!("Error parsing JSON file at path '#{options[:app_rating_config_path]}'")
|
145
187
|
end
|
146
188
|
v.update_rating(json)
|
147
189
|
end
|
@@ -10,12 +10,12 @@ module Deliver
|
|
10
10
|
|
11
11
|
old_price = app.price_tier
|
12
12
|
if options[:price_tier] == old_price
|
13
|
-
|
13
|
+
UI.success("Price Tier unchanged (tier #{options[:price_tier]})")
|
14
14
|
return
|
15
15
|
end
|
16
16
|
|
17
17
|
app.update_price_tier!(options[:price_tier])
|
18
|
-
|
18
|
+
UI.success("Successfully updated the pricing from #{old_price} to #{options[:price_tier]}")
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
@@ -7,9 +7,9 @@ module Deliver
|
|
7
7
|
app = options[:app]
|
8
8
|
|
9
9
|
v = app.edit_version
|
10
|
-
|
10
|
+
UI.user_error!("Could not find a version to edit for app '#{app.name}'") unless v
|
11
11
|
|
12
|
-
|
12
|
+
UI.message("Starting with the upload of screenshots...")
|
13
13
|
|
14
14
|
# First, clear all previously uploaded screenshots, but only where we have new ones
|
15
15
|
# screenshots.each do |screenshot|
|
@@ -25,7 +25,7 @@ module Deliver
|
|
25
25
|
|
26
26
|
screenshots_per_language = screenshots.group_by(&:language)
|
27
27
|
screenshots_per_language.each do |language, screenshots_for_language|
|
28
|
-
|
28
|
+
UI.message("Uploading #{screenshots_for_language.length} screenshots for language #{language}")
|
29
29
|
screenshots_for_language.each do |screenshot|
|
30
30
|
indized[screenshot.language] ||= {}
|
31
31
|
indized[screenshot.language][screenshot.device_type] ||= 0
|
@@ -34,11 +34,11 @@ module Deliver
|
|
34
34
|
index = indized[screenshot.language][screenshot.device_type]
|
35
35
|
|
36
36
|
if index > 5
|
37
|
-
|
37
|
+
UI.error("Too many screenshots found for device '#{screenshot.device_type}' in '#{screenshot.language}'")
|
38
38
|
next
|
39
39
|
end
|
40
40
|
|
41
|
-
|
41
|
+
UI.message("Uploading '#{screenshot.path}'...")
|
42
42
|
v.upload_screenshot!(screenshot.path,
|
43
43
|
index,
|
44
44
|
screenshot.language,
|
@@ -46,10 +46,10 @@ module Deliver
|
|
46
46
|
end
|
47
47
|
# ideally we should only save once, but itunes server can't cope it seems
|
48
48
|
# so we save per language. See issue #349
|
49
|
-
|
49
|
+
UI.message("Saving changes")
|
50
50
|
v.save!
|
51
51
|
end
|
52
|
-
|
52
|
+
UI.success("Successfully uploaded screenshots to iTunes Connect")
|
53
53
|
end
|
54
54
|
|
55
55
|
def collect_screenshots(options)
|
data/lib/deliver/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: deliver
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Felix Krause
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-02-
|
11
|
+
date: 2016-02-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fastlane_core
|