fastlane-plugin-match_keystore 0.1.12 → 0.1.17

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: 91d65c828bc6bc3ddd54e953955b1c01545fbd62481cc9aec4322f55aa9e44f8
4
- data.tar.gz: d60ed3f2b4f0df42f3b09fd2c0bad9990732f1ea609fe88fca0f448dc1740fd8
3
+ metadata.gz: 215e841f331c07eb0cc8983092e98a7bab444866adb58c13d116baf2e50d735a
4
+ data.tar.gz: c1a225a8f120ee5727182341ab354b83cc2daf9b0b514a97b5b7fe0c3c0f5f7b
5
5
  SHA512:
6
- metadata.gz: 6796ac4aed31fa6d4dee60fb649a21c0c185b6f19734b01256181c4949627f1ec4fe331c27683262f128ab243ed820e8a728d04166dda21390fd212227b6941e
7
- data.tar.gz: 7ea032e3fdaac9da9281acff0f409ab2f5abf0b1e87e58f5765b853308ddfafcbe3f2efd8530a29245db38e8fa18b740736d7c2311fdb6e4a28142f93fec8416
6
+ metadata.gz: d1573d798e69ed20b7c262d2b19a636ed0bcb5b961ef98fb88c6afc043eb84d5fd2089b3928a249429a588539cc8e303d00876e4358835fd7d08991bd62a758c
7
+ data.tar.gz: e954784d29bcede31cc6ff12944f24f50d3b3035cb1f4b35122fac72f9db57758c374a2e1b0a9b4a5aeed6565cbafdc85208d7d3120949655ba08fb3bcf64570
@@ -15,11 +15,21 @@ module Fastlane
15
15
 
16
16
  class MatchKeystoreAction < Action
17
17
 
18
+ def self.openssl_path
19
+ path = "/usr/local/opt/openssl@1.1/bin"
20
+ path
21
+ end
22
+
18
23
  def self.to_md5(value)
19
24
  hash_value = Digest::MD5.hexdigest value
20
25
  hash_value
21
26
  end
22
27
 
28
+ def self.sha512(value)
29
+ hash_value = Digest::SHA512.hexdigest value
30
+ hash_value
31
+ end
32
+
23
33
  def self.load_json(json_path)
24
34
  file = File.read(json_path)
25
35
  data_hash = JSON.parse(file)
@@ -53,54 +63,208 @@ module Fastlane
53
63
  android_home
54
64
  end
55
65
 
56
- def self.get_build_tools
66
+ def self.get_build_tools_version(targeted_version)
67
+ path = self.get_build_tools(targeted_version)
68
+ version = path.split('/').last
69
+ version
70
+ end
71
+
72
+ def self.get_build_tools(targeted_version)
57
73
  android_home = self.get_android_home()
58
74
  build_tools_root = File.join(android_home, '/build-tools')
59
75
 
60
- sub_dirs = Dir.glob(File.join(build_tools_root, '*', ''))
61
- build_tools_last_version = ''
62
- for sub_dir in sub_dirs
63
- build_tools_last_version = sub_dir
76
+ build_tools_path = ""
77
+ if !targeted_version.to_s.strip.empty?
78
+ build_tools_path = File.join(build_tools_root, "/#{targeted_version}/")
64
79
  end
65
80
 
66
- build_tools_last_version
81
+ if !File.directory?(build_tools_path)
82
+ sub_dirs = Dir.glob(File.join(build_tools_root, '*', ''))
83
+ build_tools_last_version = ''
84
+ for sub_dir in sub_dirs
85
+ build_tools_last_version = sub_dir
86
+ end
87
+ build_tools_path = build_tools_last_version
88
+ end
89
+
90
+ build_tools_path
67
91
  end
68
92
 
