mysigner 0.1.2 → 0.1.4

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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.githooks/pre-commit +15 -0
  3. data/.githooks/pre-push +21 -0
  4. data/.github/workflows/ci.yml +29 -0
  5. data/.gitignore +4 -0
  6. data/.rubocop.yml +55 -0
  7. data/.rubocop_todo.yml +126 -0
  8. data/CHANGELOG.md +96 -0
  9. data/Gemfile +5 -3
  10. data/Gemfile.lock +38 -8
  11. data/README.md +14 -16
  12. data/Rakefile +5 -3
  13. data/bin/console +4 -3
  14. data/bin/setup +3 -0
  15. data/certificate_.cer +0 -0
  16. data/exe/mysigner +19 -2
  17. data/iOS_App_Store_Profile.mobileprovision +1 -0
  18. data/iOS_Distribution_Certificate.cer +1 -0
  19. data/lib/mysigner/build/android_executor.rb +83 -63
  20. data/lib/mysigner/build/android_parser.rb +33 -40
  21. data/lib/mysigner/build/configurator.rb +17 -16
  22. data/lib/mysigner/build/detector.rb +39 -50
  23. data/lib/mysigner/build/error_analyzer.rb +70 -68
  24. data/lib/mysigner/build/executor.rb +30 -37
  25. data/lib/mysigner/build/parser.rb +18 -18
  26. data/lib/mysigner/cleanup/private_keys_purger.rb +41 -0
  27. data/lib/mysigner/cli/auth_commands.rb +771 -764
  28. data/lib/mysigner/cli/build_commands.rb +962 -796
  29. data/lib/mysigner/cli/concerns/actionable_suggestions.rb +208 -154
  30. data/lib/mysigner/cli/concerns/api_helpers.rb +46 -54
  31. data/lib/mysigner/cli/concerns/error_handlers.rb +247 -237
  32. data/lib/mysigner/cli/concerns/helpers.rb +44 -1
  33. data/lib/mysigner/cli/diagnostic_commands.rb +667 -636
  34. data/lib/mysigner/cli/resource_commands.rb +1153 -985
  35. data/lib/mysigner/cli/validate_commands.rb +25 -25
  36. data/lib/mysigner/cli.rb +11 -1
  37. data/lib/mysigner/client.rb +27 -19
  38. data/lib/mysigner/config.rb +161 -60
  39. data/lib/mysigner/export/exporter.rb +38 -37
  40. data/lib/mysigner/signing/certificate_checker.rb +18 -23
  41. data/lib/mysigner/signing/gradle_signing_injector.rb +67 -0
  42. data/lib/mysigner/signing/keystore_manager.rb +81 -61
  43. data/lib/mysigner/signing/validator.rb +38 -40
  44. data/lib/mysigner/signing/wizard.rb +329 -342
  45. data/lib/mysigner/upload/app_store_automation.rb +96 -49
  46. data/lib/mysigner/upload/app_store_submission.rb +87 -92
  47. data/lib/mysigner/upload/asc_rest_uploader.rb +119 -0
  48. data/lib/mysigner/upload/play_store_uploader.rb +164 -144
  49. data/lib/mysigner/upload/uploader.rb +136 -115
  50. data/lib/mysigner/version.rb +3 -1
  51. data/lib/mysigner.rb +13 -11
  52. data/mysigner.gemspec +36 -33
  53. data/profile_.mobileprovision +0 -0
  54. data/test_manual.rb +37 -36
  55. metadata +44 -17
  56. data/.DS_Store +0 -0
@@ -1,3 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'English'
1
4
  require 'fileutils'
2
5
  require 'tempfile'
3
6
 
@@ -20,7 +23,8 @@ module Mysigner
20
23
  # - key_alias: Key alias in keystore
21
24
  # - key_password: Key password (defaults to keystore_password)
22
25
  # - version_code: Override version code (passed via gradle property)
23
- def build_aab!(variant: 'release', keystore_path: nil, keystore_password: nil, key_alias: nil, key_password: nil, version_code: nil)
26
+ def build_aab!(variant: 'release', keystore_path: nil, keystore_password: nil, key_alias: nil, key_password: nil,
27
+ version_code: nil)
24
28
  @variant = variant
