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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/lib/pindo/base/git_handler.rb +120 -38
  3. data/lib/pindo/command/android/autobuild.rb +92 -31
  4. data/lib/pindo/command/appstore/adhocbuild.rb +1 -1
  5. data/lib/pindo/command/appstore/autobuild.rb +1 -1
  6. data/lib/pindo/command/appstore/autoresign.rb +1 -1
  7. data/lib/pindo/command/appstore/updateid.rb +229 -0
  8. data/lib/pindo/command/appstore.rb +1 -0
  9. data/lib/pindo/command/ios/autobuild.rb +70 -33
  10. data/lib/pindo/command/ios/podpush.rb +1 -1
  11. data/lib/pindo/command/unity/autobuild.rb +38 -18
  12. data/lib/pindo/command/utils/allcopyconfig.rb +144 -0
  13. data/lib/pindo/command/utils/copyconfig.rb +207 -0
  14. data/lib/pindo/command/utils/icon.rb +2 -2
  15. data/lib/pindo/command/utils/renewbundleid.rb +199 -0
  16. data/lib/pindo/command/utils/renewcert.rb +56 -54
  17. data/lib/pindo/command/utils.rb +3 -0
  18. data/lib/pindo/command/web/autobuild.rb +10 -8
  19. data/lib/pindo/config/build_info_manager.rb +1 -3
  20. data/lib/pindo/module/android/android_build_helper.rb +198 -33
  21. data/lib/pindo/module/android/android_config_helper.rb +305 -88
  22. data/lib/pindo/module/android/android_project_helper.rb +124 -14
  23. data/lib/pindo/module/android/android_res_helper.rb +349 -51
  24. data/lib/pindo/module/android/keystore_helper.rb +611 -295
  25. data/lib/pindo/module/android/workflow_gradle_injector.rb +702 -0
  26. data/lib/pindo/module/appselect.rb +4 -4
  27. data/lib/pindo/module/appstore/bundleid_helper.rb +204 -14
  28. data/lib/pindo/module/build/build_helper.rb +76 -10
  29. data/lib/pindo/module/build/git_repo_helper.rb +4 -4
  30. data/lib/pindo/module/cert/mode/base_cert_operator.rb +12 -6
  31. data/lib/pindo/module/pgyer/pgyerhelper.rb +124 -39
  32. data/lib/pindo/module/task/model/build/android_build_dev_task.rb +64 -6
  33. data/lib/pindo/module/task/model/git/git_commit_task.rb +70 -54
  34. data/lib/pindo/module/task/model/git/git_tag_task.rb +13 -9
  35. data/lib/pindo/module/task/model/jps/jps_upload_task.rb +110 -3
  36. data/lib/pindo/module/task/model/unity/unity_export_task.rb +2 -1
  37. data/lib/pindo/module/task/model/unity/unity_update_task.rb +2 -1
  38. data/lib/pindo/module/task/model/unity/unity_yoo_asset_task.rb +2 -1
  39. data/lib/pindo/module/task/model/unity_task.rb +2 -1
  40. data/lib/pindo/module/unity/unity_helper.rb +13 -10
  41. data/lib/pindo/module/unity/unity_proc_helper.rb +27 -2
  42. data/lib/pindo/module/xcode/applovin_xcode_helper.rb +6 -2
  43. data/lib/pindo/module/xcode/res/xcode_res_constant.rb +72 -0
  44. data/lib/pindo/module/xcode/res/xcode_res_handler.rb +3 -3
  45. data/lib/pindo/module/xcode/xcode_build_config.rb +46 -17
  46. data/lib/pindo/module/xcode/xcode_build_helper.rb +186 -25
  47. data/lib/pindo/module/xcode/xcode_project_helper.rb +1 -1
  48. data/lib/pindo/module/xcode/xcode_res_helper.rb +32 -16
  49. data/lib/pindo/options/groups/build_options.rb +5 -5
  50. data/lib/pindo/options/groups/git_options.rb +7 -5
  51. data/lib/pindo/options/groups/unity_options.rb +11 -0
  52. data/lib/pindo/options/helpers/bundleid_selector.rb +25 -0
  53. data/lib/pindo/options/helpers/git_constants.rb +7 -6
  54. data/lib/pindo/version.rb +3 -3
  55. metadata +12 -7
@@ -9,6 +9,7 @@ require 'pindo/config/pindoconfig'
9
9
  require 'pindo/config/pindouserlocalconfig'
10
10
  require 'pindo/base/funlog'
11
11
  require 'pindo/base/git_handler'
12
+ require 'pindo/module/build/build_helper'
12
13
 
13
14
 
14
15
  module Pindo
