pindo 5.13.1 → 5.13.3

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 (115) hide show
  1. checksums.yaml +4 -4
  2. data/lib/pindo/base/git_handler.rb +692 -0
  3. data/lib/pindo/command/android/autobuild.rb +2 -2
  4. data/lib/pindo/command/appstore/adhocbuild.rb +256 -311
  5. data/lib/pindo/command/appstore/autobuild.rb +203 -0
  6. data/lib/pindo/command/appstore/autoresign.rb +35 -17
  7. data/lib/pindo/command/appstore/bundleid.rb +120 -0
  8. data/lib/pindo/command/appstore/cert.rb +212 -0
  9. data/lib/pindo/command/appstore/configproj.rb +81 -0
  10. data/lib/pindo/command/{deploy → appstore}/getitcinfo.rb +76 -91
  11. data/lib/pindo/command/appstore/iap.rb +788 -24
  12. data/lib/pindo/command/appstore/initconfig.rb +105 -0
  13. data/lib/pindo/command/appstore/itcapp.rb +95 -13
  14. data/lib/pindo/command/{deploy → appstore}/itcinfo.rb +90 -118
  15. data/lib/pindo/command/appstore/pem.rb +136 -0
  16. data/lib/pindo/command/appstore/pullconfig.rb +99 -0
  17. data/lib/pindo/command/appstore/quswark.rb +87 -0
  18. data/lib/pindo/command/appstore/quswauth.rb +67 -0
  19. data/lib/pindo/command/appstore/tag.rb +77 -0
  20. data/lib/pindo/command/appstore.rb +13 -1
  21. data/lib/pindo/command/env/quarkenv.rb +11 -13
  22. data/lib/pindo/command/env/swarkenv.rb +11 -16
  23. data/lib/pindo/command/ios/applovin.rb +24 -182
  24. data/lib/pindo/command/ios/autobuild.rb +64 -43
  25. data/lib/pindo/command/ios/autoresign.rb +34 -19
  26. data/lib/pindo/command/ios/build.rb +9 -6
  27. data/lib/pindo/command/ios/cert.rb +27 -20
  28. data/lib/pindo/command/ios/podupdate.rb +6 -37
  29. data/lib/pindo/command/jps/upload.rb +3 -3
  30. data/lib/pindo/command/unity/autobuild.rb +2 -2
  31. data/lib/pindo/command/utils/clearcert.rb +2 -17
  32. data/lib/pindo/command/{deploy → utils}/fabric.rb +13 -13
  33. data/lib/pindo/command/utils/renewcert.rb +62 -38
  34. data/lib/pindo/command/utils/renewproj.rb +0 -3
  35. data/lib/pindo/command/{deploy → utils}/updateconfig.rb +6 -7
  36. data/lib/pindo/command/utils.rb +2 -0
  37. data/lib/pindo/command/web/autobuild.rb +2 -2
  38. data/lib/pindo/command.rb +30 -3
  39. data/lib/pindo/config/build_info_manager.rb +176 -0
  40. data/lib/pindo/config/ios_config_parser.rb +404 -0
  41. data/lib/pindo/module/android/android_config_helper.rb +9 -5
  42. data/lib/pindo/module/appstore/bundleid_helper.rb +349 -0
  43. data/lib/pindo/module/appstore/itcapp_helper.rb +228 -0
  44. data/lib/pindo/module/build/build_helper.rb +12 -0
  45. data/lib/pindo/module/build/swark_helper.rb +116 -77
  46. data/lib/pindo/module/cert/cert_helper.rb +74 -0
  47. data/lib/pindo/module/cert/pem_helper.rb +72 -0
  48. data/lib/pindo/module/cert/{xcodecerthelper.rb → xcode_cert_helper.rb} +211 -6
  49. data/lib/pindo/module/pgyer/pgyerhelper.rb +13 -5
  50. data/lib/pindo/module/task/model/appstore/appstore_task.rb +18 -0
  51. data/lib/pindo/module/task/model/appstore/appstore_upload_ipa_task.rb +151 -0
  52. data/lib/pindo/module/task/model/appstore/appstore_upload_metadata_task.rb +250 -0
  53. data/lib/pindo/module/task/model/appstore/appstore_upload_screenshot_task.rb +276 -0
  54. data/lib/pindo/module/task/model/build/android_build_adhoc_task.rb +210 -0
  55. data/lib/pindo/module/task/model/build/{android_dev_build_task.rb → android_build_dev_task.rb} +2 -2
  56. data/lib/pindo/module/task/model/build/android_build_gplay_task.rb +210 -0
  57. data/lib/pindo/module/task/model/build/android_build_task.rb +13 -0
  58. data/lib/pindo/module/task/model/build/ios_build_adhoc_task.rb +342 -0
  59. data/lib/pindo/module/task/model/build/ios_build_appstore_task.rb +341 -0
  60. data/lib/pindo/module/task/model/build/{ios_dev_build_task.rb → ios_build_dev_task.rb} +40 -59
  61. data/lib/pindo/module/task/model/build/ios_build_task.rb +23 -0
  62. data/lib/pindo/module/task/model/build/{web_dev_build_task.rb → web_build_dev_task.rb} +1 -1
  63. data/lib/pindo/module/task/model/build_task.rb +15 -12
  64. data/lib/pindo/module/task/model/jps_resign_task.rb +185 -0
  65. data/lib/pindo/module/task/model/{upload_task.rb → jps_upload_task.rb} +3 -3
  66. data/lib/pindo/module/task/model/unity_export_task.rb +3 -1
  67. data/lib/pindo/module/unity/unity_helper.rb +2 -1
  68. data/lib/pindo/module/xcode/applovin_xcode_helper.rb +271 -0
  69. data/lib/pindo/module/xcode/cocoapods_helper.rb +153 -0
  70. data/lib/pindo/module/xcode/ipa_resign_helper.rb +210 -0
  71. data/lib/pindo/module/xcode/{xcodeappconfig.rb → xcode_app_config.rb} +79 -0
  72. data/lib/pindo/module/xcode/xcode_build_config.rb +152 -17
  73. data/lib/pindo/module/xcode/xcode_build_helper.rb +151 -1
  74. data/lib/pindo/module/xcode/xcode_swark_helper.rb +341 -0
  75. data/lib/pindo/options/core/global_options_state.rb +268 -0
  76. data/lib/pindo/options/core/option_configuration.rb +206 -0
  77. data/lib/pindo/options/core/option_initializer.rb +51 -0
  78. data/lib/pindo/options/core/option_item.rb +144 -0
  79. data/lib/pindo/options/core/option_value_parser.rb +54 -0
  80. data/lib/pindo/options/groups/build_options.rb +60 -0
  81. data/lib/pindo/options/groups/jps_options.rb +70 -0
  82. data/lib/pindo/options/groups/option_group.rb +73 -0
  83. data/lib/pindo/options/helpers/bundleid_selector.rb +103 -0
  84. data/lib/pindo/options/options.rb +14 -0
  85. data/lib/pindo/version.rb +1 -1
  86. metadata +51 -40
  87. data/lib/pindo/command/appstore/import.rb +0 -259
  88. data/lib/pindo/command/deploy/build.rb +0 -250
  89. data/lib/pindo/command/deploy/bundleid.rb +0 -259
  90. data/lib/pindo/command/deploy/cert.rb +0 -202
  91. data/lib/pindo/command/deploy/check.rb +0 -93
  92. data/lib/pindo/command/deploy/configproj.rb +0 -120
  93. data/lib/pindo/command/deploy/confusecode.rb +0 -262
  94. data/lib/pindo/command/deploy/confuseproj.rb +0 -122
  95. data/lib/pindo/command/deploy/iap.rb +0 -826
  96. data/lib/pindo/command/deploy/initconfig.rb +0 -138
  97. data/lib/pindo/command/deploy/itcapp.rb +0 -146
  98. data/lib/pindo/command/deploy/pem.rb +0 -55
  99. data/lib/pindo/command/deploy/pullconfig.rb +0 -56
  100. data/lib/pindo/command/deploy/pushconfig.rb +0 -93
  101. data/lib/pindo/command/deploy/quswark.rb +0 -156
  102. data/lib/pindo/command/deploy/quswauth.rb +0 -76
  103. data/lib/pindo/command/deploy/reportbug.rb +0 -145
  104. data/lib/pindo/command/deploy/resign.rb +0 -300
  105. data/lib/pindo/command/deploy/tag.rb +0 -108
  106. data/lib/pindo/command/deploy/uploadipa.rb +0 -73
  107. data/lib/pindo/command/deploy.rb +0 -42
  108. data/lib/pindo/command/dev/autobuild.rb +0 -117
  109. data/lib/pindo/command/dev/build.rb +0 -94
  110. data/lib/pindo/command/dev/debug.rb +0 -112
  111. data/lib/pindo/module/task/model/build/android_release_build_task.rb +0 -29
  112. data/lib/pindo/module/task/model/build/ios_adhoc_build_task.rb +0 -53
  113. data/lib/pindo/module/task/model/build/ios_release_build_task.rb +0 -53
  114. data/lib/pindo/options/appconfigoptions.rb +0 -24
  115. data/lib/pindo/options/deployoptions.rb +0 -372