25
29
  @keystore_path = keystore_path
26
30
  @keystore_password = keystore_password
@@ -34,13 +38,11 @@ module Mysigner
34
38
  # Build
35
39
  success = run_gradle_build(task)
36
40
 
37
- unless success
38
- raise BuildError, "Android build failed. Check output above for errors."
39
- end
41
+ raise BuildError, 'Android build failed. Check output above for errors.' unless success
40
42
 
41
43
  # Find output AAB
42
44
  aab_path = find_aab_output(variant)
43
-
45
+
44
46
  unless aab_path && File.exist?(aab_path)
45
47
  raise BuildError, "Build reported success but AAB not found. Expected at: #{@parser.aab_output_path(variant)}"
46
48
  end
@@ -63,13 +65,11 @@ module Mysigner
63
65
  # Build
64
66
  success = run_gradle_build(task)
65
67
 
66
- unless success
67
- raise BuildError, "Android build failed. Check output above for errors."
68
- end
68
+ raise BuildError, 'Android build failed. Check output above for errors.' unless success
69
69
 
70
70
  # Find output APK
71
71
  apk_path = find_apk_output(variant)
72
-
72
+
73
73
  unless apk_path && File.exist?(apk_path)
74
74
  raise BuildError, "Build reported success but APK not found. Expected at: #{@parser.apk_output_path(variant)}"
75
75
  end
@@ -91,15 +91,27 @@ module Mysigner
91
91
  # Handle framework-specific pre-build steps
92
92
  run_pre_build_steps
93
93
 
94
- # Build command with signing properties
95
- cmd = build_gradle_command(task)
94
+ # Phase 0: inject signing via Gradle init-script + env vars. Passwords
95
+ # never appear in argv (no -Pandroid.injected.signing.*=PLAINTEXT).
96
+ injector = nil
97
+ if @keystore_path && File.exist?(@keystore_path)
98
+ require 'mysigner/signing/gradle_signing_injector'
99
+ injector = Mysigner::Signing::GradleSigningInjector.new
100
+ @signing_init_script_path = injector.write_init_script!
101
+ end
96
102
 
97
- # Execute build
98
- execute_with_output(cmd)
103
+ begin
104
+ # Build command with signing properties referencing the init script
105
+ cmd = build_gradle_command(task)
106
+ execute_with_output(cmd)
107
+ ensure
108
+ injector&.cleanup!
109
+ @signing_init_script_path = nil
110
+ end
99
111
  end
100
112
 
101
113
  def ensure_java_home!
102
- java_home = ENV['JAVA_HOME']
114
+ java_home = ENV.fetch('JAVA_HOME', nil)
103
115
 
104
116
  # Check if JAVA_HOME is set and valid
105
117
  if java_home && !java_home.empty? && Dir.exist?(java_home)
@@ -112,8 +124,8 @@ module Mysigner
112
124
  ENV['JAVA_HOME'] = detected
113
125
  elsif java_home && !java_home.empty?
114
126
  raise BuildError, "JAVA_HOME is set to invalid directory: #{java_home}\n" \
115
- "Run 'mysigner doctor' to fix, or set JAVA_HOME manually:\n" \
116
- " export JAVA_HOME=$(/usr/libexec/java_home -v 17)"
127
+ "Run 'mysigner doctor' to fix, or set JAVA_HOME manually:\n " \
128
+ 'export JAVA_HOME=$(/usr/libexec/java_home -v 17)'
117
129
  end
118
130
  end
119
131
 
@@ -122,12 +134,10 @@ module Mysigner
122
134
  end
123
135
 
124
136
  def ensure_android_home!
125
- android_home = ENV['ANDROID_HOME'] || ENV['ANDROID_SDK_ROOT']
137
+ android_home = ENV['ANDROID_HOME'] || ENV.fetch('ANDROID_SDK_ROOT', nil)
126
138
 
127
139
  # Check if already valid
128
- if android_home && !android_home.empty? && Dir.exist?(android_home)
129
- return
130
- end
140
+ return if android_home && !android_home.empty? && Dir.exist?(android_home)
131
141
 
