pindo 5.13.1 → 5.13.2

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 (110) 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 +258 -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/autobuild.rb +64 -43
  24. data/lib/pindo/command/ios/autoresign.rb +34 -19
  25. data/lib/pindo/command/ios/build.rb +9 -6
  26. data/lib/pindo/command/ios/cert.rb +27 -20
  27. data/lib/pindo/command/jps/upload.rb +3 -3
  28. data/lib/pindo/command/unity/autobuild.rb +2 -2
  29. data/lib/pindo/command/utils/clearcert.rb +2 -17
  30. data/lib/pindo/command/{deploy → utils}/fabric.rb +13 -13
  31. data/lib/pindo/command/utils/renewcert.rb +62 -38
  32. data/lib/pindo/command/utils/renewproj.rb +0 -3
  33. data/lib/pindo/command/{deploy → utils}/updateconfig.rb +6 -7
  34. data/lib/pindo/command/utils.rb +2 -0
  35. data/lib/pindo/command/web/autobuild.rb +2 -2
  36. data/lib/pindo/command.rb +30 -3
  37. data/lib/pindo/config/build_info_manager.rb +176 -0
  38. data/lib/pindo/config/ios_config_parser.rb +404 -0
  39. data/lib/pindo/module/android/android_config_helper.rb +9 -5
  40. data/lib/pindo/module/appstore/bundleid_helper.rb +349 -0
  41. data/lib/pindo/module/appstore/itcapp_helper.rb +228 -0
  42. data/lib/pindo/module/build/build_helper.rb +12 -0
  43. data/lib/pindo/module/build/swark_helper.rb +116 -77
  44. data/lib/pindo/module/cert/cert_helper.rb +74 -0
  45. data/lib/pindo/module/cert/pem_helper.rb +72 -0
  46. data/lib/pindo/module/cert/{xcodecerthelper.rb → xcode_cert_helper.rb} +208 -6
  47. data/lib/pindo/module/task/model/appstore/appstore_task.rb +18 -0
  48. data/lib/pindo/module/task/model/appstore/appstore_upload_ipa_task.rb +151 -0
  49. data/lib/pindo/module/task/model/appstore/appstore_upload_metadata_task.rb +250 -0
  50. data/lib/pindo/module/task/model/appstore/appstore_upload_screenshot_task.rb +276 -0
  51. data/lib/pindo/module/task/model/build/android_build_adhoc_task.rb +210 -0
  52. data/lib/pindo/module/task/model/build/{android_dev_build_task.rb → android_build_dev_task.rb} +2 -2
  53. data/lib/pindo/module/task/model/build/android_build_gplay_task.rb +210 -0
  54. data/lib/pindo/module/task/model/build/android_build_task.rb +13 -0
  55. data/lib/pindo/module/task/model/build/ios_build_adhoc_task.rb +197 -0
  56. data/lib/pindo/module/task/model/build/ios_build_appstore_task.rb +367 -0
  57. data/lib/pindo/module/task/model/build/{ios_dev_build_task.rb → ios_build_dev_task.rb} +37 -27
  58. data/lib/pindo/module/task/model/build/ios_build_task.rb +13 -0
  59. data/lib/pindo/module/task/model/build/{web_dev_build_task.rb → web_build_dev_task.rb} +1 -1
  60. data/lib/pindo/module/task/model/build_task.rb +15 -12
  61. data/lib/pindo/module/task/model/jps_resign_task.rb +185 -0
  62. data/lib/pindo/module/task/model/{upload_task.rb → jps_upload_task.rb} +3 -3
  63. data/lib/pindo/module/task/model/unity_export_task.rb +3 -1
  64. data/lib/pindo/module/unity/unity_helper.rb +2 -1
  65. data/lib/pindo/module/xcode/ipa_resign_helper.rb +210 -0
  66. data/lib/pindo/module/xcode/{xcodeappconfig.rb → xcode_app_config.rb} +79 -0
  67. data/lib/pindo/module/xcode/xcode_build_config.rb +152 -17
  68. data/lib/pindo/module/xcode/xcode_build_helper.rb +151 -1
  69. data/lib/pindo/module/xcode/xcode_swark_helper.rb +341 -0
  70. data/lib/pindo/options/core/global_options_state.rb +268 -0
  71. data/lib/pindo/options/core/option_configuration.rb +206 -0
  72. data/lib/pindo/options/core/option_initializer.rb +51 -0
  73. data/lib/pindo/options/core/option_item.rb +144 -0
  74. data/lib/pindo/options/core/option_value_parser.rb +54 -0
  75. data/lib/pindo/options/groups/build_options.rb +60 -0
  76. data/lib/pindo/options/groups/jps_options.rb +70 -0
  77. data/lib/pindo/options/groups/option_group.rb +73 -0
  78. data/lib/pindo/options/helpers/bundleid_selector.rb +103 -0
  79. data/lib/pindo/options/options.rb +14 -0
  80. data/lib/pindo/version.rb +1 -1
  81. metadata +49 -40
  82. data/lib/pindo/command/appstore/import.rb +0 -259
  83. data/lib/pindo/command/deploy/build.rb +0 -250
  84. data/lib/pindo/command/deploy/bundleid.rb +0 -259
  85. data/lib/pindo/command/deploy/cert.rb +0 -202
  86. data/lib/pindo/command/deploy/check.rb +0 -93
  87. data/lib/pindo/command/deploy/configproj.rb +0 -120
  88. data/lib/pindo/command/deploy/confusecode.rb +0 -262
  89. data/lib/pindo/command/deploy/confuseproj.rb +0 -122
  90. data/lib/pindo/command/deploy/iap.rb +0 -826
  91. data/lib/pindo/command/deploy/initconfig.rb +0 -138
  92. data/lib/pindo/command/deploy/itcapp.rb +0 -146
  93. data/lib/pindo/command/deploy/pem.rb +0 -55
  94. data/lib/pindo/command/deploy/pullconfig.rb +0 -56
  95. data/lib/pindo/command/deploy/pushconfig.rb +0 -93
  96. data/lib/pindo/command/deploy/quswark.rb +0 -156
  97. data/lib/pindo/command/deploy/quswauth.rb +0 -76
  98. data/lib/pindo/command/deploy/reportbug.rb +0 -145
  99. data/lib/pindo/command/deploy/resign.rb +0 -300
  100. data/lib/pindo/command/deploy/tag.rb +0 -108
  101. data/lib/pindo/command/deploy/uploadipa.rb +0 -73
  102. data/lib/pindo/command/deploy.rb +0 -42
  103. data/lib/pindo/command/dev/autobuild.rb +0 -117
  104. data/lib/pindo/command/dev/build.rb +0 -94
  105. data/lib/pindo/command/dev/debug.rb +0 -112
  106. data/lib/pindo/module/task/model/build/android_release_build_task.rb +0 -29
  107. data/lib/pindo/module/task/model/build/ios_adhoc_build_task.rb +0 -53
  108. data/lib/pindo/module/task/model/build/ios_release_build_task.rb +0 -53
  109. data/lib/pindo/options/appconfigoptions.rb +0 -24
  110. data/lib/pindo/options/deployoptions.rb +0 -372
