pindo 5.14.5 → 5.14.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.
@@ -16,6 +16,7 @@ require 'pindo/module/task/model/unity/unity_export_task'
16
16
  require 'pindo/module/task/model/build_task'
17
17
  require 'pindo/module/task/model/jps/jps_upload_task'
18
18
  require 'pindo/module/task/model/jps/jps_upload_media_task'
19
+ require 'pindo/module/task/model/jps/jps_bind_package_task'
19
20
  require 'pindo/module/task/model/jps/jps_message_task'
20
21
  require 'pindo/options/options'
21
22
  require 'pindo/options/helpers/bundleid_selector'
@@ -39,37 +40,55 @@ module Pindo
39
40
  self.description = <<-DESC
40
41
  编译IPA,自动修改工程配置并支持上传到JPS测试平台。
41
42
 
42
- 支持功能:
43
+ 参数优先级说明(从低到高):
43
44
 
44
- * 自动修改工程配置(Bundle ID、Display Name、URL Schemes)
45
+ 1. 无参数:
46
+ - Git 提交 → 编译 IPA → 打 Git Tag
47
+
48
+ 2. --upload:
49
+ - 在基础流程上增加:上传 IPA → 发送消息给自己
45
50
 
46
- * 编译生成IPA文件
51
+ 3. --media:
52
+ - 自动启用 --upload
53
+ - 在 --upload 基础上增加:上传媒体附件(JPSMedia/ 目录)
47
54
 
48
- * 支持上传到JPS测试平台
55
+ 4. --bind:
56
+ - 自动启用 --media 和 --upload
57
+ - 在 --media 基础上增加:绑定 Git commit 到已上传的包
49
58
 
50
- * 支持发送测试通知
59
+ 5. --send:
60
+ - 自动启用 --bind、--media 和 --upload
61
+ - 在 --bind 基础上增加:发送工作流消息到测试群
51
62
 
52
- * 支持CI/CD自动化构建
63
+ 支持功能:
53
64
 
65
+ * 自动修改工程配置(Bundle ID、Display Name、URL Schemes)
66
+ * 编译生成 IPA 文件
67
+ * 上传到 JPS 测试平台
68
+ * 上传媒体附件(图片、视频)
69
+ * 绑定 Git commit 到已上传的包
70
+ * 发送测试通知(自己/测试群)
71
+ * 支持 CI/CD 自动化构建
54
72
  * 支持并发任务执行(使用 --multi 参数)
55
73
 
56
74
  使用示例:
57
75
 
58
- $ pindo ios autobuild # 编译Debug包
76
+ $ pindo ios autobuild --bundleid=com.example.app # 指定 Bundle ID
77
+
78
+ $ pindo ios autobuild --proj="My App" # 指定项目名称
59
79
 
60
- $ pindo ios autobuild --upload # 编译并上传到JPS
80
+ $ pindo ios autobuild # 编译、打tag
61
81
 
62
- $ pindo ios autobuild --send # 编译、上传并发送群组通知
82
+ $ pindo ios autobuild --upload # 编译、打tag、上传、发上传消息
63
83
 
64
- $ pindo ios autobuild --media # 编译、上传并上传媒体附件
84
+ $ pindo ios autobuild --media # 编译、打tag、上传、发上传消息、上传媒体附件
65
85
 
66
- $ pindo ios autobuild --bundleid=com.example.app # 指定Bundle ID
86
+ $ pindo ios autobuild --bind # 编译、打tag、上传、发上传消息、上传媒体附件 + 绑定包到工作流
67
87
 
68
- $ pindo ios autobuild --proj="My App" # 指定项目名称
88
+ $ pindo ios autobuild --send # 编译、打tag、上传、发上传消息、上传媒体附件、绑定包到工作流 + 发送群消息
69
89
 
70
- $ pindo ios autobuild --multi # 使用并发模式执行(速度更快)
90
+ $ pindo ios autobuild --multi # 使用并发模式执行
71
91
 