132
142
  # Try to detect Android SDK
133
143
  detected = detect_android_home
@@ -137,8 +147,8 @@ module Mysigner
137
147
  ENV['ANDROID_SDK_ROOT'] = detected
138
148
  else
139
149
  raise BuildError, "Android SDK not found.\n" \
140
- "Run 'mysigner doctor' to diagnose, or set ANDROID_HOME:\n" \
141
- " export ANDROID_HOME=~/Library/Android/sdk"
150
+ "Run 'mysigner doctor' to diagnose, or set ANDROID_HOME:\n " \
151
+ 'export ANDROID_HOME=~/Library/Android/sdk'
142
152
  end
143
153
  end
144
154
 
@@ -190,7 +200,7 @@ module Mysigner
190
200
  case @project_info[:framework]
191
201
  when :capacitor
192
202
  # Capacitor: sync before build
193
- puts "🔄 Syncing Capacitor..."
203
+ puts '🔄 Syncing Capacitor...'
194
204
  Dir.chdir(@project_info[:directory]) do
195
205
  system('npx cap sync android > /dev/null 2>&1')
196
206
  end
@@ -199,14 +209,14 @@ module Mysigner
199
209
  if File.exist?(File.join(@project_info[:directory], 'node_modules'))
200
210
  # Dependencies already installed
201
211
  else
202
- puts "📦 Installing npm dependencies..."
212
+ puts '📦 Installing npm dependencies...'
203
213
  Dir.chdir(@project_info[:directory]) do
204
214
  system('npm install > /dev/null 2>&1') || system('yarn install > /dev/null 2>&1')
205
215
  end
206
216
  end
207
217
  when :flutter
208
218
  # Flutter: ensure dependencies are fetched
209
- puts "📦 Getting Flutter dependencies..."
219
+ puts '📦 Getting Flutter dependencies...'
210
220
  Dir.chdir(@project_info[:directory]) do
211
221
  system('flutter pub get > /dev/null 2>&1')
212
222
  end
@@ -218,45 +228,57 @@ module Mysigner
218
228
  gradle_cmd = @parser.gradle_command
219
229
 
220
230
  cmd_parts = []
221
-
231
+
222
232
  # Export JAVA_HOME if we detected/fixed it
223
- java_home = ENV['JAVA_HOME']
233
+ java_home = ENV.fetch('JAVA_HOME', nil)
224
234
  if java_home && Dir.exist?(java_home)
225
235
  cmd_parts << "export JAVA_HOME=#{shell_escape(java_home)}"
226
- cmd_parts << "&&"
236
+ cmd_parts << '&&'
227
237
  end
228
238
 
229
239
  # Export ANDROID_HOME if we detected/fixed it
230
- android_home = ENV['ANDROID_HOME']
240
+ android_home = ENV.fetch('ANDROID_HOME', nil)
231
241
  if android_home && Dir.exist?(android_home)
232
242
  cmd_parts << "export ANDROID_HOME=#{shell_escape(android_home)}"
233
- cmd_parts << "&&"
243
+ cmd_parts << '&&'
234
244
  cmd_parts << "export ANDROID_SDK_ROOT=#{shell_escape(android_home)}"
235
- cmd_parts << "&&"
245
+ cmd_parts << '&&'
236
246
  end
237
-
247
+
248
+ # Phase 0: export signing env vars inline so they're only visible to
249
+ # the child process, not in argv. The Gradle init script below reads
250
+ # MYSIGNER_STORE_FILE / MYSIGNER_STORE_PASSWORD / MYSIGNER_KEY_ALIAS /
251
+ # MYSIGNER_KEY_PASSWORD and configures signingConfigs.release.
252
+ if @keystore_path && File.exist?(@keystore_path) && @signing_init_script_path
253
+ cmd_parts << "export MYSIGNER_STORE_FILE=#{shell_escape(File.absolute_path(@keystore_path))}"
254
+ cmd_parts << '&&'
255
+ cmd_parts << "export MYSIGNER_STORE_PASSWORD=#{shell_escape(@keystore_password)}" if @keystore_password
256
+ cmd_parts << '&&' if @keystore_password
257
+ cmd_parts << "export MYSIGNER_KEY_ALIAS=#{shell_escape(@key_alias)}" if @key_alias
258
+ cmd_parts << '&&' if @key_alias
259
+ cmd_parts << "export MYSIGNER_KEY_PASSWORD=#{shell_escape(@key_password)}" if @key_password
260
+ cmd_parts << '&&' if @key_password
261
+ end
262
+
238
263
  # Change to android directory and run gradle