@@ -2,94 +2,133 @@ require 'highline/import'
2
2
  require 'xcodeproj'
3
3
  require 'json'
4
4
  require 'yaml'
5
-
5
+ require 'pindo/base/git_handler'
6
6
 
7
7
  module Pindo
8
- module SwarkHelper
9
-
10
- def check_swark_authorize(config_json:nil, buid_type:nil)
11
- if !config_json.nil? && config_json['project_info']['xcode_build_type'] && config_json["project_info"]["xcode_build_type"].include?("swark")
12
-
13
- app_config_dir = File.join(File::expand_path(pindo_single_config.pindo_dir), @deploy_identifier)
14
- swark_authorize_file = File.join(app_config_dir, "swark_authorize.json")
15
- if File.exist?(swark_authorize_file)
16
- swark_authorize_json=JSON.parse(File.read(swark_authorize_file))
17
- unless swark_authorize_json && swark_authorize_json['swark_authorize_status']
18
- show_swark_authorize_error(swark_authorize_json:swark_authorize_json , buid_type:buid_type)
19
- end
20
- end
21
- end
22
- end
8
+ # Swark 授权辅助类
9
+ # 负责 Swark 授权检查、权限配置等操作
10
+ class SwarkHelper
11
+
12
+ # 检查 Swark 授权状态
13
+ # @param config_json [Hash] 配置 JSON 对象
14
+ # @param buid_type [String] 构建类型(dev/adhoc/appstore)
15
+ # @param deploy_identifier [String] 部署标识符
16
+ def self.check_swark_authorize(config_json:, buid_type:, deploy_identifier:)
17
+ return unless config_json &&
18
+ config_json['project_info'] &&
19
+ config_json['project_info']['xcode_build_type'] &&
20
+ config_json['project_info']['xcode_build_type'].include?("swark")
23
21
 