@@ -394,7 +395,7 @@ module Pindo
394
395
  config_path = if conf && !conf.empty?
395
396
  File.expand_path(conf)
396
397
  else
397
- determine_config_file_path(working_directory)
398
+ Pindo::BuildHelper.share_instance.determine_jps_config_path(working_directory)
398
399
  end
399
400
 
400
401
  upload_proj_name = nil
@@ -462,7 +463,7 @@ module Pindo
462
463
  return app_info_obj, workflow_info
463
464
  end
464
465
 
465
- def prepare_upload(working_directory:nil, conf:nil, package_type:nil, manage_type: "")
466
+ def prepare_upload(working_directory:nil, conf:nil, package_type:nil, manage_type: "", bundle_name: nil)
466
467
  working_directory ||= Dir.pwd
467
468
 
468
469
  if ENV['PINDO_DEBUG']
@@ -477,7 +478,7 @@ module Pindo
477
478
  config_path = if conf && !conf.empty?
478
479
  File.expand_path(conf)
479
480
  else
480
- determine_config_file_path(working_directory)
481
+ Pindo::BuildHelper.share_instance.determine_jps_config_path(working_directory)
481
482
  end
482
483
 
483
484
  puts "[PINDO_DEBUG] 使用配置文件: #{config_path}" if ENV['PINDO_DEBUG']
@@ -509,8 +510,14 @@ module Pindo
509
510
  end
510
511
 
511
512
  puts "[PINDO_DEBUG] 正在查找项目: #{config_result[:project_name]}" if ENV['PINDO_DEBUG']
513
+ lookup_bundle_id = resolve_lookup_bundle_id(
514
+ bundle_name: bundle_name,
515
+ workflow_info: config_result[:workflow_info]
516
+ )
517
+ puts "[PINDO_DEBUG] bundle_id 查找键: #{lookup_bundle_id.inspect}" if ENV['PINDO_DEBUG']
512
518
  app_info_obj = find_app_info_with_obj_list(
513
- proj_name: config_result[:project_name]
519
+ proj_name: config_result[:project_name],
520
+ bundle_id: lookup_bundle_id
514
521
  )
515
522
 
516
523
  if app_info_obj
@@ -746,6 +753,28 @@ module Pindo
746
753
  Dir.chdir(current_project_dir)
747
754
  ipa_file_upload = web_res_zip_fullname
748
755
  end
756
+ if !ipa_file_upload.nil? &&
757
+ File.extname(ipa_file_upload).downcase.eql?(".exe")
758
+
759
+ windows_exe_path = File.expand_path(ipa_file_upload)
760
+ windows_build_dir = File.dirname(windows_exe_path)
761
+ windows_zip_dir = File.dirname(windows_build_dir)
762
+ windows_build_name = File.basename(windows_exe_path, File.extname(windows_exe_path))
763
+ windows_exe_name = File.basename(windows_exe_path)
764
+ windows_zip_fullname = File.join(windows_zip_dir, windows_build_name + ".zip")
765
+
766
+ if File.exist?(windows_zip_fullname)
767
+ FileUtils.rm_rf(windows_zip_fullname)
768
+ end
769
+
770
+ current_project_dir = Dir.pwd
771
+ Zip::File.open(windows_zip_fullname, Zip::File::CREATE) do |zipfile|
772
+ Dir.chdir windows_build_dir
773
+ zipfile.add(windows_exe_name, windows_exe_name)
774
+ end
775
+ Dir.chdir(current_project_dir)
776
+ ipa_file_upload = windows_zip_fullname
777
+ end
749
778
  unless !ipa_file_upload.nil? && File.exist?(ipa_file_upload)
750
779
  return
751
780
  end
@@ -1321,9 +1350,19 @@ module Pindo
1321
1350
 
1322
1351
  end
1323
1352
 
1324
- def find_app_info_with_obj_list(proj_name:nil)
1353
+ # 通过 project_id 获取项目详情(轻量接口,比 find_app_info_with_obj_list 更快)
1354
+ # @param project_id [String] 项目ID
1355
+ # @return [Hash, nil] 项目信息对象
1356
+ def get_project_detail(project_id:)
1357
+ return nil if project_id.nil? || project_id.to_s.empty?
1358
+
1359
+ result = @pgyer_client.get_project_detail(project_id: project_id)
1360
+ result&.dig("data")
1361
+ end
1325
1362
 
1326
- if proj_name.nil?
1363
+ def find_app_info_with_obj_list(proj_name:nil, bundle_id:nil)
1364
+
1365
+ if proj_name.nil? && bundle_id.nil?
1327
1366
  return nil
1328
1367
  end