72
- $ pindo ios autobuild --multi --upload # 并发执行并上传
73
92
  DESC
74
93
 
75
94
  # 命令的参数列表
@@ -79,28 +98,14 @@ module Pindo
79
98
 
80
99
  # 定义此命令使用的参数项(类方法,避免重复定义)
81
100
  def self.option_items
82
- @option_items ||= begin
83
- items = Pindo::Options::OptionGroup.merge(
84
- Pindo::Options::BuildOptions.select(:bundleid, :build_type),
85
- Pindo::Options::JPSOptions.select(:proj, :upload, :send, :media),
86
- Pindo::Options::UnityOptions.select(:skiplib, :skipyoo),
87
- Pindo::Options::UnityOptions.select_with_defaults(skipconfig: true),
88
- Pindo::Options::TaskOptions.select(:multi),
89
- Pindo::Options::GitOptions.all
90
- )
91
-
92
- # 为 bundleid 参数添加 value_block(交互式选择)
93
- bundleid_item = items.find { |item| item.key == :bundleid }
94
- if bundleid_item
95
- bundleid_item.value_block = proc do |command_instance|
96
- # 根据构建类型选择不同的 Bundle ID
97
- build_type = command_instance.instance_variable_get(:@build_type) || 'dev'
98
- Pindo::Options::BundleIdSelector.select_bundleid(build_type)
99
- end
100
- end
101
-
102
- items
103
- end
101
+ @option_items ||= Pindo::Options::OptionGroup.merge(
102
+ Pindo::Options::BuildOptions.select(:bundleid, :build_type),
103
+ Pindo::Options::JPSOptions.select(:proj, :upload, :send, :media, :bind),
104
+ Pindo::Options::UnityOptions.select(:skiplib, :skipyoo),
105
+ Pindo::Options::UnityOptions.select_with_defaults(skipconfig: true),
106
+ Pindo::Options::TaskOptions.select(:multi),
107
+ Pindo::Options::GitOptions.all
108
+ )
104
109
  end
105
110
 
106
111
  # 命令的选项列表
@@ -109,23 +114,26 @@ module Pindo
109
114
  end
110
115
 
111
116
  def initialize(argv)
112
- # 先提取 build_type(因为 bundleid 的 value_block 需要用到它)
113
- @build_type = argv.option('build_type', 'dev')
114
-
115
117
  @options = initialize_options(argv)
116
118
 
117
119
  # 保存参数到实例变量
118
- @build_type = @options[:build_type] || @build_type
119
- @args_send_flag = @options[:send]
120
- # send 依赖 upload:如果指定了 send,自动启用 upload
121
- @args_upload_flag = @options[:send] || @options[:upload]
122
120
  @args_proj_name = @options[:proj]
123
121
  @args_bundle_id = @options[:bundleid]
124
- # media 依赖 upload:如果指定了 media,自动启用 upload
125
- @args_media_flag = @options[:media] || false
126
- if @args_media_flag
127
- @args_upload_flag = true
128
- end
122
+ @build_type = @options[:build_type] || 'dev'
123
+
124
+
125
+ # send、media 或 bind 都依赖 upload:如果指定了任一参数,自动启用 upload
126
+ @args_upload_flag = @options[:send] || @options[:bind] || @options[:media] || @options[:upload]
127
+
128
+ # media 任务是独立的,不依赖任何其他任务,但是为输入命令参数更加简单,如果有--bind和--send, 则默认认为一定会有--media参数
129
+ @args_media_flag = @options[:send] || @options[:bind] || @options[:media] || false
130
+
131
+ # send 都依赖 bind:如果指定了任一参数,自动启用 bind
132
+ @args_bind_flag = @options[:send] ||@options[:bind] || false
133
+
134
+ @args_send_flag = @options[:send]
135
+
136
+
129
137
 
