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.
- checksums.yaml +4 -4
- data/lib/pindo/base/git_handler.rb +692 -0
- data/lib/pindo/command/android/autobuild.rb +2 -2
- data/lib/pindo/command/appstore/adhocbuild.rb +258 -311
- data/lib/pindo/command/appstore/autobuild.rb +203 -0
- data/lib/pindo/command/appstore/autoresign.rb +35 -17
- data/lib/pindo/command/appstore/bundleid.rb +120 -0
- data/lib/pindo/command/appstore/cert.rb +212 -0
- data/lib/pindo/command/appstore/configproj.rb +81 -0
- data/lib/pindo/command/{deploy → appstore}/getitcinfo.rb +76 -91
- data/lib/pindo/command/appstore/iap.rb +788 -24
- data/lib/pindo/command/appstore/initconfig.rb +105 -0
- data/lib/pindo/command/appstore/itcapp.rb +95 -13
- data/lib/pindo/command/{deploy → appstore}/itcinfo.rb +90 -118
- data/lib/pindo/command/appstore/pem.rb +136 -0
- data/lib/pindo/command/appstore/pullconfig.rb +99 -0
- data/lib/pindo/command/appstore/quswark.rb +87 -0
- data/lib/pindo/command/appstore/quswauth.rb +67 -0
- data/lib/pindo/command/appstore/tag.rb +77 -0
- data/lib/pindo/command/appstore.rb +13 -1
- data/lib/pindo/command/env/quarkenv.rb +11 -13
- data/lib/pindo/command/env/swarkenv.rb +11 -16
- data/lib/pindo/command/ios/autobuild.rb +64 -43
- data/lib/pindo/command/ios/autoresign.rb +34 -19
- data/lib/pindo/command/ios/build.rb +9 -6
- data/lib/pindo/command/ios/cert.rb +27 -20
- data/lib/pindo/command/jps/upload.rb +3 -3
- data/lib/pindo/command/unity/autobuild.rb +2 -2
- data/lib/pindo/command/utils/clearcert.rb +2 -17
- data/lib/pindo/command/{deploy → utils}/fabric.rb +13 -13
- data/lib/pindo/command/utils/renewcert.rb +62 -38
- data/lib/pindo/command/utils/renewproj.rb +0 -3
- data/lib/pindo/command/{deploy → utils}/updateconfig.rb +6 -7
- data/lib/pindo/command/utils.rb +2 -0
- data/lib/pindo/command/web/autobuild.rb +2 -2
- data/lib/pindo/command.rb +30 -3
- data/lib/pindo/config/build_info_manager.rb +176 -0
- data/lib/pindo/config/ios_config_parser.rb +404 -0
- data/lib/pindo/module/android/android_config_helper.rb +9 -5
- data/lib/pindo/module/appstore/bundleid_helper.rb +349 -0
- data/lib/pindo/module/appstore/itcapp_helper.rb +228 -0
- data/lib/pindo/module/build/build_helper.rb +12 -0
- data/lib/pindo/module/build/swark_helper.rb +116 -77
- data/lib/pindo/module/cert/cert_helper.rb +74 -0
- data/lib/pindo/module/cert/pem_helper.rb +72 -0
- data/lib/pindo/module/cert/{xcodecerthelper.rb → xcode_cert_helper.rb} +208 -6
- data/lib/pindo/module/task/model/appstore/appstore_task.rb +18 -0
- data/lib/pindo/module/task/model/appstore/appstore_upload_ipa_task.rb +151 -0
- data/lib/pindo/module/task/model/appstore/appstore_upload_metadata_task.rb +250 -0
- data/lib/pindo/module/task/model/appstore/appstore_upload_screenshot_task.rb +276 -0
- data/lib/pindo/module/task/model/build/android_build_adhoc_task.rb +210 -0
- data/lib/pindo/module/task/model/build/{android_dev_build_task.rb → android_build_dev_task.rb} +2 -2
- data/lib/pindo/module/task/model/build/android_build_gplay_task.rb +210 -0
- data/lib/pindo/module/task/model/build/android_build_task.rb +13 -0
- data/lib/pindo/module/task/model/build/ios_build_adhoc_task.rb +197 -0
- data/lib/pindo/module/task/model/build/ios_build_appstore_task.rb +367 -0
- data/lib/pindo/module/task/model/build/{ios_dev_build_task.rb → ios_build_dev_task.rb} +37 -27
- data/lib/pindo/module/task/model/build/ios_build_task.rb +13 -0
- data/lib/pindo/module/task/model/build/{web_dev_build_task.rb → web_build_dev_task.rb} +1 -1
- data/lib/pindo/module/task/model/build_task.rb +15 -12
- data/lib/pindo/module/task/model/jps_resign_task.rb +185 -0
- data/lib/pindo/module/task/model/{upload_task.rb → jps_upload_task.rb} +3 -3
- data/lib/pindo/module/task/model/unity_export_task.rb +3 -1
- data/lib/pindo/module/unity/unity_helper.rb +2 -1
- data/lib/pindo/module/xcode/ipa_resign_helper.rb +210 -0
- data/lib/pindo/module/xcode/{xcodeappconfig.rb → xcode_app_config.rb} +79 -0
- data/lib/pindo/module/xcode/xcode_build_config.rb +152 -17
- data/lib/pindo/module/xcode/xcode_build_helper.rb +151 -1
- data/lib/pindo/module/xcode/xcode_swark_helper.rb +341 -0
- data/lib/pindo/options/core/global_options_state.rb +268 -0
- data/lib/pindo/options/core/option_configuration.rb +206 -0
- data/lib/pindo/options/core/option_initializer.rb +51 -0
- data/lib/pindo/options/core/option_item.rb +144 -0
- data/lib/pindo/options/core/option_value_parser.rb +54 -0
- data/lib/pindo/options/groups/build_options.rb +60 -0
- data/lib/pindo/options/groups/jps_options.rb +70 -0
- data/lib/pindo/options/groups/option_group.rb +73 -0
- data/lib/pindo/options/helpers/bundleid_selector.rb +103 -0
- data/lib/pindo/options/options.rb +14 -0
- data/lib/pindo/version.rb +1 -1
- metadata +49 -40
- data/lib/pindo/command/appstore/import.rb +0 -259
- data/lib/pindo/command/deploy/build.rb +0 -250
- data/lib/pindo/command/deploy/bundleid.rb +0 -259
- data/lib/pindo/command/deploy/cert.rb +0 -202
- data/lib/pindo/command/deploy/check.rb +0 -93
- data/lib/pindo/command/deploy/configproj.rb +0 -120
- data/lib/pindo/command/deploy/confusecode.rb +0 -262
- data/lib/pindo/command/deploy/confuseproj.rb +0 -122
- data/lib/pindo/command/deploy/iap.rb +0 -826
- data/lib/pindo/command/deploy/initconfig.rb +0 -138
- data/lib/pindo/command/deploy/itcapp.rb +0 -146
- data/lib/pindo/command/deploy/pem.rb +0 -55
- data/lib/pindo/command/deploy/pullconfig.rb +0 -56
- data/lib/pindo/command/deploy/pushconfig.rb +0 -93
- data/lib/pindo/command/deploy/quswark.rb +0 -156
- data/lib/pindo/command/deploy/quswauth.rb +0 -76
- data/lib/pindo/command/deploy/reportbug.rb +0 -145
- data/lib/pindo/command/deploy/resign.rb +0 -300
- data/lib/pindo/command/deploy/tag.rb +0 -108
- data/lib/pindo/command/deploy/uploadipa.rb +0 -73
- data/lib/pindo/command/deploy.rb +0 -42
- data/lib/pindo/command/dev/autobuild.rb +0 -117
- data/lib/pindo/command/dev/build.rb +0 -94
- data/lib/pindo/command/dev/debug.rb +0 -112
- data/lib/pindo/module/task/model/build/android_release_build_task.rb +0 -29
- data/lib/pindo/module/task/model/build/ios_adhoc_build_task.rb +0 -53
- data/lib/pindo/module/task/model/build/ios_release_build_task.rb +0 -53
- data/lib/pindo/options/appconfigoptions.rb +0 -24
- 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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
-
|
|
53
|
-
|
|
54
|
-
entitlements_plist_dict['keychain-access-groups'] = [key_value]
|
|
54
|
+
puts "方法二:"
|
|
55
|
+
puts " pindo deploy quswark"
|
|
55
56
|
|
|
56
|
-
|
|
57
|
-
|
|
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
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|