1329
1368
 
@@ -1331,13 +1370,24 @@ module Pindo
1331
1370
 
1332
1371
  get_app_list_in_pgyer()
1333
1372
 
1334
- key_proj_name = proj_name.downcase.strip.gsub(/[\s\-_]/, '')
1373
+ key_proj_name = proj_name&.downcase&.strip&.gsub(/[\s\-_]/, '')
1374
+ key_bundle_id = bundle_id&.downcase&.strip
1335
1375
 
1336
1376
  app_info_list = Pindoconfig.instance.get_pgyerapps_info_list()
1337
- app_info_obj = app_info_list&.find do |app_info_item|
1377
+ app_info_obj = nil
1378
+ if key_bundle_id && !key_bundle_id.empty?
1379
+ app_info_obj = app_info_list&.find do |app_info_item|
1380
+ app_info_bundle_id = app_info_item["bundleId"].to_s.downcase.strip
1381
+ app_info_bundle_id.eql?(key_bundle_id)
1382
+ end
1383
+ end
1384
+
1385
+ if app_info_obj.nil? && key_proj_name && !key_proj_name.empty?
1386
+ app_info_obj = app_info_list&.find do |app_info_item|
1338
1387
  # 新 API 使用 projectName 字段
1339
1388
  app_info_item_name = app_info_item["projectName"].to_s.downcase.strip.gsub(/[\s\-_]/, '')
1340
1389
  app_info_item_name.eql?(key_proj_name)
1390
+ end
1341
1391
  end
1342
1392
 
1343
1393
  Funlog.instance.fancyinfo_success("拉取app信息列表完成,app信息获取成功!")
@@ -1345,6 +1395,31 @@ module Pindo
1345
1395
  app_info_obj
1346
1396
  end
1347
1397
 
1398
+ def wildcard_android_bundle_name?(bundle_name)
1399
+ return false if bundle_name.nil? || bundle_name.empty?
1400
+
1401
+ bundle_name.include?('*') ||
1402
+ bundle_name.end_with?('.') ||
1403
+ ['com.test', 'com.example', 'com.demo', 'com.heroneverdie101'].include?(bundle_name)
1404
+ end
1405
+
1406
+ def resolve_lookup_bundle_id(bundle_name:, workflow_info:)
1407
+ return nil if bundle_name.nil? || bundle_name.empty?
1408
+
1409
+ if wildcard_android_bundle_name?(bundle_name)
1410
+ package_name = workflow_info && workflow_info[:package_name]
1411
+ return nil if package_name.nil? || package_name.empty?
1412
+
1413
+ prefix = bundle_name.sub(/\.\*$/, '').sub(/\.$/, '')
1414
+ return nil if prefix.empty?
1415
+
1416
+ package_suffix = package_name.to_s.gsub(/[^a-zA-Z0-9]/, '').downcase
1417
+ return "#{prefix}.#{package_suffix}"
1418
+ end
1419
+
1420
+ bundle_name
1421
+ end
1422
+
1348
1423
  def get_app_version(projectId:nil, app_version_index:nil, latest_version:true, package_type:nil)
1349
1424
 
1350
1425
  params = {}
@@ -1869,28 +1944,6 @@ module Pindo
1869
1944
 
1870
1945
  private
1871
1946
 
1872
- # 确定 JPSBuildConfig.json 文件路径
1873
- # Unity 工程:仓库根目录/ProjectSettings/JPSBuildConfig.json
1874
- # iOS/Android 工程:仓库根目录/JPSBuildConfig.json
1875
- #
1876
- # @param working_directory [String] 工作目录
1877
- # @return [String] 配置文件完整路径
1878
- def determine_config_file_path(working_directory)
1879
- # 获取 Git 仓库根目录
1880
- repo_root_dir = nil
1881
- if Pindo::GitHandler.is_git_directory?(local_repo_dir: working_directory)
1882
- repo_root_dir = Pindo::GitHandler.git_root_directory(local_repo_dir: working_directory)
1883
- end
1884
- repo_root_dir ||= working_directory
1885
-
1886
- # 判断工程类型
1887
- if File.directory?(File.join(repo_root_dir, 'ProjectSettings'))
1888
- File.join(repo_root_dir, 'ProjectSettings', 'JPSBuildConfig.json')
1889
- else
1890
- File.join(repo_root_dir, 'JPSBuildConfig.json')
1891
- end
1892
- end
1893
-
1894
1947
  # 验证工作流配置是否有效
1895
1948
  #
1896
1949
  # @param workflow [Hash] 工作流配置对象
@@ -1925,13 +1978,17 @@ module Pindo
1925
1978
  # @param project_id [String] 项目ID