239
264
  cmd_parts << "cd #{shell_escape(android_dir)}"
240
- cmd_parts << "&&"
265
+ cmd_parts << '&&'
241
266
  cmd_parts << gradle_cmd
242
- cmd_parts << task
243
267
 
244
- # Add signing properties if provided
245
- if @keystore_path && File.exist?(@keystore_path)
246
- cmd_parts << "-Pandroid.injected.signing.store.file=#{shell_escape(File.absolute_path(@keystore_path))}"
247
- cmd_parts << "-Pandroid.injected.signing.store.password=#{shell_escape(@keystore_password)}" if @keystore_password
248
- cmd_parts << "-Pandroid.injected.signing.key.alias=#{shell_escape(@key_alias)}" if @key_alias
249
- cmd_parts << "-Pandroid.injected.signing.key.password=#{shell_escape(@key_password)}" if @key_password
268
+ # Reference the init script (contains the signing-config override)
269
+ if @signing_init_script_path
270
+ cmd_parts << '--init-script'
271
+ cmd_parts << shell_escape(@signing_init_script_path)
250
272
  end
251
-
273
+
274
+ cmd_parts << task
275
+
252
276
  # Add version code override if provided (no file modification needed)
253
- if @version_code
254
- cmd_parts << "-PversionCode=#{@version_code}"
255
- end
277
+ cmd_parts << "-PversionCode=#{@version_code}" if @version_code
256
278
 
257
279
  # Standard build options
258
- cmd_parts << "--no-daemon" # Avoid daemon issues in CI
259
- cmd_parts << "-q" # Quiet mode (less noise)
280
+ cmd_parts << '--no-daemon' # Avoid daemon issues in CI
281
+ cmd_parts << '-q' # Quiet mode (less noise)
260
282
 
261
283
  cmd_parts.join(' ')
262
284
  end
@@ -266,29 +288,29 @@ module Mysigner
266
288
  gradle_cmd = @parser.gradle_command
267
289
 
268
290
  exports = []
269
- java_home = ENV['JAVA_HOME']
291
+ java_home = ENV.fetch('JAVA_HOME', nil)
270
292
  exports << "export JAVA_HOME=#{shell_escape(java_home)}" if java_home && Dir.exist?(java_home)
271
-
272
- android_home = ENV['ANDROID_HOME']
293
+
294
+ android_home = ENV.fetch('ANDROID_HOME', nil)
273
295
  if android_home && Dir.exist?(android_home)
274
296
  exports << "export ANDROID_HOME=#{shell_escape(android_home)}"
275
297
  exports << "export ANDROID_SDK_ROOT=#{shell_escape(android_home)}"
276
298
  end
277
-
278
- export_str = exports.any? ? exports.join(' && ') + ' && ' : ''
299
+
300
+ export_str = exports.any? ? "#{exports.join(' && ')} && " : ''
279
301
  cmd = "#{export_str}cd #{shell_escape(android_dir)} && #{gradle_cmd} #{task} --no-daemon -q"
280
302
  system(cmd)
281
303
  end
282
304
 
283
305
  def execute_with_output(cmd)
284
306
  puts "🏗️ Running: gradle #{@variant}..."
285
- puts ""
307
+ puts ''
286
308
 
287
309
  # Run command and capture output in real-time
288
310
  IO.popen("#{cmd} 2>&1", 'r') do |io|
289
311
  io.each_line do |line|
290
312
  next if line.strip.empty?
291
-
313
+
292
314
  # Show errors and warnings
