pindo 5.13.7 → 5.13.10

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 (74) hide show
  1. checksums.yaml +4 -4
  2. data/lib/pindo/base/git_handler.rb +247 -42
  3. data/lib/pindo/command/android/autobuild.rb +104 -31
  4. data/lib/pindo/command/android/autoresign.rb +23 -322
  5. data/lib/pindo/command/android/keystore.rb +7 -130
  6. data/lib/pindo/command/appstore/adhocbuild.rb +52 -15
  7. data/lib/pindo/command/appstore/autobuild.rb +104 -8
  8. data/lib/pindo/command/appstore/autoresign.rb +3 -5
  9. data/lib/pindo/command/ios/autobuild.rb +96 -32
  10. data/lib/pindo/command/ios/build.rb +8 -186
  11. data/lib/pindo/command/jps/media.rb +146 -0
  12. data/lib/pindo/command/jps/upload.rb +49 -21
  13. data/lib/pindo/command/jps.rb +1 -0
  14. data/lib/pindo/command/unity/autobuild.rb +141 -32
  15. data/lib/pindo/command/unity/packpush.rb +5 -8
  16. data/lib/pindo/command/utils/repoinit.rb +0 -2
  17. data/lib/pindo/command/utils/tag.rb +58 -26
  18. data/lib/pindo/command/utils.rb +0 -1
  19. data/lib/pindo/command/web/autobuild.rb +98 -34
  20. data/lib/pindo/command.rb +0 -56
  21. data/lib/pindo/config/build_info_manager.rb +7 -8
  22. data/lib/pindo/module/android/android_config_helper.rb +2 -11
  23. data/lib/pindo/module/appselect.rb +15 -41
  24. data/lib/pindo/module/appstore/itcapp_helper.rb +3 -6
  25. data/lib/pindo/module/build/build_helper.rb +28 -18
  26. data/lib/pindo/module/build/git_repo_helper.rb +284 -405
  27. data/lib/pindo/module/cert/pem_helper.rb +3 -6
  28. data/lib/pindo/module/pgyer/pgyerhelper.rb +193 -25
  29. data/lib/pindo/module/task/model/appstore/appstore_task.rb +5 -0
  30. data/lib/pindo/module/task/model/build/android_build_adhoc_task.rb +13 -187
  31. data/lib/pindo/module/task/model/build/android_build_dev_task.rb +36 -34
  32. data/lib/pindo/module/task/model/build/android_build_gplay_task.rb +13 -187
  33. data/lib/pindo/module/task/model/build/ios_build_adhoc_task.rb +9 -6
  34. data/lib/pindo/module/task/model/build/ios_build_appstore_task.rb +9 -6
  35. data/lib/pindo/module/task/model/build/ios_build_dev_task.rb +37 -32
  36. data/lib/pindo/module/task/model/build/web_build_dev_task.rb +7 -5
  37. data/lib/pindo/module/task/model/build_task.rb +8 -11
  38. data/lib/pindo/module/task/model/git/git_commit_task.rb +118 -0
  39. data/lib/pindo/module/task/model/git/git_tag_task.rb +125 -0
  40. data/lib/pindo/module/task/model/git_task.rb +75 -0
  41. data/lib/pindo/module/task/model/jps/jps_message_task.rb +178 -0
  42. data/lib/pindo/module/task/model/{jps_resign_task.rb → jps/jps_resign_task.rb} +14 -23
  43. data/lib/pindo/module/task/model/jps/jps_upload_media_task.rb +248 -0
  44. data/lib/pindo/module/task/model/{jps_upload_task.rb → jps/jps_upload_task.rb} +39 -94
  45. data/lib/pindo/module/task/model/jps_task.rb +43 -0
  46. data/lib/pindo/module/task/model/{ipa_local_resign_task.rb → resign/ipa_local_resign_task.rb} +7 -2
  47. data/lib/pindo/module/task/model/unity/unity_config_task.rb +103 -0
  48. data/lib/pindo/module/task/model/{unity_export_task.rb → unity/unity_export_task.rb} +76 -78
  49. data/lib/pindo/module/task/model/unity/unity_update_task.rb +95 -0
  50. data/lib/pindo/module/task/model/unity/unity_yoo_asset_task.rb +156 -0
  51. data/lib/pindo/module/task/model/unity_task.rb +118 -0
  52. data/lib/pindo/module/task/pindo_task.rb +101 -1
  53. data/lib/pindo/module/task/task_manager.rb +29 -24
  54. data/lib/pindo/module/unity/nuget_helper.rb +7 -7
  55. data/lib/pindo/module/unity/unity_command_helper.rb +188 -0
  56. data/lib/pindo/module/unity/unity_env_helper.rb +208 -0
  57. data/lib/pindo/module/unity/unity_helper.rb +189 -746
  58. data/lib/pindo/module/unity/unity_proc_helper.rb +390 -0
  59. data/lib/pindo/options/core/global_options_state.rb +96 -26
  60. data/lib/pindo/options/core/option_configuration.rb +3 -0
  61. data/lib/pindo/options/core/option_item.rb +36 -0
  62. data/lib/pindo/options/groups/build_options.rb +23 -6
  63. data/lib/pindo/options/groups/git_options.rb +115 -0
  64. data/lib/pindo/options/groups/jps_options.rb +7 -0
  65. data/lib/pindo/options/groups/option_group.rb +15 -0
  66. data/lib/pindo/options/groups/unity_options.rb +49 -0
  67. data/lib/pindo/options/options.rb +2 -0
  68. data/lib/pindo/version.rb +2 -2
  69. metadata +25 -14
  70. data/lib/pindo/base/githelper.rb +0 -686
  71. data/lib/pindo/base/pindocontext.rb +0 -602
  72. data/lib/pindo/command/utils/feishu.rb +0 -134
  73. data/lib/pindo/module/build/version_helper.rb +0 -146
  74. data/lib/pindo/module/task/model/git_tag_task.rb +0 -80
