motion-sparkle-sandbox 2.0.1 → 2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -4
- data/bin/bundle +37 -26
- data/bin/byebug +7 -7
- data/bin/coderay +7 -7
- data/bin/fuzzy_match +7 -7
- data/bin/htmldiff +7 -7
- data/bin/httpclient +7 -7
- data/bin/ldiff +7 -7
- data/bin/pod +7 -7
- data/bin/pry +7 -7
- data/bin/rake +7 -7
- data/bin/rspec +7 -7
- data/bin/rubocop +7 -7
- data/bin/ruby-parse +7 -7
- data/bin/ruby-rewrite +7 -7
- data/bin/sandbox-pod +7 -7
- data/bin/xcodeproj +7 -7
- data/lib/motion/project/appcast.rb +236 -127
- data/lib/motion/project/project.rb +11 -2
- data/lib/motion/project/rake_tasks.rb +15 -1
- data/lib/motion/project/setup.rb +2 -2
- data/lib/motion/project/sparkle.rb +107 -34
- data/lib/motion-sparkle-sandbox/version.rb +1 -1
- data/lib/motion-sparkle-sandbox.rb +1 -1
- data/sample-app/.gitignore +1 -0
- data/sample-app/Rakefile +5 -2
- data/spec/appcast_spec.rb +60 -0
- data/spec/setup_spec.rb +30 -55
- data/spec/sparkle_spec.rb +11 -38
- data/spec/spec_helper.rb +8 -0
- data/spec/spec_utils.rb +36 -0
- metadata +4 -2
@@ -1,45 +1,178 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# rubocop:disable Metrics/ClassLength
|
3
4
|
module Motion
|
4
5
|
module Project
|
5
6
|
class Sparkle
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
7
|
+
class Appcast
|
8
|
+
PARAMS = %i[
|
9
|
+
package_base_url
|
10
|
+
package_filename
|
11
|
+
notes_base_url
|
12
|
+
notes_filename
|
13
|
+
use_exported_private_key
|
14
|
+
base_url
|
15
|
+
releases_folder
|
16
|
+
feed_base_url
|
17
|
+
feed_filename
|
18
|
+
].freeze
|
19
|
+
|
20
|
+
CLI_OPTIONS = {
|
21
|
+
account: '--account',
|
22
|
+
private_ed_key_file: '--ed-key-file',
|
23
|
+
download_url_prefix: '--download-url-prefix',
|
24
|
+
release_notes_url_prefix: '--release-notes-url-prefix',
|
25
|
+
full_release_notes_url: '--full-release-notes-url',
|
26
|
+
link: '--link',
|
27
|
+
versions: '--versions',
|
28
|
+
maximum_deltas: '--maximum-deltas',
|
29
|
+
delta_compression: '--delta-compression',
|
30
|
+
delta_compression_level: '--delta-compression-level',
|
31
|
+
channel: '--channel',
|
32
|
+
major_version: '--major-version',
|
33
|
+
ignore_skipped_upgrades_below_version: '--ignore-skipped-upgrades-below-version',
|
34
|
+
phased_rollout_interval: '--phased-rollout-interval',
|
35
|
+
critical_update_version: '--critical-update-version',
|
36
|
+
informational_update_versions: '--informational-update-versions',
|
37
|
+
output_path: '-o'
|
38
|
+
}.freeze
|
39
|
+
|
40
|
+
attr_accessor :base_url,
|
41
|
+
:feed_base_url,
|
42
|
+
:feed_filename,
|
43
|
+
:notes_filename,
|
44
|
+
:package_filename,
|
45
|
+
:releases_folder,
|
46
|
+
:use_exported_private_key,
|
47
|
+
:cli_options
|
48
|
+
attr_writer :notes_base_url,
|
49
|
+
:package_base_url
|
50
|
+
|
51
|
+
def initialize(sparkle_object)
|
52
|
+
@sparkle = sparkle_object
|
53
|
+
@cli_options = {
|
54
|
+
account: 'ed25519' # Sparkle's default account
|
55
|
+
}
|
56
|
+
|
57
|
+
@feed_base_url = nil
|
58
|
+
@feed_filename = 'releases.xml'
|
59
|
+
@notes_base_url = nil
|
60
|
+
@notes_filename = nil
|
61
|
+
@package_base_url = nil
|
62
|
+
@package_filename = nil
|
63
|
+
@base_url = nil
|
64
|
+
@releases_folder = nil
|
65
|
+
@use_exported_private_key = false
|
66
|
+
end
|
67
|
+
|
68
|
+
def process_option(key, value)
|
69
|
+
if CLI_OPTIONS.keys.include?(key)
|
70
|
+
cli_options[key] = value
|
71
|
+
elsif PARAMS.include?(key)
|
72
|
+
send("#{key}=", value)
|
73
|
+
else
|
74
|
+
return false
|
75
|
+
end
|
76
|
+
|
77
|
+
true
|
78
|
+
end
|
79
|
+
|
80
|
+
def feed_url
|
81
|
+
"#{feed_base_url || base_url}#{feed_filename}"
|
82
|
+
end
|
83
|
+
|
84
|
+
def notes_base_url
|
85
|
+
@notes_base_url || base_url
|
86
|
+
end
|
14
87
|
|
15
|
-
|
88
|
+
def package_base_url
|
89
|
+
@package_base_url || base_url
|
90
|
+
end
|
91
|
+
|
92
|
+
def prepare_args
|
93
|
+
args = []
|
94
|
+
|
95
|
+
account(args)
|
96
|
+
private_ed_key_file(args)
|
97
|
+
download_url_prefix(args)
|
98
|
+
release_notes_url_prefix(args)
|
99
|
+
full_release_notes_url(args)
|
100
|
+
link(args)
|
101
|
+
versions(args)
|
102
|
+
maximum_deltas(args)
|
103
|
+
delta_compression(args)
|
104
|
+
delta_compression_level(args)
|
105
|
+
channel(args)
|
106
|
+
major_version(args)
|
107
|
+
ignore_skipped_upgrades_below_version(args)
|
108
|
+
phased_rollout_interval(args)
|
109
|
+
critical_update_version(args)
|
110
|
+
informational_update_versions(args)
|
111
|
+
output_path(args)
|
112
|
+
|
113
|
+
args
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
16
117
|
|
17
|
-
|
118
|
+
# --account <account> The account name in your keychain associated with
|
119
|
+
# your private EdDSA (ed25519) key to use for signing
|
120
|
+
# new updates. (default: ed25519)
|
121
|
+
def account(args)
|
122
|
+
return unless cli_options[:account].present?
|
18
123
|
|
19
|
-
|
20
|
-
|
124
|
+
args << "--account=#{cli_options[:account]}"
|
125
|
+
end
|
21
126
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
127
|
+
# -s <private-EdDSA-key> The private EdDSA string (128 characters). If not
|
128
|
+
# specified, the private EdDSA key will be read from
|
129
|
+
# the Keychain instead.
|
130
|
+
def private_ed_key_file(args)
|
131
|
+
if cli_options[:private_ed_key_file].present?
|
132
|
+
args << "--ed-key-file=#{cli_options[:private_ed_key_file]}"
|
133
|
+
elsif use_exported_private_key && File.exist?(@sparkle.private_key_path)
|
134
|
+
args << "--ed-key-file=#{@sparkle.private_key_path}"
|
135
|
+
end
|
28
136
|
end
|
29
137
|
|
30
138
|
# --download-url-prefix <url> A URL that will be used as prefix for the URL from
|
31
139
|
# where updates will be downloaded.
|
32
|
-
args
|
140
|
+
def download_url_prefix(args)
|
141
|
+
if cli_options[:download_url_prefix].present?
|
142
|
+
args << "--download-url-prefix=#{cli_options[:download_url_prefix]}"
|
143
|
+
elsif package_base_url.present?
|
144
|
+
args << "--download-url-prefix=#{package_base_url}"
|
145
|
+
end
|
146
|
+
end
|
33
147
|
|
34
148
|
# --release-notes-url-prefix <url> A URL that will be used as prefix for constructing
|
35
149
|
# URLs for release notes.
|
36
|
-
args
|
150
|
+
def release_notes_url_prefix(args)
|
151
|
+
if cli_options[:release_notes_url_prefix].present?
|
152
|
+
args << "--release-notes-url-prefix=#{cli_options[:release_notes_url_prefix]}"
|
153
|
+
elsif notes_base_url.present?
|
154
|
+
args << "--release-notes-url-prefix=#{notes_base_url}"
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# --full-release-notes-url <url>
|
159
|
+
# A URL that will be used for the full release notes.
|
160
|
+
def full_release_notes_url(args)
|
161
|
+
return unless cli_options[:full_release_notes_url].present?
|
162
|
+
|
163
|
+
args << "--full-release-notes-url=#{cli_options[:full_release_notes_url]}"
|
164
|
+
end
|
37
165
|
|
38
166
|
# --link <link> A URL to the application's website which Sparkle may
|
39
167
|
# use for directing users to if they cannot download a
|
40
168
|
# new update from within the application. This will be
|
41
169
|
# used for new generated update items. By default, no
|
42
170
|
# product link is used.
|
171
|
+
def link(args)
|
172
|
+
return unless cli_options[:link].present?
|
173
|
+
|
174
|
+
args << "--link=#{cli_options[:link]}"
|
175
|
+
end
|
43
176
|
|
44
177
|
# --versions <versions> An optional comma delimited list of application
|
45
178
|
# versions (specified by CFBundleVersion) to generate
|
@@ -47,27 +180,88 @@ module Motion
|
|
47
180
|
# are inferred from the available archives and are only
|
48
181
|
# generated if they are in the latest 5 updates in the
|
49
182
|
# appcast.
|
183
|
+
def versions(args)
|
184
|
+
return unless cli_options[:versions].present?
|
185
|
+
|
186
|
+
args << "--versions=#{cli_options[:versions]}"
|
187
|
+
end
|
50
188
|
|
51
189
|
# --maximum-deltas <maximum-deltas>
|
52
190
|
# The maximum number of delta items to create for the
|
53
191
|
# latest update for each minimum required operating
|
54
192
|
# system. (default: 5)
|
193
|
+
def maximum_deltas(args)
|
194
|
+
return unless cli_options[:maximum_deltas].present?
|
195
|
+
|
196
|
+
args << "--maximum-deltas=#{cli_options[:maximum_deltas]}"
|
197
|
+
end
|
198
|
+
|
199
|
+
# --delta-compression <delta-compression>
|
200
|
+
# The compression method to use for generating delta
|
201
|
+
# updates. Supported methods for version 3 delta files
|
202
|
+
# are 'lzma', 'bzip2', 'zlib', 'lzfse', 'lz4', 'none',
|
203
|
+
# and 'default'. Note that version 2 delta files only
|
204
|
+
# support 'bzip2', 'none', and 'default' so other
|
205
|
+
# methods will be ignored if version 2 files are being
|
206
|
+
# generated. The 'default' compression for version 3
|
207
|
+
# delta files is currently lzma. (default: default)
|
208
|
+
def delta_compression(args)
|
209
|
+
return unless cli_options[:delta_compression].present?
|
210
|
+
|
211
|
+
args << "--delta-compression=#{cli_options[:delta_compression]}"
|
212
|
+
end
|
213
|
+
|
214
|
+
# --delta-compression-level <delta-compression-level>
|
215
|
+
# The compression level to use for generating delta
|
216
|
+
# updates. This only applies if the compression method
|
217
|
+
# used is bzip2 which accepts values from 1 - 9. A
|
218
|
+
# special value of 0 will use the default compression
|
219
|
+
# level. (default: 0)
|
220
|
+
def delta_compression_level(args)
|
221
|
+
return unless cli_options[:delta_compression_level].present?
|
222
|
+
|
223
|
+
args << "--delta-compression-level=#{cli_options[:delta_compression_level]}"
|
224
|
+
end
|
55
225
|
|
56
226
|
# --channel <channel-name>
|
57
227
|
# The Sparkle channel name that will be used for
|
58
228
|
# generating new updates. By default, no channel is
|
59
229
|
# used. Old applications need to be using Sparkle 2 to
|
60
230
|
# use this feature.
|
231
|
+
def channel(args)
|
232
|
+
return unless cli_options[:channel].present?
|
233
|
+
|
234
|
+
args << "--channel=#{cli_options[:channel]}"
|
235
|
+
end
|
61
236
|
|
62
237
|
# --major-version <major-version>
|
63
238
|
# The last major or minimum autoupdate sparkle:version
|
64
239
|
# that will be used for generating new updates. By
|
65
240
|
# default, no last major version is used.
|
241
|
+
def major_version(args)
|
242
|
+
return unless cli_options[:major_version].present?
|
243
|
+
|
244
|
+
args << "--major-version=#{cli_options[:major_version]}"
|
245
|
+
end
|
246
|
+
|
247
|
+
# --ignore-skipped-upgrades-below-version <below-version>
|
248
|
+
# Ignore skipped major upgrades below this specified
|
249
|
+
# version. Only applicable for major upgrades.
|
250
|
+
def ignore_skipped_upgrades_below_version(args)
|
251
|
+
return unless cli_options[:ignore_skipped_upgrades_below_version].present?
|
252
|
+
|
253
|
+
args << "--ignore-skipped-upgrades-below-version=#{cli_options[:ignore_skipped_upgrades_below_version]}"
|
254
|
+
end
|
66
255
|
|
67
256
|
# --phased-rollout-interval <phased-rollout-interval>
|
68
257
|
# The phased rollout interval in seconds that will be
|
69
258
|
# used for generating new updates. By default, no
|
70
259
|
# phased rollout interval is used.
|
260
|
+
def phased_rollout_interval(args)
|
261
|
+
return unless cli_options[:phased_rollout_interval].present?
|
262
|
+
|
263
|
+
args << "--phased-rollout-interval=#{cli_options[:phased_rollout_interval]}"
|
264
|
+
end
|
71
265
|
|
72
266
|
# --critical-update-version <critical-update-version>
|
73
267
|
# The last critical update sparkle:version that will be
|
@@ -76,125 +270,40 @@ module Motion
|
|
76
270
|
# from any application version. By default, no last
|
77
271
|
# critical update version is used. Old applications
|
78
272
|
# need to be using Sparkle 2 to use this feature.
|
273
|
+
def critical_update_version(args)
|
274
|
+
return unless cli_options[:critical_update_version].present?
|
275
|
+
|
276
|
+
args << "--critical-update-version=#{cli_options[:critical_update_version]}"
|
277
|
+
end
|
79
278
|
|
80
279
|
# --informational-update-versions <informational-update-versions>
|
81
280
|
# A comma delimited list of application
|
82
281
|
# sparkle:version's that will see newly generated
|
83
282
|
# updates as being informational only. An empty string
|
84
283
|
# argument will treat this update as informational
|
85
|
-
# coming from any application version.
|
86
|
-
#
|
87
|
-
#
|
88
|
-
#
|
284
|
+
# coming from any application version. Prefix a version
|
285
|
+
# string with '<' to indicate (eg "<2.5") to indicate
|
286
|
+
# older versions than the one specified should treat
|
287
|
+
# the update as informational only. By default, updates
|
288
|
+
# are not informational only. --link must also be
|
289
|
+
# provided. Old applications need to be using Sparkle 2
|
290
|
+
# to use this feature, and 2.1 or later to use the '<'
|
291
|
+
# upper bound feature.
|
292
|
+
def informational_update_versions(args)
|
293
|
+
return unless cli_options[:informational_update_versions].present?
|
294
|
+
|
295
|
+
args << "--informational-update-versions=#{cli_options[:informational_update_versions]}"
|
296
|
+
end
|
89
297
|
|
90
298
|
# -o <output-path> Path to filename for the generated appcast (allowed
|
91
299
|
# when only one will be created).
|
300
|
+
def output_path(args)
|
301
|
+
return unless cli_options[:output_path].present?
|
92
302
|
|
93
|
-
|
94
|
-
# option for transitioning to EdDSA from older updates.
|
95
|
-
# Note: only for supporting a legacy app that used DSA keys. Check if the
|
96
|
-
# default DSA key exists in `sparkle/config/dsa_priv.pem` and if it does,
|
97
|
-
# add it to the command.
|
98
|
-
if File.exist?(legacy_private_key_path)
|
99
|
-
App.info 'Sparkle', "Also signing with legacy DSA key at #{legacy_private_key_path}"
|
100
|
-
args << "-f=#{legacy_private_key_path}"
|
101
|
-
end
|
102
|
-
|
103
|
-
args << "-o=#{appcast_filename}" if appcast_filename.present?
|
104
|
-
|
105
|
-
App.info 'Executing', [generate_appcast_app, *args, path.to_s].join(' ')
|
106
|
-
|
107
|
-
results, status = Open3.capture2e(generate_appcast_app, *args, path.to_s)
|
108
|
-
|
109
|
-
App.info('Sparkle', "Saved appcast to `#{appcast_filename}`") if status.success?
|
110
|
-
puts results.indent(11)
|
111
|
-
|
112
|
-
return unless status.success?
|
113
|
-
|
114
|
-
puts
|
115
|
-
puts "SUFeedURL : #{feed_url}".indent(11)
|
116
|
-
puts "SUPublicEDKey : #{public_EdDSA_key}".indent(11)
|
117
|
-
end
|
118
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
119
|
-
|
120
|
-
def generate_appcast_help
|
121
|
-
generate_appcast_app = "#{vendored_sparkle_path}/bin/generate_appcast"
|
122
|
-
results, _status = Open3.capture2e(generate_appcast_app, '--help')
|
123
|
-
puts results
|
124
|
-
end
|
125
|
-
|
126
|
-
def create_release_notes
|
127
|
-
App.fail "Release notes template not found as expected at ./#{release_notes_template_path}" unless File.exist?(release_notes_template_path)
|
128
|
-
|
129
|
-
create_release_folder
|
130
|
-
|
131
|
-
File.open(release_notes_path.to_s, 'w') do |f|
|
132
|
-
template = File.read(release_notes_template_path)
|
133
|
-
f << ERB.new(template).result(binding)
|
134
|
-
end
|
135
|
-
|
136
|
-
App.info 'Create', "./#{release_notes_path}"
|
137
|
-
end
|
138
|
-
|
139
|
-
def release_notes_template_path
|
140
|
-
sparkle_config_path.join('release_notes.template.erb')
|
141
|
-
end
|
142
|
-
|
143
|
-
def release_notes_content_path
|
144
|
-
sparkle_config_path.join('release_notes.content.html')
|
145
|
-
end
|
146
|
-
|
147
|
-
def release_notes_path
|
148
|
-
sparkle_release_path + (appcast.notes_filename || "#{app_name}.#{@config.short_version}.html")
|
149
|
-
end
|
150
|
-
|
151
|
-
def release_notes_content
|
152
|
-
if File.exist?(release_notes_content_path)
|
153
|
-
File.read(release_notes_content_path)
|
154
|
-
else
|
155
|
-
App.fail "Missing #{release_notes_content_path}"
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
def release_notes_html
|
160
|
-
release_notes_content
|
161
|
-
end
|
162
|
-
|
163
|
-
class Appcast
|
164
|
-
attr_accessor :base_url,
|
165
|
-
:feed_base_url,
|
166
|
-
:feed_filename,
|
167
|
-
:notes_filename,
|
168
|
-
:package_filename,
|
169
|
-
:archive_folder,
|
170
|
-
:use_exported_private_key
|
171
|
-
attr_writer :notes_base_url,
|
172
|
-
:package_base_url
|
173
|
-
|
174
|
-
def initialize
|
175
|
-
@feed_base_url = nil
|
176
|
-
@feed_filename = 'releases.xml'
|
177
|
-
@notes_base_url = nil
|
178
|
-
@notes_filename = nil
|
179
|
-
@package_base_url = nil
|
180
|
-
@package_filename = nil
|
181
|
-
@base_url = nil
|
182
|
-
@archive_folder = nil
|
183
|
-
@use_exported_private_key = false
|
184
|
-
end
|
185
|
-
|
186
|
-
def feed_url
|
187
|
-
"#{feed_base_url || base_url}#{feed_filename}"
|
188
|
-
end
|
189
|
-
|
190
|
-
def notes_base_url
|
191
|
-
@notes_base_url || base_url
|
192
|
-
end
|
193
|
-
|
194
|
-
def package_base_url
|
195
|
-
@package_base_url || base_url
|
303
|
+
args << "-o=#{cli_options[:output_path]}"
|
196
304
|
end
|
197
305
|
end
|
198
306
|
end
|
199
307
|
end
|
200
308
|
end
|
309
|
+
# rubocop:enable Metrics/ClassLength
|
@@ -10,6 +10,7 @@ module Motion
|
|
10
10
|
def sparkle(&block)
|
11
11
|
@sparkle ||= Motion::Project::Sparkle.new(self)
|
12
12
|
@sparkle.instance_eval(&block) if block
|
13
|
+
@sparkle.after_initialize
|
13
14
|
@sparkle
|
14
15
|
end
|
15
16
|
end
|
@@ -39,10 +40,18 @@ module Motion
|
|
39
40
|
bundle_path = App.config.app_bundle('MacOSX')
|
40
41
|
sparkle_path = File.join(bundle_path, 'Frameworks', 'Sparkle.framework')
|
41
42
|
|
43
|
+
# strip out any header files, as they are not needed for a built product, and Xcode
|
44
|
+
# typically does this. Their permissions are set such that it conflicts
|
45
|
+
# with building the deltas. See https://github.com/sparkle-project/Sparkle/issues/1972
|
46
|
+
`rm -fr "#{sparkle_path}/Versions/B/PrivateHeaders"`
|
47
|
+
`rm "#{sparkle_path}/PrivateHeaders"`
|
48
|
+
`rm -fr "#{sparkle_path}/Versions/B/Headers"`
|
49
|
+
`rm "#{sparkle_path}/Headers"`
|
50
|
+
|
42
51
|
`/usr/bin/codesign -f -s "#{config.codesign_certificate}" -o runtime "#{sparkle_path}/Versions/B/Autoupdate"`
|
43
52
|
`/usr/bin/codesign -f -s "#{config.codesign_certificate}" -o runtime "#{sparkle_path}/Versions/B/Updater.app"`
|
44
|
-
`/usr/bin/codesign -f -s "#{config.codesign_certificate}" -o runtime "#{sparkle_path}/Versions/B/XPCServices/
|
45
|
-
`/usr/bin/codesign -f -s "#{config.codesign_certificate}" -o runtime --entitlements "./vendor/Pods/Sparkle/Entitlements/
|
53
|
+
`/usr/bin/codesign -f -s "#{config.codesign_certificate}" -o runtime "#{sparkle_path}/Versions/B/XPCServices/Installer.xpc"`
|
54
|
+
`/usr/bin/codesign -f -s "#{config.codesign_certificate}" -o runtime --entitlements "./vendor/Pods/Sparkle/Entitlements/Downloader.entitlements" "#{sparkle_path}/Versions/B/XPCServices/Downloader.xpc"` # rubocop:disable Layout/LineLength
|
46
55
|
|
47
56
|
`/usr/bin/codesign -f -s "#{config.codesign_certificate}" -o runtime "#{sparkle_path}"`
|
48
57
|
end
|
@@ -1,17 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Sparkle specific rake tasks
|
4
|
+
# rubocop:disable Metrics/BlockLength
|
4
5
|
namespace :sparkle do
|
5
6
|
desc 'Sparkle Help'
|
6
7
|
task :help do
|
7
8
|
puts <<~HELP
|
9
|
+
|
10
|
+
|
8
11
|
During initial Sparkle setup, run these rake tasks:
|
9
12
|
|
10
13
|
1. `rake sparkle:setup_certificates`
|
11
14
|
2. `rake sparkle:setup`
|
12
15
|
|
13
16
|
Then after running `rake build:release`, you can run
|
14
|
-
|
17
|
+
|
18
|
+
3. `rake sparkle:package` create the zipped package and release notes
|
19
|
+
4. `rake sparkle:copy_to_release` copy package/notes into release folder
|
20
|
+
5. `rake sparkle:generate_appcast` generate the appcast
|
15
21
|
HELP
|
16
22
|
end
|
17
23
|
|
@@ -40,6 +46,13 @@ namespace :sparkle do
|
|
40
46
|
sparkle.sign_package
|
41
47
|
end
|
42
48
|
|
49
|
+
desc 'Copy the release notes and zip archive to the release folder'
|
50
|
+
task :copy_to_release do
|
51
|
+
App.config_without_setup.build_mode = :release
|
52
|
+
sparkle = App.config.sparkle
|
53
|
+
sparkle.copy_to_release
|
54
|
+
end
|
55
|
+
|
43
56
|
desc "Generate the appcast xml feed using Sparkle's `generate_appcast`"
|
44
57
|
task :generate_appcast do
|
45
58
|
App.config_without_setup.build_mode = :release
|
@@ -83,3 +96,4 @@ namespace :clean do
|
|
83
96
|
end
|
84
97
|
end
|
85
98
|
end
|
99
|
+
# rubocop:enable Metrics/BlockLength
|
data/lib/motion/project/setup.rb
CHANGED
@@ -27,7 +27,7 @@ module Motion
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def check_public_key
|
30
|
-
return true if
|
30
|
+
return true if public_ed_dsa_key.present?
|
31
31
|
|
32
32
|
App.fail 'Sparkle :public_key is nil or blank. Please check your Rakefile.'
|
33
33
|
end
|
@@ -45,7 +45,7 @@ module Motion
|
|
45
45
|
App.fail "Missing `#{private_key_path}`. Please run `rake sparkle:setup_certificates` or check the docs to know where to put them."
|
46
46
|
end
|
47
47
|
|
48
|
-
unless
|
48
|
+
unless public_ed_dsa_key.present?
|
49
49
|
return false if silence
|
50
50
|
|
51
51
|
App.fail "Missing `#{public_key_path}`. Did you configure `release :public_key` correctly in the Rakefile? Advanced: recreate your public key with `rake sparkle:recreate_public_key`"
|