24
- def show_swark_authorize_error(swark_authorize_json:nil, buid_type:nil)
25
-
26
- puts "++++ +++ Need authorize !!! ++++"
27
- puts "+++ Need authorize !!! ++++"
28
- puts "+++ Need authorize !!! +++++"
29
- puts " =========================="
30
- puts
31
-
32
- puts "方法一:"
33
- command = " 1. swark authorize "
34
- command = command + swark_authorize_json["swark_authorize_teamid"] + "." + swark_authorize_json["swark_authorize_bundleid"]
35
- puts command
36
- command = " 2. 修改swark_authorize.json 中的 swark_authorize_status = true 并且提交"
37
- puts
38
-
39
- puts "方法二:"
40
- puts " pindo deploy quswark"
41
- if buid_type.downcase.to_s.include?("appstore")
42
- raise Informative, "Need swark authorize !!!"
43
- end
22
+ require 'pindo/config/pindoconfig'
23
+ app_config_dir = File.join(File.expand_path(Pindoconfig.instance.pindo_dir), deploy_identifier)
24
+ swark_authorize_file = File.join(app_config_dir, "swark_authorize.json")
25
+
26
+ if File.exist?(swark_authorize_file)
27
+ swark_authorize_json = JSON.parse(File.read(swark_authorize_file))
28
+ unless swark_authorize_json && swark_authorize_json['swark_authorize_status']
29
+ show_swark_authorize_error(
30
+ swark_authorize_json: swark_authorize_json,
31
+ buid_type: buid_type
32
+ )
44
33
  end
34
+ end
35
+ end
45
36
 
37
+ # 显示 Swark 授权错误信息
38
+ # @param swark_authorize_json [Hash] Swark 授权配置 JSON
39
+ # @param buid_type [String] 构建类型
40
+ def self.show_swark_authorize_error(swark_authorize_json:, buid_type:)
41
+ puts "++++ +++ Need authorize !!! ++++"
42
+ puts "+++ Need authorize !!! ++++"
43
+ puts "+++ Need authorize !!! +++++"
44
+ puts " =========================="
45
+ puts
46
46
 
47
- def add_swark_entitlement(entitlements_plist_path:nil, bundle_id_dict:nil)
48
- if @config_json['project_info']['xcode_build_type'] && @config_json["project_info"]["xcode_build_type"].include?("swark")
49
- if File.exist?(entitlements_plist_path)
50
- entitlements_plist_dict = Xcodeproj::Plist.read_from_path(entitlements_plist_path)
47
+ puts "方法一:"
48
+ command = " 1. swark authorize "
49
+ command += swark_authorize_json["swark_authorize_teamid"] + "." + swark_authorize_json["swark_authorize_bundleid"]
50
+ puts command
51
+ puts " 2. 修改swark_authorize.json 中的 swark_authorize_status = true 并且提交"
52
+ puts
51
53
 
52
- key_value = @team_id_vaule
53
- key_value = key_value + "." + @bundle_id
54
- entitlements_plist_dict['keychain-access-groups'] = [key_value]
54
+ puts "方法二:"
55
+ puts " pindo deploy quswark"
55
56
 
56
- Xcodeproj::Plist.write_to_path(entitlements_plist_dict, entitlements_plist_path)
57
- end
58
- end
57
+ if buid_type.downcase.to_s.include?("appstore")
58
+ raise Informative, "Need swark authorize !!!"
59
59
  end
60
+ end
61
+
62
+ # 添加 Swark 权限配置到 entitlements
63
+ # @param entitlements_plist_path [String] entitlements.plist 文件路径
64
+ # @param bundle_id_dict [Hash] Bundle ID 字典
65
+ # @param config_json [Hash] 配置 JSON 对象
66
+ # @param team_id [String] Team ID
67
+ # @param bundle_id [String] Bundle ID
68
+ def self.add_swark_entitlement(
69
+ entitlements_plist_path:,
70
+ bundle_id_dict:,
71
+ config_json:,
72
+ team_id:,
73
+ bundle_id:
74
+ )
75
+ return unless config_json &&
76
+ config_json['project_info'] &&
77
+ config_json['project_info']['xcode_build_type'] &&
78
+ config_json['project_info']['xcode_build_type'].include?("swark")
79
+
80
+ return unless File.exist?(entitlements_plist_path)
81
+
82
+ entitlements_plist_dict = Xcodeproj::Plist.read_from_path(entitlements_plist_path)
60
83
 