69
- def self.check_openssl_version
70
- output = `openssl version`
71
- if !output.start_with?("OpenSSL")
72
- raise "Please install OpenSSL 1.1.1 at least https://www.openssl.org/"
93
+ def self.check_ssl_version(forceOpenSSL)
94
+ libressl_min = '2.9'
95
+ openssl_min = '1.1.1'
96
+
97
+ openssl = self.openssl(forceOpenSSL)
98
+ output = `#{openssl} version`
99
+ if !output.start_with?("LibreSSL") && !output.start_with?("OpenSSL")
100
+ raise "Please install OpenSSL '#{openssl_min}' at least OR LibreSSL #{libressl_min}' at least"
101
+ end
102
+ UI.message("SSL/TLS protocol library: '#{output.strip!}'")
103
+
104
+ # Check minimum verion:
105
+ vesion = output.to_str.scan(/[0-9\.]{1,}/).first
106
+ UI.message("SSL/TLS protocol version: '#{vesion}'")
107
+ if self.is_libre_ssl(forceOpenSSL)
108
+ if Gem::Version.new(vesion) < Gem::Version.new(libressl_min)
109
+ raise "Minimum version for LibreSSL is '#{libressl_min}', please update it. Use homebrew is your are Mac user, and update ~/.bah_profile or ~/.zprofile"
110
+ end
111
+ else
112
+ if Gem::Version.new(vesion) > Gem::Version.new(openssl_min)
113
+ raise "Minimum version for OpenSSL is '#{openssl_min}' please update it. Use homebrew is your are Mac user, and update ~/.bah_profile or ~/.zprofile"
114
+ end
115
+ end
116
+
117
+ output.strip
118
+ end
119
+
120
+ def self.openssl(forceOpenSSL)
121
+ if forceOpenSSL
122
+ path = openssl_path
123
+ output = "#{path}/openssl"
124
+ else
125
+ output = "openssl"
126
+ end
127
+ output
128
+ end
129
+
130
+ def self.is_libre_ssl(forceOpenSSL)
131
+ result = false
132
+ openssl = self.openssl(forceOpenSSL)
133
+ output = `#{openssl} version`
134
+ if output.start_with?("LibreSSL")
135
+ result = true
73
136
  end
74
- UI.message("OpenSSL version: " + output.strip)
137
+ result
75
138
  end
76
139
 
77
140
  def self.gen_key(key_path, password)
78
141
  `rm -f '#{key_path}'`
79
- `echo "#{password}" | openssl dgst -sha512 | awk '{print $2}' | cut -c1-128 > '#{key_path}'`
142
+ shaValue = self.sha512(password)
143
+ `echo "#{shaValue}" > '#{key_path}'`
80
144
  end
81
145
 
82
- def self.encrypt_file(clear_file, encrypt_file, key_path)
146
+ def self.encrypt_file(clear_file, encrypt_file, key_path, forceOpenSSL)
83
147
  `rm -f '#{encrypt_file}'`
84
- `openssl enc -aes-256-cbc -salt -pbkdf2 -in '#{clear_file}' -out '#{encrypt_file}' -pass file:'#{key_path}'`
148
+ libre_ssl = self.is_libre_ssl(forceOpenSSL)
149
+ openssl_bin = self.openssl(forceOpenSSL)
150
+ `#{openssl_bin} enc -aes-256-cbc -salt -pbkdf2 -in '#{clear_file}' -out '#{encrypt_file}' -pass file:'#{key_path}'`
85
151
  end
86
152
 
87
- def self.decrypt_file(encrypt_file, clear_file, key_path)
153
+ def self.decrypt_file(encrypt_file, clear_file, key_path, forceOpenSSL)
88
154
  `rm -f '#{clear_file}'`
