pindo 5.13.4 → 5.13.6
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/aeshelper.rb +15 -13
- data/lib/pindo/command/appstore/adhocbuild.rb +61 -30
- data/lib/pindo/command/appstore/autobuild.rb +18 -5
- data/lib/pindo/command/appstore/autoresign.rb +294 -163
- data/lib/pindo/command/ios/autobuild.rb +6 -0
- data/lib/pindo/command/jps/upload.rb +1 -1
- data/lib/pindo/command/unity/autobuild.rb +6 -0
- data/lib/pindo/config/build_info_manager.rb +32 -0
- data/lib/pindo/config/ios_config_parser.rb +163 -1
- data/lib/pindo/module/cert/cert_helper.rb +1 -1
- data/lib/pindo/module/pgyer/pgyerhelper.rb +162 -0
- data/lib/pindo/module/task/model/build/ios_build_adhoc_task.rb +94 -15
- data/lib/pindo/module/task/model/build/ios_build_appstore_task.rb +41 -14
- data/lib/pindo/module/task/model/build/ios_build_dev_task.rb +23 -14
- data/lib/pindo/module/task/model/ipa_local_resign_task.rb +189 -0
- data/lib/pindo/module/task/model/jps_upload_task.rb +65 -21
- data/lib/pindo/module/xcode/cocoapods_helper.rb +127 -4
- data/lib/pindo/module/xcode/ipa_resign_helper.rb +1 -1
- data/lib/pindo/module/xcode/res/xcode_res_handler.rb +9 -8
- data/lib/pindo/module/xcode/xcode_app_config.rb +9 -1
- data/lib/pindo/module/xcode/xcode_build_config.rb +7 -2
- data/lib/pindo/module/xcode/xcode_swark_helper.rb +9 -1
- data/lib/pindo/version.rb +1 -1
- metadata +2 -1
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
require_relative '../pindo_task'
|
|
2
|
+
require_relative '../task_config'
|
|
3
|
+
|
|
4
|
+
module Pindo
|
|
5
|
+
module TaskSystem
|
|
6
|
+
# IPA 本地重签名任务
|
|
7
|
+
# 使用新的证书和 Bundle ID 对 IPA 文件进行重签名
|
|
8
|
+
class IpaLocalResignTask < PindoTask
|
|
9
|
+
attr_reader :ipa_path, :ipa_file, :bundle_id, :build_type
|
|
10
|
+
|
|
11
|
+
# 任务类型
|
|
12
|
+
def self.task_type
|
|
13
|
+
:resign
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# 重试配置
|
|
17
|
+
def self.default_retry_mode
|
|
18
|
+
RetryMode::DELAYED
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.default_retry_count
|
|
22
|
+
2 # 允许重试 2 次
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.default_retry_delay
|
|
26
|
+
5 # 延迟 5 秒
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# 初始化重签名任务
|
|
30
|
+
# @param ipa_path [String] IPA 搜索路径(当 ipa_file 为 nil 时使用)
|
|
31
|
+
# @param ipa_file [String] 指定的 IPA 文件(nil 表示自动查找)
|
|
32
|
+
# @param bundle_id [String] 目标 Bundle ID
|
|
33
|
+
# @param options [Hash] 选项
|
|
34
|
+
# @option options [String] :build_type 构建类型('dev' 或 'adhoc',默认 'adhoc')
|
|
35
|
+
# @option options [String] :project_dir 项目目录(用于加载 config.json)
|
|
36
|
+
def initialize(ipa_path, ipa_file, bundle_id, options = {})
|
|
37
|
+
@ipa_path = ipa_path # IPA 搜索路径
|
|
38
|
+
@ipa_file = ipa_file # 指定的 IPA 文件(nil 表示自动查找)
|
|
39
|
+
@bundle_id = bundle_id # 目标 Bundle ID
|
|
40
|
+
@build_type = options[:build_type] || 'adhoc'
|
|
41
|
+
@project_dir = options[:project_dir] || Dir.pwd
|
|
42
|
+
|
|
43
|
+
# 设置任务优先级
|
|
44
|
+
options[:priority] ||= TaskPriority::HIGH
|
|
45
|
+
|
|
46
|
+
super("重签名 IPA", options)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# 验证任务参数
|
|
50
|
+
def validate
|
|
51
|
+
# 验证 Bundle ID
|
|
52
|
+
unless @bundle_id && !@bundle_id.empty?
|
|
53
|
+
@error = "缺少必需参数: bundle_id"
|
|
54
|
+
return false
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# 验证 build_type
|
|
58
|
+
unless ['dev', 'adhoc'].include?(@build_type)
|
|
59
|
+
@error = "无效的 build_type: #{@build_type}(必须是 'dev' 或 'adhoc')"
|
|
60
|
+
return false
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# 验证 ipa_path(当 ipa_file 为空时)
|
|
64
|
+
if (@ipa_file.nil? || @ipa_file.empty?)
|
|
65
|
+
unless @ipa_path && !@ipa_path.empty?
|
|
66
|
+
@error = "缺少必需参数: ipa_path(当 ipa_file 未指定时)"
|
|
67
|
+
return false
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
true
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
protected
|
|
75
|
+
|
|
76
|
+
# 执行重签名
|
|
77
|
+
def do_work
|
|
78
|
+
# 1. 确定要重签名的 IPA 文件
|
|
79
|
+
ipa_to_resign = determine_ipa_file
|
|
80
|
+
unless ipa_to_resign && File.exist?(ipa_to_resign)
|
|
81
|
+
raise "未找到需要重签名的 IPA 文件"
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
puts "\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
85
|
+
puts " 正在重签名 IPA"
|
|
86
|
+
puts "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
87
|
+
puts " IPA 文件: #{ipa_to_resign}"
|
|
88
|
+
puts " Bundle ID: #{@bundle_id}"
|
|
89
|
+
puts " 构建类型: #{@build_type}"
|
|
90
|
+
puts " 修改时间: #{File.mtime(ipa_to_resign)}"
|
|
91
|
+
puts "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
|
|
92
|
+
|
|
93
|
+
# 2. 加载配置(如果尚未加载)
|
|
94
|
+
load_config_if_needed
|
|
95
|
+
|
|
96
|
+
# 3. 安装证书
|
|
97
|
+
install_certificate
|
|
98
|
+
|
|
99
|
+
# 4. 执行重签名
|
|
100
|
+
require 'pindo/module/xcode/ipa_resign_helper'
|
|
101
|
+
resigned_ipa = Pindo::IpaResignHelper.resign_ipa(
|
|
102
|
+
ipa_file_path: ipa_to_resign,
|
|
103
|
+
bundle_id: @bundle_id
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
# 5. 验证重签名结果
|
|
107
|
+
unless resigned_ipa && File.exist?(resigned_ipa)
|
|
108
|
+
raise "重签名失败:未生成重签名后的 IPA 文件"
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
puts "\n✅ 重签名成功!"
|
|
112
|
+
puts " 重签名后的 IPA: #{resigned_ipa}"
|
|
113
|
+
|
|
114
|
+
# 6. 返回重签名后的 IPA 路径
|
|
115
|
+
@result = resigned_ipa
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
private
|
|
119
|
+
|
|
120
|
+
# 确定要重签名的 IPA 文件
|
|
121
|
+
def determine_ipa_file
|
|
122
|
+
if @ipa_file && !@ipa_file.empty? && File.exist?(@ipa_file)
|
|
123
|
+
# 使用指定的 IPA 文件
|
|
124
|
+
puts " 使用指定的 IPA 文件: #{@ipa_file}"
|
|
125
|
+
return @ipa_file
|
|
126
|
+
else
|
|
127
|
+
# 在 ipa_path 中查找最新的非 _resigned 的 IPA
|
|
128
|
+
find_latest_ipa_file
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# 查找最新的 IPA 文件(排除 _resigned.ipa)
|
|
133
|
+
def find_latest_ipa_file
|
|
134
|
+
unless File.directory?(@ipa_path)
|
|
135
|
+
return nil
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
ipa_files = Dir.glob(File.join(@ipa_path, "*.ipa"))
|
|
139
|
+
|
|
140
|
+
# 过滤掉 _resigned.ipa 文件
|
|
141
|
+
ipa_files = ipa_files.reject { |f| File.basename(f).include?("_resigned") }
|
|
142
|
+
|
|
143
|
+
if ipa_files.empty?
|
|
144
|
+
return nil
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# 返回最新的 IPA 文件
|
|
148
|
+
latest_ipa = ipa_files.max_by { |f| File.mtime(f) }
|
|
149
|
+
puts " 自动查找到 IPA 文件: #{latest_ipa}"
|
|
150
|
+
|
|
151
|
+
latest_ipa
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# 加载配置(如果尚未加载)
|
|
155
|
+
def load_config_if_needed
|
|
156
|
+
require 'pindo/config/ios_config_parser'
|
|
157
|
+
config_parser = Pindo::IosConfigParser.instance
|
|
158
|
+
|
|
159
|
+
# 如果配置已加载,直接返回
|
|
160
|
+
if config_parser.config_json && !config_parser.config_json.empty?
|
|
161
|
+
puts " 使用已加载的配置"
|
|
162
|
+
return
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# 加载 config.json
|
|
166
|
+
config_file = File.join(@project_dir, "config.json")
|
|
167
|
+
if File.exist?(config_file)
|
|
168
|
+
puts " 加载配置文件: #{config_file}"
|
|
169
|
+
config_parser.load_config(config_file: config_file)
|
|
170
|
+
else
|
|
171
|
+
raise "配置文件不存在: #{config_file}"
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
# 安装证书
|
|
176
|
+
def install_certificate
|
|
177
|
+
puts "\n📜 安装证书..."
|
|
178
|
+
puts " 证书类型: #{@build_type}"
|
|
179
|
+
|
|
180
|
+
# 调用证书安装命令
|
|
181
|
+
require 'pindo/command/appstore/cert'
|
|
182
|
+
cert_args = ["--build_type=#{@build_type}"]
|
|
183
|
+
Pindo::Command::Appstore::Cert.run(cert_args)
|
|
184
|
+
|
|
185
|
+
puts " ✓ 证书安装完成"
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
@@ -34,6 +34,7 @@ module Pindo
|
|
|
34
34
|
# @option options [Hash] :app_info_obj JPS 应用信息对象(可选,如为 nil 则延迟获取)
|
|
35
35
|
# @option options [Hash] :workflow_info 工作流信息(可选,如为 nil 则延迟获取)
|
|
36
36
|
# @option options [String] :project_name 项目名称(可选)
|
|
37
|
+
# @option options [String] :upload_desc 上传描述(可选)
|
|
37
38
|
def initialize(file_type, upload_path, upload_file, options = {})
|
|
38
39
|
@file_type = file_type # 'ipa' | 'apk' | 'html' | 'app'
|
|
39
40
|
@upload_path = upload_path # 搜索文件的路径
|
|
@@ -43,6 +44,7 @@ module Pindo
|
|
|
43
44
|
@app_info_obj = options[:app_info_obj]
|
|
44
45
|
@workflow_info = options[:workflow_info]
|
|
45
46
|
@project_name = options[:project_name]
|
|
47
|
+
@upload_desc = options[:upload_desc] # 上传描述
|
|
46
48
|
|
|
47
49
|
# 设置上传任务的优先级为 LOW,确保在构建任务之后执行
|
|
48
50
|
options[:priority] ||= TaskPriority::LOW
|
|
@@ -180,38 +182,80 @@ module Pindo
|
|
|
180
182
|
result_data = pgyer_helper.start_upload(
|
|
181
183
|
app_info_obj: @app_info_obj,
|
|
182
184
|
ipa_file_upload: file_path,
|
|
183
|
-
description: @
|
|
185
|
+
description: @upload_desc, # 使用上传描述
|
|
184
186
|
workflow_info: @workflow_info
|
|
185
187
|
)
|
|
186
188
|
|
|
187
|
-
#
|
|
188
|
-
|
|
189
|
-
|
|
189
|
+
# 验证上传结果
|
|
190
|
+
unless result_data && result_data["data"] && result_data["data"]["id"]
|
|
191
|
+
raise "上传失败:未获取到有效的返回数据"
|
|
192
|
+
end
|
|
190
193
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
app_version_info_obj: app_version_info
|
|
195
|
-
)
|
|
194
|
+
# ========== 上传成功,后续操作失败不应导致重试 ==========
|
|
195
|
+
# 将重试次数设为 0,即使后续操作失败也不会重复上传
|
|
196
|
+
@retry_count = 0
|
|
196
197
|
|
|
197
|
-
|
|
198
|
-
pgyer_helper.send_apptest_msg(
|
|
199
|
-
app_info_obj: @app_info_obj,
|
|
200
|
-
app_version_info_obj: app_version_info,
|
|
201
|
-
receiveType: "self"
|
|
202
|
-
)
|
|
198
|
+
app_version_info = result_data["data"]
|
|
203
199
|
|
|
204
|
-
|
|
205
|
-
|
|
200
|
+
# 处理上传成功后的操作
|
|
201
|
+
handle_post_upload_actions(app_version_info)
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
# 处理上传成功后的操作
|
|
205
|
+
# @param app_version_info [Hash] 应用版本信息
|
|
206
|
+
def handle_post_upload_actions(app_version_info)
|
|
207
|
+
puts "\n 📋 开始处理上传后续操作..."
|
|
208
|
+
|
|
209
|
+
begin
|
|
210
|
+
pgyer_helper = PgyerHelper.share_instace
|
|
211
|
+
|
|
212
|
+
# 打印应用版本信息(失败只警告,不中断)
|
|
213
|
+
begin
|
|
214
|
+
puts " 📝 打印应用版本信息..."
|
|
215
|
+
pgyer_helper.print_app_version_info(
|
|
216
|
+
app_info_obj: @app_info_obj,
|
|
217
|
+
app_version_info_obj: app_version_info
|
|
218
|
+
)
|
|
219
|
+
puts " ✓ 应用版本信息打印成功"
|
|
220
|
+
rescue => e
|
|
221
|
+
puts " ⚠️ 打印应用版本信息失败: #{e.message}"
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
# 发送消息给自己(失败只警告,不中断)
|
|
225
|
+
begin
|
|
226
|
+
puts " 📨 发送消息给自己..."
|
|
206
227
|
pgyer_helper.send_apptest_msg(
|
|
207
228
|
app_info_obj: @app_info_obj,
|
|
208
229
|
app_version_info_obj: app_version_info,
|
|
209
|
-
|
|
210
|
-
receiveType: "chat"
|
|
230
|
+
receiveType: "self"
|
|
211
231
|
)
|
|
232
|
+
puts " ✓ 消息发送成功"
|
|
233
|
+
rescue => e
|
|
234
|
+
puts " ⚠️ 发送消息给自己失败: #{e.message}"
|
|
212
235
|
end
|
|
213
|
-
|
|
214
|
-
|
|
236
|
+
|
|
237
|
+
# 如果需要发送到测试群(失败只警告,不中断)
|
|
238
|
+
if @context[:send_to_chat]
|
|
239
|
+
begin
|
|
240
|
+
puts " 📢 发送消息到测试群..."
|
|
241
|
+
pgyer_helper.send_apptest_msg(
|
|
242
|
+
app_info_obj: @app_info_obj,
|
|
243
|
+
app_version_info_obj: app_version_info,
|
|
244
|
+
chatEnv: "DevTest",
|
|
245
|
+
receiveType: "chat"
|
|
246
|
+
)
|
|
247
|
+
puts " ✓ 测试群消息发送成功"
|
|
248
|
+
rescue => e
|
|
249
|
+
puts " ⚠️ 发送消息到测试群失败: #{e.message}"
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
puts " ✅ 上传后续操作全部完成\n"
|
|
254
|
+
rescue => e
|
|
255
|
+
# 外层错误保护:任何未预期的错误都不应影响上传任务的成功状态
|
|
256
|
+
puts " ⚠️ 上传后续操作发生未预期错误: #{e.message}"
|
|
257
|
+
puts " ⚠️ 错误堆栈: #{e.backtrace.first(3).join("\n ")}" if e.backtrace
|
|
258
|
+
puts " ℹ️ 上传已成功,后续操作失败不影响上传结果\n"
|
|
215
259
|
end
|
|
216
260
|
end
|
|
217
261
|
end
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
require 'cocoapods'
|
|
2
2
|
require 'fileutils'
|
|
3
|
+
require 'digest'
|
|
4
|
+
require 'json'
|
|
3
5
|
require 'pindo/base/git_handler'
|
|
4
6
|
require 'pindo/config/pindoconfig'
|
|
5
7
|
|
|
@@ -55,14 +57,22 @@ module Pindo
|
|
|
55
57
|
|
|
56
58
|
# 清理并重新安装 CocoaPods
|
|
57
59
|
# @param project_dir [String] 项目目录
|
|
58
|
-
|
|
60
|
+
# @param clean_podfile_lock [Boolean] 是否在安装前删除 Podfile.lock,默认为 true
|
|
61
|
+
def deintegrate_and_install(project_dir, clean_podfile_lock: true)
|
|
59
62
|
return unless File.exist?(File.join(project_dir, "Podfile"))
|
|
60
63
|
|
|
61
64
|
Dir.chdir(project_dir) do
|
|
62
65
|
begin
|
|
63
|
-
#
|
|
64
|
-
|
|
65
|
-
|
|
66
|
+
# 如果需要,删除 Podfile.lock
|
|
67
|
+
if clean_podfile_lock && File.exist?("Podfile.lock")
|
|
68
|
+
FileUtils.rm_rf("Podfile.lock")
|
|
69
|
+
puts "已删除 Podfile.lock"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# 删除 Pods 目录
|
|
73
|
+
if File.exist?("Pods")
|
|
74
|
+
FileUtils.rm_rf("Pods")
|
|
75
|
+
end
|
|
66
76
|
|
|
67
77
|
puts "正在执行 pod deintegrate..."
|
|
68
78
|
system 'pod deintegrate'
|
|
@@ -106,6 +116,119 @@ module Pindo
|
|
|
106
116
|
end
|
|
107
117
|
end
|
|
108
118
|
|
|
119
|
+
# 移除测试相关的 Pod 模块
|
|
120
|
+
# @param project_dir [String] 项目目录
|
|
121
|
+
# @return [Boolean] 是否成功
|
|
122
|
+
def remove_test_pods(project_dir)
|
|
123
|
+
pod_file = File.join(project_dir, "Podfile")
|
|
124
|
+
return false unless File.exist?(pod_file)
|
|
125
|
+
|
|
126
|
+
begin
|
|
127
|
+
# 测试插件列表
|
|
128
|
+
test_plugins = [
|
|
129
|
+
"FancySettingsPlugin",
|
|
130
|
+
"TYSettingsPlugin",
|
|
131
|
+
"CSSettingsPlugin",
|
|
132
|
+
"FunnySettingsPlugin"
|
|
133
|
+
]
|
|
134
|
+
|
|
135
|
+
# 使用 sed 命令删除测试插件
|
|
136
|
+
test_plugins.each do |plugin_name|
|
|
137
|
+
command = "sed -i \"\" \"/.*#{plugin_name}.*/d\" #{pod_file}"
|
|
138
|
+
system command
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
puts "已移除测试 Pod 模块"
|
|
142
|
+
true
|
|
143
|
+
rescue => e
|
|
144
|
+
puts "移除测试 Pod 模块失败: #{e.message}"
|
|
145
|
+
false
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# 从配置仓库拷贝 Podfile.lock 到项目目录
|
|
150
|
+
# @param project_dir [String] 项目目录
|
|
151
|
+
# @param app_config_dir [String] 应用配置目录
|
|
152
|
+
# @return [Boolean] 是否成功
|
|
153
|
+
def copy_podfile_lock_from_config(project_dir, app_config_dir)
|
|
154
|
+
begin
|
|
155
|
+
config_pod_file = File.join(app_config_dir, "Podfile.lock")
|
|
156
|
+
unless File.exist?(config_pod_file)
|
|
157
|
+
puts "配置仓库中不存在 Podfile.lock,跳过拷贝"
|
|
158
|
+
return false
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# 拷贝 Podfile.lock 到项目目录
|
|
162
|
+
project_pod_file = File.join(project_dir, "Podfile.lock")
|
|
163
|
+
FileUtils.cp(config_pod_file, project_pod_file)
|
|
164
|
+
|
|
165
|
+
puts "✅ 已从配置仓库拷贝 Podfile.lock"
|
|
166
|
+
true
|
|
167
|
+
rescue => error
|
|
168
|
+
puts "拷贝 Podfile.lock 失败: #{error.message}"
|
|
169
|
+
false
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# 备份 Podfile.lock 到配置仓库
|
|
174
|
+
# @param project_dir [String] 项目目录
|
|
175
|
+
# @param app_config_dir [String] 应用配置目录
|
|
176
|
+
# @param app_version [String] 应用版本号
|
|
177
|
+
# @return [Boolean] 是否成功
|
|
178
|
+
def backup_podfile_lock(project_dir, app_config_dir, app_version)
|
|
179
|
+
begin
|
|
180
|
+
proj_pod_file = File.join(project_dir, "Podfile.lock")
|
|
181
|
+
unless File.exist?(proj_pod_file)
|
|
182
|
+
puts "Podfile.lock 不存在,跳过备份"
|
|
183
|
+
return false
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# 复制 Podfile.lock 到配置仓库
|
|
187
|
+
FileUtils.cp(proj_pod_file, File.join(app_config_dir, "Podfile.lock"))
|
|
188
|
+
Pindo::GitHandler.git_addpush_repo(
|
|
189
|
+
path: app_config_dir,
|
|
190
|
+
message: "#{app_version} backup podfile.lock",
|
|
191
|
+
commit_file_params: ["Podfile.lock"]
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
# 计算 Podfile.lock 的 MD5 checksum
|
|
195
|
+
bytes = File.binread(proj_pod_file)
|
|
196
|
+
checksum = Digest::MD5.hexdigest(bytes)
|
|
197
|
+
|
|
198
|
+
# 更新 build_verify.json
|
|
199
|
+
build_verify_file = File.join(app_config_dir, "build_verify.json")
|
|
200
|
+
build_verify_json = {}
|
|
201
|
+
if File.exist?(build_verify_file)
|
|
202
|
+
begin
|
|
203
|
+
build_verify_json = JSON.parse(File.read(build_verify_file))
|
|
204
|
+
rescue => error
|
|
205
|
+
# 忽略解析错误,使用空 hash
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
build_verify_json["output_code_commit"] = Pindo::GitHandler.git_latest_commit_id(local_repo_dir: project_dir)
|
|
210
|
+
build_verify_json["output_config_commit"] = Pindo::GitHandler.git_latest_commit_id(local_repo_dir: app_config_dir)
|
|
211
|
+
build_verify_json["output_podfile_checksum"] = checksum
|
|
212
|
+
build_verify_json["output_time"] = Time.now.strftime('%y/%m/%d %H:%M:%S')
|
|
213
|
+
|
|
214
|
+
File.open(build_verify_file, "w") do |file|
|
|
215
|
+
file.write(JSON.pretty_generate(build_verify_json))
|
|
216
|
+
file.close
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
Pindo::GitHandler.git_addpush_repo(
|
|
220
|
+
path: app_config_dir,
|
|
221
|
+
message: "backup #{app_version} output info",
|
|
222
|
+
commit_file_params: ["build_verify.json"]
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
puts "✅ 已备份 Podfile.lock 到配置仓库"
|
|
226
|
+
true
|
|
227
|
+
rescue => error
|
|
228
|
+
raise Informative, "保存 Podfile.lock 文件失败: #{error.message}"
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
109
232
|
private
|
|
110
233
|
|
|
111
234
|
# 获取私有 Pod 索引地址
|
|
@@ -184,7 +184,7 @@ module Pindo
|
|
|
184
184
|
def sign_ipa_with_new_cert(ipa_name:, bundle_id:)
|
|
185
185
|
require 'pindo/config/pindoconfig'
|
|
186
186
|
|
|
187
|
-
profil_info_array = Pindo::
|
|
187
|
+
profil_info_array = Pindo::Pindoconfig.instance.get_cert_info
|
|
188
188
|
bundle_id_signing_identity = profil_info_array.first['signing_identity']
|
|
189
189
|
|
|
190
190
|
profile_dict = build_resign_profile_dict(profil_info_array: profil_info_array)
|
|
@@ -207,19 +207,20 @@ module Pindo
|
|
|
207
207
|
|
|
208
208
|
def install_launchimg(launchimg_pub_path:nil)
|
|
209
209
|
|
|
210
|
-
xcodeproj_launchimg_path = get_xcodeproj_launchimg_path
|
|
211
210
|
pub_launchimg_files = Dir.glob(File.join(launchimg_pub_path, "*.{png,jpg}"))
|
|
212
211
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
raise Informative, "有需要替换的资源,但是未找到工程启动图目录,替换启动图失败!"
|
|
216
|
-
end
|
|
212
|
+
# 如果配置仓库中没有启动图,直接跳过
|
|
213
|
+
if pub_launchimg_files.nil? || pub_launchimg_files.size == 0
|
|
217
214
|
return
|
|
218
215
|
end
|
|
219
216
|
|
|
220
|
-
#
|
|
221
|
-
|
|
222
|
-
|
|
217
|
+
# 配置仓库中有启动图,需要进行替换
|
|
218
|
+
xcodeproj_launchimg_path = get_xcodeproj_launchimg_path
|
|
219
|
+
|
|
220
|
+
# 如果项目中没有启动图目录,报错中断
|
|
221
|
+
if xcodeproj_launchimg_path.nil? || !File.exist?(xcodeproj_launchimg_path)
|
|
222
|
+
raise Informative, "配置仓库中有 #{pub_launchimg_files.size} 个启动图资源需要替换,但项目中未找到 LaunchImage.launchimage 目录,替换启动图失败!"
|
|
223
|
+
end
|
|
223
224
|
|
|
224
225
|
xcodeproj_launchimg_json_file = File.join(xcodeproj_launchimg_path, "Contents.json")
|
|
225
226
|
if !File.exist?(xcodeproj_launchimg_json_file)
|
|
@@ -218,11 +218,19 @@ module Pindo
|
|
|
218
218
|
def create_release_tag(project_dir:, config_json:, bundle_id:, delete_tag_name: nil)
|
|
219
219
|
require 'pindo/base/git_handler'
|
|
220
220
|
require 'pindo/config/pindoconfig'
|
|
221
|
+
require 'pindo/config/ios_config_parser'
|
|
221
222
|
require_relative '../../base/funlog'
|
|
222
223
|
|
|
223
224
|
begin
|
|
224
225
|
pindo_dir = File.expand_path(Pindo::Pindoconfig.instance.pindo_dir)
|
|
225
|
-
|
|
226
|
+
|
|
227
|
+
# 使用原始 Bundle ID(app_repo_name)访问配置仓库
|
|
228
|
+
# 在 AdHoc/AppStore 构建中,bundle_id 参数可能已被替换
|
|
229
|
+
# 需要使用 app_repo_name(原始 Bundle ID)访问正确的配置仓库
|
|
230
|
+
config_parser = Pindo::IosConfigParser.instance
|
|
231
|
+
app_repo_name = config_parser.app_repo_name || bundle_id # 回退到参数 bundle_id 以兼容独立命令
|
|
232
|
+
|
|
233
|
+
app_config_dir = File.join(pindo_dir, app_repo_name)
|
|
226
234
|
|
|
227
235
|
# 如果指定了要删除的 tag
|
|
228
236
|
if !delete_tag_name.nil? && !delete_tag_name.empty?
|
|
@@ -517,6 +517,11 @@ module Pindo
|
|
|
517
517
|
raise Informative, "无法从配置中获取 Bundle ID"
|
|
518
518
|
end
|
|
519
519
|
|
|
520
|
+
# 获取原始 Bundle ID(用于配置仓库名称)
|
|
521
|
+
# 在 AdHoc 构建中,bundle_id 已被替换为 AdHoc Bundle ID
|
|
522
|
+
# 需要使用 app_repo_name(原始 Bundle ID)来访问正确的配置仓库
|
|
523
|
+
app_repo_name = config_parser.app_repo_name
|
|
524
|
+
|
|
520
525
|
# 获取项目名称
|
|
521
526
|
project_fullname = Dir.glob(File.join(project_dir, "/*.xcodeproj")).max_by {|f| File.mtime(f)}
|
|
522
527
|
if project_fullname.nil? || !File.exist?(project_fullname)
|
|
@@ -526,7 +531,7 @@ module Pindo
|
|
|
526
531
|
|
|
527
532
|
# 1. 安装 Google Plist
|
|
528
533
|
Funlog.instance.fancyinfo_start("正在替换 google-info.plist...")
|
|
529
|
-
google_info_config_dir = Pindo::GitHandler.clong_buildconfig_repo(repo_name:
|
|
534
|
+
google_info_config_dir = Pindo::GitHandler.clong_buildconfig_repo(repo_name: app_repo_name)
|
|
530
535
|
Pindo::XcodeBuildHelper.install_google_plist(
|
|
531
536
|
project_dir: project_dir,
|
|
532
537
|
app_config_dir: google_info_config_dir
|
|
@@ -620,7 +625,7 @@ module Pindo
|
|
|
620
625
|
rescue StandardError => e
|
|
621
626
|
Funlog.instance.fancyinfo_error("配置 Xcode 项目失败: #{e.message}")
|
|
622
627
|
puts e.backtrace
|
|
623
|
-
|
|
628
|
+
raise Informative, "配置 Xcode 项目失败: #{e.message}"
|
|
624
629
|
end
|
|
625
630
|
|
|
626
631
|
end
|
|
@@ -286,12 +286,20 @@ module Pindo
|
|
|
286
286
|
require_relative '../../base/funlog'
|
|
287
287
|
require 'pindo/base/git_handler'
|
|
288
288
|
require 'pindo/config/pindoconfig'
|
|
289
|
+
require 'pindo/config/ios_config_parser'
|
|
289
290
|
|
|
290
291
|
begin
|
|
291
292
|
Funlog.instance.fancyinfo_start("正在执行 Swark 授权...")
|
|
292
293
|
|
|
293
294
|
pindo_dir = Pindo::Pindoconfig.instance.pindo_dir
|
|
294
|
-
|
|
295
|
+
|
|
296
|
+
# 使用原始 Bundle ID(app_repo_name)访问配置仓库
|
|
297
|
+
# 在 AdHoc 构建中,bundle_id 参数已被替换为 AdHoc Bundle ID
|
|
298
|
+
# 需要使用 app_repo_name(原始 Bundle ID)访问正确的配置仓库
|
|
299
|
+
config_parser = Pindo::IosConfigParser.instance
|
|
300
|
+
app_repo_name = config_parser.app_repo_name || bundle_id # 回退到参数 bundle_id 以兼容独立命令
|
|
301
|
+
|
|
302
|
+
app_config_dir = File.join(File.expand_path(pindo_dir), app_repo_name)
|
|
295
303
|
swark_authorize_file = File.join(app_config_dir, "swark_authorize.json")
|
|
296
304
|
|
|
297
305
|
unless File.exist?(swark_authorize_file)
|
data/lib/pindo/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pindo
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 5.13.
|
|
4
|
+
version: 5.13.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- wade
|
|
@@ -441,6 +441,7 @@ files:
|
|
|
441
441
|
- lib/pindo/module/task/model/build/web_build_dev_task.rb
|
|
442
442
|
- lib/pindo/module/task/model/build_task.rb
|
|
443
443
|
- lib/pindo/module/task/model/git_tag_task.rb
|
|
444
|
+
- lib/pindo/module/task/model/ipa_local_resign_task.rb
|
|
444
445
|
- lib/pindo/module/task/model/jps_resign_task.rb
|
|
445
446
|
- lib/pindo/module/task/model/jps_upload_task.rb
|
|
446
447
|
- lib/pindo/module/task/model/unity_export_task.rb
|