130
138
  # Unity 参数
131
139
  @args_skip_lib = @options[:skiplib] || false
@@ -145,8 +153,20 @@ module Pindo
145
153
  end
146
154
 
147
155
  def validate!
148
-
149
- super
156
+ super # 基类的 HelpValidator 会统一处理 --help
157
+
158
+ # 如果没有指定 bundleid,进行交互式选择
159
+ if @args_bundle_id.nil? || @args_bundle_id.empty?
160
+ @args_bundle_id = Pindo::Options::BundleIdSelector.select_bundleid(@build_type)
161
+
162
+ # 如果用户取消选择或选择失败,报错
163
+ if @args_bundle_id.nil? || @args_bundle_id.empty?
164
+ help! "未选择有效的 Bundle ID"
165
+ end
166
+
167
+ # 重要:将交互式选择的值同步回 @options,确保能被缓存系统保存
168
+ @options[:bundleid] = @args_bundle_id
169
+ end
150
170
  end
151
171
 
152
172
  def run
@@ -275,8 +295,6 @@ module Pindo
275
295
  project_path: ios_project_path,
276
296
  bundle_id: config[:bundle_id],
277
297
  proj_name: @args_proj_name,
278
- upload: @args_upload_flag,
279
- send: @args_send_flag,
280
298
  app_info_obj: config[:app_info_obj],
281
299
  workflow_info: config[:workflow_info],
282
300
  # Git 版本参数
@@ -302,6 +320,7 @@ module Pindo
302
320
  tasks << git_tag_task
303
321
 
304
322
  # 5. 上传和消息发送任务(如果需要)
323
+ upload_task = nil # 声明变量以便后续绑定任务使用
305
324
  if @args_upload_flag
306
325
  # 5.1 创建上传任务
307
326
  upload_task = Pindo::TaskSystem::JPSUploadTask.new(
@@ -315,15 +334,15 @@ module Pindo
315
334
  upload_task.dependencies << build_task.id
316
335
  tasks << upload_task
317
336
 
318
- # 5.2 创建消息发送任务(只依赖上传任务)
337
+ # 5.2 创建消息发送任务(只依赖上传任务,固定发送给自己)
319
338
  # app_version_info 将从 upload_task 的数据参数中获取
320
339
  message_task = Pindo::TaskSystem::JPSMessageTask.new(
321
340
  nil, # app_version_info 为 nil,从依赖任务获取
322
341
  app_info_obj: config[:app_info_obj],
323
342
  project_name: @args_proj_name,
324
- send_message_type: @args_send_flag ? 'group' : 'self',
325
- dependencies: [upload_task.id] # 从 upload_task 获取数据
343
+ send_message_type: 'self' # 固定发送给自己
326
344
  )
345
+ message_task.dependencies << upload_task.id
327
346
  tasks << message_task
328
347
  end
329
348
 
@@ -344,11 +363,52 @@ module Pindo
344
363
  workflow_info: git_workflow_info,
345
364
  project_name: @args_proj_name
346
365
  )
347
- # 只依赖 Git 提交任务
366
+ # 依赖 Git 提交任务
348
367
  media_upload_task.dependencies << git_commit_task.id
349
368
  tasks << media_upload_task
350
369
  end
351
370
 