89
- `openssl enc -d -aes-256-cbc -pbkdf2 -in '#{encrypt_file}' -out '#{clear_file}' -pass file:'#{key_path}'`
155
+ libre_ssl = self.is_libre_ssl(forceOpenSSL)
156
+ openssl_bin = self.openssl(forceOpenSSL)
157
+ `#{openssl_bin} enc -d -aes-256-cbc -pbkdf2 -in '#{encrypt_file}' -out '#{clear_file}' -pass file:'#{key_path}'`
158
+ end
159
+
160
+ def self.assert_equals(test_name, excepted, value)
161
+ puts "Unit Test: #{test_name}"
162
+ if value != excepted
163
+ puts " - Excepted: #{excepted}"
164
+ puts " - Returned: #{value}"
165
+ raise "Unit Test - #{test_name} error!"
166
+ else
167
+ puts " - OK"
168
+ end
169
+ end
170
+
171
+ def self.test_security
172
+
173
+ self.check_ssl_version(false)
174
+
175
+ # Clear temp files
176
+ temp_dir = File.join(Dir.pwd, '/temp/')
177
+ FileUtils.rm_rf(temp_dir)
178
+ Dir.mkdir(temp_dir)
179
+
180
+ fakeValue = "4esfsf4dsfds!efs5ZDOJF"
181
+ # Check MD5
182
+ md5value = self.to_md5(fakeValue)
183
+ excepted = "1c815cd208fe08076c9e7b6595d121d1"
184
+ self.assert_equals("MD5", excepted, md5value)
185
+
186
+ # Check SHA-512
187
+ shaValue = self.sha512(fakeValue)
188
+ excepted = "cc6a7b0d89cc61c053f7018a305672bdb82bc07e5015f64bb063d9662be4ec81ec8afa819b009de266482b6bd56b7068def2524c32f5b5d4d9db49ee4578499d"
189
+ self.assert_equals("SHA-512", excepted, shaValue)
190
+
191
+ # Check SHA-512-File
192
+ key_path = File.join(Dir.pwd, '/temp/key.txt')
193
+ self.gen_key(key_path, fakeValue)
194
+ shaValue = self.get_file_content(key_path).strip!
195
+ excepted = "cc6a7b0d89cc61c053f7018a305672bdb82bc07e5015f64bb063d9662be4ec81ec8afa819b009de266482b6bd56b7068def2524c32f5b5d4d9db49ee4578499d"
196
+ self.assert_equals("SHA-512-File", excepted, shaValue)
197
+
198
+
199
+ # Check LibreSSL
200
+ result = self.is_libre_ssl(false)
201
+ self.assert_equals("Is-LibreSSL", true, result)
202
+ result = self.is_libre_ssl(true)
203
+ self.assert_equals("Is-LibreSSL", false, result)
204
+
205
+ # Encrypt OpenSSL
206
+ clear_file = File.join(Dir.pwd, '/temp/clear.txt')
207
+ openssl_encrypt_file = File.join(Dir.pwd, '/temp/openssl_encrypted.txt')
208
+ self.content_to_file(clear_file, fakeValue)
209
+ self.encrypt_file(clear_file, openssl_encrypt_file, key_path, true)
210
+ result = File.file?(openssl_encrypt_file) && File.size(openssl_encrypt_file) > 10
211
+ self.assert_equals("Encrypt-OpenSSL", true, result)
212
+
213
+ # Encrypt LibreSSL
214
+ encrypt_file_libre = File.join(Dir.pwd, '/temp/libressl_encrypted.txt')
215
+ self.content_to_file(clear_file, fakeValue)
216
+ self.encrypt_file(clear_file, encrypt_file_libre, key_path, false)
217
+ result = File.file?(encrypt_file_libre) && File.size(encrypt_file_libre) > 10
218
+ self.assert_equals("Encrypt-LibreSSL", true, result)
219
+
220
+ # exit!
221
+
222
+ # Decrypt OpenSSL (from OpenSSL)
223
+ openssl_clear_file = File.join(Dir.pwd, '/temp/openssl_clear.txt')
224
+ self.decrypt_file(openssl_encrypt_file, openssl_clear_file, key_path, true)
225
+ decrypted = self.get_file_content(openssl_clear_file).strip!
226
+ self.assert_equals("Decrypt-OpenSSL", fakeValue, decrypted)
227
+
228
+ # Decrypt LibreSSL (from LibreSSL)
229
+ libressl_clear_file = File.join(Dir.pwd, '/temp/libressl_clear.txt')
230
+ self.decrypt_file(encrypt_file_libre, libressl_clear_file, key_path, false)
231
+ decrypted = self.get_file_content(libressl_clear_file).strip!
232
+ self.assert_equals("Decrypt-LibreSSL", fakeValue, decrypted)
233
+
234
+ # Decrypt LibreSSL (from OpenSSL)
235
+ libressl_clear_file = File.join(Dir.pwd, '/temp/libressl_from_openssl_clear.txt')
236
+ self.decrypt_file(openssl_encrypt_file, libressl_clear_file, key_path, false)
237
+ decrypted = self.get_file_content(libressl_clear_file).strip!
238
+ self.assert_equals("Decrypt-LibreSSL-from-OpenSSL", fakeValue, decrypted)
239
+
240
+ # Decrypt OpenSSL (from LibreSSL)
241
+ openssl_clear_file = File.join(Dir.pwd, '/temp/openssl_from_libressl_clear.txt')
242
+ self.decrypt_file(encrypt_file_libre, openssl_clear_file, key_path, true)
243
+ decrypted = self.get_file_content(openssl_clear_file).strip!
244
+ self.assert_equals("Decrypt-OpenSSL-from-LibreSSL", fakeValue, decrypted)
245
+
90
246
  end