61
- def add_swark_authorize_json
62
- if @build_type == "appstore" && @config_json['project_info']['xcode_build_type'] && @config_json["project_info"]["xcode_build_type"].include?("swark")
63
-
64
- app_config_dir = clong_buildconfig_repo(repo_name: @deploy_repo_name)
65
- swark_authorize_file = File.join(app_config_dir, "swark_authorize.json")
66
- if File.exist?(swark_authorize_file)
67
- swark_authorize_json=JSON.parse(File.read(swark_authorize_file))
68
- if swark_authorize_json && swark_authorize_json['swark_authorize_status']
69
- puts "swark already authorize success !!! "
70
- else
71
- swark_authorize_json = swark_authorize_json || {}
72
- swark_authorize_json['swark_authorize_teamid'] = @team_id_vaule
73
- swark_authorize_json['swark_authorize_bundleid'] = @bundle_id
74
- swark_authorize_json['swark_authorize_status'] = false
75
- File.open(swark_authorize_file, "w") do |f|
76
- f.write(JSON.pretty_generate(swark_authorize_json))
77
- end
78
- git_addpush_repo(path:app_config_dir, message:"add swark authorize json")
79
- end
80
- else
81
- swark_authorize_json = swark_authorize_json || {}
82
- swark_authorize_json['swark_authorize_teamid'] = @team_id_vaule
83
- swark_authorize_json['swark_authorize_bundleid'] = @bundle_id
84
- swark_authorize_json['swark_authorize_status'] = false
85
- File.open(swark_authorize_file, "w") do |f|
86
- f.write(JSON.pretty_generate(swark_authorize_json))
87
- end
88
- git_addpush_repo(path:app_config_dir, message:"add swark authorize json")
84
+ key_value = team_id + "." + bundle_id
85
+ entitlements_plist_dict['keychain-access-groups'] = [key_value]
86
+
87
+ Xcodeproj::Plist.write_to_path(entitlements_plist_dict, entitlements_plist_path)
88
+ end
89
+
90
+ # 添加 Swark 授权配置文件
91
+ # @param build_type [String] 构建类型(dev/adhoc/appstore)
92
+ # @param config_json [Hash] 配置 JSON 对象
93
+ # @param team_id [String] Team ID
94
+ # @param bundle_id [String] Bundle ID
95
+ # @param deploy_repo_name [String] 部署仓库名称
96
+ def self.add_swark_authorize_json(
97
+ build_type:,
98
+ config_json:,
99
+ team_id:,
100
+ bundle_id:,
101
+ deploy_repo_name:
102
+ )
103
+ return unless build_type == "appstore" &&
104
+ config_json &&
105
+ config_json['project_info'] &&
106
+ config_json['project_info']['xcode_build_type'] &&
107
+ config_json['project_info']['xcode_build_type'].include?("swark")
108
+
109
+ app_config_dir = Pindo::GitHandler.clong_buildconfig_repo(repo_name: deploy_repo_name)
110
+ swark_authorize_file = File.join(app_config_dir, "swark_authorize.json")
111
+
112
+ if File.exist?(swark_authorize_file)
113
+ swark_authorize_json = JSON.parse(File.read(swark_authorize_file))
114
+ if swark_authorize_json && swark_authorize_json['swark_authorize_status']
115
+ puts "swark already authorize success !!! "
116
+ return
89
117
  end
90
-
91
- end
92
118
  end
93
119
 
120
+ # 创建或更新授权文件
121
+ swark_authorize_json = {}
122
+ swark_authorize_json['swark_authorize_teamid'] = team_id
123
+ swark_authorize_json['swark_authorize_bundleid'] = bundle_id
124
+ swark_authorize_json['swark_authorize_status'] = false
125
+
126
+ File.open(swark_authorize_file, "w") do |f|
127
+ f.write(JSON.pretty_generate(swark_authorize_json))
128
+ end
129
+
130
+ Pindo::GitHandler.git_addpush_repo(path: app_config_dir, message: "add swark authorize json")
131
+ end
132
+
94
133
  end
95
- end
134
+ end
@@ -2,6 +2,8 @@
2
2
 
3
3
  require 'match'
4
4
  require 'openssl'
5
+ require 'open3'
6
+ require 'fileutils'
5
7
  require 'pindo/base/aeshelper'
6
8
  require 'pindo/module/cert/keychain_helper'
7
9
  require 'pindo/module/cert/provisioning_helper'
@@ -14,6 +16,78 @@ module Pindo
14
16
  @@password_cache = {}
15
17
 
16
18
  class << self