293
315
  if line.include?('FAILURE') || line.include?('ERROR') || line.include?('error:')
294
316
  puts line
@@ -304,14 +326,14 @@ module Mysigner
304
326
  end
305
327
  end
306
328
 
307
- puts "" # New line after dots
329
+ puts '' # New line after dots
308
330
 
309
- $?.success?
331
+ $CHILD_STATUS.success?
310
332
  end
311
333
 
312
334
  def find_aab_output(variant)
313
335
  android_dir = @parser.android_directory
314
-
336
+
315
337
  # Search patterns for AAB files
316
338
  patterns = [
317
339
  File.join(android_dir, "app/build/outputs/bundle/#{variant}/*.aab"),
@@ -332,7 +354,7 @@ module Mysigner
332
354
 
333
355
  def find_apk_output(variant)
334
356
  android_dir = @parser.android_directory
335
-
357
+
336
358
  # Search patterns for APK files
337
359
  patterns = [
338
360
  File.join(android_dir, "app/build/outputs/apk/#{variant}/*.apk"),
@@ -353,14 +375,12 @@ module Mysigner
353
375
 
354
376
  def shell_escape(str)
355
377
  return "''" if str.nil? || str.empty?
356
-
378
+
357
379
  # If string contains no special characters, return as-is
358
- if str =~ /\A[a-zA-Z0-9_.\-\/]+\z/
359
- return str
360
- end
361
-
380
+ return str if str =~ %r{\A[a-zA-Z0-9_.\-/]+\z}
381
+
362
382
  # Otherwise, quote it
363
- "'" + str.gsub("'", "'\\''") + "'"
383
+ "'#{str.gsub("'", "'\\''")}'"
364
384
  end
365
385
  end
366
386
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mysigner
2
4
  module Build
3
5
  class AndroidParser
@@ -57,42 +59,41 @@ module Mysigner
57
59
  # Get all build types (debug, release, etc.)
58
60
  def build_types
59
61
  types = []
60
-
62
+
61
63
  # Match buildTypes block
62
64
  if @gradle_content =~ /buildTypes\s*\{(.*?)\n\s*\}/m
63
- block = $1
65
+ block = ::Regexp.last_match(1)
64
66
  # Find all type names (e.g., "release {" or "debug {")
65
67
  block.scan(/(\w+)\s*\{/) do |match|
66
68
  types << match[0] unless %w[debug release].include?(match[0]) && types.include?(match[0])
67
69
  types << match[0]
68
70
  end
69
71
  end
70
-
72
+
71
73
  # Default build types if none found
72
- types = ['debug', 'release'] if types.empty?
74
+ types = %w[debug release] if types.empty?
73
75
  types.uniq
74
76
  end
75
77
 
76
78
  # Get all product flavors
77
79
  def product_flavors
78
80
  flavors = []
79
-
81
+
80
82
  if @gradle_content =~ /productFlavors\s*\{(.*?)\n\s{4}\}/m
81
- block = $1
83
+ block = ::Regexp.last_match(1)
82
84
  block.scan(/(\w+)\s*\{/) do |match|
83
85
  flavors << match[0]
84
86
  end
85
87
  end
86
-
88
+
87
89
  flavors
88
90
  end
89
91
 
90
92
  # Get signing config for a build type
91
93
  def signing_config(build_type = 'release')
92
94
  # Look for signingConfig in the build type block
93
- if @gradle_content =~ /#{build_type}\s*\{[^}]*signingConfig\s*(?:=\s*)?signingConfigs\.(\w+)/m
94
- return $1
95
- end
95
+ return ::Regexp.last_match(1) if @gradle_content =~ /#{build_type}\s*\{[^}]*signingConfig\s*(?:=\s*)?signingConfigs\.(\w+)/m
96
+
96
97
  nil
97
98
  end
98
99
 
@@ -104,30 +105,28 @@ module Mysigner
104
105
  # Get signing configs defined in the project
105
106
  def signing_configs
106
107
  configs = []
107
-
108
+
108
109
  if @gradle_content =~ /signingConfigs\s*\{(.*?)\n\s{4}\}/m
109
- block = $1
110
+ block = ::Regexp.last_match(1)
110
111
  block.scan(/(\w+)\s*\{/) do |match|
111
112
  configs << match[0]
112
113
  end
113
114
  end
114
-
115
+
115
116
  configs
116
117
  end
117
118
 
118
119
  # Get keystore path from signing config
119
120
  def keystore_path(config_name = 'release')
120
- if @gradle_content =~ /#{config_name}\s*\{[^}]*storeFile\s*(?:=\s*)?(?:file\()?"?([^")\n]+)"?\)?/m
121
- return $1
122
- end
121
+ return ::Regexp.last_match(1) if @gradle_content =~ /#{config_name}\s*\{[^}]*storeFile\s*(?:=\s*)?(?:file\()?"?([^")\n]+)"?\)?/m
122
+
123
123
  nil
124
124
  end
125
125
 
126
126
  # Get keystore alias from signing config
127
127
  def keystore_alias(config_name = 'release')
128
- if @gradle_content =~ /#{config_name}\s*\{[^}]*keyAlias\s*(?:=\s*)?["']?([^"'\n]+)["']?/m
129
- return $1.strip
130
- end
128
+ return ::Regexp.last_match(1).strip if @gradle_content =~ /#{config_name}\s*\{[^}]*keyAlias\s*(?:=\s*)?["']?([^"'\n]+)["']?/m
129
+
131
130
  nil
132
131
  end
133
132
 
@@ -137,15 +136,11 @@ module Mysigner
137
136
  strings_path = File.join(android_directory, 'app/src/main/res/values/strings.xml')
138
137
  if File.exist?(strings_path)
139
138
  content = File.read(strings_path)
140
- if content =~ /<string\s+name="app_name"[^>]*>([^<]+)<\/string>/
141
- return $1
142
- end
139
+ return ::Regexp.last_match(1) if content =~ %r{<string\s+name="app_name"[^>]*>([^<]+)</string>}
143
140
  end
144
141
 
145
142
  # Fallback to manifest label
146
- if @manifest_content && @manifest_content =~ /android:label="([^"]+)"/
147
- return $1
148
- end
143
+ return ::Regexp.last_match(1) if @manifest_content && @manifest_content =~ /android:label="([^"]+)"/
149
144
 
150
145
  # Fallback to directory name
151
146
  File.basename(@project_info[:directory])
@@ -217,7 +212,7 @@ module Mysigner
217
212
 
218
213
  def read_gradle_file
219
214
  gradle_path = @project_info[:app_build_gradle]
220
-
215
+
221
216
  unless gradle_path && File.exist?(gradle_path)
222
217
  # Try to find it
223
218
  android_dir = android_directory
@@ -228,12 +223,14 @@ module Mysigner
228
223
  end
229
224
 
230
225
  return '' unless File.exist?(gradle_path)
226
+
231
227
  File.read(gradle_path)
232
228
  end
233
229
 
234
230
  def read_manifest_file
235
231
  manifest_path = File.join(android_directory, 'app/src/main/AndroidManifest.xml')
236
232
  return nil unless File.exist?(manifest_path)
233
+
237
234
  File.read(manifest_path)
238
235
  end
239
236
 
@@ -241,7 +238,7 @@ module Mysigner
241
238
  # Handle both Groovy and Kotlin DSL syntax
242
239
  # Groovy: applicationId "com.example.app" or applicationId = "com.example.app"
243
240
  # Kotlin: applicationId = "com.example.app"
244
-
241
+
245
242
  patterns = [
246
243
  /#{property}\s*=?\s*["']([^"']+)["']/,
247
244
  /#{property}\s+["']([^"']+)["']/,
@@ -250,9 +247,7 @@ module Mysigner
250
247
  ]
251
248
 
252
249
  patterns.each do |pattern|
253
- if @gradle_content =~ pattern
254
- return $1
255
- end
250
+ return ::Regexp.last_match(1) if @gradle_content =~ pattern
256
251
  end
257
252
 
258
253
  nil
@@ -260,11 +255,9 @@ module Mysigner
260
255
 
261
256
  def extract_package_from_manifest
262
257
  return nil unless @manifest_content
263
-
264
- if @manifest_content =~ /package="([^"]+)"/
265
- return $1
266
- end
267
-
258
+
259
+ return ::Regexp.last_match(1) if @manifest_content =~ /package="([^"]+)"/
260
+
268
261
  nil
