pindo 5.13.12 → 5.13.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/lib/pindo/base/funlog.rb +62 -5
  3. data/lib/pindo/base/git_handler.rb +83 -22
  4. data/lib/pindo/base/output_sink.rb +69 -0
  5. data/lib/pindo/command/android/autobuild.rb +57 -8
  6. data/lib/pindo/command/appstore/autobuild.rb +10 -1
  7. data/lib/pindo/command/ios/autobuild.rb +59 -7
  8. data/lib/pindo/command/jps/media.rb +164 -13
  9. data/lib/pindo/command/jps/upload.rb +14 -9
  10. data/lib/pindo/command/unity/autobuild.rb +64 -10
  11. data/lib/pindo/command/utils/tag.rb +9 -1
  12. data/lib/pindo/command/web/autobuild.rb +59 -10
  13. data/lib/pindo/module/android/android_build_helper.rb +6 -7
  14. data/lib/pindo/module/build/git_repo_helper.rb +29 -25
  15. data/lib/pindo/module/pgyer/pgyerhelper.rb +174 -77
  16. data/lib/pindo/module/task/core/concurrent_execution_strategy.rb +237 -0
  17. data/lib/pindo/module/task/core/dependency_checker.rb +123 -0
  18. data/lib/pindo/module/task/core/execution_strategy.rb +61 -0
  19. data/lib/pindo/module/task/core/resource_lock_manager.rb +190 -0
  20. data/lib/pindo/module/task/core/serial_execution_strategy.rb +60 -0
  21. data/lib/pindo/module/task/core/task_executor.rb +131 -0
  22. data/lib/pindo/module/task/core/task_queue.rb +221 -0
  23. data/lib/pindo/module/task/model/build/android_build_dev_task.rb +1 -1
  24. data/lib/pindo/module/task/model/build/android_build_task.rb +6 -2
  25. data/lib/pindo/module/task/model/build/ios_build_dev_task.rb +2 -3
  26. data/lib/pindo/module/task/model/build/ios_build_task.rb +6 -0
  27. data/lib/pindo/module/task/model/build_task.rb +22 -0
  28. data/lib/pindo/module/task/model/git/git_commit_task.rb +11 -2
  29. data/lib/pindo/module/task/model/git_task.rb +6 -0
  30. data/lib/pindo/module/task/model/jps/jps_message_task.rb +9 -11
  31. data/lib/pindo/module/task/model/jps/jps_upload_media_task.rb +204 -103
  32. data/lib/pindo/module/task/model/jps_task.rb +0 -1
  33. data/lib/pindo/module/task/model/unity_task.rb +38 -2
  34. data/lib/pindo/module/task/output/multi_line_output_manager.rb +380 -0
  35. data/lib/pindo/module/task/output/multi_line_task_display.rb +185 -0
  36. data/lib/pindo/module/task/output/stdout_redirector.rb +95 -0
  37. data/lib/pindo/module/task/pindo_task.rb +133 -9
  38. data/lib/pindo/module/task/task_manager.rb +98 -268
  39. data/lib/pindo/module/task/task_reporter.rb +135 -0
  40. data/lib/pindo/module/task/task_resources/resource_instance.rb +90 -0
  41. data/lib/pindo/module/task/task_resources/resource_registry.rb +105 -0
  42. data/lib/pindo/module/task/task_resources/resource_type.rb +59 -0
  43. data/lib/pindo/module/task/task_resources/types/directory_based_resource.rb +63 -0
  44. data/lib/pindo/module/task/task_resources/types/global_exclusive_resource.rb +33 -0
  45. data/lib/pindo/module/task/task_resources/types/global_shared_resource.rb +34 -0
  46. data/lib/pindo/module/xcode/xcode_build_helper.rb +26 -8
  47. data/lib/pindo/options/groups/jps_options.rb +10 -0
  48. data/lib/pindo/options/groups/task_options.rb +39 -0
  49. data/lib/pindo/version.rb +3 -2
  50. metadata +20 -1
@@ -2,6 +2,7 @@ require 'pindo/module/pgyer/pgyerhelper'
2
2
  require 'pindo/module/task/task_manager'
3
3
  require 'pindo/module/task/model/jps/jps_upload_media_task'
4
4
  require 'pindo/options/options'
5
+ require 'pindo/options/groups/task_options'
5
6
 
6
7
  module Pindo