19
+ # 清理 Git 仓库中的证书
20
+ # @param apple_id [String] Apple ID
21
+ # @param pindo_dir [String] Pindo 目录路径
22
+ # @param deploy_cert_giturl [String] 部署证书 Git URL
23
+ # @param dev_cert_giturl [String] 开发证书 Git URL
24
+ # @param demo_apple_id [String] Demo Apple ID
25
+ def clean_git_certs(apple_id:, pindo_dir:, deploy_cert_giturl:, dev_cert_giturl:, demo_apple_id:)
26
+ require_relative '../../base/git_handler'
27
+
28
+ # 确定使用哪个 Git URL
29
+ git_url = apple_id.eql?(demo_apple_id) ? dev_cert_giturl : deploy_cert_giturl
30
+
31
+ puts "正在清理 Git 仓库中的证书..."
32
+ puts "Apple ID: #{apple_id}"
33
+ puts "Git URL: #{git_url}"
34
+
35
+ # 克隆或更新证书仓库
36
+ cert_repo_dir = Pindo::GitHandler.getcode_to_dir(
37
+ reponame: Pindo::GitHandler.get_repo_base_name(repo_url: git_url),
38
+ remote_url: git_url,
39
+ path: pindo_dir,
40
+ new_branch: apple_id
41
+ )
42
+
43
+ # 删除 certs 和 profiles 目录
44
+ certs_dir = File.join(cert_repo_dir, "certs")
45
+ profiles_dir = File.join(cert_repo_dir, "profiles")
46
+
47
+ FileUtils.rm_rf(certs_dir) if File.exist?(certs_dir)
48
+ FileUtils.rm_rf(profiles_dir) if File.exist?(profiles_dir)
49
+
50
+ puts "✓ 已删除 certs 和 profiles 目录"
51
+
52
+ # 提交并推送到远程仓库
53
+ Pindo::GitHandler.prepare_gitenv()
54
+ Pindo::GitHandler.git_addpush_repo(path: cert_repo_dir, message: "remove #{apple_id} certs")
55
+
56
+ puts "✓ Git 仓库证书清理完成"
57
+ end
58
+
59
+ # 清理本地证书
60
+ # 删除系统中所有的 Apple Development 和 Apple Distribution 证书
61
+ # 清理 Provisioning Profiles 文件夹
62
+ def clean_local_certs
63
+ puts "正在清理本地证书..."
64
+
65
+ # 获取所有代码签名证书
66
+ output, _ = Open3.capture2('security find-identity -p codesigning')
67
+ identity_ids_0 = []
68
+ identity_ids_1 = output.split("\n").map { |line| line.split(' ')[1] if line.include?('Apple Development') }.compact
69
+ identity_ids_2 = output.split("\n").map { |line| line.split(' ')[1] if line.include?('Apple Distribution') }.compact
70
+ identity_ids = identity_ids_0 + identity_ids_1 + identity_ids_2
71
+ identity_ids = identity_ids.uniq
72
+
73
+ puts "找到 #{identity_ids.size} 个证书:"
74
+ puts identity_ids
75
+
76
+ # 删除证书
77
+ identity_ids.each do |identity_id|
78
+ system "security delete-certificate -Z #{identity_id}"
79
+ end
80
+
81
+ # 清理 Provisioning Profiles
82
+ profile_file_dir = File.expand_path("~/Library/MobileDevice")
83
+ profile_file_path = File.join(profile_file_dir, "Provisioning Profiles")
84
+ if File.exist?(profile_file_path)
85
+ FileUtils.rm_rf(profile_file_path)
86
+ puts "✓ 已清理 Provisioning Profiles 文件夹"
87
+ end
88
+
89
+ puts "✓ 本地证书清理完成"
90
+ end
17
91
  # 获取密码的辅助方法,使用缓存避免重复获取
18
92
  def get_cached_password(cert_url)
19
93
  unless @@password_cache[cert_url]
@@ -4,6 +4,78 @@ module Pindo
4
4
  class PemHelper
5
5
  class << self
6
6
 