269
262
  end
270
263
 
@@ -272,19 +265,19 @@ module Mysigner
272
265
  # Check for app.json in project root
273
266
  project_dir = @project_info[:directory]
274
267
  app_json_path = File.join(project_dir, 'app.json')
275
-
268
+
276
269
  return nil unless File.exist?(app_json_path)
277
-
270
+
278
271
  begin
279
272
  require 'json'
280
273
  config = JSON.parse(File.read(app_json_path))
281
-
274
+
282
275
  # Expo config can be nested under 'expo' key or at root
283
276
  expo_config = config['expo'] || config
284
-
277
+
285
278
  # Get Android package name
286
279
  expo_config.dig('android', 'package')
287
- rescue
280
+ rescue StandardError
288
281
  nil
289
282
  end
290
283
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mysigner
2
4
  module Build
3
5
  class Configurator
@@ -15,7 +17,7 @@ module Mysigner
15
17
  target = @parser.find_target(target_name)
16
18
  bundle_id = @parser.bundle_id(target_name, configuration)
17
19
 
18
- raise "Bundle ID not found in project" if bundle_id.to_s.empty?
20
+ raise 'Bundle ID not found in project' if bundle_id.to_s.empty?
19
21
 
20
22
  # Map build type to profile type
21
23
  profile_type = map_build_type_to_profile_type(build_type)