371
+ # 7. 创建 Git Commit 绑定任务(如果需要,依赖上传任务)
372
+ bind_package_task = nil # 声明变量以便后续工作流消息任务使用
373
+ if @args_bind_flag
374
+ bind_package_task = Pindo::TaskSystem::JPSBindPackageTask.new(
375
+ nil, # app_version_list 为 nil,从依赖任务获取
376
+ project_dir: config[:project_path],
377
+ app_info_obj: config[:app_info_obj],
378
+ workflow_info: config[:workflow_info],
379
+ project_name: @args_proj_name
380
+ )
381
+ # 依赖上传任务和 Git 提交任务
382
+ bind_package_task.dependencies << upload_task.id
383
+ bind_package_task.dependencies << git_commit_task.id
384
+ tasks << bind_package_task
385
+ end
386
+
387
+ # 8. 创建工作流消息任务(如果需要,发送到测试群)
388
+ if @args_send_flag
389
+ # 获取 Git 工作流信息
390
+ git_app_info_obj, git_workflow_info = PgyerHelper.share_instace.prepare_upload(
391
+ working_directory: config[:project_path],
392
+ proj_name: @args_proj_name,
393
+ package_type: "",
394
+ manage_type: "git"
395
+ )
396
+
397
+ workflow_message_task = Pindo::TaskSystem::JPSWorkFlowMessageTask.new(
398
+ project_id: git_app_info_obj["id"],
399
+ workflow_id: git_workflow_info["id"],
400
+ branch: 'master',
401
+ single: true,
402
+ app_info_obj: git_app_info_obj,
403
+ workflow_info: git_workflow_info
404
+ )
405
+ # 依赖 Git Commit、Git Tag 和 Bind Package 任务
406
+ workflow_message_task.dependencies << git_commit_task.id
407
+ workflow_message_task.dependencies << git_tag_task.id
408
+ workflow_message_task.dependencies << bind_package_task.id
409
+ tasks << workflow_message_task
410
+ end
411
+
352
412
  tasks
353
413
  else
354
414
  raise Informative, "当前目录不是工程目录,不能编译"
@@ -1,105 +1,184 @@
1
- require 'highline/import'
2
- require 'fileutils'
3
1
  require 'pindo/module/pgyer/pgyerhelper'
2
+ require 'pindo/module/task/task_manager'
3
+ require 'pindo/module/task/model/jps/jps_message_task'
4
+ require 'pindo/module/task/model/jps/jps_workflow_message_task'
5
+ require 'pindo/options/options'
4
6
 
5
7
  module Pindo
6
8
  class Command
7
9
  class Jps < Command
8
10
  class Apptest < Jps
9
11
 
10
- self.summary = '获取jps中指定app的测试链接和二维码'
12
+ self.summary = '获取 JPS 中指定 App 的测试链接并发送消息'
11
13
 
12
14
  self.description = <<-DESC
13
- 获取jps中指定app的测试链接和二维码。
15
+ 获取 JPS 中指定 App 的测试链接和二维码,并发送测试消息。
14
16
 
15
17
  支持功能:
16
18
 
17
- * 获取app测试链接
18
- * 获取app二维码
19
- * 发送测试信息
20
- * 查看历史版本
19
+ * 获取 App 测试链接和二维码
20
+ * 发送测试信息给自己(默认)
21
+ * 发送工作流消息到测试群(使用 --send 参数)
22
+ * 查看历史版本(使用 --list 参数)
21
23
 
22
24
  使用示例:
23
25
 
24
- $ pindo jps apptest # 获取当前目录项目的测试链接
26
+ $ pindo jps apptest # 获取测试链接并发送给自己
25
27
 
26
28
  $ pindo jps apptest --proj=demo # 获取指定项目的测试链接
27
29
 
28
30
  $ pindo jps apptest --list # 列出历史版本供选择
29
31
 
30
- $ pindo jps apptest --send # 发送测试信息
32
+ $ pindo jps apptest --send # 发送工作流消息到测试群
31
33
  DESC
32
34
 
33
- self.arguments = [
35
+ self.arguments = []
34
36
 
35
- ]
37
+ # 定义此命令使用的参数项
38
+ def self.option_items
39
+ @option_items ||= Pindo::Options::OptionGroup.merge(
40
+ Pindo::Options::JPSOptions.select(:proj, :send, :list, :group)
41
+ )
42
+ end
36
43
 
37
44
  def self.options