7
+ # 从配置文件中提取所有必要的信息
8
+ # @param config_json [Hash] 配置 JSON 对象
9
+ # @return [Hash] 提取的配置信息
10
+ def extract_config_info(config_json)
11
+ config_info = {}
12
+
13
+ # 提取 Apple ID
14
+ if config_json['account_info'] && config_json['account_info']['apple_acount_id']
15
+ config_info[:apple_id] = config_json['account_info']['apple_acount_id']
16
+ end
17
+
18
+ # 提取 Bundle ID
19
+ if config_json['app_info'] && config_json['app_info']['app_identifier']
20
+ config_info[:bundle_id] = config_json['app_info']['app_identifier']
21
+ end
22
+
23
+ config_info
24
+ end
25
+
26
+ # 执行 Push 证书创建流程
27
+ # @param config_json [Hash] 配置 JSON 对象
28
+ # @param dev_flag [Boolean] 是否为开发证书
29
+ # @param deploy_repo_name [String, nil] 部署仓库名称
30
+ def execute_pem_creation(config_json:, dev_flag: false, deploy_repo_name: nil)
31
+ require_relative '../../base/githelper'
32
+ include Pindo::Githelper
33
+
34
+ # 提取配置信息
35
+ config_info = extract_config_info(config_json)
36
+
37
+ # 验证必需字段
38
+ raise "配置文件中缺少 Apple ID" if config_info[:apple_id].nil? || config_info[:apple_id].empty?
39
+ raise "配置文件中缺少 Bundle ID" if config_info[:bundle_id].nil? || config_info[:bundle_id].empty?
40
+
41
+ # 登录 Apple 开发者中心
42
+ puts config_info[:apple_id]
43
+ puts "Login #{config_info[:apple_id]}..."
44
+ login(apple_id: config_info[:apple_id])
45
+
46
+ # 确定证书类型
47
+ pem_type = dev_flag ? "dev" : "prod"
48
+
49
+ # 创建输出目录
50
+ temp_dir = "push_" + Time.now.to_i.to_s
51
+ push_path = File.join(File.expand_path('~/Desktop/'), temp_dir)
52
+ FileUtils.mkdir_p(push_path) unless File.exist?(push_path)
53
+ puts "证书输出路径: #{push_path}"
54
+
55
+ # 创建证书
56
+ x509_cert_path = create_certificate(
57
+ bundle_id: config_info[:bundle_id],
58
+ type: pem_type,
59
+ output_path: push_path
60
+ )
61
+
62
+ # 如果提供了部署仓库名称,则上传到 Git 仓库
63
+ if !deploy_repo_name.nil? && !deploy_repo_name.empty? && File.exist?(x509_cert_path) && File.exist?(push_path)
64
+ app_config_dir = clong_buildconfig_repo(repo_name: deploy_repo_name)
65
+ push_repo_dir = File.join(app_config_dir, "push")
66
+
67
+ FileUtils.mkdir_p(push_repo_dir) unless File.exist?(push_repo_dir)
68
+ FileUtils.cp_r(File.join(push_path, "."), push_repo_dir)
69
+
70
+ prepare_gitenv()
71
+ git_addpush_repo(path: app_config_dir, message: "add push cert")
72
+
73
+ puts "✓ 证书已上传到配置仓库: #{push_repo_dir}"
74
+ end
75
+
76
+ x509_cert_path
77
+ end
78
+
7
79
  def create_certificate(bundle_id:nil, type:"prod", output_path:"")
8
80
 
9
81
  if bundle_id.empty? || output_path.empty?
@@ -4,8 +4,139 @@ require 'pindo/base/aeshelper'
4
4
 
5
5
  module Pindo
6
6
 