7
8
  class Command
@@ -20,6 +21,7 @@ module Pindo
20
21
  * 自动关联到当前 HEAD commit 记录
21
22
  * 支持追加模式(保留已有附件)
22
23
  * 自动模式:从项目 JPSMedia/ 目录查找 3 小时内的文件
24
+ * 支持选择历史 commit(使用 --select 参数)
23
25
 
24
26
  使用示例:
25
27
 
@@ -29,6 +31,10 @@ module Pindo
29
31
 
30
32
  $ pindo jps media --proj=demo # 指定项目
31
33
 
34
+ $ pindo jps media --select # 交互式选择历史 commit
35
+
36
+ $ pindo jps media --select path/to/file.png # 选择 commit 并上传指定文件
37
+
32
38
  DESC
33
39
 
34
40
  self.arguments = [
@@ -38,7 +44,8 @@ module Pindo
38
44
  # 定义此命令使用的参数项
39
45
  def self.option_items
40
46
  @option_items ||= Pindo::Options::OptionGroup.merge(
41
- Pindo::Options::JPSOptions.only(:proj),
47
+ Pindo::Options::JPSOptions.select(:proj),
48
+ Pindo::Options::TaskOptions.select(:select),
42
49
  Pindo::Options::GitOptions.all
43
50
  )
44
51
  end
@@ -60,11 +67,8 @@ module Pindo
60
67
  # JPS 参数
61
68
  @args_proj_name = @options[:proj]
62
69
 
63
- # Git 参数
64
- @args_release_branch = @options[:release_branch] || 'master'
65
- @args_ver_inc = Pindo::Options::GitOptions.parse_version_increase_type(@options[:ver_inc] || 'mini')
66
- @args_tag_type = Pindo::Options::GitOptions.parse_create_tag_type(@options[:tag_type] || 'new')
67
- @args_tag_pre = @options[:tag_pre] || 'v'
70
+ # Task 参数
71
+ @args_select_flag = @options[:select] || false
68
72
 
69
73
  super(argv)
70
74
  end
@@ -76,11 +80,30 @@ module Pindo
76
80
  def run
77
81
  project_path = Dir.pwd
78
82
 
83
+ # 如果启用 --select 参数,获取用户选择的 commit
84
+ selected_commit_info = nil
85
+ if @args_select_flag
86
+ selected_commit_info = select_git_commit(project_path)
87
+
88
+ if selected_commit_info.nil?
89
+ puts "未选择任何提交,已取消操作"
90
+ return
91
+ end
92
+
93
+ puts "\n已选择提交:"
94
+ puts " Commit ID: #{selected_commit_info[:commit_id][0..7]}"
95
+ puts " 时间: #{selected_commit_info[:commit_time]}"
96
+ puts " 描述: #{selected_commit_info[:commit_desc]}"
97
+ puts ""
98
+ end
99
+
79
100
  # 获取 JPS 配置(app_info_obj 和 workflow_info)
101
+ # 使用 manage_type: "git" 来获取 git 管理类型的工作流
80
102
  app_info_obj, workflow_info = PgyerHelper.share_instace.prepare_upload(
81
103
  working_directory: project_path,
82
104
  proj_name: @args_proj_name,
83
- package_type: 'ipa' # 任意类型,只是为了获取 workflow_id
105
+ package_type: "", # package_type 在 manage_type=git 时会被忽略
106
+ manage_type: "git"
84
107
  )
85
108
 
86
109
  if app_info_obj.nil?
@@ -88,23 +111,51 @@ module Pindo
88
111
  end
89
112
 
90
113
  # 获取 workflow_id
91
- workflow_id = workflow_info&.dig('id')
114
+ workflow_id = workflow_info&.dig(:workflow_id) || workflow_info&.dig('id')
115
+
116
+ # 创建任务链
117
+ tasks = []
92
118
 
93
- # 创建并执行任务
119
+ # 1. 提前询问用户如何处理未提交的文件
120
+ process_type = Pindo::GitHandler.get_uncommitted_files_process_type(
121
+ project_dir: project_path,
122
+ interactive: true
123
+ )
124
+
125
+ # 2. 创建 Git 提交任务
126
+ git_commit_task = Pindo::TaskSystem::GitCommitTask.new(
127
+ project_path,
128
+ {
129
+ process_type: process_type,
130
+ commit_message: "feat: jps media 上传前提交"
131
+ }
132
+ )
133
+ tasks << git_commit_task
134
+
135
+ # 3. 创建 JPS Media 上传任务
94
136
  # 所有逻辑都在 Task 中处理:
95
137
  # - 自动查找 git 仓库和 HEAD 信息
96
138
  # - 展开文件路径(通配符、目录)
97
139
  # - 自动查找 JPSMedia/ 目录
98
140
  # - 匹配 git_commit_id 到 JPS commit_log
99
- task = Pindo::TaskSystem::JPSUploadMediaTask.new(
141
+ media_upload_task = Pindo::TaskSystem::JPSUploadMediaTask.new(
100
142
  @file_paths,
101
- workflow_id: workflow_id,
102
- project_path: project_path
143
+ project_path, # upload_path
144
+ app_info_obj: app_info_obj,
145
+ workflow_info: workflow_info,
146
+ project_name: @args_proj_name,
147
+ git_commit_id: selected_commit_info&.dig(:commit_id),
148
+ git_commit_time: selected_commit_info&.dig(:commit_time),
149
+ git_commit_desc: selected_commit_info&.dig(:commit_desc)
103
150
  )
151
+ # Media 上传任务依赖 Git 提交任务
152
+ media_upload_task.dependencies << git_commit_task.id
153
+ tasks << media_upload_task
104
154
 
155
+ # 执行任务链
105
156
  task_manager = Pindo::TaskSystem::TaskManager.instance
106
157
  task_manager.clear_all
107
- task_manager.add_task(task)
158
+ tasks.each { |task| task_manager.add_task(task) }
108
159
  task_manager.start
109
160
 
110
161
  # 输出结果
@@ -116,6 +167,106 @@ module Pindo
116
167
  end
117
168
  end
118
169
 
170
+ private
171
+
172
+ # 交互式选择 git commit
173
+ # @param project_path [String] 项目路径
174
+ # @return [Hash, nil] 包含 :commit_id, :commit_time, :commit_desc,或 nil(取消)
175
+ def select_git_commit(project_path)
176
+ # 1. 查找 git 根目录
177
+ git_root = find_git_root(project_path)
178
+ unless git_root
179
+ raise Informative, "当前目录不是 git 仓库"
180
+ end
181
+
182
+ # 2. 获取最近 15 条 commit 历史
183
+ all_commits = get_recent_commits(git_root, limit: 15)
184
+
185
+ if all_commits.empty?
186
+ raise Informative, "未找到 git commit 历史"
187
+ end
188
+
189
+ # 3. 筛选符合规范的提交(以 feat:, fix: 等开头)
190
+ valid_prefixes = ['feat:', 'fix:', 'docs:', 'style:', 'refactor:', 'perf:', 'test:', 'build:', 'ci:', 'chore:', 'revert:']
191
+ commits = all_commits.select do |commit|
192
+ desc = commit[:commit_desc].to_s.strip
193
+ valid_prefixes.any? { |prefix| desc.downcase.start_with?(prefix) }
194
+ end
195
+
196
+ # 如果没有符合规范的提交,提示用户并使用全部提交
197
+ if commits.empty?
198
+ puts "\n警告:在最近15个提交中未找到符合规范的提交(feat:, fix: 等开头)"
199
+ puts "显示所有提交供您选择:"
200
+ commits = all_commits
201
+ else
202
+ puts "\n从最近15个提交中筛选出 #{commits.size} 个符合规范的提交:"
203
+ end
204
+
205
+ # 4. 显示 commit 列表
206
+ puts "\n请选择要上传 media 的 git 提交:"
207
+ puts "━" * 80
208
+ commits.each_with_index do |commit, index|
209
+ puts "#{index + 1}. [#{commit[:commit_id][0..7]}] #{commit[:commit_time]} - #{commit[:commit_desc]}"
210
+ end
211
+ puts "0. 取消操作"
212
+ puts "━" * 80
213
+
214
+ # 5. 获取用户选择
215
+ choice = nil
216
+ loop do
217
+ print "\n请输入序号 (0-#{commits.size}): "
218
+ input = $stdin.gets.strip
219
+
220
+ choice = input.to_i
221
+ break if choice >= 0 && choice <= commits.size
222
+
223
+ puts "无效输入,请输入 0-#{commits.size} 之间的数字"
224
+ end
225
+
226
+ # 6. 返回选择的 commit(0 表示取消)
227
+ choice == 0 ? nil : commits[choice - 1]
228
+ end
229
+
230
+ # 查找 git 根目录
231
+ # @param path [String] 起始路径
232
+ # @return [String, nil] git 根目录,未找到返回 nil
233
+ def find_git_root(path)
234
+ current = File.expand_path(path)
235
+ while current != '/'
236
+ if File.exist?(File.join(current, '.git'))
237
+ return current
238
+ end
239
+ current = File.dirname(current)
240
+ end
241
+ nil
242
+ end
243
+
244
+ # 获取最近的 git commits
245
+ # @param git_root [String] git 根目录
246
+ # @param limit [Integer] 获取的 commit 数量
247
+ # @return [Array<Hash>] commit 列表,每个元素包含 :commit_id, :commit_time, :commit_desc
248
+ def get_recent_commits(git_root, limit: 20)
249
+ Dir.chdir(git_root) do
250
+ # 使用 git log 获取 commit 历史
251
+ # 格式:commit_id|commit_time|commit_desc
252
+ output = `git log -#{limit} --format="%H|%ci|%s" 2>/dev/null`.strip
253
+
254
+ return [] if output.empty?
255
+
256
+ output.split("\n").map do |line|
257
+ parts = line.split('|', 3)
258
+ {
259
+ commit_id: parts[0],
260
+ commit_time: parts[1],
261
+ commit_desc: parts[2]
262
+ }
263
+ end
264
+ end
265
+ rescue => e
266
+ Funlog.instance.fancyinfo_error("获取 git commit 历史失败: #{e.message}")
267
+ []
268
+ end
269
+
119
270
  end
120
271
  end
121
272
  end
@@ -8,7 +8,6 @@ require 'pindo/module/build/build_helper'
8
8
  require 'pindo/module/task/task_manager'
9
9
  require 'pindo/module/task/model/jps/jps_upload_task'
10
10
  require 'pindo/module/task/model/git/git_commit_task'
11
- require 'pindo/module/task/model/git/git_tag_task'
12
11
  require 'pindo/options/options'
13
12
 
14
13
  module Pindo
@@ -164,20 +163,26 @@ module Pindo
164
163
  }
165
164
 
166
165
  # 1. Git 提交和标签任务
166
+ # 1.0 提前询问用户如何处理未提交的文件
167
+ process_type = Pindo::GitHandler.get_uncommitted_files_process_type(
168
+ project_dir: project_dir,
169
+ interactive: true
170
+ )
171
+
172
+ git_options_with_process = git_options.merge({
173
+ process_type: process_type,
174
+ commit_message: "feat: jps upload 构建前提交"
175
+ })
176
+
167
177
  # 1.1 Git 提交任务
168
- git_commit_task = Pindo::TaskSystem::GitCommitTask.new(project_dir, git_options)
178
+ git_commit_task = Pindo::TaskSystem::GitCommitTask.new(project_dir, git_options_with_process)
169
179
  tasks << git_commit_task
170
180
 
171
- # 1.2 Git 标签任务(依赖提交任务)
172
- git_tag_task = Pindo::TaskSystem::GitTagTask.new(project_dir, git_options)
173
- git_tag_task.dependencies << git_commit_task.id
174
- tasks << git_tag_task
175
-
176
181
  # 2. 查找并创建上传任务
177
182
  upload_tasks = find_and_create_upload_tasks(project_dir)
178
- # 让所有上传任务依赖 Git Tag 任务
183
+ # 让所有上传任务依赖 Git 提交任务
179
184
  upload_tasks.each do |upload_task|
180
- upload_task.dependencies << git_tag_task.id
185
+ upload_task.dependencies << git_commit_task.id
181
186
  end
182
187
  tasks.concat(upload_tasks)
183
188
 
@@ -13,12 +13,14 @@ require 'pindo/module/task/model/unity/unity_update_task'
13
13
  require 'pindo/module/task/model/unity/unity_yoo_asset_task'
14
14
  require 'pindo/module/task/model/unity/unity_export_task'
15
15
  require 'pindo/module/task/model/jps/jps_upload_task'
16
+ require 'pindo/module/task/model/jps/jps_upload_media_task'
16
17
  require 'pindo/module/task/model/jps/jps_message_task'
17
18
  require 'pindo/module/task/model/git/git_commit_task'
18
19
  require 'pindo/module/task/model/git/git_tag_task'
19
20
  require 'pindo/config/build_info_manager'
20
21
  require 'pindo/config/ios_config_parser'
21
22
  require 'pindo/options/options'
23
+ require 'pindo/options/groups/task_options'
22
24
 
23
25
  module Pindo
24
26
  class Command
@@ -50,9 +52,13 @@ module Pindo
50
52
 
51
53
  * 支持发送测试通知
52
54
 
55
+ * 支持并发任务执行(使用 --multi 参数)
56
+
53
57
  使用示例:
54
58
 
55
- $ pindo unity autobuild # 编译所有类型(默认)
59
+ $ pindo unity autobuild # 编译所有类型(默认串行执行)
60
+
61
+ $ pindo unity autobuild --multi # 使用并发模式执行(速度更快)
56
62
 
57
63
  $ pindo unity autobuild --types=ipa # 仅编译IPA
58
64
 
@@ -63,6 +69,10 @@ module Pindo
63
69
  $ pindo unity autobuild --upload # 编译所有类型并上传到JPS
64
70
 
65
71
  $ pindo unity autobuild --proj="My App" # 指定项目名称
72
+
73
+ $ pindo unity autobuild --media # 编译并上传媒体附件
74
+
75
+ $ pindo unity autobuild --multi --upload # 并发执行并上传
66
76
  DESC
67
77
 
68
78
  # 命令参数
@@ -73,9 +83,10 @@ module Pindo
73
83
  # 定义此命令使用的参数项
74
84
  def self.option_items
75
85
  @option_items ||= Pindo::Options::OptionGroup.merge(
76
- Pindo::Options::JPSOptions.select(:proj, :upload, :send),
86
+ Pindo::Options::JPSOptions.select(:proj, :upload, :send, :media),
77
87
  Pindo::Options::UnityOptions.select(:skiplib, :skipyoo),
78
88
  Pindo::Options::UnityOptions.select_with_defaults(skipconfig: true),
89
+ Pindo::Options::TaskOptions.select(:multi),
79
90
  Pindo::Options::GitOptions.all
80
91
  )
81
92
  end
@@ -99,6 +110,7 @@ module Pindo
99
110
  @args_proj_name = @options[:proj]
100
111
  @args_upload_flag = @options[:upload] || false
101
112
  @args_send_flag = @options[:send] || false
113
+ @args_media_flag = @options[:media] || false
102
114
  @args_adhoc_flag = argv.flag?('adhoc', false)
103
115
  @args_deploy_flag = argv.flag?('deploy', false)
104
116
  @args_release_flag = argv.flag?('release', false)
@@ -108,14 +120,17 @@ module Pindo
108
120
  @args_skip_lib = @options[:skiplib] || false
109
121
  @args_skip_yoo = @options[:skipyoo] || false
110
122
 
123
+ # Task 参数
124
+ @args_multi_flag = @options[:multi] || false
125
+
111
126
  # Git 参数
112
127
  @args_release_branch = @options[:release_branch] || 'master'
113
128
  @args_ver_inc = Pindo::Options::GitOptions.parse_version_increase_type(@options[:ver_inc] || 'mini')
114
129
  @args_tag_type = Pindo::Options::GitOptions.parse_create_tag_type(@options[:tag_type] || 'new')
115
130
  @args_tag_pre = @options[:tag_pre] || 'v'
116
131
 
117
- # 如果开启 send,自动开启 upload
118
- if @args_send_flag
132
+ # 如果开启 send 或 media,自动开启 upload
133
+ if @args_send_flag || @args_media_flag
119
134
  @args_upload_flag = true
120
135
  end
121
136
 
@@ -180,8 +195,18 @@ module Pindo
180
195
  task_manager.add_task(task)
181
196
  end
182
197
 
183
- # 执行任务
184
- task_manager.start
198
+ # # 启用输出管理(自动处理多线程日志隔离)
199
+ # task_manager.enable_output_management(
200
+ # log_dir: File.join(pindo_project_dir, 'pindo_logs'),
201
+ # max_lines_per_task: 0
202
+ # )
203
+
204
+ # 执行任务(根据 --multi 参数决定模式)
205
+ if @args_multi_flag
206
+ task_manager.start(mode: :concurrent, max_workers: 3)
207
+ else
208
+ task_manager.start(mode: :serial)
209
+ end
185
210
  end
186
211
 
187
212
  # 按平台顺序创建所有任务
@@ -194,12 +219,20 @@ module Pindo
194
219
  selected_platforms = selected_platforms.sort_by { |p| platform_order.index(p) || 999 }
195
220
 
196
221
  # 第零步:创建 Git 提交任务
222
+ # 提前询问用户如何处理未提交的文件
223
+ process_type = Pindo::GitHandler.get_uncommitted_files_process_type(
224
+ project_dir: Dir.pwd,
225
+ interactive: true # 允许交互,因为这是在任务执行前的主线程中
226
+ )
227
+
197
228
  git_commit_task = Pindo::TaskSystem::GitCommitTask.new(
198
229
  Dir.pwd,
199
230
  release_branch: @args_release_branch,
200
231
  ver_inc: @args_ver_inc,
201
232
  tag_type: @args_tag_type,
202
- tag_pre: @args_tag_pre
233
+ tag_pre: @args_tag_pre,
234
+ process_type: process_type,
235
+ commit_message: "feat: unity autobuild 构建前提交"
203
236
  )
204
237
  all_tasks << git_commit_task
205
238
 
@@ -293,19 +326,40 @@ module Pindo
293
326
  upload_task = create_upload_task(platform, all_platform_configs, build_task)
294
327
  all_tasks << upload_task
295
328
 
296
- # 创建消息发送任务(依赖上传任务)
329
+ # 创建消息发送任务(只依赖上传任务)
297
330
  message_task = Pindo::TaskSystem::JPSMessageTask.new(
298
331
  nil, # app_version_info 为 nil,从依赖任务获取
299
332
  app_info_obj: all_platform_configs["app_info_obj"],
300
333
  project_name: all_platform_configs["project_name"],
301
334
  send_message_type: @args_send_flag ? 'group' : 'self',
302
- data_dependencies: [upload_task.id] # 从 upload_task 获取数据
335
+ dependencies: [upload_task.id] # 从 upload_task 获取数据
303
336
  )
304
- message_task.dependencies << upload_task.id # 执行顺序依赖
305
337
  all_tasks << message_task
306
338
  end
307
339
  end
308
340
 
341
+ # 第五步:创建媒体附件上传任务(如果需要,只依赖 Git 提交任务)
342
+ if @args_media_flag
343
+ # 获取 Git 管理类型的工作流(不同于包上传的工作流)
344
+ git_app_info_obj, git_workflow_info = PgyerHelper.share_instace.prepare_upload(
345
+ working_directory: Dir.pwd,
346
+ proj_name: all_platform_configs["project_name"],
347
+ package_type: "", # package_type 在 manage_type=git 时会被忽略
348
+ manage_type: "git"
349
+ )
350
+
351
+ media_upload_task = Pindo::TaskSystem::JPSUploadMediaTask.new(
352
+ [], # 空数组,自动从 JPSMedia/ 目录查找
353
+ Dir.pwd, # upload_path
354
+ app_info_obj: git_app_info_obj,
355
+ workflow_info: git_workflow_info,
356
+ project_name: all_platform_configs["project_name"]
357
+ )
358
+ # 只依赖 Git 提交任务
359
+ media_upload_task.dependencies << git_commit_task.id
360
+ all_tasks << media_upload_task
361
+ end
362
+
309
363
  # 返回所有任务
310
364
  all_tasks
311
365
  end
@@ -76,13 +76,21 @@ module Pindo
76
76
  # 创建任务列表
77
77
  tasks = []
78
78
 
79
+ # 0. 提前询问用户如何处理未提交的文件
80
+ process_type = Pindo::GitHandler.get_uncommitted_files_process_type(
81
+ project_dir: pindo_project_dir,
82
+ interactive: true
83
+ )
84
+
79
85
  # 1. Git 提交任务
80
86
  git_commit_task = Pindo::TaskSystem::GitCommitTask.new(
81
87
  pindo_project_dir,
82
88
  release_branch: @args_release_branch,
83
89
  ver_inc: @args_ver_inc,
84
90
  tag_type: @args_tag_type,
85
- tag_pre: @args_tag_pre
91
+ tag_pre: @args_tag_pre,
92
+ process_type: process_type,
93
+ commit_message: "feat: tag 操作前提交"
86
94
  )
87
95
  tasks << git_commit_task
88
96
 
@@ -13,6 +13,7 @@ require 'pindo/module/task/model/unity/unity_yoo_asset_task'
13
13
  require 'pindo/module/task/model/unity/unity_export_task'
14
14
  require 'pindo/module/task/model/build_task'
15
15
  require 'pindo/module/task/model/jps/jps_upload_task'
16
+ require 'pindo/module/task/model/jps/jps_upload_media_task'
16
17
  require 'pindo/module/task/model/jps/jps_message_task'
17
18
  require 'pindo/options/options'
18
19
 
@@ -33,15 +34,17 @@ module Pindo
33
34
  # 命令的详细说明,包含用法示例
34
35
  self.description = <<-DESC
35
36
  编译WebGL包并支持上传到测试平台。
36
-
37
+
37
38
  支持功能:
38
39
 
39
40
  * 编译Debug包
40
41
 
41
- * 上传到测试平台
42
+ * 上传到测试平台
42
43
 
43
44
  * 发送测试通知
44
45
 
46
+ * 支持并发任务执行(使用 --multi 参数)
47
+
45
48
  使用示例:
46
49
 
47
50
  $ pindo web autobuild # 编译Debug包
@@ -50,7 +53,13 @@ module Pindo
50
53
 
51
54
  $ pindo web autobuild --proj=myapp # 指定项目名称
52
55
 
53
- $ pindo web autobuild --run # 编译完成后再本地打开webgl包
56
+ $ pindo web autobuild --media # 编译、上传并上传媒体附件
57
+
58
+ $ pindo web autobuild --run # 编译完成后再本地打开webgl包
59
+
60
+ $ pindo web autobuild --multi # 使用并发模式执行(速度更快)
61
+
62
+ $ pindo web autobuild --multi --upload # 并发执行并上传
54
63
  DESC
55
64
 
56
65
  # 命令的参数列表
@@ -61,9 +70,10 @@ module Pindo
61
70
  # 定义此命令使用的参数项
62
71
  def self.option_items
63
72
  @option_items ||= Pindo::Options::OptionGroup.merge(
64
- Pindo::Options::JPSOptions.select(:proj, :upload, :send),
73
+ Pindo::Options::JPSOptions.select(:proj, :upload, :send, :media),
65
74
  Pindo::Options::UnityOptions.select(:skiplib, :skipyoo),
66
75
  Pindo::Options::UnityOptions.select_with_defaults(skipconfig: true),
76
+ Pindo::Options::TaskOptions.select(:multi),
67
77
  Pindo::Options::GitOptions.all
68
78
  )
69
79
  end
@@ -83,19 +93,23 @@ module Pindo
83
93
  @args_adhoc_flag = argv.flag?('adhoc', false)
84
94
  @args_upload_flag = @options[:upload] || false
85
95
  @args_send_flag = @options[:send] || false
96
+ @args_media_flag = @options[:media] || false
86
97
  @args_proj_name = @options[:proj]
87
98
  @args_bundle_id = argv.option('bundleid')
88
99
  @args_run_flag = argv.flag?('run', false)
89
100
  @args_skip_lib = @options[:skiplib] || false
90
101
  @args_skip_yoo = @options[:skipyoo] || false
91
102
 
103
+ # Task 参数
104
+ @args_multi_flag = @options[:multi] || false
105
+
92
106
  # Git 参数
93
107
  @args_release_branch = @options[:release_branch] || 'master'
94
108
  @args_ver_inc = Pindo::Options::GitOptions.parse_version_increase_type(@options[:ver_inc] || 'mini')
95
109
  @args_tag_type = Pindo::Options::GitOptions.parse_create_tag_type(@options[:tag_type] || 'new')
96
110
  @args_tag_pre = @options[:tag_pre] || 'v'
97
111
 
98
- if @args_send_flag
112
+ if @args_send_flag || @args_media_flag
99
113
  @args_upload_flag = true
100
114
  end
101
115
 
@@ -124,7 +138,13 @@ module Pindo
124
138
  task_manager = Pindo::TaskSystem::TaskManager.instance
125
139
  task_manager.clear_all
126
140
  tasks.each { |task| task_manager.add_task(task) }
127
- task_manager.start
141
+
142
+ # 执行任务(根据 --multi 参数决定模式)
143
+ if @args_multi_flag
144
+ task_manager.start(mode: :concurrent, max_workers: 3)
145
+ else
146
+ task_manager.start
147
+ end
128
148
 
129
149
  system "open #{pindo_project_dir}"
130
150
 
@@ -204,12 +224,20 @@ module Pindo
204
224
 
205
225
  # 1. Git 提交任务(如果需要上传)
206
226
  if @args_upload_flag
227
+ # 提前询问用户如何处理未提交的文件
228
+ process_type = Pindo::GitHandler.get_uncommitted_files_process_type(
229
+ project_dir: config[:project_path],
230
+ interactive: true
231
+ )
232
+
207
233
  git_commit_task = Pindo::TaskSystem::GitCommitTask.new(
208
234
  config[:project_path],
209
235
  release_branch: @args_release_branch,
210
236
  ver_inc: @args_ver_inc,
211
237
  tag_type: @args_tag_type,
212
- tag_pre: @args_tag_pre
238
+ tag_pre: @args_tag_pre,
239
+ process_type: process_type,
240
+ commit_message: "feat: web autobuild 构建前提交"
213
241
  )
214
242
  tasks << git_commit_task
215
243
  last_task = git_commit_task
@@ -300,19 +328,40 @@ module Pindo
300
328
  upload_task.dependencies << build_task.id
301
329
  tasks << upload_task
302
330
 
303
- # 7.2 创建消息发送任务(依赖上传任务)
331
+ # 7.2 创建消息发送任务(只依赖上传任务)
304
332
  # app_version_info 将从 upload_task 的数据参数中获取
305
333
  message_task = Pindo::TaskSystem::JPSMessageTask.new(
306
334
  nil, # app_version_info 为 nil,从依赖任务获取
307
335
  app_info_obj: config[:app_info_obj],
308
336
  project_name: @args_proj_name,
309
337
  send_message_type: @args_send_flag ? 'group' : 'self',
310
- data_dependencies: [upload_task.id] # 从 upload_task 获取数据
338
+ dependencies: [upload_task.id] # 从 upload_task 获取数据
311
339
  )
312
- message_task.dependencies << upload_task.id # 执行顺序依赖
313
340
  tasks << message_task
314
341
  end
315
342
 
343
+ # 8. 创建媒体附件上传任务(如果需要,只依赖 Git 提交任务)
344
+ if @args_media_flag
345
+ # 获取 Git 管理类型的工作流(不同于 HTML 上传的工作流)
346
+ git_app_info_obj, git_workflow_info = PgyerHelper.share_instace.prepare_upload(
347
+ working_directory: config[:project_path],
348
+ proj_name: @args_proj_name,
349
+ package_type: "", # package_type 在 manage_type=git 时会被忽略
350
+ manage_type: "git"
351
+ )
352
+
353
+ media_upload_task = Pindo::TaskSystem::JPSUploadMediaTask.new(
354
+ [], # 空数组,自动从 JPSMedia/ 目录查找
355
+ config[:project_path], # upload_path
356
+ app_info_obj: git_app_info_obj,
357
+ workflow_info: git_workflow_info,
358
+ project_name: @args_proj_name
359
+ )
360
+ # 只依赖 Git 提交任务
361
+ media_upload_task.dependencies << git_commit_task.id
362
+ tasks << media_upload_task
363
+ end
364
+
316
365
  tasks
317
366
  else
318
367
  raise Informative, "Web 编译只支持 Unity 工程"
@@ -239,16 +239,15 @@ module Pindo
239
239
  end
240
240
 
241
241
  def build_aab(project_path, debug)
242
- Dir.chdir(project_path) do
243
- system("./gradlew bundle#{debug ? 'Debug' : 'Release'}")
244
- end
242
+ # 使用子 Shell 切换目录执行,避免影响主进程当前目录 (Thread Safe)
243
+ cmd = "cd \"#{project_path}\" && ./gradlew bundle#{debug ? 'Debug' : 'Release'}"
244
+ system(cmd)
245
245
  end
246
246
 
247
247
  def build_so_library(project_path)
248
- # 编译so库
249
- Dir.chdir(project_path) do
250
- system("./gradlew unityLibrary:BuildIl2CppTask")
251
- end
248
+ # 编译so库 (Thread Safe)
249
+ cmd = "cd \"#{project_path}\" && ./gradlew unityLibrary:BuildIl2CppTask"
250
+ system(cmd)
252
251
  end
253
252
 
254
253
  def copy_so_files(source_path, target_path)