1926
1979
  # @param project_name [String] 项目名称
1927
1980
  # @param project_scheme [String] 项目scheme
1981
+ # @param bundle_group_name [String, nil] 非通配符组名(来自 API bundleId)
1982
+ # @param wildcard_bundle_group_name [String, nil] 通配符组名(来自 API wildcardBundleId)
1928
1983
  # @param workflow_key [String] 工作流键名
1929
1984
  # @param workflow_data [Hash] 工作流数据
1930
- def create_new_config(config_file, project_id, project_name, project_scheme, workflow_key, workflow_data)
1985
+ def create_new_config(config_file:, project_id:, project_name:, project_scheme:, bundle_group_name: nil, wildcard_bundle_group_name: nil, workflow_key:, workflow_data:)
1931
1986
  new_config = {
1932
1987
  "project_name" => project_name,
1933
1988
  "project_scheme" => project_scheme,
1934
1989
  "project_id" => project_id,
1990
+ "bundle_group_name" => bundle_group_name,
1991
+ "wildcard_bundle_group_name" => wildcard_bundle_group_name,
1935
1992
  workflow_key => workflow_data
1936
1993
  }
1937
1994
 
@@ -1954,7 +2011,7 @@ module Pindo
1954
2011
  return if working_directory.nil? || app_info_obj.nil? || workflow_info.nil?
1955
2012
 
1956
2013
  # 1. 确定配置文件路径
1957
- config_file = determine_config_file_path(working_directory)
2014
+ config_file = Pindo::BuildHelper.share_instance.determine_jps_config_path(working_directory)
1958
2015
 
1959
2016
  # 2. 根据 manage_type 或 package_type 确定 workflow_key
1960
2017
  workflow_key = nil
@@ -1976,6 +2033,8 @@ module Pindo
1976
2033
  # 3. 准备新的项目基础信息
1977
2034
  new_project_id = app_info_obj["id"]
1978
2035
  new_project_name = app_info_obj["projectName"]
2036
+ new_bundle_group_name = app_info_obj["bundleId"]
2037
+ new_wildcard_bundle_group_name = app_info_obj["wildcardBundleId"]
1979
2038
  new_project_scheme = app_info_obj["scheme"] ||
1980
2039
  app_info_obj["projectName"].to_s.downcase.strip.gsub(/[\s\-_]/, '')
1981
2040
 
@@ -1990,8 +2049,16 @@ module Pindo
1990
2049
 
1991
2050
  # 5. 配置文件不存在 → 创建新配置
1992
2051
  if !File.exist?(config_file)
1993
- create_new_config(config_file, new_project_id, new_project_name,
1994
- new_project_scheme, workflow_key, new_workflow_data)
2052
+ create_new_config(
2053
+ config_file: config_file,
2054
+ project_id: new_project_id,
2055
+ project_name: new_project_name,
2056
+ project_scheme: new_project_scheme,
2057
+ bundle_group_name: new_bundle_group_name,
2058
+ wildcard_bundle_group_name: new_wildcard_bundle_group_name,
2059
+ workflow_key: workflow_key,
2060
+ workflow_data: new_workflow_data
2061
+ )
1995
2062
  return
1996
2063
  end
1997
2064
 
@@ -2000,8 +2067,16 @@ module Pindo
2000
2067
  existing_config = JSON.parse(File.read(config_file))
2001
2068
  rescue => e
2002
2069
  puts "[PgyerHelper] 读取配置文件失败: #{e.message},将创建新配置"
2003
- create_new_config(config_file, new_project_id, new_project_name,
2004
- new_project_scheme, workflow_key, new_workflow_data)
2070
+ create_new_config(
2071
+ config_file: config_file,
2072
+ project_id: new_project_id,
2073
+ project_name: new_project_name,
2074
+ project_scheme: new_project_scheme,
2075
+ bundle_group_name: new_bundle_group_name,
2076
+ wildcard_bundle_group_name: new_wildcard_bundle_group_name,
2077
+ workflow_key: workflow_key,
2078
+ workflow_data: new_workflow_data
2079
+ )
2005
2080
  return
2006
2081
  end
2007
2082
 
@@ -2011,8 +2086,16 @@ module Pindo
2011
2086
  existing_config['project_id'] != new_project_id
2012
2087
 
2013
2088
  puts "项目ID变更,重新写入完整配置"