38
- [
39
- ['--login', '强制再次登录jps网站'],
40
- ['--proj', '指定哪个项目(忽略大小写空格等等字符),用法:pindo jps apptest --proj=prancksoundv4'],
41
- ['--list', '列出上传记录并选择,用法:pindo jps apptest --list'],
42
- ['--send', '发送消息到项目群(注意:不带此参数也会发送给自己),用法:pindo jps apptest --send'],
43
- ].concat(super)
45
+ option_items.map(&:to_claide_option).concat(super)
44
46
  end
45
47
 
46
48
  def initialize(argv)
49
+ # 使用 Options 系统解析参数
50
+ @options = initialize_options(argv)
47
51
 
48
- @args_login_flag = argv.flag?('login', false)
49
- @args_list_flag = argv.flag?('list', false)
50
- @args_send_flag = argv.flag?('send', false)
51
- @args_proj_name = argv.option('proj')
52
+ # JPS 参数
53
+ @args_proj_name = @options[:proj]
54
+ @args_list_flag = @options[:list] || false
55
+ @args_send_flag = @options[:send] || false
56
+ @args_group_flag = @options[:group] || false
52
57
 
53
58
  super(argv)
54
- @additional_args = argv.remainder!
55
59
  end
56
60
 
57
61
  def validate!
58
-
59
62
  super
60
63
  end
61
64
 
62
65
  def run
66
+ project_path = Dir.pwd
67
+
68
+ # 1. 登录并获取 JPS 配置
69
+ pgyer_helper = PgyerHelper.share_instace
70
+ pgyer_helper.login
63
71
 
64
- PgyerHelper.share_instace.setForeLogin(beforeLogin:@args_login_flag)
65
- app_info_obj = PgyerHelper.share_instace.prepare_upload(working_directory:Dir.pwd, proj_name:@args_proj_name)
72
+ app_info_obj, workflow_info = pgyer_helper.prepare_upload(
73
+ working_directory: project_path,
74
+ proj_name: @args_proj_name,
75
+ package_type: 'ipa' # 获取 IPA 工作流信息
76
+ )
66
77
 
67
78
  if app_info_obj.nil?
68
- raise Informative, "#{proj_name} 错误, 请输入正确的App代号名称, jps网站没有该App"
79
+ raise Informative, "#{@args_proj_name} 错误,请输入正确的 App 代号名称"
69
80
  end
70
81
 
71
- if !app_info_obj.nil?
72
-
73
- version_item_obj = PgyerHelper.share_instace.get_versioon_history_item(app_info_obj:app_info_obj, list_select_flat:@args_list_flag)
74
-
75
- if version_item_obj.nil?
76
- raise Informative, "没有找到上传记录"
77
- end
82
+ # 2. 获取版本信息
83
+ version_item_obj = pgyer_helper.get_versioon_history_item(
84
+ app_info_obj: app_info_obj,
85
+ list_select_flat: @args_list_flag
86
+ )
78
87
 
79
- PgyerHelper.share_instace.print_app_version_info(
80
- app_info_obj: app_info_obj,
81
- app_version_info_obj: version_item_obj
82
- )
88
+ if version_item_obj.nil?
89
+ raise Informative, "没有找到上传记录"
90
+ end
83
91
 