@@ -0,0 +1,349 @@
1
+ require 'spaceship'
2
+ require 'json'
3
+
4
+ module Pindo
5
+ # Bundle ID 管理辅助类
6
+ # 负责在 Apple 开发者中心创建和配置 Bundle ID
7
+ class BundleIdHelper
8
+
9
+ # 从配置文件中提取所有必要的信息
10
+ # @param config_json [Hash] 配置 JSON 对象
11
+ # @return [Hash] 提取的配置信息
12
+ def self.extract_config_info(config_json)
13
+ config_info = {}
14
+
15
+ # 提取 Apple ID
16
+ if config_json['account_info'] && config_json['account_info']['apple_acount_id']
17
+ config_info[:apple_id] = config_json['account_info']['apple_acount_id']
18
+ end
19
+
20
+ # 提取 Bundle ID 信息
21
+ if config_json['app_info']
22
+ app_info = config_json['app_info']
23
+ config_info[:bundle_id] = app_info['app_identifier']
24
+ config_info[:bundle_id_pushcontent] = app_info['app_identifier_pushcontent']
25
+ config_info[:bundle_id_pushservice] = app_info['app_identifier_pushservice']
26
+ config_info[:bundle_id_keyboard] = app_info['app_identifier_keyboard']
27
+ config_info[:bundle_id_imessage] = app_info['app_identifier_imessage']
28
+ config_info[:bundle_id_extension] = app_info['app_identifier_extension']
29
+ config_info[:bundle_id_siri] = app_info['app_identifier_siri']
30
+ config_info[:bundle_id_siriui] = app_info['app_identifier_siriui']
31
+ config_info[:bundle_id_widget] = app_info['app_identifier_widget']
32
+ config_info[:bundle_id_extensionad] = app_info['app_identifier_extensionad']
33
+ config_info[:bundle_id_watchapp] = app_info['app_identifier_watchapp']
34
+ config_info[:bundle_id_watchapp_extension] = app_info['app_identifier_watchapp_extension']
35
+ end
36
+
37
+ # 提取 App Group 和 iCloud ID
38
+ if config_json['app_setting']
39
+ app_setting = config_json['app_setting']
40
+ config_info[:group_id] = app_setting['app_group_id']
41
+ config_info[:icloud_id] = app_setting['app_icloud_id']
42
+ end
43
+
44
+ config_info
45
+ end
46
+
47
+ # 执行 Bundle ID 创建流程
48
+ # @param config_json [Hash] 配置 JSON 对象
49
+ # @param sign_flag [Boolean] 签名标志
50
+ def self.execute_bundleid_creation(config_json:, sign_flag: false)
51
+ # 提取配置信息
52
+ config_info = extract_config_info(config_json)
53
+
54
+ # 验证必需字段
55
+ raise "配置文件中缺少 Apple ID" if config_info[:apple_id].nil? || config_info[:apple_id].empty?
56
+ raise "配置文件中缺少 Bundle ID" if config_info[:bundle_id].nil? || config_info[:bundle_id].empty?
57
+
58
+ # 登录 Apple 开发者中心
59
+ puts config_info[:apple_id]
60
+ puts "Login #{config_info[:apple_id]}..."
61
+ Spaceship.login(config_info[:apple_id].to_s)
62
+ Spaceship.select_team
63
+
64
+ # 创建 App Group
65
+ app_group = nil
66
+ if !config_info[:group_id].nil?
67
+ app_group = create_group_id(group_id: config_info[:group_id])
68
+ end
69
+
70
+ # 配置参数
71
+ parms = ["push_notification", "app_group"]
72
+
73
+ # 创建 iCloud ID
74
+ app_icloud = nil
75
+ if !config_info[:icloud_id].nil?
76
+ app_icloud = create_icloud_id(icloud_id: config_info[:icloud_id])
77
+ parms << "iclound"
78
+ end
79
+
80
+ # 创建主应用 Bundle ID
81
+ app = create_bundleid(
82
+ bundle_id: config_info[:bundle_id],
83
+ app_group: app_group,
84
+ app_icloud: app_icloud,
85
+ setting_array: parms
86
+ )
87
+
88
+ # 创建各种扩展的 Bundle ID
89
+ create_extension_bundleids(app, app_group, app_icloud, config_info)
90
+ end
91
+
92
+ # 创建 Bundle ID
93
+ # @param bundle_id [String] Bundle ID
94
+ # @param app_group [Object] App Group 对象
95
+ # @param app_icloud [Object] iCloud Container 对象
96
+ # @param setting_array [Array] 配置数组
97
+ # @return [Object] 创建的 App 对象
98
+ def self.create_bundleid(bundle_id:, app_group: nil, app_icloud: nil, setting_array: [])
99
+ return nil if bundle_id.nil?
100
+
101
+ # 查找或创建 Bundle ID
102
+ app = Spaceship::Portal.app.find(bundle_id)
103
+ puts
104
+
105
+ if app.nil?
106
+ puts "Create bundle id #{bundle_id} in apple developer center..."
107
+ app = Spaceship::Portal.app.create!(bundle_id: bundle_id, name: bundle_id.gsub('.', ''))
108
+ else
109
+ puts "Find bundle id #{bundle_id} in apple developer center..."
110
+ end
111
+
112
+ bundle_id_obj = Spaceship::ConnectAPI::BundleId.find(bundle_id)
113
+
114
+ # 配置 Game Center
115
+ if !bundle_id_obj.nil?
116
+ if !setting_array.nil? && setting_array.to_s.include?("game_center")
117
+ puts "Enable #{bundle_id} game_center on"
118
+ bundle_id_obj.update_capability("GAME_CENTER", enabled: true)
119
+ else
120
+ puts "Enable #{bundle_id} game_center off"
121
+ bundle_id_obj.update_capability("GAME_CENTER", enabled: false)
122
+ end
123
+ end
124
+
125
+ return nil if setting_array.nil? || setting_array.length == 0
126
+
127
+ # 配置 Push Notification
128
+ if !app.nil? && setting_array.to_s.include?("push_notification")
129
+ puts "Enable #{bundle_id} push on"
130
+ app.update_service(Spaceship::Portal.app_service.push_notification.on)
131
+ else
132
+ app.update_service(Spaceship::Portal.app_service.push_notification.off)
133
+ puts "Enable #{bundle_id} push off"
134
+ end
135
+
136
+ # 配置 Siri
137
+ if !app.nil? && setting_array.to_s.include?("siri")
138
+ puts "Enable #{bundle_id} siri on"
139
+ app.update_service(Spaceship::Portal.app_service.siri_kit.on)
140
+ else
141
+ app.update_service(Spaceship::Portal.app_service.siri_kit.off)
142
+ puts "Enable #{bundle_id} siri off"
143
+ end
144
+
145
+ # 配置 Sign with Apple
146
+ if !bundle_id_obj.nil? && setting_array.to_s.include?("apple_signin")
147
+ puts "Enable #{bundle_id} Sign with Apple on"
148
+ settings = build_settings_for(settings_key: "APPLE_ID_AUTH_APP_CONSENT", options_key: "PRIMARY_APP_CONSENT")
149
+ bundle_id_obj.update_capability("APPLE_ID_AUTH", enabled: true, settings: settings)
150
+ else
151
+ puts "Enable #{bundle_id} Sign with Apple off"
152
+ bundle_id_obj.update_capability("APPLE_ID_AUTH", enabled: false)
153
+ end
154
+
155
+ # 配置 App Group
156
+ if !app_group.nil? && setting_array.to_s.include?("app_group")
157
+ puts "Enable #{bundle_id} group on"
158
+ app.update_service(Spaceship::Portal.app_service.app_group.on)
159
+ app.associate_groups([app_group])
160
+ else
161
+ puts "Enable #{bundle_id} group off"
162
+ app.update_service(Spaceship::Portal.app_service.app_group.off)
163
+ end
164
+
165
+ # 配置 iCloud
166
+ if !app_icloud.nil? && setting_array.to_s.include?("iclound")
167
+ puts "Enable #{bundle_id} icloud on"
168
+ app.update_service(Spaceship::Portal.app_service.cloud.on)
169
+ app.update_service(Spaceship::Portal.app_service.cloud_kit.cloud_kit)
170
+ app.associate_cloud_containers([app_icloud])
171
+ else
172
+ puts "Enable #{bundle_id} icloud off"
173
+ app.update_service(Spaceship::Portal.app_service.cloud.off)
174
+ end
175
+
176
+ app
177
+ end
178
+
179
+ # 创建 App Group
180
+ # @param group_id [String] Group ID
181
+ # @return [Object] App Group 对象
182
+ def self.create_group_id(group_id:)
183
+ return nil if group_id.nil?
184
+
185
+ app_group = Spaceship::Portal.app_group.find(group_id)
186
+
187
+ if app_group.nil?
188
+ puts "Create group_id #{group_id} in apple developer center..."
189
+ app_group = Spaceship::Portal.app_group.create!(group_id: group_id, name: group_id.gsub('.', ''))
190
+ else
191
+ puts "Group_id #{group_id} is existed in apple developer center !!!"
192
+ end
193
+
194
+ app_group
195
+ end
196
+
197
+ # 创建 iCloud Container
198
+ # @param icloud_id [String] iCloud ID
199
+ # @return [Object] iCloud Container 对象
200
+ def self.create_icloud_id(icloud_id:)
201
+ return nil if icloud_id.nil?
202
+
203
+ puts "icloud_id +++++ #{icloud_id}"
204
+ app_icloud = Spaceship::Portal.cloud_container.find(icloud_id)
205
+
206
+ if app_icloud.nil?
207
+ puts "Create icloud_id #{icloud_id} in apple developer center..."
208
+ app_icloud = Spaceship::Portal.cloud_container.create!(identifier: icloud_id, name: icloud_id.gsub('.', ''))
209
+ else
210
+ puts "icloud_id #{icloud_id} is existed in apple developer center !!!"
211
+ end
212
+
213
+ app_icloud
214
+ end
215
+
216
+ # 构建设置
217
+ # @param settings_key [String] 设置键
218
+ # @param options_key [String] 选项键
219
+ # @return [Array] 设置数组
220
+ def self.build_settings_for(settings_key:, options_key:)
221
+ [{
222
+ key: settings_key,
223
+ options: [{
224
+ key: options_key
225
+ }]
226
+ }]
227
+ end
228
+
229
+ # 创建扩展的 Bundle ID
230
+ # @param app [Object] 主应用对象
231
+ # @param app_group [Object] App Group 对象
232
+ # @param app_icloud [Object] iCloud Container 对象
233
+ # @param config_info [Hash] 配置信息
234
+ def self.create_extension_bundleids(app, app_group, app_icloud, config_info)
235
+ return if app.nil?
236
+
237
+ # Push Content Extension
238
+ if !config_info[:bundle_id_pushcontent].nil?
239
+ create_bundleid(
240
+ bundle_id: config_info[:bundle_id_pushcontent],
241
+ app_group: app_group,
242
+ app_icloud: app_icloud,
243
+ setting_array: ["push_notification"]
244
+ )
245
+ end
246
+
247
+ # Push Service Extension
248
+ if !config_info[:bundle_id_pushservice].nil?
249
+ create_bundleid(
250
+ bundle_id: config_info[:bundle_id_pushservice],
251
+ app_group: app_group,
252
+ app_icloud: app_icloud,
253
+ setting_array: ["push_notification"]
254
+ )
255
+ end
256
+
257
+ # Keyboard Extension
258
+ if !config_info[:bundle_id_keyboard].nil?
259
+ create_bundleid(
260
+ bundle_id: config_info[:bundle_id_keyboard],
261
+ app_group: app_group,
262
+ app_icloud: app_icloud,
263
+ setting_array: ["app_group"]
264
+ )
265
+ end
266
+
267
+ # iMessage Extension
268
+ if !config_info[:bundle_id_imessage].nil?
269
+ create_bundleid(
270
+ bundle_id: config_info[:bundle_id_imessage],
271
+ app_group: app_group,
272
+ app_icloud: app_icloud,
273
+ setting_array: ["app_group"]
274
+ )
275
+ end
276
+
277
+ # Siri Extension
278
+ if !config_info[:bundle_id_siri].nil?
279
+ create_bundleid(
280
+ bundle_id: config_info[:bundle_id_siri],
281
+ app_group: app_group,
282
+ app_icloud: app_icloud,
283
+ setting_array: ["app_group", "siri"]
284
+ )
285
+ end
286
+
287
+ # Siri UI Extension
288
+ if !config_info[:bundle_id_siriui].nil?
289
+ create_bundleid(
290
+ bundle_id: config_info[:bundle_id_siriui],
291
+ app_group: app_group,
292
+ app_icloud: app_icloud,
293
+ setting_array: ["app_group", "siri"]
294
+ )
295
+ end
296
+
297
+ # Widget Extension
298
+ if !config_info[:bundle_id_widget].nil?
299
+ create_bundleid(
300
+ bundle_id: config_info[:bundle_id_widget],
301
+ app_group: app_group,
302
+ app_icloud: app_icloud,
303
+ setting_array: ["app_group"]
304
+ )
305
+ end
306
+
307
+ # General Extension
308
+ if !config_info[:bundle_id_extension].nil?
309
+ create_bundleid(
310
+ bundle_id: config_info[:bundle_id_extension],
311
+ app_group: app_group,
312
+ app_icloud: app_icloud,
313
+ setting_array: ["app_group"]
314
+ )
315
+ end
316
+
317
+ # Ad Extension
318
+ if !config_info[:bundle_id_extensionad].nil?
319
+ create_bundleid(
320
+ bundle_id: config_info[:bundle_id_extensionad],
321
+ app_group: app_group,
322
+ app_icloud: app_icloud,
323
+ setting_array: ["app_group"]
324
+ )
325
+ end
326
+
327
+ # Watch App
328
+ if !config_info[:bundle_id_watchapp].nil?
329
+ create_bundleid(
330
+ bundle_id: config_info[:bundle_id_watchapp],
331
+ app_group: nil,
332
+ app_icloud: app_icloud,
333
+ setting_array: ["push_notification"]
334
+ )
335
+ end
336
+
337
+ # Watch App Extension
338
+ if !config_info[:bundle_id_watchapp_extension].nil?
339
+ create_bundleid(
340
+ bundle_id: config_info[:bundle_id_watchapp_extension],
341
+ app_group: nil,
342
+ app_icloud: app_icloud,
343
+ setting_array: ["push_notification"]
344
+ )
345
+ end
346
+ end
347
+
348
+ end
349
+ end
@@ -0,0 +1,228 @@
1
+ require 'spaceship'
2
+ require 'json'
3
+ require 'highline/import'
4
+
5
+ module Pindo
6
+ # iTunes Connect App 管理辅助类
7
+ # 负责在 App Store Connect 中创建和管理应用
8
+ class ItcAppHelper
9
+
10
+ # 从配置文件中提取所有必要的信息
11
+ # @param config_json [Hash] 配置 JSON 对象
12
+ # @return [Hash] 提取的配置信息
13
+ def self.extract_config_info(config_json)
14
+ config_info = {}
15
+
16
+ # 提取 Apple ID
17
+ if config_json['account_info'] && config_json['account_info']['apple_acount_id']
18
+ config_info[:apple_id] = config_json['account_info']['apple_acount_id']
19
+ end
20
+
21
+ # 提取 Company Name
22
+ if config_json['account_info'] && config_json['account_info']['acount_company_name']
23
+ config_info[:company_name] = config_json['account_info']['acount_company_name'].strip
24
+ end
25
+
26
+ # 提取 Bundle ID
27
+ if config_json['app_info'] && config_json['app_info']['app_identifier']
28
+ config_info[:bundle_id] = config_json['app_info']['app_identifier']
29
+ end
30
+
31
+ # 提取版本号
32
+ if config_json['app_info'] && config_json['app_info']['app_version']
33
+ config_info[:app_version] = config_json['app_info']['app_version']
34
+ else
35
+ config_info[:app_version] = "1.0.0" # 默认版本
36
+ end
37
+
38
+ config_info
39
+ end
40
+
41
+ # 执行 iTunes Connect App 创建流程
42
+ # @param config_json [Hash] 配置 JSON 对象
43
+ # @param config_path [String] 配置文件路径
44
+ # @param app_version [String, nil] 应用版本号
45
+ # @param company_name [String, nil] 公司名称
46
+ def self.execute_itcapp_creation(config_json:, config_path:, app_version: nil, company_name: nil)
47
+ # 提取配置信息
48
+ config_info = extract_config_info(config_json)
49
+
50
+ # 使用命令行参数覆盖配置
51
+ config_info[:app_version] = app_version if app_version
52
+ config_info[:company_name] = company_name if company_name
53
+
54
+ # 验证必需字段
55
+ raise "配置文件中缺少 Apple ID" if config_info[:apple_id].nil? || config_info[:apple_id].empty?
56
+ raise "配置文件中缺少 Bundle ID" if config_info[:bundle_id].nil? || config_info[:bundle_id].empty?
57
+
58
+ # 确保 Bundle ID 在开发者中心存在
59
+ ensure_bundle_id_exists(
60
+ apple_id: config_info[:apple_id],
61
+ bundle_id: config_info[:bundle_id],
62
+ config_path: config_path
63
+ )
64
+
65
+ # 创建 iTunes Connect App
66
+ puts "Create app in itc ..."
67
+ puts config_info[:apple_id]
68
+ puts "Login #{config_info[:apple_id]}..."
69
+
70
+ Spaceship::Tunes.login(config_info[:apple_id].to_s)
71
+ Spaceship::Tunes.select_team
72
+
73
+ app = create_itcapp(
74
+ bundle_id: config_info[:bundle_id],
75
+ app_version: config_info[:app_version],
76
+ company_name: config_info[:company_name]
77
+ )
78
+
79
+ # 修改配置文件,添加 App ID
80
+ if app
81
+ modify_appconfig_with_appid(
82
+ config_path: config_path,
83
+ bundle_id: config_info[:bundle_id],
84
+ app: app
85
+ )
86
+ end
87
+
88
+ app
89
+ end
90
+
91
+ # 确保 Bundle ID 在开发者中心存在
92
+ # @param apple_id [String] Apple ID
93
+ # @param bundle_id [String] Bundle ID
94
+ # @param config_path [String] 配置文件路径
95
+ def self.ensure_bundle_id_exists(apple_id:, bundle_id:, config_path:)
96
+ Spaceship::Portal.login(apple_id.to_s)
97
+ Spaceship::Portal.select_team
98
+
99
+ app = Spaceship::Portal.app.find(bundle_id)
100
+ if app.nil?
101
+ puts "Bundle ID #{bundle_id} 不存在,需要先创建"
102
+ puts "请先运行: pindo appstore bundleid #{config_path}"
103
+ raise "Bundle ID #{bundle_id} 不存在于 Apple 开发者中心"
104
+ end
105
+ end
106
+
107
+ # 创建 iTunes Connect App
108
+ # @param bundle_id [String] Bundle ID
109
+ # @param app_version [String] 应用版本号
110
+ # @param company_name [String, nil] 公司名称
111
+ # @return [Object] 创建的 App 对象
112
+ def self.create_itcapp(bundle_id:, app_version:, company_name: nil)
113
+ return nil if bundle_id.nil?
114
+
115
+ # 检查 App 是否已存在
116
+ app = Spaceship::ConnectAPI::App.find(bundle_id)
117
+ if app
118
+ puts "App is already exist !!!"
119
+ return app
120
+ end
121
+
122
+ # 生成默认 SKU ID
123
+ app_sku_id_fixed = bundle_id + ".sku"
124
+ puts "App的默认sku id 为: #{app_sku_id_fixed}"
125
+
126
+ # 让用户自定义 SKU ID
127
+ input_skuid = ask("请自定义输入App Sku ID: ") || nil
128
+ if !input_skuid.nil? && input_skuid.length > 1
129
+ app_sku_id_fixed = input_skuid
130
+ end
131
+
132
+ # 获取公司名称
133
+ if company_name.nil?
134
+ company_name = ask('Company Name : ') || nil
135
+ end
136
+
137
+ puts "App Sku ID : #{app_sku_id_fixed}"
138
+ puts "Company Name : #{company_name}"
139
+
140
+ # 确认信息
141
+ answer = agree("请确认上面信息是否正确(Y/n):")
142
+ unless answer
143
+ raise "用户取消创建,请重新运行命令"
144
+ end
145
+
146
+ # 生成 App 名称(移除点号,最多30个字符)
147
+ app_default_name = bundle_id.gsub('.', '')
148
+ if app_default_name.length > 30
149
+ app_default_name = app_default_name[0, 30]
150
+ end
151
+
152
+ # 创建 App
153
+ app = Spaceship::ConnectAPI::App.create(
154
+ name: app_default_name,
155
+ version_string: app_version,
156
+ sku: app_sku_id_fixed,
157
+ primary_locale: "en-US",
158
+ bundle_id: bundle_id,
159
+ platforms: ["IOS"],
160
+ company_name: company_name
161
+ )
162
+
163
+ puts "App is created !!!"
164
+ app
165
+ end
166
+
167
+ # 修改配置文件,添加 App ID
168
+ # @param config_path [String] 配置文件路径
169
+ # @param bundle_id [String] Bundle ID
170
+ # @param app [Object] App 对象
171
+ def self.modify_appconfig_with_appid(config_path:, bundle_id:, app:)
172
+ return if app.nil?
173
+
174
+ puts
175
+ puts "app.id : #{app.id} +++++++++"
176
+ puts
177
+
178
+ # 修改本地配置文件
179
+ modify_appconfig_file(config_file: config_path, app_info_detail: app)
180
+
181
+ # 修改远程配置仓库
182
+ begin
183
+ require_relative '../../base/githelper'
184
+ include Pindo::Githelper
185
+
186
+ app_config_dir = clong_buildconfig_repo(repo_name: bundle_id)
187
+ app_config_file = File.join(app_config_dir, "config.json")
188
+
189
+ if File.exist?(app_config_file)
190
+ modify_appconfig_file(config_file: app_config_file, app_info_detail: app)
191
+ prepare_gitenv()
192
+ git_addpush_repo(path: app_config_dir, message: "modify apple id")
193
+ end
194
+ rescue StandardError => e
195
+ puts "更新远程配置仓库失败: #{e.message}"
196
+ end
197
+ end
198
+
199
+ # 修改单个配置文件
200
+ # @param config_file [String] 配置文件路径
201
+ # @param app_info_detail [Object] App 信息对象
202
+ def self.modify_appconfig_file(config_file:, app_info_detail:)
203
+ return unless File.exist?(config_file)
204
+
205
+ config_content = JSON.parse(File.read(config_file))
206
+
207
+ File.open(config_file, "w") do |f|
208
+ # 更新 app_id_ios
209
+ config_content['app_info']['app_id_ios'] = app_info_detail.id
210
+
211
+ # 更新 apple_app_id(如果存在)
212
+ if config_content['app_setting'] && config_content['app_setting']["apple_app_id"]
213
+ config_content['app_setting']["apple_app_id"] = app_info_detail.id
214
+ end
215
+
216
+ # 更新 kGUKeyAppId(如果存在)
217
+ if config_content['app_setting'] && config_content['app_setting']["kGUKeyAppId"]
218
+ config_content['app_setting']["kGUKeyAppId"] = app_info_detail.id
219
+ end
220
+
221
+ f.write(JSON.pretty_generate(config_content))
222
+ end
223
+
224
+ puts "✓ 配置文件已更新: #{config_file}"
225
+ end
226
+
227
+ end
228
+ end
@@ -196,6 +196,18 @@ module Pindo
196
196
  nil
197
197
  end
198
198
  end
199
+
200
+ # 拉取应用配置仓库(委托给 BuildInfoManager)
201
+ # @param repo_name [String] 仓库名称(Bundle ID)
202
+ # @param target_dir [String, nil] 目标目录(默认:当前目录)
203
+ # @return [Boolean] 是否成功拉取配置
204
+ def pull_appconfig_with_reponame(repo_name:, target_dir: nil)
205
+ require_relative '../../config/build_info_manager'
206
+ Pindo::BuildInfoManager.share_instance.pull_appconfig_with_reponame(
207
+ repo_name: repo_name,
208
+ target_dir: target_dir
209
+ )
210
+ end
199
211
  end
200
212
 
201
213
  end