2014
- create_new_config(config_file, new_project_id, new_project_name,
2015
- new_project_scheme, workflow_key, new_workflow_data)
2089
+ create_new_config(
2090
+ config_file: config_file,
2091
+ project_id: new_project_id,
2092
+ project_name: new_project_name,
2093
+ project_scheme: new_project_scheme,
2094
+ bundle_group_name: new_bundle_group_name,
2095
+ wildcard_bundle_group_name: new_wildcard_bundle_group_name,
2096
+ workflow_key: workflow_key,
2097
+ workflow_data: new_workflow_data
2098
+ )
2016
2099
  return
2017
2100
  end
2018
2101
 
@@ -2024,9 +2107,11 @@ module Pindo
2024
2107
  existing_workflow_id.to_s.empty? ||
2025
2108
  existing_workflow_id != workflow_info[:workflow_id]
2026
2109
 
2027
- # Workflow ID 变更 → 仅更新对应的 workflow
2110
+ # Workflow ID 变更 → 更新对应的 workflow 和项目信息
2028
2111
  puts "#{workflow_key} 变更,更新工作流配置"
2029
2112
  existing_config[workflow_key] = new_workflow_data
2113
+ existing_config["bundle_group_name"] = new_bundle_group_name
2114
+ existing_config["wildcard_bundle_group_name"] = new_wildcard_bundle_group_name
2030
2115
  File.write(config_file, JSON.pretty_generate(existing_config))
2031
2116
  puts "已更新 #{workflow_key}"
2032
2117
  return
@@ -44,6 +44,13 @@ module Pindo
44
44
  update_project_config
45
45
  update_version_info
46
46
  handle_bundle_name_config if @bundle_name
47
+ if @bundle_name.nil?
48
+ # 当用户不选择 bundle_name 时,仍在 google-services.json 中合并工作流 applicationId(追加 client,不覆盖旧包名)
49
+ Pindo::AndroidConfigHelper.update_google_services_package_name(
50
+ project_dir: @project_path,
51
+ package_name: expected_android_package_name_from_workflow
52
+ )
53
+ end
47
54
  add_application_id_scheme
48
55
  end
49
56
 
@@ -177,13 +184,30 @@ module Pindo
177
184
  puts "\n正在处理指定的 Bundle Name: #{@bundle_name}..."
178
185
 
179
186
  # 检查是否为通配符
180
- is_wildcard = @bundle_name.include?('*') ||
181
- @bundle_name.end_with?('.') ||
182
- ['com.test', 'com.example', 'com.demo'].include?(@bundle_name)
187
+ is_wildcard = wildcard_bundle_name?(@bundle_name)
183
188
 
184
189
  if is_wildcard
185
190
  puts " ⚠️ 检测到通配符或通用 Bundle Name: #{@bundle_name}"
186
- puts " ⚠️ 跳过 google-services.json Application ID 更新"
191
+ # 通配符模式下,applicationId google-services.json 需与工作流的 package_name(当前项目名)一致;json 侧为合并追加 client。
192
+ expected_package_name = expected_android_package_name_from_workflow
193
+ Pindo::AndroidConfigHelper.update_application_id(
194
+ project_dir: @project_path,
195
+ application_id: expected_package_name
196
+ )
197
+ gs_paths = Pindo::AndroidConfigHelper.existing_google_services_json_paths(@project_path)
198
+ if gs_paths.any?
199
+ merged = Pindo::AndroidConfigHelper.update_google_services_package_name(
200
+ project_dir: @project_path,
201
+ package_name: expected_package_name
202
+ )
203
+ if merged
204
+ puts " ✓ 通配符模式已更新 applicationId 并已合并 google-services client: #{expected_package_name}"
205
+ else
206
+ puts " ✓ 通配符模式已更新 applicationId: #{expected_package_name}(google-services 无需追加新 client)"
207
+ end
208
+ else
209
+ puts " ✓ 通配符模式已更新 applicationId: #{expected_package_name}(项目内无 google-services.json,跳过 client 合并)"
210
+ end
187
211
  else
188
212
  # 拉取配置仓库
189
213
  config_repo_dir = Pindo::GitHandler.clong_buildconfig_repo(repo_name: @bundle_name)
@@ -201,6 +225,12 @@ module Pindo
201
225
  application_id: @bundle_name
202
226
  )
203
227
 
228
+ # 合并 google-services.json:追加与 applicationId 一致的 client,不删除历史 package_name
229
+ Pindo::AndroidConfigHelper.update_google_services_package_name(
230
+ project_dir: @project_path,
231
+ package_name: @bundle_name
232
+ )
233
+
204
234
  puts " ✓ Bundle Name 配置处理完成"
205
235
  else
206
236
  raise Informative, "无法获取配置仓库"
@@ -215,11 +245,39 @@ module Pindo
215
245
  )
216
246
  end
217
247
 