91
247
 
92
- def self.sign_apk(apk_path, keystore_path, key_password, alias_name, alias_password, zip_align)
248
+ def self.sign_apk(apk_path, keystore_path, key_password, alias_name, alias_password, zip_align, version_targeted)
93
249
 
94
- build_tools_path = self.get_build_tools()
250
+ build_tools_path = self.get_build_tools(version_targeted)
251
+ UI.message("Build-tools path: #{build_tools_path}")
95
252
 
96
253
  # https://developer.android.com/studio/command-line/zipalign
97
- if zip_align == true
254
+ if zip_align != false
98
255
  apk_path_aligned = apk_path.gsub(".apk", "-aligned.apk")
99
256
  `rm -f '#{apk_path_aligned}'`
100
- UI.message("Aligning APK (zipalign): #{apk_path_aligned}")
101
- `#{build_tools_path}zipalign 4 '#{apk_path}' '#{apk_path_aligned}'`
257
+ UI.message("Aligning APK (zipalign): #{apk_path}")
258
+ output = `#{build_tools_path}zipalign -v 4 '#{apk_path}' '#{apk_path_aligned}'`
259
+ puts ""
260
+ puts output
261
+
262
+ if !File.file?(apk_path_aligned)
263
+ raise "Aligned APK not exists!"
264
+ end
265
+
102
266
  else
103
- UI.message("No zip align!")
267
+ UI.message("No zip align - deactivated via parameter!")
104
268
  apk_path_aligned = apk_path
105
269
  end
106
270
  apk_path_signed = apk_path.gsub(".apk", "-signed.apk")
@@ -109,12 +273,44 @@ module Fastlane
109
273
 
110
274
  # https://developer.android.com/studio/command-line/apksigner
111
275
  `rm -f '#{apk_path_signed}'`
112
- `#{build_tools_path}apksigner sign --ks '#{keystore_path}' --ks-key-alias '#{alias_name}' --ks-pass pass:'#{key_password}' --key-pass pass:'#{alias_password}' --v1-signing-enabled true --v2-signing-enabled true --out '#{apk_path_signed}' '#{apk_path_aligned}'`
113
-
114
- `#{build_tools_path}apksigner verify '#{apk_path_signed}'`
115
- `rm -f '#{apk_path_aligned}'`
276
+ UI.message("Signing APK: #{apk_path_aligned}")
277
+ apksigner_opts = ""
278
+ build_tools_version = self.get_build_tools_version(version_targeted)
279
+ UI.message("Build-tools version: #{build_tools_version}")
280
+ if Gem::Version.new(build_tools_version) >= Gem::Version.new('30')
281
+ apksigner_opts = "--v4-signing-enabled false "
282
+ end
283
+ output = `#{build_tools_path}apksigner sign --ks '#{keystore_path}' --ks-key-alias '#{alias_name}' --ks-pass pass:'#{key_password}' --key-pass pass:'#{alias_password}' --v1-signing-enabled true --v2-signing-enabled true #{apksigner_opts}--out '#{apk_path_signed}' '#{apk_path_aligned}'`
284
+ puts ""
285
+ puts output
286
+
287
+ UI.message("Verifing APK signature: #{apk_path_signed}")
288
+ output = `#{build_tools_path}apksigner verify '#{apk_path_signed}'`
289
+ puts ""
290
+ puts output
291
+ if zip_align != false
292
+ `rm -f '#{apk_path_aligned}'`
293
+ end
116
294
 
117
295
  apk_path_signed
296
+ end
297
+
298
+ def self.resolve_dir(path)
299
+ if !File.directory?(path)
300
+ path = File.join(Dir.pwd, path)
301
+ end
302
+ path
303
+ end
304
+
305
+ def self.resolve_file(path)
306
+ if !File.file?(path)
307
+ path = File.join(Dir.pwd, path)
308
+ end
309
+ path
310
+ end
311
+
312
+ def self.content_to_file(file_path, content)
313
+ `echo #{content} > #{file_path}`
118
314
  end