84
- # 始终发送给自己
85
- PgyerHelper.share_instace.send_apptest_msg(
86
- app_info_obj: app_info_obj,
87
- app_version_info_obj: version_item_obj,
88
- receiveType: "self"
92
+ # 3. 打印版本信息
93
+ pgyer_helper.print_app_version_info(
94
+ app_info_obj: app_info_obj,
95
+ app_version_info_obj: version_item_obj
96
+ )
97
+
98
+ # 4. 创建任务
99
+ tasks = []
100
+
101
+ # 4.1 始终创建 JPSMessageTask(根据 --group 参数决定发送给自己还是组)
102
+ message_type = @args_group_flag ? 'group' : 'self'
103
+ message_task = Pindo::TaskSystem::JPSMessageTask.new(
104
+ version_item_obj, # app_version_info
105
+ app_info_obj: app_info_obj,
106
+ project_name: @args_proj_name,
107
+ send_message_type: message_type
108
+ )
109
+ tasks << message_task
110
+
111
+ # 4.2 如果有 --send 参数,创建 JPSWorkFlowMessageTask(发送到工作流群组)
112
+ if @args_send_flag
113
+ # 获取 Git 工作流信息
114
+ git_app_info_obj, git_workflow_info = pgyer_helper.prepare_upload(
115
+ working_directory: project_path,
116
+ proj_name: @args_proj_name,
117
+ package_type: "",
118
+ manage_type: "git"
89
119
  )
90
120
 
91
- # 如果有 --send 参数,额外发送到测试群
92
- if @args_send_flag
93
- PgyerHelper.share_instace.send_apptest_msg(
94
- app_info_obj: app_info_obj,
95
- app_version_info_obj: version_item_obj,
96
- chatEnv: "DevTest",
97
- receiveType: "chat"
121
+ # 获取 git_commit_id
122
+ git_commit_id = nil
123
+ git_commit_time = nil
124
+ git_commit_desc = nil
125
+
126
+ # 1. 检测是否在 Git 仓库中
127
+ git_root = Pindo::GitHandler.git_root_directory(local_repo_dir: project_path)
128
+
129
+ if git_root
130
+ # 2. 在 Git 仓库中,获取当前的 commit 信息
131
+ puts " 📍 检测到 Git 仓库,使用当前 commit..."
132
+ git_info = Pindo::GitHandler.get_latest_conventional_commit(project_dir: git_root)
133
+ git_commit_id = git_info[:commit_id]
134
+ git_commit_time = git_info[:commit_time]
135
+ git_commit_desc = git_info[:commit_desc]
136
+
137
+ if git_commit_id
138
+ puts " └─ Commit: #{git_commit_id[0..7]}"
139
+ puts " └─ Desc: #{git_commit_desc}" if git_commit_desc
140
+ end
141
+ else
142
+ # 3. 不在 Git 仓库中,获取工作流中最新的 commit id
143
+ puts " 📡 未检测到 Git 仓库,从工作流获取最新 commit..."
144
+ git_commit_id = pgyer_helper.get_workflow_latest_commit_id(
145
+ workflow_id: git_workflow_info["id"]
98
146
  )
147
+
148
+ if git_commit_id
149
+ puts " └─ Commit: #{git_commit_id[0..7]}"
150
+ else
151
+ puts " └─ ⚠️ 未能获取工作流中的 commit,将尝试使用空 commit"
152
+ end
99
153
  end
100
154
 
155
+ workflow_message_task = Pindo::TaskSystem::JPSWorkFlowMessageTask.new(
156
+ project_id: git_app_info_obj["id"],
157
+ workflow_id: git_workflow_info["id"],
158
+ git_commit_id: git_commit_id,
159
+ git_commit_time: git_commit_time,
160
+ git_commit_desc: git_commit_desc,
161
+ branch: 'master',
162
+ single: true,
163
+ app_info_obj: git_app_info_obj,
164
+ workflow_info: git_workflow_info
165
+ )
166
+ tasks << workflow_message_task
101
167
  end
102
168
 
169
+ # 5. 执行任务
170
+ task_manager = Pindo::TaskSystem::TaskManager.instance
171
+ task_manager.clear_all
172
+ tasks.each { |task| task_manager.add_task(task) }
173
+ task_manager.start
174
+
175
+ # 6. 输出结果
176
+ report = task_manager.execution_report
177
+ if report[:success] > 0
178
+ puts "\n✅ 消息发送完成!"
179
+ else
180
+ raise Informative, "消息发送失败"
181
+ end
103
182
  end
104
183
 
105
184
  end