7
- module XcodeCertHelper
8
-
7
+ class XcodeCertHelper
8
+
9
+ class << self
10
+
11
+ # 标准化构建类型
12
+ # @param build_type [String, Symbol] 构建类型 ('dev', 'adhoc', 'release', 'development', 'appstore')
13
+ # @return [String] 标准化后的证书类型 ('development', 'adhoc', 'appstore')
14
+ def normalize_build_type(build_type)
15
+ case build_type.to_s.downcase
16
+ when 'dev', 'development'
17
+ 'development'
18
+ when 'adhoc'
19
+ 'adhoc'
20
+ when 'release', 'appstore'
21
+ 'appstore'
22
+ else
23
+ raise ArgumentError, "无效的构建类型: #{build_type},支持的类型: dev/development, adhoc, release/appstore"
24
+ end
25
+ end
26
+
27
+ # 安装证书并配置 Xcode 工程
28
+ # @param build_type [String, Symbol] 构建类型 ('dev', 'adhoc', 'release' 或 'development', 'adhoc', 'appstore')
29
+ # @param platform_type [String] 平台类型 ('ios', 'macos')
30
+ # @param project_dir [String] 项目目录
31
+ # @param config_file [String, nil] 配置文件路径(可选,默认从 project_dir 加载)
32
+ # @param skip_xcode_config [Boolean] 是否跳过 Xcode 配置
33
+ # @return [Hash] 返回证书信息 { provisioning_info_array:, team_id: }
34
+ def install_and_config_certs(
35
+ build_type:,
36
+ platform_type: 'ios',
37
+ project_dir: Dir.pwd,
38
+ config_file: nil,
39
+ skip_xcode_config: false
40
+ )
41
+ # 标准化构建类型
42
+ cert_type = normalize_build_type(build_type)
43
+
44
+ # 配置加载
45
+ require 'pindo/config/ios_config_parser'
46
+ config_parser = Pindo::IosConfigParser.instance
47
+ config_path = config_file || File.join(project_dir, 'config.json')
48
+ config_parser.load_config(config_file: config_path)
49
+
50
+ apple_id = config_parser.apple_id
51
+ bundle_id_map = config_parser.get_bundle_id_map
52
+
53
+ # 安装证书
54
+ require 'pindo/config/pindoconfig'
55
+ require 'pindo/base/git_handler'
56
+ require 'pindo/module/cert/cert_helper'
57
+
58
+ pindo_config = Pindoconfig.instance
59
+
60
+ cert_git_url = apple_id.eql?(pindo_config.demo_apple_id) ?
61
+ pindo_config.dev_cert_giturl :
62
+ pindo_config.deploy_cert_giturl
63
+
64
+ cert_reponame = cert_git_url.split("/").last.chomp(".git")
65
+ certs_dir = Pindo::GitHandler.getcode_to_dir(
66
+ reponame: cert_reponame,
67
+ remote_url: cert_git_url,
68
+ path: pindo_config.pindo_dir,
69
+ new_branch: apple_id
70
+ )
71
+
72
+ # 安装证书和配置文件
73
+ Pindo::CertHelper.install_certs(
74
+ cert_url: cert_git_url,
75
+ certs_dir: certs_dir,
76
+ cert_type: cert_type,
77
+ platform_type: platform_type
78
+ )
79
+
80
+ provisioning_info_array = Pindo::CertHelper.install_provisionfiles(
81
+ cert_url: cert_git_url,
82
+ certs_dir: certs_dir,
83
+ bundle_id_map: bundle_id_map,
84
+ cert_type: cert_type,
85
+ platform_type: platform_type
86
+ )
87
+
88
+ pindo_config.set_cert_info(dict: provisioning_info_array)
89
+
90
+ raise Informative, "未找到证书信息" if provisioning_info_array.nil? || provisioning_info_array.empty?
91
+
92
+ team_id = provisioning_info_array.first["team_id"]
93
+
94
+ # Swark 授权检查
95
+ main_bundle_id = config_parser.bundle_id
96
+ if config_parser.config_json && main_bundle_id
97
+ require 'pindo/module/build/swark_helper'
98
+ Pindo::SwarkHelper.add_swark_authorize_json(
99
+ build_type: cert_type,
100
+ config_json: config_parser.config_json,
101
+ team_id: team_id,
102
+ bundle_id: main_bundle_id,
103
+ deploy_repo_name: main_bundle_id
104
+ )
105
+ end
106
+
107
+ # 配置 Xcode 工程 (如果需要)
108
+ unless skip_xcode_config
109
+ project_fullname = Dir.glob(File.join(project_dir, "/*.xcodeproj")).max_by { |f| File.mtime(f) }
110
+ if project_fullname && File.exist?(project_fullname)
111
+ proj_name = File.basename(project_fullname, ".xcodeproj")
112
+
113
+ Funlog.instance.fancyinfo_start("正在给Xcode配置证书...")
114
+ config_project_cert(
115
+ new_proj_name: proj_name,
116
+ new_project_dir: project_dir,
117
+ cert_type: cert_type,
118
+ platform_type: platform_type,
119
+ team_id_vaule: team_id,
120
+ provisioning_info_array: provisioning_info_array
121
+ )
122
+
123
+ config_infoplist_cert(
124
+ new_proj_name: proj_name,
125
+ new_project_dir: project_dir,
126
+ icloud_id: config_parser.icloud_id,
127
+ group_id: config_parser.group_id,
128
+ provisioning_info_array: provisioning_info_array
129
+ )
130
+ Funlog.instance.fancyinfo_success("Xcode配置证书完成!")
131
+ end
132
+ end
133
+
134
+ {
135
+ provisioning_info_array: provisioning_info_array,
136
+ team_id: team_id
137
+ }
138
+ end
139
+
9
140
  def get_target_name_map
10
141
  return {
11
142
  "MainTarget" => "bundle_id",
@@ -28,7 +159,9 @@ module Pindo
28
159
 
29
160
  provisioning_info_array = []
30
161
 
31
- bundle_id_map = get_bundle_id_map
162
+ # 使用 IosConfigParser 单例获取 bundle_id_map
163
+ config_parser = Pindo::IosConfigParser.instance
164
+ bundle_id_map = config_parser.get_bundle_id_map
32
165
 
33
166
  bundle_id_map.each do |type, bundle_id_temp|
34
167
  provisioning_info = {}
@@ -224,7 +357,29 @@ module Pindo
224
357
  end
225
358
 
226
359
  if target.product_type.to_s.eql?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:application]) then