248
+ # 从 workflow_packname 生成符合 Android applicationId/google-services.json 的包名后缀
249
+ def expected_android_package_name_from_workflow
250
+ workflow_packname = @workflow_info[:package_name]
251
+ app_id_suffix = workflow_packname.gsub(/[^a-zA-Z0-9]/, '').downcase
252
+ "com.heroneverdie101.#{app_id_suffix}"
253
+ end
254
+
218
255
  # 构建 Android 工程
219
256
  def build_android_project
220
257
  android_build_helper = Pindo::AndroidBuildHelper.share_instance
221
- # 第二个参数 true 表示 debug 模式
222
- android_build_helper.auto_build_apk(@project_path, true)
258
+ # 第二个参数 true 表示 debug 模式,bundle_name 会用于 JPS JKS 查询和签名
259
+ resolved_bundle_id = signing_bundle_id
260
+ puts " 使用签名 Bundle ID: #{resolved_bundle_id}"
261
+ android_build_helper.auto_build_apk(
262
+ @project_path,
263
+ true,
264
+ bundle_name: resolved_bundle_id,
265
+ workflow_name: @workflow_info[:package_name]
266
+ )
267
+ end
268
+
269
+ def wildcard_bundle_name?(bundle_name)
270
+ return false if bundle_name.nil? || bundle_name.empty?
271
+
272
+ bundle_name.include?('*') ||
273
+ bundle_name.end_with?('.') ||
274
+ ['com.test', 'com.example', 'com.demo', 'com.heroneverdie101'].include?(bundle_name)
275
+ end
276
+
277
+ def signing_bundle_id
278
+ return @bundle_name if @bundle_name && !wildcard_bundle_name?(@bundle_name)
279
+
280
+ expected_android_package_name_from_workflow
223
281
  end
224
282
  end
225
283
  end
@@ -37,7 +37,7 @@ module Pindo
37
37
  def initialize(project_path, options = {})
38
38
  # GitCommitTask 特有的属性
39
39
  @fixed_version = options[:fixed_version] # 外部指定的固定版本号
40
- @process_type = options[:process_type] || Pindo::UncommittedFilesProcessType::SKIP # 默认跳过
40
+ @process_type = options[:process_type] || Pindo::UncommittedFilesProcessType::SKIP_WITH_TAG # 默认跳过但打tag
41
41
  @commit_message = options[:commit_message] || 'build: 构建产生提交' # 默认提交消息
42
42
 
43
43
  options[:project_path] = project_path
@@ -103,7 +103,25 @@ module Pindo
103
103
  raise e
104
104
  end
105
105
 
106
+ # skip_without_tag 模式:跳过所有 git 同步操作,直接返回
107
+ if @process_type == Pindo::UncommittedFilesProcessType::SKIP_WITHOUT_TAG
108
+ coding_branch = get_current_branch_name
109
+ @build_number, @commit_hash = git_repo_helper.get_build_number_from_commit(project_dir: root_dir)
110
+ @build_version = "0.0.0"
111
+ Funlog.instance.fancyinfo_warning("skip_without_tag 模式:跳过分支合并和 tag 创建")
112
+
113
+ # 显示 commit 信息后直接返回
114
+ display_all_repos_commit_info(root_dir)
115
+ return {
116
+ success: true,
117
+ root_dir: root_dir,
118
+ current_branch: coding_branch,
119
+ message: "skip_without_tag: 跳过 Git 同步操作"
120
+ }
121
+ end
122
+
106
123
  # 4. Stash 工作目录的残留修改(为分支同步做准备)
124
+ coding_branch = nil
107
125
  stash_saved = false
108
126
  stash_name = "pindo_stash_#{Time.now.strftime('%Y%m%d%H%M%S')}_#{rand(1000)}"
