pindo 5.12.2 → 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/android.rb +0 -1
- 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 +10 -7
- 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_build_helper.rb +110 -0
- data/lib/pindo/module/android/android_config_helper.rb +9 -5
- data/lib/pindo/module/android/gradle_helper.rb +88 -0
- 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/task/pindo_task.rb +19 -10
- 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 -41
- data/lib/pindo/command/android/build.rb +0 -186
- 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
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
require 'spaceship'
|
|
2
|
+
require 'json'
|
|
3
|
+
require 'highline/import'
|
|
4
|
+
|
|
5
|
+
module Pindo
|
|
6
|
+
# iTunes Connect App 管理辅助类
|
|
7
|
+
# 负责在 App Store Connect 中创建和管理应用
|
|
8
|
+
class ItcAppHelper
|
|
9
|
+
|
|
10
|
+
# 从配置文件中提取所有必要的信息
|
|
11
|
+
# @param config_json [Hash] 配置 JSON 对象
|
|
12
|
+
# @return [Hash] 提取的配置信息
|
|
13
|
+
def self.extract_config_info(config_json)
|
|
14
|
+
config_info = {}
|
|
15
|
+
|
|
16
|
+
# 提取 Apple ID
|
|
17
|
+
if config_json['account_info'] && config_json['account_info']['apple_acount_id']
|
|
18
|
+
config_info[:apple_id] = config_json['account_info']['apple_acount_id']
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# 提取 Company Name
|
|
22
|
+
if config_json['account_info'] && config_json['account_info']['acount_company_name']
|
|
23
|
+
config_info[:company_name] = config_json['account_info']['acount_company_name'].strip
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# 提取 Bundle ID
|
|
27
|
+
if config_json['app_info'] && config_json['app_info']['app_identifier']
|
|
28
|
+
config_info[:bundle_id] = config_json['app_info']['app_identifier']
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# 提取版本号
|
|
32
|
+
if config_json['app_info'] && config_json['app_info']['app_version']
|
|
33
|
+
config_info[:app_version] = config_json['app_info']['app_version']
|
|
34
|
+
else
|
|
35
|
+
config_info[:app_version] = "1.0.0" # 默认版本
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
config_info
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# 执行 iTunes Connect App 创建流程
|
|
42
|
+
# @param config_json [Hash] 配置 JSON 对象
|
|
43
|
+
# @param config_path [String] 配置文件路径
|
|
44
|
+
# @param app_version [String, nil] 应用版本号
|
|
45
|
+
# @param company_name [String, nil] 公司名称
|
|
46
|
+
def self.execute_itcapp_creation(config_json:, config_path:, app_version: nil, company_name: nil)
|
|
47
|
+
# 提取配置信息
|
|
48
|
+
config_info = extract_config_info(config_json)
|
|
49
|
+
|
|
50
|
+
# 使用命令行参数覆盖配置
|
|
51
|
+
config_info[:app_version] = app_version if app_version
|
|
52
|
+
config_info[:company_name] = company_name if company_name
|
|
53
|
+
|
|
54
|
+
# 验证必需字段
|
|
55
|
+
raise "配置文件中缺少 Apple ID" if config_info[:apple_id].nil? || config_info[:apple_id].empty?
|
|
56
|
+
raise "配置文件中缺少 Bundle ID" if config_info[:bundle_id].nil? || config_info[:bundle_id].empty?
|
|
57
|
+
|
|
58
|
+
# 确保 Bundle ID 在开发者中心存在
|
|
59
|
+
ensure_bundle_id_exists(
|
|
60
|
+
apple_id: config_info[:apple_id],
|
|
61
|
+
bundle_id: config_info[:bundle_id],
|
|
62
|
+
config_path: config_path
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
# 创建 iTunes Connect App
|
|
66
|
+
puts "Create app in itc ..."
|
|
67
|
+
puts config_info[:apple_id]
|
|
68
|
+
puts "Login #{config_info[:apple_id]}..."
|
|
69
|
+
|
|
70
|
+
Spaceship::Tunes.login(config_info[:apple_id].to_s)
|
|
71
|
+
Spaceship::Tunes.select_team
|
|
72
|
+
|
|
73
|
+
app = create_itcapp(
|
|
74
|
+
bundle_id: config_info[:bundle_id],
|
|
75
|
+
app_version: config_info[:app_version],
|
|
76
|
+
company_name: config_info[:company_name]
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
# 修改配置文件,添加 App ID
|
|
80
|
+
if app
|
|
81
|
+
modify_appconfig_with_appid(
|
|
82
|
+
config_path: config_path,
|
|
83
|
+
bundle_id: config_info[:bundle_id],
|
|
84
|
+
app: app
|
|
85
|
+
)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
app
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# 确保 Bundle ID 在开发者中心存在
|
|
92
|
+
# @param apple_id [String] Apple ID
|
|
93
|
+
# @param bundle_id [String] Bundle ID
|
|
94
|
+
# @param config_path [String] 配置文件路径
|
|
95
|
+
def self.ensure_bundle_id_exists(apple_id:, bundle_id:, config_path:)
|
|
96
|
+
Spaceship::Portal.login(apple_id.to_s)
|
|
97
|
+
Spaceship::Portal.select_team
|
|
98
|
+
|
|
99
|
+
app = Spaceship::Portal.app.find(bundle_id)
|
|
100
|
+
if app.nil?
|
|
101
|
+
puts "Bundle ID #{bundle_id} 不存在,需要先创建"
|
|
102
|
+
puts "请先运行: pindo appstore bundleid #{config_path}"
|
|
103
|
+
raise "Bundle ID #{bundle_id} 不存在于 Apple 开发者中心"
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# 创建 iTunes Connect App
|
|
108
|
+
# @param bundle_id [String] Bundle ID
|
|
109
|
+
# @param app_version [String] 应用版本号
|
|
110
|
+
# @param company_name [String, nil] 公司名称
|
|
111
|
+
# @return [Object] 创建的 App 对象
|
|
112
|
+
def self.create_itcapp(bundle_id:, app_version:, company_name: nil)
|
|
113
|
+
return nil if bundle_id.nil?
|
|
114
|
+
|
|
115
|
+
# 检查 App 是否已存在
|
|
116
|
+
app = Spaceship::ConnectAPI::App.find(bundle_id)
|
|
117
|
+
if app
|
|
118
|
+
puts "App is already exist !!!"
|
|
119
|
+
return app
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# 生成默认 SKU ID
|
|
123
|
+
app_sku_id_fixed = bundle_id + ".sku"
|
|
124
|
+
puts "App的默认sku id 为: #{app_sku_id_fixed}"
|
|
125
|
+
|
|
126
|
+
# 让用户自定义 SKU ID
|
|
127
|
+
input_skuid = ask("请自定义输入App Sku ID: ") || nil
|
|
128
|
+
if !input_skuid.nil? && input_skuid.length > 1
|
|
129
|
+
app_sku_id_fixed = input_skuid
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# 获取公司名称
|
|
133
|
+
if company_name.nil?
|
|
134
|
+
company_name = ask('Company Name : ') || nil
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
puts "App Sku ID : #{app_sku_id_fixed}"
|
|
138
|
+
puts "Company Name : #{company_name}"
|
|
139
|
+
|
|
140
|
+
# 确认信息
|
|
141
|
+
answer = agree("请确认上面信息是否正确(Y/n):")
|
|
142
|
+
unless answer
|
|
143
|
+
raise "用户取消创建,请重新运行命令"
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# 生成 App 名称(移除点号,最多30个字符)
|
|
147
|
+
app_default_name = bundle_id.gsub('.', '')
|
|
148
|
+
if app_default_name.length > 30
|
|
149
|
+
app_default_name = app_default_name[0, 30]
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# 创建 App
|
|
153
|
+
app = Spaceship::ConnectAPI::App.create(
|
|
154
|
+
name: app_default_name,
|
|
155
|
+
version_string: app_version,
|
|
156
|
+
sku: app_sku_id_fixed,
|
|
157
|
+
primary_locale: "en-US",
|
|
158
|
+
bundle_id: bundle_id,
|
|
159
|
+
platforms: ["IOS"],
|
|
160
|
+
company_name: company_name
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
puts "App is created !!!"
|
|
164
|
+
app
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# 修改配置文件,添加 App ID
|
|
168
|
+
# @param config_path [String] 配置文件路径
|
|
169
|
+
# @param bundle_id [String] Bundle ID
|
|
170
|
+
# @param app [Object] App 对象
|
|
171
|
+
def self.modify_appconfig_with_appid(config_path:, bundle_id:, app:)
|
|
172
|
+
return if app.nil?
|
|
173
|
+
|
|
174
|
+
puts
|
|
175
|
+
puts "app.id : #{app.id} +++++++++"
|
|
176
|
+
puts
|
|
177
|
+
|
|
178
|
+
# 修改本地配置文件
|
|
179
|
+
modify_appconfig_file(config_file: config_path, app_info_detail: app)
|
|
180
|
+
|
|
181
|
+
# 修改远程配置仓库
|
|
182
|
+
begin
|
|
183
|
+
require_relative '../../base/githelper'
|
|
184
|
+
include Pindo::Githelper
|
|
185
|
+
|
|
186
|
+
app_config_dir = clong_buildconfig_repo(repo_name: bundle_id)
|
|
187
|
+
app_config_file = File.join(app_config_dir, "config.json")
|
|
188
|
+
|
|
189
|
+
if File.exist?(app_config_file)
|
|
190
|
+
modify_appconfig_file(config_file: app_config_file, app_info_detail: app)
|
|
191
|
+
prepare_gitenv()
|
|
192
|
+
git_addpush_repo(path: app_config_dir, message: "modify apple id")
|
|
193
|
+
end
|
|
194
|
+
rescue StandardError => e
|
|
195
|
+
puts "更新远程配置仓库失败: #{e.message}"
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# 修改单个配置文件
|
|
200
|
+
# @param config_file [String] 配置文件路径
|
|
201
|
+
# @param app_info_detail [Object] App 信息对象
|
|
202
|
+
def self.modify_appconfig_file(config_file:, app_info_detail:)
|
|
203
|
+
return unless File.exist?(config_file)
|
|
204
|
+
|
|
205
|
+
config_content = JSON.parse(File.read(config_file))
|
|
206
|
+
|
|
207
|
+
File.open(config_file, "w") do |f|
|
|
208
|
+
# 更新 app_id_ios
|
|
209
|
+
config_content['app_info']['app_id_ios'] = app_info_detail.id
|
|
210
|
+
|
|
211
|
+
# 更新 apple_app_id(如果存在)
|
|
212
|
+
if config_content['app_setting'] && config_content['app_setting']["apple_app_id"]
|
|
213
|
+
config_content['app_setting']["apple_app_id"] = app_info_detail.id
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
# 更新 kGUKeyAppId(如果存在)
|
|
217
|
+
if config_content['app_setting'] && config_content['app_setting']["kGUKeyAppId"]
|
|
218
|
+
config_content['app_setting']["kGUKeyAppId"] = app_info_detail.id
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
f.write(JSON.pretty_generate(config_content))
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
puts "✓ 配置文件已更新: #{config_file}"
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
end
|
|
228
|
+
end
|
|
@@ -196,6 +196,18 @@ module Pindo
|
|
|
196
196
|
nil
|
|
197
197
|
end
|
|
198
198
|
end
|
|
199
|
+
|
|
200
|
+
# 拉取应用配置仓库(委托给 BuildInfoManager)
|
|
201
|
+
# @param repo_name [String] 仓库名称(Bundle ID)
|
|
202
|
+
# @param target_dir [String, nil] 目标目录(默认:当前目录)
|
|
203
|
+
# @return [Boolean] 是否成功拉取配置
|
|
204
|
+
def pull_appconfig_with_reponame(repo_name:, target_dir: nil)
|
|
205
|
+
require_relative '../../config/build_info_manager'
|
|
206
|
+
Pindo::BuildInfoManager.share_instance.pull_appconfig_with_reponame(
|
|
207
|
+
repo_name: repo_name,
|
|
208
|
+
target_dir: target_dir
|
|
209
|
+
)
|
|
210
|
+
end
|
|
199
211
|
end
|
|
200
212
|
|
|
201
213
|
end
|
|
@@ -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?
|