@@ -0,0 +1,125 @@
1
+ require 'pindo/module/task/model/git_task'
2
+ require 'pindo/base/git_handler'
3
+ require 'pindo/module/build/git_repo_helper'
4
+
5
+ module Pindo
6
+ module TaskSystem
7
+ # Git 标签任务
8
+ # 负责在构建成功后创建 Git 标签
9
+ class GitTagTask < GitTask
10
+ attr_reader :release_branch, :ver_inc, :tag_type, :tag_pre
11
+ attr_reader :build_version, :build_number
12
+
13
+ # 任务键
14
+ def self.task_key
15
+ :git_tag
16
+ end
17
+
18
+ # 重试配置:失败后重试 1 次
19
+ def self.default_retry_count
20
+ 2
21
+ end
22
+
23
+ # 初始化 Git 标签任务
24
+ # @param project_path [String] 项目路径
25
+ # @param options [Hash] 选项(与 GitOptions 参数名一致)
26
+ # - release_branch: 发布分支名称,默认 'master'
27
+ # - ver_inc: 版本号增加类型,默认 :mini
28
+ # - tag_type: 创建tag类型,默认 :new
29
+ # - tag_pre: tag前缀,默认 'v'
30
+ # - fixed_version: 外部指定的固定版本号,如果设置则跳过版本号计算
31
+ def initialize(project_path, options = {})
32
+ @release_branch = options[:release_branch] || 'master'
33
+ @ver_inc = options[:ver_inc] || Pindo::VersionIncreaseType::MINI
34
+ @tag_type = options[:tag_type] || Pindo::CreateTagType::NEW
35
+ @tag_pre = options[:tag_pre] || 'v'
36
+ @fixed_version = options[:fixed_version] # 外部指定的固定版本号
37
+
38
+ @build_version = nil
39
+ @build_number = nil
40
+ options[:project_path] = project_path
41
+
42
+ super("Git仓库打Tag", options)
43
+ end
44
+
45
+ def validate
46
+ super
47
+ true
48
+ end
49
+
50
+ protected
51
+
52
+ def do_work
53
+ # 检查是否为 Git 仓库,如果不是则直接成功返回
54
+ unless valid_git_repository?
55
+ Funlog.instance.fancyinfo_warning("当前目录不是Git仓库,跳过Git打Tag")
56
+ return {
57
+ success: true,
58
+ is_git_repo: false,
59
+ message: "当前目录不是Git仓库,已跳过Git打Tag"
60
+ }
61
+ end
62
+
63
+ root_dir = @git_root_path
64
+ git_repo_helper = Pindo::GitRepoHelper.share_instance
65
+ stash_saved = false
66
+ coding_branch = Pindo::GitHandler.git!(%W(-C #{root_dir} rev-parse --abbrev-ref HEAD)).strip
67
+
68
+ begin
69
+ # 1. 检查工作目录,不干净则 stash
70
+ status = Pindo::GitHandler.git!(%W(-C #{root_dir} status --porcelain)).strip
71
+ unless status.empty?
72
+ Funlog.instance.fancyinfo_update("工作目录有未提交更改,暂存到 stash")
73
+ Pindo::GitHandler.git!(%W(-C #{root_dir} stash -u))
74
+ stash_saved = true
75
+ end
76
+
77
+ # 2. 合并到发布分支(方法内部会切回 coding_branch)
78
+ if coding_branch != @release_branch
79
+ Pindo::GitHandler.merge_to_release_branch(
80
+ project_dir: root_dir,
81
+ release_branch: @release_branch,
82
+ coding_branch: coding_branch
83
+ )
84
+ end
85
+
86
+ # 3. 计算版本信息
87
+ # 如果指定了固定版本号,使用它;否则计算版本号
88
+ if @fixed_version && !@fixed_version.empty?
89
+ @build_version = @fixed_version
90
+ @build_number = nil
91
+ else
92
+ @build_number = git_repo_helper.get_build_number_from_commit(project_dir: root_dir)
93
+ @build_version = git_repo_helper.calculate_build_version(
94
+ project_dir: root_dir,
95
+ tag_prefix: @tag_pre,
96
+ create_tag_type: @tag_type,
97
+ version_increase_type: @ver_inc
98
+ )
99
+ end
100
+
101
+ # 4. 创建并推送 Tag
102
+ tag_name = "#{@tag_pre}#{@build_version}"
103
+ git_repo_helper.create_and_push_tag(
104
+ project_dir: root_dir,
105
+ tag_name: tag_name,
106
+ tag_type: @tag_type
107
+ )
108
+
109
+ ensure
110
+ # 5. 还原 stash
111
+ if stash_saved
112
+ begin
113
+ Pindo::GitHandler.git!(%W(-C #{root_dir} stash pop))
114
+ Funlog.instance.fancyinfo_success("已还原 stash")
115
+ rescue => e
116
+ Pindo::GitHandler.git!(%W(-C #{root_dir} stash apply))
117
+ raise Informative, "stash 还原时发生冲突,已使用 stash apply 保留更改,请手动处理!"
118
+ end
119
+ end
120
+ end
121
+ end
122
+
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,75 @@
1
+ require 'pindo/module/task/pindo_task'
2
+ require 'pindo/base/git_handler'
3
+
4
+ module Pindo
5
+ module TaskSystem
6
+ # Git 任务基类
7
+ # 所有 Git 相关任务的父类,提供通用的 Git 操作和配置
8
+ class GitTask < PindoTask
9
+ attr_reader :project_path, :git_root_path
10
+
11
+ def initialize(name, options = {})
12
+ @project_path = options[:project_path] ? File.expand_path(options[:project_path]) : nil
13
+
14
+ # 通过 project_path 获取 git_root_path
15
+ @git_root_path = @project_path ? Pindo::GitHandler.git_root_directory(local_repo_dir: @project_path) : nil
16
+
17
+ super(name, options)
18
+ end
19
+
20
+ # Git 任务类型
21
+ def self.task_type
22
+ :git
23
+ end
24
+
25
+ # Git 任务类型显示名称
26
+ def self.task_type_name
27
+ "Git操作"
28
+ end
29
+
30
+ # Git 任务默认重试配置
31
+ def self.default_retry_mode
32
+ RetryMode::IMMEDIATE # 立即重试
33
+ end
34
+
35
+ def self.default_retry_count
36
+ 0 # 默认不重试
37
+ end
38
+
39
+ def self.default_retry_delay
40
+ 5 # 默认延迟 5 秒
41
+ end
42
+
43
+ # 验证项目路径
44
+ def validate
45
+ super
46
+
47
+ unless @project_path && Dir.exist?(@project_path)
48
+ @error = "项目路径不存在:#{@project_path}"
49
+ return false
50
+ end
51
+
52
+ true
53
+ end
54
+
55
+ protected
56
+
57
+ # 检查是否为 Git 仓库
58
+ def valid_git_repository?
59
+ Pindo::GitHandler.is_git_directory?(local_repo_dir: @project_path)
60
+ end
61
+
62
+ # 检查是否有未提交的更改
63
+ def has_uncommitted_changes?
64
+ return false unless @git_root_path
65
+ Pindo::GitHandler.has_uncommitted_changes?(git_root_dir: @git_root_path)
66
+ end
67
+
68
+ # 获取当前分支名称
69
+ def get_current_branch_name
70
+ return nil unless @git_root_path
71
+ Pindo::GitHandler.git!(%W(-C #{@git_root_path} rev-parse --abbrev-ref HEAD)).strip
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,178 @@
1
+ require 'pindo/module/task/model/jps_task'
2
+ require 'pindo/module/task/task_config'
3
+ require 'pindo/module/pgyer/pgyerhelper'
4
+
5
+ module Pindo
6
+ module TaskSystem
7
+ # JPS 消息发送任务
8
+ # 负责发送 JPS 应用测试消息(打印信息、发送给自己、发送到测试群)
9
+ class JPSMessageTask < JPSTask
10
+ attr_reader :app_version_info, :send_message_type
11
+
12
+ # 任务键
13
+ def self.task_key
14
+ :jps_message
15
+ end
16
+
17
+ # 初始化消息发送任务
18
+ # @param app_version_info [Hash, nil] 应用版本信息对象(可选,如为 nil 则从依赖任务获取)
19
+ # @param options [Hash] 选项
20
+ # @option options [Hash] :app_info_obj JPS 应用信息对象(可选,如为 nil 则从依赖任务获取)
21
+ # @option options [String] :project_name 项目名称(可选)
22
+ # @option options [String] :send_message_type 消息发送类型:'self'(只给自己) | 'group'(发送到测试群),默认 'self'
23
+ def initialize(app_version_info = nil, options = {})
24
+ @app_version_info = app_version_info
25
+ @send_message_type = options[:send_message_type] || 'self'
26
+
27
+ # 消息发送任务优先级为 LOW,确保在上传任务之后执行
28
+ options[:priority] ||= TaskPriority::LOW
29
+
30
+ super("JPS 消息发送", options)
31
+ end
32
+
33
+ def validate
34
+ # 如果没有传入 app_version_info,则需要有依赖任务
35
+ if @app_version_info.nil? && @dependencies.empty?
36
+ @error = "缺少 app_version_info 且没有依赖任务"
37
+ return false
38
+ end
39
+
40
+ # 如果传入了 app_version_info,验证其格式
41
+ if @app_version_info && !@app_version_info.is_a?(Hash)
42
+ @error = "app_version_info 必须是 Hash 类型"
43
+ return false
44
+ end
45
+
46
+ true
47
+ end
48
+
49
+ protected
50
+
51
+ def do_work
52
+ puts "\n 📋 开始处理 JPS 消息发送..."
53
+
54
+ begin
55
+ # 如果没有传入 app_version_info,从依赖任务获取
56
+ if @app_version_info.nil?
57
+ fetch_data_from_dependencies
58
+ end
59
+
60
+ # 验证必需数据
61
+ unless @app_version_info
62
+ raise "无法获取 app_version_info"
63
+ end
64
+
65
+ unless @app_info_obj
66
+ raise "无法获取 app_info_obj"
67
+ end
68
+
69
+ pgyer_helper = PgyerHelper.share_instace
70
+
71
+ # 1. 打印应用版本信息(失败只警告,不中断)
72
+ print_version_info(pgyer_helper)
73
+
74
+ # 2. 发送消息给自己(失败只警告,不中断)
75
+ send_message_to_self(pgyer_helper)
76
+
77
+ # 3. 如果消息类型为 group,发送到测试群(失败只警告,不中断)
78
+ send_message_to_group(pgyer_helper) if @send_message_type == 'group'
79
+
80
+ puts " ✅ JPS 消息发送全部完成\n"
81
+
82
+ {
83
+ success: true,
84
+ version_info: @app_version_info
85
+ }
86
+ rescue => e
87
+ # 外层错误保护:消息发送失败不应影响整体流程
88
+ puts " ⚠️ JPS 消息发送发生未预期错误: #{e.message}"
89
+ puts " ⚠️ 错误堆栈: #{e.backtrace.first(3).join("\n ")}" if e.backtrace
90
+ puts " ℹ️ 消息发送失败不影响主流程\n"
91
+
92
+ # 消息发送失败不抛出异常,返回成功但带警告
93
+ {
94
+ success: true,
95
+ warning: e.message,
96
+ version_info: @app_version_info
97
+ }
98
+ end
99
+ end
100
+
101
+ private
102
+
103
+ # 从依赖任务获取数据
104
+ def fetch_data_from_dependencies
105
+ # 优先从 data_dependencies 获取数据(新机制)
106
+ unless @data_dependencies.empty?
107
+ upload_data = get_data_param_by_key(:jps_upload)
108
+
109
+ if upload_data && upload_data[:task_param]
110
+ param = upload_data[:task_param]
111
+ @app_version_info = param[:app_version_info] if @app_version_info.nil?
112
+ @app_info_obj = param[:app_info_obj] if @app_info_obj.nil?
113
+ return
114
+ end
115
+ end
116
+
117
+ # 兼容旧机制:从 dependencies 获取数据(向后兼容)
118
+ unless @dependencies.empty?
119
+ upload_result = get_dependency_result(@dependencies.first)
120
+
121
+ if upload_result
122
+ @app_version_info = upload_result[:app_version_info]
123
+
124
+ # 如果 @app_info_obj 也未设置,尝试从依赖任务结果获取
125
+ if @app_info_obj.nil? && upload_result[:app_info_obj]
126
+ @app_info_obj = upload_result[:app_info_obj]
127
+ end
128
+ end
129
+ end
130
+ end
131
+
132
+ # 打印应用版本信息
133
+ def print_version_info(pgyer_helper)
134
+ puts " 📝 打印应用版本信息..."
135
+ begin
136
+ pgyer_helper.print_app_version_info(
137
+ app_info_obj: @app_info_obj,
138
+ app_version_info_obj: @app_version_info
139
+ )
140
+ puts " ✓ 应用版本信息打印成功"
141
+ rescue => e
142
+ puts " ⚠️ 打印应用版本信息失败: #{e.message}"
143
+ end
144
+ end
145
+
146
+ # 发送消息给自己
147
+ def send_message_to_self(pgyer_helper)
148
+ puts " 📨 发送消息给自己..."
149
+ begin
150
+ pgyer_helper.send_apptest_msg(
151
+ app_info_obj: @app_info_obj,
152
+ app_version_info_obj: @app_version_info,
153
+ receiveType: "self"
154
+ )
155
+ puts " ✓ 消息发送成功"
156
+ rescue => e
157
+ puts " ⚠️ 发送消息给自己失败: #{e.message}"
158
+ end
159
+ end
160
+
161
+ # 发送消息到测试群
162
+ def send_message_to_group(pgyer_helper)
163
+ puts " 📢 发送消息到测试群..."
164
+ begin
165
+ pgyer_helper.send_apptest_msg(
166
+ app_info_obj: @app_info_obj,
167
+ app_version_info_obj: @app_version_info,
168
+ chatEnv: "DevTest",
169
+ receiveType: "chat"
170
+ )
171
+ puts " ✓ 测试群消息发送成功"
172
+ rescue => e
173
+ puts " ⚠️ 发送消息到测试群失败: #{e.message}"
174
+ end
175
+ end
176
+ end
177
+ end
178
+ end
@@ -1,31 +1,19 @@
1
- require_relative '../pindo_task'
2
- require_relative '../task_config'
1
+ require 'pindo/module/task/model/jps_task'
2
+ require 'pindo/module/task/task_config'
3
3
  require 'pindo/module/pgyer/pgyerhelper'
4
4
 
5
5
  module Pindo
6
6
  module TaskSystem
7
7
  # JPS 重签名任务
8
8
  # 从 JPS 平台下载应用并使用指定证书重签名
9
- class JPSResignTask < PindoTask
10
- attr_reader :app_info_obj, :version_info, :cert_id, :send_flag
11
-
12
- def self.task_type
13
- :jps_resign
14
- end
15
-
16
- # 重试配置
17
- def self.default_retry_mode
18
- RetryMode::DELAYED # 延迟重试
19
- end
9
+ class JPSResignTask < JPSTask
10
+ attr_reader :version_info, :cert_id, :send_flag
20
11
 
12
+ # 重试配置(降低重试次数)
21
13
  def self.default_retry_count
22
14
  2 # 默认可以重试 2 次
23
15
  end
24
16
 
25
- def self.default_retry_delay
26
- 10 # 默认延迟 10 秒
27
- end
28
-
29
17
  # 初始化 JPS 重签名任务
30
18
  # @param options [Hash] 选项
31
19
  # @option options [Hash] :app_info_obj JPS 应用信息对象(可选,如为 nil 则延迟获取)
@@ -33,8 +21,6 @@ module Pindo
33
21
  # @option options [String] :cert_id 重签名使用的 Bundle ID(可选,nil 表示交互选择)
34
22
  # @option options [Boolean] :send_flag 是否发送到测试群(默认 false,始终会发送给自己)
35
23
  def initialize(options = {})
36
- @app_info_obj = options[:app_info_obj]
37
- @project_name = options[:project_name]
38
24
  @cert_id = options[:cert_id]
39
25
  @send_flag = options[:send_flag] || false
40
26
  @version_info = nil
@@ -57,7 +43,7 @@ module Pindo
57
43
 
58
44
  # 1. 如果没有 app_info_obj,延迟获取
59
45
  if @app_info_obj.nil?
60
- fetch_jps_config
46
+ @app_info_obj = fetch_jps_config
61
47
  end
62
48
 
63
49
  # 2. 获取要重签名的版本
@@ -139,15 +125,18 @@ module Pindo
139
125
 
140
126
  private
141
127
 
142
- # 延迟获取 JPS 配置
128
+ # 延迟获取 JPS 配置(重签名任务专用)
129
+ # @return [Hash] 返回 app_info_obj
143
130
  def fetch_jps_config
144
131
  puts " 获取 JPS 配置..."
145
132
 
146
133
  # 获取当前工作目录
147
134
  working_directory = Dir.pwd
148
135
 
149
- # 调用 PgyerHelper 获取配置
150
- @app_info_obj = PgyerHelper.share_instace.prepare_upload(
136
+ pgyer_helper = PgyerHelper.share_instace
137
+
138
+ # 重签名任务不需要 package_type,只获取 app_info_obj
139
+ @app_info_obj = pgyer_helper.prepare_upload(
151
140
  working_directory: working_directory,
152
141
  proj_name: @project_name
153
142
  )
@@ -155,6 +144,8 @@ module Pindo
155
144
  unless @app_info_obj
156
145
  raise "无法获取 JPS 配置"
157
146
  end
147
+
148
+ @app_info_obj
158
149
  end
159
150
 
160
151
  # 选择证书