pindo 5.17.4 → 5.18.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.
- checksums.yaml +4 -4
- data/lib/pindo/base/git_handler.rb +120 -38
- data/lib/pindo/command/android/autobuild.rb +92 -31
- data/lib/pindo/command/appstore/adhocbuild.rb +1 -1
- data/lib/pindo/command/appstore/autobuild.rb +1 -1
- data/lib/pindo/command/appstore/autoresign.rb +1 -1
- data/lib/pindo/command/appstore/updateid.rb +229 -0
- data/lib/pindo/command/appstore.rb +1 -0
- data/lib/pindo/command/ios/autobuild.rb +70 -33
- data/lib/pindo/command/ios/podpush.rb +1 -1
- data/lib/pindo/command/unity/autobuild.rb +38 -18
- data/lib/pindo/command/utils/allcopyconfig.rb +144 -0
- data/lib/pindo/command/utils/copyconfig.rb +207 -0
- data/lib/pindo/command/utils/icon.rb +2 -2
- data/lib/pindo/command/utils/renewbundleid.rb +199 -0
- data/lib/pindo/command/utils/renewcert.rb +56 -54
- data/lib/pindo/command/utils.rb +3 -0
- data/lib/pindo/command/web/autobuild.rb +10 -8
- data/lib/pindo/config/build_info_manager.rb +1 -3
- data/lib/pindo/module/android/android_build_helper.rb +198 -33
- data/lib/pindo/module/android/android_config_helper.rb +305 -88
- data/lib/pindo/module/android/android_project_helper.rb +124 -14
- data/lib/pindo/module/android/android_res_helper.rb +349 -51
- data/lib/pindo/module/android/keystore_helper.rb +611 -295
- data/lib/pindo/module/android/workflow_gradle_injector.rb +702 -0
- data/lib/pindo/module/appselect.rb +4 -4
- data/lib/pindo/module/appstore/bundleid_helper.rb +204 -14
- data/lib/pindo/module/build/build_helper.rb +76 -10
- data/lib/pindo/module/build/git_repo_helper.rb +4 -4
- data/lib/pindo/module/cert/mode/base_cert_operator.rb +12 -6
- data/lib/pindo/module/pgyer/pgyerhelper.rb +124 -39
- data/lib/pindo/module/task/model/build/android_build_dev_task.rb +64 -6
- data/lib/pindo/module/task/model/git/git_commit_task.rb +70 -54
- data/lib/pindo/module/task/model/git/git_tag_task.rb +13 -9
- data/lib/pindo/module/task/model/jps/jps_upload_task.rb +110 -3
- data/lib/pindo/module/task/model/unity/unity_export_task.rb +2 -1
- data/lib/pindo/module/task/model/unity/unity_update_task.rb +2 -1
- data/lib/pindo/module/task/model/unity/unity_yoo_asset_task.rb +2 -1
- data/lib/pindo/module/task/model/unity_task.rb +2 -1
- data/lib/pindo/module/unity/unity_helper.rb +13 -10
- data/lib/pindo/module/unity/unity_proc_helper.rb +27 -2
- data/lib/pindo/module/xcode/applovin_xcode_helper.rb +6 -2
- data/lib/pindo/module/xcode/res/xcode_res_constant.rb +72 -0
- data/lib/pindo/module/xcode/res/xcode_res_handler.rb +3 -3
- data/lib/pindo/module/xcode/xcode_build_config.rb +46 -17
- data/lib/pindo/module/xcode/xcode_build_helper.rb +186 -25
- data/lib/pindo/module/xcode/xcode_project_helper.rb +1 -1
- data/lib/pindo/module/xcode/xcode_res_helper.rb +32 -16
- data/lib/pindo/options/groups/build_options.rb +5 -5
- data/lib/pindo/options/groups/git_options.rb +7 -5
- data/lib/pindo/options/groups/unity_options.rb +11 -0
- data/lib/pindo/options/helpers/bundleid_selector.rb +25 -0
- data/lib/pindo/options/helpers/git_constants.rb +7 -6
- data/lib/pindo/version.rb +3 -3
- metadata +12 -7
|
@@ -166,8 +166,8 @@ module Pindo
|
|
|
166
166
|
puts
|
|
167
167
|
puts "选择的bundle id是: #{menu_choice}"
|
|
168
168
|
puts
|
|
169
|
-
if menu_choice.
|
|
170
|
-
menu_choice =
|
|
169
|
+
if menu_choice.include?("*")
|
|
170
|
+
menu_choice = menu_choice.gsub(".*", "")
|
|
171
171
|
end
|
|
172
172
|
|
|
173
173
|
# 保存选择到 GlobalOptionsState
|
|
@@ -239,7 +239,7 @@ module Pindo
|
|
|
239
239
|
puts "选择的Bundle Name是: #{menu_choice}"
|
|
240
240
|
puts
|
|
241
241
|
|
|
242
|
-
# 去除通配符后缀(如 com.
|
|
242
|
+
# 去除通配符后缀(如 com.heroneverdie101.* -> com.heroneverdie101)
|
|
243
243
|
if menu_choice.end_with?(".*")
|
|
244
244
|
menu_choice = menu_choice.sub(/\.\*$/, '')
|
|
245
245
|
puts "去除通配符后的Bundle Name: #{menu_choice}"
|
|
@@ -277,7 +277,7 @@ module Pindo
|
|
|
277
277
|
puts "选择的Bundle Name是: #{menu_choice}"
|
|
278
278
|
puts
|
|
279
279
|
|
|
280
|
-
# 去除通配符后缀(如 com.
|
|
280
|
+
# 去除通配符后缀(如 com.heroneverdie101.* -> com.heroneverdie101)
|
|
281
281
|
if menu_choice.end_with?(".*")
|
|
282
282
|
menu_choice = menu_choice.sub(/\.\*$/, '')
|
|
283
283
|
puts "去除通配符后的Bundle Name: #{menu_choice}"
|
|
@@ -1,11 +1,69 @@
|
|
|
1
1
|
require 'spaceship'
|
|
2
2
|
require 'json'
|
|
3
|
+
require 'app_store_dev_api'
|
|
3
4
|
|
|
4
5
|
module Pindo
|
|
5
6
|
# Bundle ID 管理辅助类
|
|
6
7
|
# 负责在 Apple 开发者中心创建和配置 Bundle ID
|
|
7
8
|
class BundleIdHelper
|
|
8
9
|
|
|
10
|
+
# 根据 Bundle ID 生成显示名称
|
|
11
|
+
# 规则:去掉前两段(如 com.heroneverdie101),剩余部分去掉点号拼接
|
|
12
|
+
# @param bundle_id [String] Bundle ID 字符串
|
|
13
|
+
# @return [String] 显示名称
|
|
14
|
+
#
|
|
15
|
+
# 示例:
|
|
16
|
+
# "com.heroneverdie101.fancyapptest" => "fancyapptest"
|
|
17
|
+
# "com.heroneverdie101.fancyapptest.content" => "fancyapptestcontent"
|
|
18
|
+
# "com.heroneverdie101.fancyapptest.service" => "fancyapptestservice"
|
|
19
|
+
# "com.heroneverdie101.*" => "wildcarddevelopmentid"
|
|
20
|
+
def self.generate_bundleid_name(bundle_id)
|
|
21
|
+
return "wildcarddevelopmentid" if bundle_id.nil? || bundle_id.include?("*")
|
|
22
|
+
|
|
23
|
+
parts = bundle_id.split('.')
|
|
24
|
+
# 去掉前两段(如 com.heroneverdie101),剩余部分拼接
|
|
25
|
+
parts[2..].join('')
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# 通过 App Store Connect API 更新 Bundle ID 名称
|
|
29
|
+
# @param bundle_id [String] Bundle ID 字符串
|
|
30
|
+
# @param new_name [String] 新名称
|
|
31
|
+
def self.update_bundleid_name(bundle_id:, new_name:)
|
|
32
|
+
bundle_id_obj = Spaceship::ConnectAPI::BundleId.find(bundle_id)
|
|
33
|
+
return if bundle_id_obj.nil?
|
|
34
|
+
|
|
35
|
+
api_key_json = load_api_key_config
|
|
36
|
+
if api_key_json.nil?
|
|
37
|
+
puts "未配置 API Key,跳过名称更新"
|
|
38
|
+
return
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
client = AppStoreDevApi::Client.new(
|
|
42
|
+
issuer_id: api_key_json["issuer_id"],
|
|
43
|
+
key_id: api_key_json["key_id"],
|
|
44
|
+
private_key: api_key_json["private_key"]
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
client.update_bundle_id(id: bundle_id_obj.id, name: new_name)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# 加载 API Key 配置
|
|
51
|
+
# @return [Hash, nil] API Key 配置,包含 issuer_id、key_id、private_key
|
|
52
|
+
def self.load_api_key_config
|
|
53
|
+
pindo_dir = File.expand_path("~/.pindo")
|
|
54
|
+
api_key_file = File.join(pindo_dir, "api_key.json")
|
|
55
|
+
return nil unless File.exist?(api_key_file)
|
|
56
|
+
|
|
57
|
+
api_key_json = JSON.parse(File.read(api_key_file))
|
|
58
|
+
# 取第一个有效的 API Key 配置
|
|
59
|
+
api_key_json.each do |_apple_id, config|
|
|
60
|
+
if config.is_a?(Hash) && config["issuer_id"] && config["key_id"] && config["private_key"]
|
|
61
|
+
return config
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
nil
|
|
65
|
+
end
|
|
66
|
+
|
|
9
67
|
# 从配置文件中提取所有必要的信息
|
|
10
68
|
# @param config_json [Hash] 配置 JSON 对象
|
|
11
69
|
# @return [Hash] 提取的配置信息
|
|
@@ -106,17 +164,33 @@ module Pindo
|
|
|
106
164
|
app = Spaceship::Portal.app.find(bundle_id)
|
|
107
165
|
puts
|
|
108
166
|
|
|
167
|
+
display_name = generate_bundleid_name(bundle_id)
|
|
109
168
|
if app.nil?
|
|
110
|
-
puts "Create bundle id #{bundle_id} in apple developer center..."
|
|
111
|
-
app = Spaceship::Portal.app.create!(bundle_id: bundle_id, name:
|
|
169
|
+
puts "Create bundle id #{bundle_id} (#{display_name}) in apple developer center..."
|
|
170
|
+
app = Spaceship::Portal.app.create!(bundle_id: bundle_id, name: display_name)
|
|
112
171
|
else
|
|
113
172
|
puts "Find bundle id #{bundle_id} in apple developer center..."
|
|
173
|
+
# 更新名称
|
|
174
|
+
if app.name != display_name
|
|
175
|
+
puts "Update bundle id name: #{app.name} -> #{display_name}"
|
|
176
|
+
begin
|
|
177
|
+
app.update_name!(display_name)
|
|
178
|
+
rescue => e
|
|
179
|
+
puts "Portal 更新名称失败: #{e.message},尝试通过 API Key 更新..."
|
|
180
|
+
begin
|
|
181
|
+
update_bundleid_name(bundle_id: bundle_id, new_name: display_name)
|
|
182
|
+
rescue => e2
|
|
183
|
+
puts "更新名称失败: #{e2.message}"
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
end
|
|
114
187
|
end
|
|
115
188
|
|
|
116
189
|
bundle_id_obj = Spaceship::ConnectAPI::BundleId.find(bundle_id)
|
|
117
190
|
|
|
118
|
-
# 配置 Game Center
|
|
119
|
-
|
|
191
|
+
# 配置 Game Center(通配符 App ID 不支持 GAME_CENTER)
|
|
192
|
+
is_wildcard = bundle_id.include?("*")
|
|
193
|
+
if !bundle_id_obj.nil? && !is_wildcard
|
|
120
194
|
if !setting_array.nil? && setting_array.to_s.include?("game_center")
|
|
121
195
|
puts "Enable #{bundle_id} game_center on"
|
|
122
196
|
bundle_id_obj.update_capability("GAME_CENTER", enabled: true)
|
|
@@ -124,6 +198,8 @@ module Pindo
|
|
|
124
198
|
puts "Enable #{bundle_id} game_center off"
|
|
125
199
|
bundle_id_obj.update_capability("GAME_CENTER", enabled: false)
|
|
126
200
|
end
|
|
201
|
+
elsif is_wildcard
|
|
202
|
+
puts "Skip #{bundle_id} game_center (wildcard App ID not supported)"
|
|
127
203
|
end
|
|
128
204
|
|
|
129
205
|
return nil if setting_array.nil? || setting_array.length == 0
|
|
@@ -146,14 +222,18 @@ module Pindo
|
|
|
146
222
|
puts "Enable #{bundle_id} siri off"
|
|
147
223
|
end
|
|
148
224
|
|
|
149
|
-
# 配置 Sign with Apple
|
|
150
|
-
if !
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
225
|
+
# 配置 Sign with Apple(通配符 App ID 不支持)
|
|
226
|
+
if !is_wildcard && !bundle_id_obj.nil?
|
|
227
|
+
if setting_array.to_s.include?("apple_signin")
|
|
228
|
+
puts "Enable #{bundle_id} Sign with Apple on"
|
|
229
|
+
settings = build_settings_for(settings_key: "APPLE_ID_AUTH_APP_CONSENT", options_key: "PRIMARY_APP_CONSENT")
|
|
230
|
+
bundle_id_obj.update_capability("APPLE_ID_AUTH", enabled: true, settings: settings)
|
|
231
|
+
else
|
|
232
|
+
puts "Enable #{bundle_id} Sign with Apple off"
|
|
233
|
+
bundle_id_obj.update_capability("APPLE_ID_AUTH", enabled: false)
|
|
234
|
+
end
|
|
235
|
+
elsif is_wildcard
|
|
236
|
+
puts "Skip #{bundle_id} Sign with Apple (wildcard App ID not supported)"
|
|
157
237
|
end
|
|
158
238
|
|
|
159
239
|
# 配置 App Group
|
|
@@ -190,7 +270,7 @@ module Pindo
|
|
|
190
270
|
|
|
191
271
|
if app_group.nil?
|
|
192
272
|
puts "Create group_id #{group_id} in apple developer center..."
|
|
193
|
-
app_group = Spaceship::Portal.app_group.create!(group_id: group_id, name: group_id
|
|
273
|
+
app_group = Spaceship::Portal.app_group.create!(group_id: group_id, name: generate_bundleid_name(group_id))
|
|
194
274
|
else
|
|
195
275
|
puts "Group_id #{group_id} is existed in apple developer center !!!"
|
|
196
276
|
end
|
|
@@ -209,7 +289,7 @@ module Pindo
|
|
|
209
289
|
|
|
210
290
|
if app_icloud.nil?
|
|
211
291
|
puts "Create icloud_id #{icloud_id} in apple developer center..."
|
|
212
|
-
app_icloud = Spaceship::Portal.cloud_container.create!(identifier: icloud_id, name: icloud_id
|
|
292
|
+
app_icloud = Spaceship::Portal.cloud_container.create!(identifier: icloud_id, name: generate_bundleid_name(icloud_id))
|
|
213
293
|
else
|
|
214
294
|
puts "icloud_id #{icloud_id} is existed in apple developer center !!!"
|
|
215
295
|
end
|
|
@@ -349,5 +429,115 @@ module Pindo
|
|
|
349
429
|
end
|
|
350
430
|
end
|
|
351
431
|
|
|
432
|
+
# 从 Apple Developer Portal 读取指定 Bundle ID 的 Capability 状态
|
|
433
|
+
# @param bundle_id [String] Bundle ID 字符串
|
|
434
|
+
# @return [Hash, nil] capabilities 对象,Bundle ID 不存在时返回 nil
|
|
435
|
+
def self.fetch_capabilities_from_portal(bundle_id:)
|
|
436
|
+
return nil if bundle_id.nil? || bundle_id.empty?
|
|
437
|
+
|
|
438
|
+
# 通过 Spaceship Portal 查找 Bundle ID
|
|
439
|
+
app = Spaceship::Portal.app.find(bundle_id)
|
|
440
|
+
if app.nil?
|
|
441
|
+
puts "Bundle ID #{bundle_id} 在 Apple Developer Portal 中未找到"
|
|
442
|
+
return nil
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
# 更新 Bundle ID 名称
|
|
446
|
+
expected_name = generate_bundleid_name(bundle_id)
|
|
447
|
+
if app.name != expected_name
|
|
448
|
+
puts "Update bundle id name: #{app.name} -> #{expected_name}"
|
|
449
|
+
begin
|
|
450
|
+
app.update_name!(expected_name)
|
|
451
|
+
rescue => e
|
|
452
|
+
puts "Portal 更新名称失败: #{e.message},尝试通过 API Key 更新..."
|
|
453
|
+
begin
|
|
454
|
+
update_bundleid_name(bundle_id: bundle_id, new_name: expected_name)
|
|
455
|
+
rescue => e2
|
|
456
|
+
puts "更新名称失败: #{e2.message}"
|
|
457
|
+
end
|
|
458
|
+
end
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
capabilities = {}
|
|
462
|
+
|
|
463
|
+
# --- Spaceship Portal 侧:读取 features/services ---
|
|
464
|
+
begin
|
|
465
|
+
app_details = app.details
|
|
466
|
+
features = app_details.features
|
|
467
|
+
|
|
468
|
+
# Push Notification
|
|
469
|
+
push_enabled = features["push"] == true || features["push"].to_s == "true"
|
|
470
|
+
capabilities["push_notification"] = push_enabled
|
|
471
|
+
|
|
472
|
+
# App Group
|
|
473
|
+
app_group_enabled = features["APG3427HIY"] == true || features["appGroup"] == true ||
|
|
474
|
+
features["APG3427HIY"].to_s == "true" || features["appGroup"].to_s == "true"
|
|
475
|
+
if app_group_enabled
|
|
476
|
+
groups = app_details.associated_groups rescue []
|
|
477
|
+
if groups && !groups.empty?
|
|
478
|
+
capabilities["app_group"] = groups.first.group_id
|
|
479
|
+
else
|
|
480
|
+
capabilities["app_group"] = true
|
|
481
|
+
end
|
|
482
|
+
else
|
|
483
|
+
capabilities["app_group"] = false
|
|
484
|
+
end
|
|
485
|
+
|
|
486
|
+
# iCloud
|
|
487
|
+
icloud_enabled = features["cloudKitVersion"] == 2 || features["iCloud"] == true ||
|
|
488
|
+
features["cloudKitVersion"].to_i > 0 || features["iCloud"].to_s == "true"
|
|
489
|
+
if icloud_enabled
|
|
490
|
+
containers = app_details.associated_cloud_containers rescue []
|
|
491
|
+
if containers && !containers.empty?
|
|
492
|
+
capabilities["icloud"] = containers.first.identifier
|
|
493
|
+
else
|
|
494
|
+
capabilities["icloud"] = true
|
|
495
|
+
end
|
|
496
|
+
else
|
|
497
|
+
capabilities["icloud"] = false
|
|
498
|
+
end
|
|
499
|
+
|
|
500
|
+
# Siri
|
|
501
|
+
siri_enabled = features["SI015DKUHP"] == true || features["siriKit"] == true ||
|
|
502
|
+
features["SI015DKUHP"].to_s == "true" || features["siriKit"].to_s == "true"
|
|
503
|
+
capabilities["siri"] = siri_enabled
|
|
504
|
+
|
|
505
|
+
# In-App Purchase
|
|
506
|
+
iap_enabled = features["inAppPurchase"] == true || features["inAppPurchase"].to_s == "true"
|
|
507
|
+
capabilities["in_app_purchase"] = iap_enabled
|
|
508
|
+
|
|
509
|
+
rescue => e
|
|
510
|
+
puts "读取 Portal features 失败: #{e.message},尝试通过 ConnectAPI 读取..."
|
|
511
|
+
end
|
|
512
|
+
|
|
513
|
+
# --- ConnectAPI 侧:补充 game_center 和 apple_signin ---
|
|
514
|
+
begin
|
|
515
|
+
bundle_id_obj = Spaceship::ConnectAPI::BundleId.find(bundle_id)
|
|
516
|
+
if bundle_id_obj
|
|
517
|
+
api_capabilities = bundle_id_obj.get_capabilities
|
|
518
|
+
|
|
519
|
+
capabilities["game_center"] = api_capabilities.any? { |c| c.is_type?("GAME_CENTER") } rescue false
|
|
520
|
+
capabilities["apple_signin"] = api_capabilities.any? { |c| c.is_type?("APPLE_ID_AUTH") } rescue false
|
|
521
|
+
|
|
522
|
+
# 如果 Portal 侧读取失败,用 ConnectAPI 补充
|
|
523
|
+
if !capabilities.key?("push_notification")
|
|
524
|
+
capabilities["push_notification"] = api_capabilities.any? { |c| c.is_type?("PUSH_NOTIFICATIONS") } rescue false
|
|
525
|
+
end
|
|
526
|
+
if !capabilities.key?("in_app_purchase")
|
|
527
|
+
capabilities["in_app_purchase"] = api_capabilities.any? { |c| c.is_type?("IN_APP_PURCHASE") } rescue false
|
|
528
|
+
end
|
|
529
|
+
if !capabilities.key?("siri")
|
|
530
|
+
capabilities["siri"] = api_capabilities.any? { |c| c.is_type?("SIRIKIT") } rescue false
|
|
531
|
+
end
|
|
532
|
+
end
|
|
533
|
+
rescue => e
|
|
534
|
+
puts "读取 ConnectAPI capabilities 失败: #{e.message}"
|
|
535
|
+
capabilities["game_center"] ||= false
|
|
536
|
+
capabilities["apple_signin"] ||= false
|
|
537
|
+
end
|
|
538
|
+
|
|
539
|
+
capabilities
|
|
540
|
+
end
|
|
541
|
+
|
|
352
542
|
end
|
|
353
543
|
end
|
|
@@ -191,28 +191,94 @@ module Pindo
|
|
|
191
191
|
)
|
|
192
192
|
end
|
|
193
193
|
|
|
194
|
-
#
|
|
194
|
+
# 定位 JPSBuildConfig.json 文件路径
|
|
195
|
+
# 先找 git root,再判断是否 Unity 项目来确定配置文件位置
|
|
196
|
+
# @param working_dir [String] 当前工作目录
|
|
197
|
+
# @return [String] 配置文件绝对路径
|
|
198
|
+
def determine_jps_config_path(working_dir)
|
|
199
|
+
# 获取 Git 仓库根目录
|
|
200
|
+
repo_root_dir = nil
|
|
201
|
+
if Pindo::GitHandler.is_git_directory?(local_repo_dir: working_dir)
|
|
202
|
+
repo_root_dir = Pindo::GitHandler.git_root_directory(local_repo_dir: working_dir)
|
|
203
|
+
end
|
|
204
|
+
repo_root_dir ||= working_dir
|
|
205
|
+
|
|
206
|
+
# 判断工程类型
|
|
207
|
+
if File.directory?(File.join(repo_root_dir, 'ProjectSettings'))
|
|
208
|
+
File.join(repo_root_dir, 'ProjectSettings', 'JPSBuildConfig.json')
|
|
209
|
+
else
|
|
210
|
+
File.join(repo_root_dir, 'JPSBuildConfig.json')
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
# 加载 JPSBuildConfig.json,设置全局状态,缺失字段时通过 JPS 请求补全
|
|
195
215
|
# @param project_dir [String] 项目目录
|
|
196
|
-
# @
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
config_file = if
|
|
200
|
-
File.
|
|
216
|
+
# @param conf [String, nil] 显式指定的配置文件路径(优先于自动查找)
|
|
217
|
+
# @return [Hash, nil] JPSBuildConfig 的完整配置,文件不存在时返回 nil
|
|
218
|
+
def load_jps_build_config(project_dir, conf = nil, **_)
|
|
219
|
+
config_file = if conf && !conf.to_s.empty?
|
|
220
|
+
File.expand_path(conf)
|
|
201
221
|
else
|
|
202
|
-
|
|
222
|
+
determine_jps_config_path(project_dir)
|
|
203
223
|
end
|
|
204
224
|
|
|
205
225
|
return nil unless File.exist?(config_file)
|
|
206
226
|
|
|
207
227
|
begin
|
|
208
228
|
config = JSON.parse(File.read(config_file))
|
|
229
|
+
state = Pindo::Options::GlobalOptionsState.instance
|
|
230
|
+
|
|
209
231
|
project_name = config['project_name']
|
|
210
232
|
if project_name && !project_name.empty?
|
|
211
|
-
|
|
212
|
-
Pindo::Options::GlobalOptionsState.instance[:proj] = project_name
|
|
233
|
+
state[:proj] = project_name
|
|
213
234
|
puts "使用 JPS 配置的项目名称: #{project_name}"
|
|
214
|
-
return project_name
|
|
215
235
|
end
|
|
236
|
+
|
|
237
|
+
# 检查 wildcard_bundle_group_name 和 bundle_group_name(兼容旧字段名)
|
|
238
|
+
wildcard_bundle_group_name = config['wildcard_bundle_group_name'] || config['wildcardBundleId']
|
|
239
|
+
bundle_group_name = config['bundle_group_name'] || config['bundleId']
|
|
240
|
+
|
|
241
|
+
# 如果缺失,通过 JPS 请求获取并回写
|
|
242
|
+
if (wildcard_bundle_group_name.nil? || wildcard_bundle_group_name.empty?) ||
|
|
243
|
+
(bundle_group_name.nil? || bundle_group_name.empty?)
|
|
244
|
+
project_id = config['project_id']
|
|
245
|
+
app_info_data = nil
|
|
246
|
+
|
|
247
|
+
if project_id && !project_id.to_s.empty?
|
|
248
|
+
app_info_data = PgyerHelper.share_instace.get_project_detail(project_id: project_id)
|
|
249
|
+
elsif project_name && !project_name.empty?
|
|
250
|
+
app_info_data = PgyerHelper.share_instace.find_app_info_with_obj_list(proj_name: project_name)
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
if app_info_data
|
|
254
|
+
wildcard_bundle_group_name = app_info_data["wildcardBundleId"]
|
|
255
|
+
bundle_group_name = app_info_data["bundleId"]
|
|
256
|
+
|
|
257
|
+
if wildcard_bundle_group_name && !wildcard_bundle_group_name.empty?
|
|
258
|
+
config['wildcard_bundle_group_name'] = wildcard_bundle_group_name
|
|
259
|
+
config['bundle_group_name'] = bundle_group_name
|
|
260
|
+
File.write(config_file, JSON.pretty_generate(config) + "\n")
|
|
261
|
+
puts "已从 JPS 获取并保存: wildcard_bundle_group_name=#{wildcard_bundle_group_name}, bundle_group_name=#{bundle_group_name}"
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
# 设置全局状态
|
|
267
|
+
if wildcard_bundle_group_name && !wildcard_bundle_group_name.empty?
|
|
268
|
+
state[:wildcard_bundle_group_name] = wildcard_bundle_group_name
|
|
269
|
+
state[:bundle_group_name] = bundle_group_name
|
|
270
|
+
|
|
271
|
+
# 通过映射表将 wildcard_bundle_group_name 解析为真实 bundle_id
|
|
272
|
+
require 'pindo/options/helpers/bundleid_selector'
|
|
273
|
+
resolved_bundle_id = Pindo::Options::BundleIdSelector.resolve_bundleid_by_group_name(wildcard_bundle_group_name)
|
|
274
|
+
if resolved_bundle_id && !resolved_bundle_id.empty?
|
|
275
|
+
state[:bundleid] = resolved_bundle_id # iOS 使用
|
|
276
|
+
state[:bundle_name] = resolved_bundle_id # Android 使用
|
|
277
|
+
puts "使用 JPSBuildConfig 的 Bundle Name: #{resolved_bundle_id} (#{wildcard_bundle_group_name})"
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
return config
|
|
216
282
|
rescue => e
|
|
217
283
|
puts "加载 JPSBuildConfig.json 失败: #{e.message}" if ENV['PINDO_VERBOSE'] == '1'
|
|
218
284
|
end
|
|
@@ -347,7 +347,7 @@ module Pindo
|
|
|
347
347
|
# 删除旧 tag(本地和远程)
|
|
348
348
|
if Pindo::GitHandler.remote_tag_exists?(local_repo_dir: project_dir, tag_name: tag_name)
|
|
349
349
|
Funlog.instance.fancyinfo_update("删除远程 Tag: #{tag_name}")
|
|
350
|
-
Pindo::GitHandler.
|
|
350
|
+
Pindo::GitHandler.git_remote!(project_dir, %W(-C #{project_dir} push origin :refs/tags/#{tag_name}))
|
|
351
351
|
end
|
|
352
352
|
if Pindo::GitHandler.local_tag_exists?(local_repo_dir: project_dir, tag_name: tag_name)
|
|
353
353
|
Funlog.instance.fancyinfo_update("删除本地 Tag: #{tag_name}")
|
|
@@ -361,7 +361,7 @@ module Pindo
|
|
|
361
361
|
if local_exists && Pindo::GitHandler.is_tag_at_head?(git_root_dir: project_dir, tag_name: tag_name)
|
|
362
362
|
if !remote_exists
|
|
363
363
|
# 本地存在且在 HEAD,但远程不存在,推送到远程
|
|
364
|
-
Pindo::GitHandler.
|
|
364
|
+
Pindo::GitHandler.git_remote!(project_dir, %W(-C #{project_dir} push origin #{tag_name}))
|
|
365
365
|
Funlog.instance.fancyinfo_success("推送 Tag 到远程: #{tag_name}")
|
|
366
366
|
else
|
|
367
367
|
Funlog.instance.fancyinfo_success("Tag 已存在且在 HEAD: #{tag_name}")
|
|
@@ -372,7 +372,7 @@ module Pindo
|
|
|
372
372
|
# tag 不在 HEAD 上,需要删除后重新创建
|
|
373
373
|
if remote_exists
|
|
374
374
|
Funlog.instance.fancyinfo_update("删除远程 Tag: #{tag_name}")
|
|
375
|
-
Pindo::GitHandler.
|
|
375
|
+
Pindo::GitHandler.git_remote!(project_dir, %W(-C #{project_dir} push origin :refs/tags/#{tag_name}))
|
|
376
376
|
end
|
|
377
377
|
if local_exists
|
|
378
378
|
Funlog.instance.fancyinfo_update("删除本地 Tag: #{tag_name}")
|
|
@@ -383,7 +383,7 @@ module Pindo
|
|
|
383
383
|
|
|
384
384
|
# 创建并推送 tag
|
|
385
385
|
Pindo::GitHandler.git!(%W(-C #{project_dir} tag #{tag_name}))
|
|
386
|
-
Pindo::GitHandler.
|
|
386
|
+
Pindo::GitHandler.git_remote!(project_dir, %W(-C #{project_dir} push origin #{tag_name}))
|
|
387
387
|
Funlog.instance.fancyinfo_success("创建并推送 Tag: #{tag_name}")
|
|
388
388
|
tag_name
|
|
389
389
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require 'pindo/module/xcode/xcode_build_helper'
|
|
2
|
+
|
|
1
3
|
module Pindo
|
|
2
4
|
module CertProcess
|
|
3
5
|
|
|
@@ -234,6 +236,8 @@ module Pindo
|
|
|
234
236
|
project = Xcodeproj::Project.open(proj_fullname)
|
|
235
237
|
|
|
236
238
|
project.targets.each do |target|
|
|
239
|
+
# 跳过非 native target(如 PBXAggregateTarget)
|
|
240
|
+
next unless target.respond_to?(:product_type)
|
|
237
241
|
# 跳过 framework、library 等类型
|
|
238
242
|
if target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:framework]) ||
|
|
239
243
|
target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:dynamic_library]) ||
|
|
@@ -286,6 +290,8 @@ module Pindo
|
|
|
286
290
|
target_map = get_target_name_map
|
|
287
291
|
|
|
288
292
|
project.targets.each do |target|
|
|
293
|
+
# 跳过非 native target(如 PBXAggregateTarget)
|
|
294
|
+
next unless target.respond_to?(:product_type)
|
|
289
295
|
# 跳过 framework、library 等类型
|
|
290
296
|
if target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:framework]) ||
|
|
291
297
|
target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:dynamic_library]) ||
|
|
@@ -346,7 +352,7 @@ module Pindo
|
|
|
346
352
|
end
|
|
347
353
|
|
|
348
354
|
# 设置 Bundle ID(跳过通配符)
|
|
349
|
-
unless provisioning_info["bundle_id"].
|
|
355
|
+
unless provisioning_info["bundle_id"].include?("*")
|
|
350
356
|
config.build_settings['PRODUCT_BUNDLE_IDENTIFIER'] = provisioning_info["bundle_id"]
|
|
351
357
|
end
|
|
352
358
|
end
|
|
@@ -401,13 +407,13 @@ module Pindo
|
|
|
401
407
|
|
|
402
408
|
# 配置 Info.plist 文件
|
|
403
409
|
def configure_info_plist_file(target, project_dir, icloud_id)
|
|
404
|
-
|
|
405
|
-
return if
|
|
410
|
+
raw_path = target.build_configurations.first.build_settings['INFOPLIST_FILE']
|
|
411
|
+
return if raw_path.nil? || raw_path.empty?
|
|
406
412
|
|
|
407
|
-
info_plist_path =
|
|
413
|
+
info_plist_path = Pindo::XcodeBuildHelper.resolve_info_plist_path(project_dir, raw_path, target: target)
|
|
408
414
|
|
|
409
|
-
unless
|
|
410
|
-
raise Informative, "Missing Target #{target.name} Info.plist!!! #{
|
|
415
|
+
unless info_plist_path
|
|
416
|
+
raise Informative, "Missing Target #{target.name} Info.plist!!! #{raw_path}"
|
|
411
417
|
end
|
|
412
418
|
|
|
413
419
|
# 标准化 CFBundleIdentifier 为宏变量
|