@@ -30,21 +32,21 @@ module Mysigner
30
32
  # Set manual signing
31
33
  config.build_settings['CODE_SIGN_STYLE'] = 'Manual'
32
34
  config.build_settings['PROVISIONING_PROFILE_SPECIFIER'] = profile['name']
33
-
35
+
34
36
  # Set code sign identity based on type
35
37
  code_sign_identity = case build_type
36
- when :development
37
- 'iPhone Developer'
38
- else
39
- 'iPhone Distribution'
40
- end
38
+ when :development
39
+ 'iPhone Developer'
40
+ else
41
+ 'iPhone Distribution'
42
+ end
41
43
  config.build_settings['CODE_SIGN_IDENTITY'] = code_sign_identity
42
44
 
43
45
  # Ensure development team is set
44
46
  team_id = @parser.team_id(target_name, configuration)
45
- if team_id.to_s.empty?
47
+ if team_id.to_s.empty? && profile['team_id']
46
48
  # Try to get from profile or use organization default
47
- config.build_settings['DEVELOPMENT_TEAM'] = profile['team_id'] if profile['team_id']
49
+ config.build_settings['DEVELOPMENT_TEAM'] = profile['team_id']
48
50
  end
49
51
 
50
52
  # Save project
@@ -93,9 +95,9 @@ module Mysigner
93
95
  type: profile_type
94
96
  }
95
97
  )
96
-
98
+
97
99
  return response[:profile] if response[:profile]
98
- rescue Mysigner::NotFoundError => e
100
+ rescue Mysigner::NotFoundError
99
101
  # Profile matching returned no match, fall through to manual search
100
102
  end
101
103
 
@@ -110,11 +112,11 @@ module Mysigner
110
112
  )
111
113
 
112
114
  profiles = response[:profiles] || []
113
-
115
+
114
116
  if profiles.empty?
115
- raise ProfileNotFoundError,
116
- "No active #{profile_type} profile found for bundle ID '#{bundle_id}'. " \
117
- "Create one at the My Signer dashboard or run 'mysigner profiles'"
117
+ raise ProfileNotFoundError,
118
+ "No active #{profile_type} profile found for bundle ID '#{bundle_id}'. " \
119
+ "Create one at the My Signer dashboard or run 'mysigner profiles'"
118
120
  end
119
121
 
120
122
  # Return the profile expiring furthest in the future
@@ -123,4 +125,3 @@ module Mysigner
123
125
  end
124
126
  end
125
127
  end
126
-