109
127
  status = Pindo::GitHandler.git!(%W(-C #{root_dir} status --porcelain)).strip
@@ -113,66 +131,64 @@ module Pindo
113
131
  stash_saved = true
114
132
  end
115
133
 
116
- # 5. 获取当前分支
117
- coding_branch = get_current_branch_name
118
-
119
- # 6. 检查并推送本地提交到远程(确保本地和远程同步)
120
- Pindo::GitHandler.check_unpushed_commits(project_dir: root_dir, branch: coding_branch)
134
+ begin
135
+ # 5. 获取当前分支
136
+ coding_branch = get_current_branch_name
121
137
 
122
- # 7. 分支同步:将 coding_branch 和 release_branch 双向合并(确保两分支在同一节点)
123
- if coding_branch != @release_branch
124
- Funlog.instance.fancyinfo_start("开始同步 #{coding_branch} 和 #{@release_branch} 分支")
125
- Pindo::GitHandler.merge_branches(
126
- project_dir: root_dir,
127
- source_branch: coding_branch,
128
- target_branch: @release_branch,
129
- sync_branches: true # 双向合并,确保两分支完全同步
130
- )
131
- Funlog.instance.fancyinfo_success("分支同步完成,#{coding_branch} 和 #{@release_branch} 现在在同一节点")
132
- end
138
+ # 6. 检查并推送本地提交到远程(确保本地和远程同步)
139
+ Pindo::GitHandler.check_unpushed_commits(project_dir: root_dir, branch: coding_branch)
133
140
 
134
- # 8. 计算 build_version
135
- # 优先级 1: 如果指定了 fixed_version(外部传入或从 HEAD tag 获取),使用它
136
- if @fixed_version && !@fixed_version.empty?
137
- @build_version = @fixed_version
138
- @build_number, @commit_hash = git_repo_helper.get_build_number_from_commit(project_dir: root_dir)
139
- commit_short = @commit_hash ? @commit_hash[0..7] : "unknown"
140
- Funlog.instance.fancyinfo_success("Version: #{@build_version}, Build: #{@build_number}, Commit: #{commit_short}")
141
+ # 7. 分支同步:将 coding_branch 和 release_branch 双向合并(确保两分支在同一节点)
142
+ if coding_branch != @release_branch
143
+ Funlog.instance.fancyinfo_start("开始同步 #{coding_branch} 和 #{@release_branch} 分支")
144
+ Pindo::GitHandler.merge_branches(
145
+ project_dir: root_dir,
146
+ source_branch: coding_branch,
147
+ target_branch: @release_branch,
148
+ sync_branches: true # 双向合并,确保两分支完全同步
149
+ )
150
+ Funlog.instance.fancyinfo_success("分支同步完成,#{coding_branch} 和 #{@release_branch} 现在在同一节点")
151
+ end
141
152
 
142
- # 优先级 2: 计算新版本号
143
- else
144
- @build_number, @commit_hash = git_repo_helper.get_build_number_from_commit(project_dir: root_dir)
145
- @build_version = git_repo_helper.calculate_build_version(
146
- project_dir: root_dir,
147
- tag_prefix: @tag_pre,
148
- create_tag_type: @tag_type,
149
- version_increase_type: @ver_inc
150
- )
151
- commit_short = @commit_hash ? @commit_hash[0..7] : "unknown"
152
- Funlog.instance.fancyinfo_success("Version: #{@build_version}, Build: #{@build_number}, Commit: #{commit_short}")
153
- end
153
+ # 8. 计算 build_version
154
+ # 优先级 1: 如果指定了 fixed_version(外部传入或从 HEAD tag 获取),使用它
155
+ if @fixed_version && !@fixed_version.empty?
156
+ @build_version = @fixed_version
157
+ @build_number, @commit_hash = git_repo_helper.get_build_number_from_commit(project_dir: root_dir)
158
+ commit_short = @commit_hash ? @commit_hash[0..7] : "unknown"
159
+ Funlog.instance.fancyinfo_success("Version: #{@build_version}, Build: #{@build_number}, Commit: #{commit_short}")
154
160
 
161
+ # 优先级 2: 计算新版本号
162
+ else
163
+ @build_number, @commit_hash = git_repo_helper.get_build_number_from_commit(project_dir: root_dir)
164
+ @build_version = git_repo_helper.calculate_build_version(
165
+ project_dir: root_dir,
166
+ tag_prefix: @tag_pre,
167
+ create_tag_type: @tag_type,
168
+ version_increase_type: @ver_inc
169
+ )
170
+ commit_short = @commit_hash ? @commit_hash[0..7] : "unknown"
171
+ Funlog.instance.fancyinfo_success("Version: #{@build_version}, Build: #{@build_number}, Commit: #{commit_short}")
172
+ end
155
173
 
156
- # 9. 还原 stash(如果之前有 stash)
157
- if stash_saved
158
- begin
159
- # 查找指定名字的 stash
160
- stash_list = Pindo::GitHandler.git!(%W(-C #{root_dir} stash list)).strip
161
- matched_line = stash_list.lines.find { |l| l.include?(stash_name) }
174
+ ensure
175
+ # 9. 还原 stash(无论成功或失败都执行)
176
+ if stash_saved
177
+ begin
178
+ stash_list = Pindo::GitHandler.git!(%W(-C #{root_dir} stash list)).strip
179
+ matched_line = stash_list.lines.find { |l| l.include?(stash_name) }
162
180
 
163
- if matched_line && (stash_id = matched_line.match(/(stash@\{\d+\})/)&.[](1))
164
- # 先应用 stash(不删除)
165
- Pindo::GitHandler.git!(%W(-C #{root_dir} stash apply #{stash_id}))
166
- # 应用成功后再删除 stash
167
- Pindo::GitHandler.git!(%W(-C #{root_dir} stash drop #{stash_id}))
168
- Funlog.instance.fancyinfo_success("已还原 stash: #{stash_name} (#{stash_id})")
169
- else
170
- Funlog.instance.fancyinfo_warning("未找到名为 #{stash_name} 的 stash,请手动检查")
181
+ if matched_line && (stash_id = matched_line.match(/(stash@\{\d+\})/)&.[](1))
182
+ Pindo::GitHandler.git!(%W(-C #{root_dir} stash apply #{stash_id}))
183
+ Pindo::GitHandler.git!(%W(-C #{root_dir} stash drop #{stash_id}))
184
+ Funlog.instance.fancyinfo_success("已还原 stash: #{stash_name} (#{stash_id})")
185
+ else
186
+ Funlog.instance.fancyinfo_warning("未找到名为 #{stash_name} 的 stash,请手动检查")
187
+ end
188
+ rescue => e
189
+ Funlog.instance.fancyinfo_warning("stash 还原时发生冲突: #{e.message}")
190
+ Funlog.instance.fancyinfo_warning("stash 已保留,请手动执行 'git stash pop' 处理冲突")
171
191
  end
172
- rescue => e
173
- Funlog.instance.fancyinfo_warning("stash 还原时发生冲突: #{e.message}")
174
- Funlog.instance.fancyinfo_warning("stash 已保留,请手动执行 'git stash pop' 处理冲突")
175
- # 不抛出异常,任务继续(版本号已计算成功,stash 冲突不影响构建)
176
192
  end
177
193
  end
178
194
 
@@ -64,7 +64,17 @@ module Pindo
64
64
  stash_saved = true
65
65
  end
66
66
 
67
- # 2. 合并到发布分支(双向同步,确保 coding_branch release_branch 保持一致)
67
+ # 2. GitCommitTask 获取参数(必须在合并之前,确保 release_branch 等参数正确)
68
+ git_commit_data = get_data_param_by_key(:git_commit)
69
+ if git_commit_data && git_commit_data[:task_param]
70
+ param = git_commit_data[:task_param]
71
+ @release_branch = param[:release_branch] if param[:release_branch]
72
+ @tag_pre = param[:tag_pre] if param[:tag_pre]
73
+ @tag_type = param[:tag_type] if param[:tag_type]
74
+ @ver_inc = param[:ver_inc] if param[:ver_inc]
75
+ end
76
+
77
+ # 3. 合并到发布分支(使用已回填的 @release_branch)
68
78
  if coding_branch != @release_branch
69
79
  Pindo::GitHandler.merge_branches(
70
80
  project_dir: root_dir,
@@ -74,20 +84,14 @@ module Pindo
74
84
  )
75
85
  end
76
86
 
77
- # 3. 获取版本信息
78
- # 优先级 1: 从 GitCommitTask 获取所有版本相关参数(标准方式)
79
- git_commit_data = get_data_param_by_key(:git_commit)
87
+ # 4. 获取版本信息
80
88
  if git_commit_data && git_commit_data[:task_param] &&
81
89
  git_commit_data[:task_param][:build_version] && git_commit_data[:task_param][:build_number]
82
90
  @build_version = git_commit_data[:task_param][:build_version]
83
91
  @build_number = git_commit_data[:task_param][:build_number]
84
- @tag_pre = git_commit_data[:task_param][:tag_pre] if git_commit_data[:task_param][:tag_pre]
85
- @release_branch = git_commit_data[:task_param][:release_branch] if git_commit_data[:task_param][:release_branch]
86
- @tag_type = git_commit_data[:task_param][:tag_type] if git_commit_data[:task_param][:tag_type]
87
- @ver_inc = git_commit_data[:task_param][:ver_inc] if git_commit_data[:task_param][:ver_inc]
88
92
  Funlog.instance.fancyinfo_success("使用 GitCommitTask 的版本号: #{@build_version}, Build: #{@build_number}, Tag前缀: #{@tag_pre}, Tag类型: #{@tag_type}")
89
93
 
90
- # 优先级 2: 自己计算(降级方案,用于向后兼容或 GitCommitTask 无有效数据)
94
+ # 降级:自己计算(向后兼容或 GitCommitTask 无有效数据)
91
95
  else
92
96
  @build_number, @commit_hash = git_repo_helper.get_build_number_from_commit(project_dir: root_dir)
93
97
  @build_version = git_repo_helper.calculate_build_version(