227
- add_swark_entitlement(entitlements_plist_path:entitlements_plist_path, bundle_id_dict:provisioning_info_array)
360
+ # 调用 SwarkHelper 添加权限配置
361
+ # 读取 config.json(如果存在)
362
+ config_json = nil
363
+ config_json_file = File.join(new_project_dir, "config.json")
364
+ if File.exist?(config_json_file)
365
+ config_json = JSON.parse(File.read(config_json_file))
366
+ end
367
+
368
+ # 获取 team_id 和 bundle_id
369
+ team_id = provisioning_info_array.first["team_id"] if provisioning_info_array && provisioning_info_array.any?
370
+ bundle_id = provisioning_info_array.first["bundle_id"] if provisioning_info_array && provisioning_info_array.any?
371
+
372
+ if config_json && team_id && bundle_id
373
+ require 'pindo/module/build/swark_helper'
374
+ Pindo::SwarkHelper.add_swark_entitlement(
375
+ entitlements_plist_path: entitlements_plist_path,
376
+ bundle_id_dict: provisioning_info_array,
377
+ config_json: config_json,
378
+ team_id: team_id,
379
+ bundle_id: bundle_id
380
+ )
381
+ end
382
+
228
383
  if !icloud_id.nil?
229
384
  modify_entitlements_plist(entitlements_plist_path:entitlements_plist_path, icloud_id:icloud_id)
230
385
  end
@@ -315,6 +470,7 @@ module Pindo
315
470
  end
316
471
 
317
472
  def create_upload_cert_info(apple_id:nil, cert_type:nil, platform_type:nil)
473
+ pindo_single_config = Pindoconfig.instance
318
474
 
319
475
  cert_dest_dir = File.join(Dir.pwd, "cert")
320
476
  if !File.exist?(cert_dest_dir)
@@ -483,6 +639,52 @@ module Pindo
483
639
  return account_cert_set
484
640
  end
485
641
 
642
+ def get_create_cert_match_values(apple_id:nil, bundle_id_array:nil, build_type:nil, platform_type:nil, renew_flag:false)
643
+ pindo_single_config = Pindoconfig.instance
644
+
645
+ if build_type.eql?("appstore") && (apple_id.eql?(pindo_single_config.demo_apple_id))
646
+ raise Informative, "#{apple_id} 是测试账号,不能创建appstore证书!!!"
647
+ end
648
+ if !build_type.eql?("appstore") && !apple_id.eql?(pindo_single_config.demo_apple_id)
649
+ raise Informative, "账号#{apple_id} 不能创建dev或者adhoc证书!!!"
650
+ end
651
+
652
+ git_url = pindo_single_config.deploy_cert_giturl
653
+ if apple_id.eql?(pindo_single_config.demo_apple_id)
654
+ git_url = pindo_single_config.dev_cert_giturl
655
+ end
656
+
657
+ force_for_new_devices_flag = true
658
+ if build_type.eql?("appstore")
659
+ force_for_new_devices_flag = false
660
+ end
661
+
662
+ if platform_type.downcase.include?("macos") && build_type.eql?("adhoc")
663
+ build_type = "developer_id"
664
+ end
665
+
666
+ values = {
667
+ username:apple_id,
668
+ app_identifier: bundle_id_array,
669
+ type: build_type,
670
+ keychain_password:"goodcert1",
671
+ git_url: git_url,
672
+ readonly:!renew_flag,
673
+ force:renew_flag,
674
+ clone_branch_directly:!renew_flag,
675
+ include_mac_in_profiles:true,
676
+ include_all_certificates:true,
677
+ generate_apple_certs:true,
678
+ shallow_clone:!renew_flag,
679
+ git_branch: apple_id,
680
+ platform:platform_type,
681
+ force_for_new_devices:force_for_new_devices_flag
682
+ }
683
+ return values
684
+
685
+ end
686
+
687
+ end # class << self
486
688
 
487
- end
488
- end
689
+ end # class XcodeCertHelper
690
+ end # module Pindo
@@ -0,0 +1,18 @@
1
+ require_relative '../pindo_task'
2
+
3
+ module Pindo
4
+ module TaskSystem
5
+ # App Store 任务基类
6
+ # 所有 App Store 相关任务的抽象基类
7
+ # 子类包括:AppStoreUploadIpaTask、AppStoreUploadMetadataTask、AppStoreUploadScreenshotTask
8
+ class AppStoreTask < PindoTask
9
+ # 空基类,仅用于类型标识
10
+ # 所有具体实现由子类完成
11
+
12
+ # 任务类型
13
+ def self.task_type
14
+ :appstore
15
+ end
16
+ end
17
+ end
18
+ end