119
315
 
120
316
  def self.get_file_content(file_path)
@@ -131,9 +327,7 @@ module Fastlane
131
327
 
132
328
  if !apk_path.to_s.end_with?(".apk")
133
329
 
134
- if !File.directory?(apk_path)
135
- apk_path = File.join(Dir.pwd, apk_path)
136
- end
330
+ apk_path = self.resolve_dir(apk_path)
137
331
 
138
332
  pattern = File.join(apk_path, '*.apk')
139
333
  files = Dir[pattern]
@@ -146,11 +340,7 @@ module Fastlane
146
340
  end
147
341
 
148
342
  else
149
-
150
- if !File.file?(apk_path)
151
- apk_path = File.join(Dir.pwd, apk_path)
152
- end
153
-
343
+ apk_path = self.resolve_file(apk_path)
154
344
  end
155
345
 
156
346
  apk_path
@@ -176,6 +366,16 @@ module Fastlane
176
366
  match_secret = params[:match_secret]
177
367
  override_keystore = params[:override_keystore]
178
368
  keystore_data = params[:keystore_data]
369
+ clear_keystore = params[:clear_keystore]
370
+ unit_test = params[:unit_test]
371
+ build_tools_version = params[:build_tools_version]
372
+ zip_align = params[:zip_align]
373
+
374
+ # Test OpenSSL/LibreSSL
375
+ if unit_test
376
+ result_test = self.test_security
377
+ exit!
378
+ end
179
379
 
180
380
  # Init constants:
181
381
  keystore_name = 'keystore.jks'
@@ -191,7 +391,7 @@ module Fastlane
191
391
  end
192
392
 
193
393
  # Check OpenSSL:
194
- self.check_openssl_version
394
+ self.check_ssl_version(false)
195
395
 
196
396
  # Init workign local directory:
197
397
  dir_name = ENV['HOME'] + '/.match_keystore'
@@ -221,14 +421,30 @@ module Fastlane
221
421
  raise "The security key '#{key_name}' is malformed, or not initialized!"
222
422
  end
223
423
 
224
- # Create repo directory to sync remote Keystores repository:
424
+ # Clear repo Keystore (local) - mostly for testing:
225
425
  repo_dir = File.join(dir_name, self.to_md5(git_url))
226
- # UI.message(repo_dir)
426
+ if clear_keystore && File.directory?(repo_dir)
427
+ FileUtils.rm_rf(repo_dir)
428
+ UI.message("Local repo keystore (#{repo_dir}) directory deleted!")
429
+ end
430
+
431
+ # Create repo directory to sync remote Keystores repository:
227
432
  unless File.directory?(repo_dir)
228
433
  UI.message("Creating 'repo' directory...")
229
434
  FileUtils.mkdir_p(repo_dir)
230
435
  end
231
436
 
437
+ # Check if package name defined:
438
+ if package_name.to_s.strip.empty?
439
+ raise "Package name is not defined!"
440
+ end
441
+
442
+ # Define paths:
443
+ keystoreAppDir = File.join(repo_dir, package_name)
444
+ keystore_path = File.join(keystoreAppDir, keystore_name)
445
+ properties_path = File.join(keystoreAppDir, properties_name)
446
+ properties_encrypt_path = File.join(keystoreAppDir, properties_encrypt_name)
447
+
232
448
  # Cloning/pulling GIT remote repository:
233
449
  gitDir = File.join(repo_dir, '/.git')
234
450
  if !File.directory?(gitDir)
@@ -243,20 +459,6 @@ module Fastlane
243
459
  puts ''
244
460
  end
245
461
 
246
- # Create sub-directory for Android app:
247
- if package_name.to_s.strip.empty?
248
- raise "Package name is not defined!"
249
- end
250
- keystoreAppDir = File.join(repo_dir, package_name)
251
- unless File.directory?(keystoreAppDir)
252
- UI.message("Creating '#{package_name}' keystore directory...")
253
- FileUtils.mkdir_p(keystoreAppDir)
254
- end
255
-
256
- keystore_path = File.join(keystoreAppDir, keystore_name)
257
- properties_path = File.join(keystoreAppDir, properties_name)
258
- properties_encrypt_path = File.join(keystoreAppDir, properties_encrypt_name)
259
-
260
462
  # Load parameters from JSON for CI or Unit Tests:
