pindo 5.13.5 → 5.13.7
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/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/fixproj.rb +92 -0
- data/lib/pindo/command/ios.rb +1 -0
- data/lib/pindo/command/jps/upload.rb +1 -1
- data/lib/pindo/module/pgyer/pgyerhelper.rb +163 -1
- 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/ipa_resign_helper.rb +1 -1
- data/lib/pindo/module/xcode/xcode_build_helper.rb +3 -3
- data/lib/pindo/version.rb +1 -1
- metadata +3 -1
|
@@ -220,6 +220,168 @@ module Pindo
|
|
|
220
220
|
}
|
|
221
221
|
end
|
|
222
222
|
|
|
223
|
+
# AdHoc 专用工作流选择
|
|
224
|
+
# 筛选条件:
|
|
225
|
+
# 1. package_type 匹配
|
|
226
|
+
# 2. tab_name 必须包含 "提交包"
|
|
227
|
+
#
|
|
228
|
+
# @param project_id [String] 项目ID
|
|
229
|
+
# @param package_type [String] 包类型(ipa/apk/zip/app)
|
|
230
|
+
# @return [Hash] 选择的工作流信息
|
|
231
|
+
def select_workflow_for_adhoc(project_id:, package_type:)
|
|
232
|
+
# 1. 从 JPS API 获取可用工作流列表
|
|
233
|
+
workflow_result = @pgyer_client.get_project_workflows(project_id: project_id)
|
|
234
|
+
|
|
235
|
+
if workflow_result.nil? || workflow_result['data'].nil?
|
|
236
|
+
raise Informative, "获取工作流列表失败"
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
workflows = workflow_result['data']
|
|
240
|
+
|
|
241
|
+
if workflows.empty?
|
|
242
|
+
raise Informative, "该项目没有可用的工作流"
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
# 2. 第一层过滤:根据 package_type
|
|
246
|
+
filtered_by_type = workflows.select do |w|
|
|
247
|
+
if w['packageType']
|
|
248
|
+
case package_type
|
|
249
|
+
when 'ipa'
|
|
250
|
+
w['packageType'] == 'ipa'
|
|
251
|
+
when 'apk'
|
|
252
|
+
w['packageType'] == 'apk'
|
|
253
|
+
when 'zip'
|
|
254
|
+
w['packageType'] == 'zip'
|
|
255
|
+
when 'app'
|
|
256
|
+
w['packageType'] == 'app'
|
|
257
|
+
else
|
|
258
|
+
true
|
|
259
|
+
end
|
|
260
|
+
else
|
|
261
|
+
# 如果没有 packageType 字段,保留(后续通过名称筛选)
|
|
262
|
+
true
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
# 3. 第二层过滤:tab_name 必须包含 "提交包"
|
|
267
|
+
adhoc_workflows = filtered_by_type.select do |w|
|
|
268
|
+
tab_name = w['tabName'] || w['tab_name'] || ''
|
|
269
|
+
tab_name.include?('提交包')
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
if adhoc_workflows.empty?
|
|
273
|
+
raise Informative, "未找到符合条件的 AdHoc 工作流\n" \
|
|
274
|
+
"要求:package_type=#{package_type} 且 tab_name 包含 '提交包'\n" \
|
|
275
|
+
"请检查 JPS 工作流配置"
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
# 4. 根据匹配数量决定选择方式
|
|
279
|
+
workflow = nil
|
|
280
|
+
|
|
281
|
+
if adhoc_workflows.size == 1
|
|
282
|
+
# 只有 1 个匹配,自动选择
|
|
283
|
+
workflow = adhoc_workflows.first
|
|
284
|
+
else
|
|
285
|
+
# 有多个匹配,让用户选择
|
|
286
|
+
require 'highline/import'
|
|
287
|
+
cli = HighLine.new
|
|
288
|
+
|
|
289
|
+
workflow_choices = adhoc_workflows.map do |w|
|
|
290
|
+
tab_name = w['tabName'] || w['tab_name']
|
|
291
|
+
workflow_id = w['id'] || w['workflow_id']
|
|
292
|
+
"#{tab_name} (ID: #{workflow_id})"
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
selected = cli.choose do |menu|
|
|
296
|
+
menu.prompt = "请选择 AdHoc 工作流:"
|
|
297
|
+
menu.choices(*workflow_choices)
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
# 提取选择的工作流
|
|
301
|
+
selected_index = workflow_choices.index(selected)
|
|
302
|
+
workflow = adhoc_workflows[selected_index]
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
# 5. 返回标准化的工作流信息
|
|
306
|
+
{
|
|
307
|
+
workflow_id: workflow['id'] || workflow['workflow_id'],
|
|
308
|
+
tab_name: workflow['tabName'] || workflow['tab_name'],
|
|
309
|
+
package_type: workflow['packageType'] || package_type,
|
|
310
|
+
package_name: workflow['packageName'] || workflow['package_name'] || '',
|
|
311
|
+
manage_type: workflow['manageType'] || workflow['manage_type'] || ''
|
|
312
|
+
}
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
# 获取 AdHoc 上传信息
|
|
316
|
+
# 用于 adhoc 编译命令,不保存配置到 JPSBuildConfig.json
|
|
317
|
+
#
|
|
318
|
+
# @param working_directory [String] 工作目录
|
|
319
|
+
# @param package_type [String] 包类型(ipa/apk/zip/app)
|
|
320
|
+
# @param proj_name [String] 项目名称(可选)
|
|
321
|
+
# @param skip_config_file [Boolean] 是否跳过从 config.json 获取项目名称(默认 false)
|
|
322
|
+
# @return [Array] [app_info_obj, workflow_info]
|
|
323
|
+
def get_adhoc_upload_info(working_directory:, package_type:, proj_name: nil, skip_config_file: false)
|
|
324
|
+
upload_proj_name = proj_name
|
|
325
|
+
|
|
326
|
+
# 1. 项目名称获取逻辑
|
|
327
|
+
# 1.1 如果 proj_name 为空,从环境变量获取
|
|
328
|
+
if upload_proj_name.nil? || upload_proj_name.empty?
|
|
329
|
+
upload_proj_name = ENV['PINDO_PROJECT_NAME']
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
# 1.2 如果仍为空且未禁用,从 IosConfigParser 获取
|
|
333
|
+
if (upload_proj_name.nil? || upload_proj_name.empty?) && !skip_config_file
|
|
334
|
+
require 'pindo/config/ios_config_parser'
|
|
335
|
+
config_parser = Pindo::IosConfigParser.instance
|
|
336
|
+
if config_parser.config_json
|
|
337
|
+
upload_proj_name = config_parser.config_json.dig("project_info", "project_name")
|
|
338
|
+
end
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
# 1.3 如果还是为空,让用户输入
|
|
342
|
+
if upload_proj_name.nil? || upload_proj_name.empty?
|
|
343
|
+
require 'highline/import'
|
|
344
|
+
puts "\n未找到项目名称配置"
|
|
345
|
+
upload_proj_name = ask("请输入 JPS 项目名称: ") do |q|
|
|
346
|
+
q.validate = /\S+/
|
|
347
|
+
q.responses[:not_valid] = "项目名称不能为空"
|
|
348
|
+
end
|
|
349
|
+
upload_proj_name = upload_proj_name.strip if upload_proj_name
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
# 2. 确保已登录
|
|
353
|
+
unless login
|
|
354
|
+
raise Informative, "请先登录 JPS 网站"
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
# 3. 获取 app_info_obj
|
|
358
|
+
app_info_obj = find_app_info_with_obj_list(proj_name: upload_proj_name)
|
|
359
|
+
|
|
360
|
+
unless app_info_obj
|
|
361
|
+
raise Informative, "未找到项目: #{upload_proj_name},请检查项目名称是否正确"
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
# 4. 获取 AdHoc 工作流(调用专用函数)
|
|
365
|
+
workflow_info = select_workflow_for_adhoc(
|
|
366
|
+
project_id: app_info_obj["id"],
|
|
367
|
+
package_type: package_type
|
|
368
|
+
)
|
|
369
|
+
|
|
370
|
+
unless workflow_info
|
|
371
|
+
raise Informative, "未能获取 AdHoc 工作流信息"
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
# 5. 输出最终选择的项目和工作流
|
|
375
|
+
puts "\n✓ 项目: #{app_info_obj['projectName']}"
|
|
376
|
+
puts "✓ 工作流: #{workflow_info[:tab_name]}"
|
|
377
|
+
|
|
378
|
+
# 6. 保存项目名称到实例变量
|
|
379
|
+
@proj_name = upload_proj_name
|
|
380
|
+
|
|
381
|
+
# 7. 返回结果(不保存配置到 JPSBuildConfig.json)
|
|
382
|
+
return app_info_obj, workflow_info
|
|
383
|
+
end
|
|
384
|
+
|
|
223
385
|
def prepare_upload(working_directory:nil, proj_name:nil, package_type:nil)
|
|
224
386
|
upload_proj_name = proj_name
|
|
225
387
|
if upload_proj_name.nil? || upload_proj_name.empty?
|
|
@@ -508,7 +670,7 @@ module Pindo
|
|
|
508
670
|
args_ipa_file_dir = File.expand_path(File::dirname(ipa_file_upload))
|
|
509
671
|
ipa_file_upload=File.join(args_ipa_file_dir, File.basename(ipa_file_upload))
|
|
510
672
|
current_project_dir = Dir.pwd
|
|
511
|
-
description = get_description_from_git(current_project_dir:current_project_dir)
|
|
673
|
+
# description = get_description_from_git(current_project_dir:current_project_dir)
|
|
512
674
|
# get_description_from_git 现在会在失败时抛出异常,成功时返回有效的描述
|
|
513
675
|
# 所以不需要再检查 nil 或空值
|
|
514
676
|
|
|
@@ -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
|
|
@@ -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)
|
|
@@ -356,7 +356,7 @@ module Pindo
|
|
|
356
356
|
|
|
357
357
|
end
|
|
358
358
|
|
|
359
|
-
# 修复
|
|
359
|
+
# 修复Xcode 26 链接器兼容性问题
|
|
360
360
|
# 自动移除 -ld_classic 和 -ld64 标志
|
|
361
361
|
def fix_xcode16_linker_flags(project_dir: nil)
|
|
362
362
|
begin
|
|
@@ -428,11 +428,11 @@ module Pindo
|
|
|
428
428
|
end
|
|
429
429
|
|
|
430
430
|
if fixed_count > 0
|
|
431
|
-
puts "✅ 修复
|
|
431
|
+
puts "✅ 修复Xcode 26 链接器兼容性配置".green
|
|
432
432
|
end
|
|
433
433
|
|
|
434
434
|
rescue => error
|
|
435
|
-
puts "⚠️
|
|
435
|
+
puts "⚠️ 修复Xcode 26 链接器标志时出现错误: #{error.message}".yellow
|
|
436
436
|
# 不中断构建流程
|
|
437
437
|
end
|
|
438
438
|
end
|
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.7
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- wade
|
|
@@ -355,6 +355,7 @@ files:
|
|
|
355
355
|
- lib/pindo/command/ios/autoresign.rb
|
|
356
356
|
- lib/pindo/command/ios/build.rb
|
|
357
357
|
- lib/pindo/command/ios/cert.rb
|
|
358
|
+
- lib/pindo/command/ios/fixproj.rb
|
|
358
359
|
- lib/pindo/command/ios/podlint.rb
|
|
359
360
|
- lib/pindo/command/ios/podpush.rb
|
|
360
361
|
- lib/pindo/command/ios/podupdate.rb
|
|
@@ -441,6 +442,7 @@ files:
|
|
|
441
442
|
- lib/pindo/module/task/model/build/web_build_dev_task.rb
|
|
442
443
|
- lib/pindo/module/task/model/build_task.rb
|
|
443
444
|
- lib/pindo/module/task/model/git_tag_task.rb
|
|
445
|
+
- lib/pindo/module/task/model/ipa_local_resign_task.rb
|
|
444
446
|
- lib/pindo/module/task/model/jps_resign_task.rb
|
|
445
447
|
- lib/pindo/module/task/model/jps_upload_task.rb
|
|
446
448
|
- lib/pindo/module/task/model/unity_export_task.rb
|