261
463
  if keystore_data != nil && File.file?(keystore_data)
262
464
  data_json = self.load_json(keystore_data)
@@ -273,6 +475,7 @@ module Fastlane
273
475
 
274
476
  # Create keystore with command
275
477
  override_keystore = !existing_keystore.to_s.strip.empty? && File.file?(existing_keystore)
478
+ UI.message("Existing Keystore: #{existing_keystore}")
276
479
  if !File.file?(keystore_path) || override_keystore
277
480
 
278
481
  if File.file?(keystore_path)
@@ -293,7 +496,7 @@ module Fastlane
293
496
  end
294
497
 
295
498
  # https://developer.android.com/studio/publish/app-signing
296
- if !File.file?(existing_keystore)
499
+ if existing_keystore.to_s.strip.empty? || !File.file?(existing_keystore)
297
500
  UI.message("Generating Android Keystore...")
298
501
 
299
502
  full_name = self.prompt2(text: "Certificate First and Last Name: ", value: data_full_name)
@@ -334,7 +537,7 @@ module Fastlane
334
537
  out_file.puts("aliasPassword=#{alias_password}")
335
538
  out_file.close
336
539
 
337
- self.encrypt_file(properties_path, properties_encrypt_path, key_path)
540
+ self.encrypt_file(properties_path, properties_encrypt_path, key_path, false)
338
541
  File.delete(properties_path)
339
542
 
340
543
  # Print Keystore data in repo:
@@ -351,7 +554,7 @@ module Fastlane
351
554
  else
352
555
  UI.message "Keystore file already exists, continue..."
353
556
 
354
- self.decrypt_file(properties_encrypt_path, properties_path, key_path)
557
+ self.decrypt_file(properties_encrypt_path, properties_path, key_path, false)
355
558
 
356
559
  properties = self.load_properties(properties_path)
357
560
  key_password = properties['keyPassword']
@@ -379,12 +582,13 @@ module Fastlane
379
582
  key_password,
380
583
  alias_name,
381
584
  alias_password,
382
- true # Zip align
585
+ zip_align, # Zip align
586
+ build_tools_version # Buil-tools version
383
587
  )
384
588
  puts ''
385
589
  end
386
590
  else
387
- UI.message("No APK file found to sign!")
591
+ UI.message("No APK file found at: #{apk_path}")
388
592
  end
389
593
 
390
594
  # Prepare contect shared values for next lanes:
@@ -456,7 +660,27 @@ module Fastlane
456
660
  env_name: "MATCH_KEYSTORE_JSON_PATH",
457
661
  description: "Required data to import an existing keystore, or create a new one",
458
662
  optional: true,
459
- type: String)
663
+ type: String),
664
+ FastlaneCore::ConfigItem.new(key: :build_tools_version,
665
+ env_name: "MATCH_KEYSTORE_BUILD_TOOLS_VERSION",
666
+ description: "Set built-tools version (by default latest available on machine)",
667
+ optional: true,
668
+ type: String),
669
+ FastlaneCore::ConfigItem.new(key: :zip_align,
670
+ env_name: "MATCH_KEYSTORE_ZIPALIGN",
671
+ description: "Define if plugin will run zipalign on APK before sign it (true by default)",
672
+ optional: true,
673
+ type: Boolean),
674
+ FastlaneCore::ConfigItem.new(key: :clear_keystore,
675
+ env_name: "MATCH_KEYSTORE_CLEAR",
676
+ description: "Clear the local keystore (false by default)",
677
+ optional: true,
678
+ type: Boolean),
679
+ FastlaneCore::ConfigItem.new(key: :unit_test,
680
+ env_name: "MATCH_KEYSTORE_UNIT_TESTS",
681
+ description: "launch Unit Tests (false by default)",
682
+ optional: true,
683
+ type: Boolean)
460
684
  ]
461
685
  end
462
686
 
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module MatchKeystore
3
- VERSION = "0.1.12"
3
+ VERSION = "0.1.17"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane-plugin-match_keystore
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.12
4
+ version: 0.1.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christopher NEY
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-07 00:00:00.000000000 Z
11
+ date: 2020-09-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry