pindo 5.11.4 → 5.12.1
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/android/autobuild.rb +111 -184
- data/lib/pindo/command/android/build.rb +10 -2
- data/lib/pindo/command/ios/autobuild.rb +115 -210
- data/lib/pindo/command/ios/build.rb +12 -3
- data/lib/pindo/command/jps/upload.rb +257 -117
- data/lib/pindo/command/unity/autobuild.rb +308 -220
- data/lib/pindo/command/unity.rb +0 -3
- data/lib/pindo/command/utils/boss.rb +18 -15
- data/lib/pindo/command/utils/clearcert.rb +26 -18
- data/lib/pindo/command/utils/device.rb +28 -19
- data/lib/pindo/command/utils/feishu.rb +11 -4
- data/lib/pindo/command/utils/icon.rb +26 -20
- data/lib/pindo/command/utils/renewcert.rb +35 -29
- data/lib/pindo/command/utils/renewproj.rb +32 -25
- data/lib/pindo/command/utils/repoinit.rb +1 -1
- data/lib/pindo/command/utils/tag.rb +6 -180
- data/lib/pindo/command/utils/tgate.rb +34 -28
- data/lib/pindo/command/utils/xcassets.rb +30 -20
- data/lib/pindo/command/web/autobuild.rb +148 -128
- data/lib/pindo/module/android/android_build_helper.rb +0 -6
- data/lib/pindo/module/android/android_config_helper.rb +4 -26
- data/lib/pindo/module/build/build_helper.rb +18 -294
- data/lib/pindo/module/build/git_repo_helper.rb +519 -0
- data/lib/pindo/module/build/icon_downloader.rb +85 -0
- data/lib/pindo/module/pgyer/pgyerhelper.rb +16 -11
- data/lib/pindo/module/task/model/build/android_dev_build_task.rb +209 -0
- data/lib/pindo/module/task/model/build/android_release_build_task.rb +29 -0
- data/lib/pindo/module/task/model/build/ios_adhoc_build_task.rb +53 -0
- data/lib/pindo/module/task/model/build/ios_dev_build_task.rb +251 -0
- data/lib/pindo/module/task/model/build/ios_release_build_task.rb +53 -0
- data/lib/pindo/module/task/model/build/web_dev_build_task.rb +43 -0
- data/lib/pindo/module/task/model/build_task.rb +125 -301
- data/lib/pindo/module/task/model/git_tag_task.rb +80 -0
- data/lib/pindo/module/task/model/unity_export_task.rb +53 -41
- data/lib/pindo/module/task/model/upload_task.rb +149 -208
- data/lib/pindo/module/task/pindo_task.rb +135 -95
- data/lib/pindo/module/task/task_manager.rb +202 -352
- data/lib/pindo/module/unity/unity_helper.rb +7 -3
- data/lib/pindo/module/xcode/xcode_build_config.rb +4 -10
- data/lib/pindo/module/xcode/xcode_build_helper.rb +19 -0
- data/lib/pindo/version.rb +1 -1
- metadata +10 -4
- data/lib/pindo/command/unity/apk.rb +0 -185
- data/lib/pindo/command/unity/ipa.rb +0 -198
- data/lib/pindo/command/unity/web.rb +0 -163
|
@@ -3,359 +3,183 @@ require_relative '../task_config'
|
|
|
3
3
|
|
|
4
4
|
module Pindo
|
|
5
5
|
module TaskSystem
|
|
6
|
+
# BuildTask 抽象基类
|
|
7
|
+
# 提供构建任务的通用框架和工厂方法
|
|
6
8
|
class BuildTask < PindoTask
|
|
7
|
-
attr_reader :platform, :
|
|
9
|
+
attr_reader :platform, :project_path, :output_path, :mode
|
|
8
10
|
|
|
11
|
+
# 任务类型
|
|
9
12
|
def self.task_type
|
|
10
13
|
:build
|
|
11
14
|
end
|
|
12
15
|
|
|
13
|
-
|
|
14
|
-
|
|
16
|
+
# 重试配置
|
|
17
|
+
def self.default_retry_mode
|
|
18
|
+
RetryMode::DELAYED
|
|
15
19
|
end
|
|
16
20
|
|
|
17
|
-
def self.
|
|
18
|
-
|
|
21
|
+
def self.default_retry_count
|
|
22
|
+
0
|
|
19
23
|
end
|
|
20
24
|
|
|
21
|
-
def
|
|
22
|
-
|
|
23
|
-
@build_type = options[:build_type] || platform
|
|
24
|
-
@project_path = options[:project_path] || Dir.pwd
|
|
25
|
-
@build_config = options[:build_config] || {}
|
|
26
|
-
@output_path = nil
|
|
27
|
-
|
|
28
|
-
name = case platform
|
|
29
|
-
when 'ios', 'ipa'
|
|
30
|
-
"构建 IPA"
|
|
31
|
-
when 'android', 'apk'
|
|
32
|
-
"构建 APK"
|
|
33
|
-
when 'web', 'html'
|
|
34
|
-
"构建 HTML"
|
|
35
|
-
else
|
|
36
|
-
"构建 #{platform.upcase}"
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
super(name, options)
|
|
25
|
+
def self.default_retry_delay
|
|
26
|
+
10
|
|
40
27
|
end
|
|
41
28
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
29
|
+
# ========== 静态工厂方法 ==========
|
|
30
|
+
|
|
31
|
+
# 根据 platform 和 mode 创建对应的构建任务实例
|
|
32
|
+
# @param platform [String, Symbol] 平台:ios/android/web
|
|
33
|
+
# @param mode [String, Symbol] 模式:dev/adhoc/release
|
|
34
|
+
# @param options [Hash] 构建选项
|
|
35
|
+
# @return [BuildTask] 对应的构建任务实例
|
|
36
|
+
def self.create_task(platform:, mode:, options: {})
|
|
37
|
+
normalized_platform = normalize_platform(platform)
|
|
38
|
+
normalized_mode = normalize_mode(mode)
|
|
39
|
+
|
|
40
|
+
case normalized_platform
|
|
41
|
+
when :ios
|
|
42
|
+
create_ios_task(normalized_mode, options)
|
|
43
|
+
when :android
|
|
44
|
+
create_android_task(normalized_mode, options)
|
|
45
|
+
when :web
|
|
46
|
+
create_web_task(normalized_mode, options)
|
|
54
47
|
else
|
|
55
|
-
raise "
|
|
48
|
+
raise ArgumentError, "不支持的平台: #{platform}"
|
|
56
49
|
end
|
|
57
50
|
end
|
|
58
51
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
52
|
+
# 标准化平台名称
|
|
53
|
+
def self.normalize_platform(platform)
|
|
54
|
+
platform_str = platform.to_s.downcase
|
|
55
|
+
case platform_str
|
|
56
|
+
when 'ios', 'ipa'
|
|
57
|
+
:ios
|
|
58
|
+
when 'android', 'apk', 'aab'
|
|
59
|
+
:android
|
|
60
|
+
when 'web', 'html', 'webgl'
|
|
61
|
+
:web
|
|
62
|
+
else
|
|
63
|
+
raise ArgumentError, "未知平台: #{platform}"
|
|
69
64
|
end
|
|
65
|
+
end
|
|
70
66
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
67
|
+
# 标准化构建模式
|
|
68
|
+
def self.normalize_mode(mode)
|
|
69
|
+
mode_str = mode.to_s.downcase
|
|
70
|
+
case mode_str
|
|
71
|
+
when 'dev', 'debug', 'development'
|
|
72
|
+
:dev
|
|
73
|
+
when 'adhoc', 'ad-hoc'
|
|
74
|
+
:adhoc
|
|
75
|
+
when 'release', 'production', 'deploy'
|
|
76
|
+
:release
|
|
77
|
+
else
|
|
78
|
+
raise ArgumentError, "未知构建模式: #{mode}"
|
|
79
79
|
end
|
|
80
|
+
end
|
|
80
81
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
82
|
+
# 创建 iOS 构建任务
|
|
83
|
+
def self.create_ios_task(mode, options)
|
|
84
|
+
require_relative 'build/ios_dev_build_task'
|
|
85
|
+
require_relative 'build/ios_adhoc_build_task'
|
|
86
|
+
require_relative 'build/ios_release_build_task'
|
|
87
|
+
|
|
88
|
+
case mode
|
|
89
|
+
when :dev
|
|
90
|
+
IosDevBuildTask.new(options)
|
|
91
|
+
when :adhoc
|
|
92
|
+
IosAdhocBuildTask.new(options)
|
|
93
|
+
when :release
|
|
94
|
+
IosReleaseBuildTask.new(options)
|
|
91
95
|
else
|
|
92
|
-
|
|
93
|
-
require 'pindo/command/ios/autobuild'
|
|
94
|
-
Pindo::Command::Ios::Autobuild::run(args_temp)
|
|
96
|
+
raise ArgumentError, "不支持的 iOS 构建模式: #{mode}"
|
|
95
97
|
end
|
|
96
|
-
|
|
97
|
-
update_progress(90, "iOS 构建完成")
|
|
98
|
-
|
|
99
|
-
# TODO: 获取实际的输出路径
|
|
100
|
-
@output_path = find_ipa_output_path
|
|
101
|
-
|
|
102
|
-
update_progress(100, "IPA 构建成功")
|
|
103
|
-
{
|
|
104
|
-
success: true,
|
|
105
|
-
platform: 'ios',
|
|
106
|
-
output: @output_path
|
|
107
|
-
}
|
|
108
98
|
end
|
|
109
99
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
bundle_name = @context[:bundle_name] || @build_config[:bundle_name]
|
|
115
|
-
|
|
116
|
-
update_progress(20, "准备编译参数...")
|
|
117
|
-
|
|
118
|
-
args_temp = []
|
|
119
|
-
|
|
120
|
-
if bundle_name
|
|
121
|
-
args_temp << "--bundle_name=#{bundle_name}"
|
|
122
|
-
end
|
|
100
|
+
# 创建 Android 构建任务
|
|
101
|
+
def self.create_android_task(mode, options)
|
|
102
|
+
require_relative 'build/android_dev_build_task'
|
|
103
|
+
require_relative 'build/android_release_build_task'
|
|
123
104
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
105
|
+
case mode
|
|
106
|
+
when :dev, :debug
|
|
107
|
+
AndroidDevBuildTask.new(options)
|
|
108
|
+
when :release
|
|
109
|
+
AndroidReleaseBuildTask.new(options)
|
|
110
|
+
else
|
|
111
|
+
raise ArgumentError, "不支持的 Android 构建模式: #{mode}"
|
|
127
112
|
end
|
|
113
|
+
end
|
|
128
114
|
|
|
129
|
-
|
|
115
|
+
# 创建 Web 构建任务
|
|
116
|
+
def self.create_web_task(mode, options)
|
|
117
|
+
require_relative 'build/web_dev_build_task'
|
|
130
118
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
# 调用 Android autobuild 命令(不包含上传)
|
|
136
|
-
require 'pindo/command/android/autobuild'
|
|
137
|
-
Pindo::Command::Android::Autobuild::run(args_temp)
|
|
138
|
-
end
|
|
119
|
+
case mode
|
|
120
|
+
when :dev, :debug, :release
|
|
121
|
+
# Web 目前只有一个构建任务类
|
|
122
|
+
WebDevBuildTask.new(options)
|
|
139
123
|
else
|
|
140
|
-
|
|
141
|
-
require 'pindo/command/android/autobuild'
|
|
142
|
-
Pindo::Command::Android::Autobuild::run(args_temp)
|
|
124
|
+
raise ArgumentError, "不支持的 Web 构建模式: #{mode}"
|
|
143
125
|
end
|
|
144
|
-
|
|
145
|
-
update_progress(90, "Android 构建完成")
|
|
146
|
-
|
|
147
|
-
# TODO: 获取实际的输出路径
|
|
148
|
-
@output_path = find_apk_output_path
|
|
149
|
-
|
|
150
|
-
update_progress(100, "APK 构建成功")
|
|
151
|
-
{
|
|
152
|
-
success: true,
|
|
153
|
-
platform: 'android',
|
|
154
|
-
output: @output_path
|
|
155
|
-
}
|
|
156
126
|
end
|
|
157
127
|
|
|
158
|
-
|
|
159
|
-
update_progress(10, "配置 Web 工程...")
|
|
160
|
-
|
|
161
|
-
# 获取 Bundle Name (Web 也可能需要)
|
|
162
|
-
bundle_name = @context[:bundle_name] || @build_config[:bundle_name]
|
|
128
|
+
# ========== 实例方法 ==========
|
|
163
129
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
130
|
+
def initialize(platform, mode, options = {})
|
|
131
|
+
@platform = platform
|
|
132
|
+
@mode = mode
|
|
133
|
+
@project_path = options[:project_path] || Dir.pwd
|
|
134
|
+
@output_path = nil
|
|
167
135
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
end
|
|
136
|
+
# 构建任务名称
|
|
137
|
+
name = build_task_name
|
|
171
138
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
args_temp << "--proj=#{@context[:project_name]}"
|
|
175
|
-
end
|
|
139
|
+
super(name, options)
|
|
140
|
+
end
|
|
176
141
|
|
|
177
|
-
|
|
142
|
+
protected
|
|
178
143
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
# TODO: 需要确认 Web autobuild 命令的正确模块
|
|
184
|
-
# 暂时使用 Android::Autobuild(根据原代码)
|
|
185
|
-
require 'pindo/command/android/autobuild'
|
|
186
|
-
Pindo::Command::Android::Autobuild::run(args_temp)
|
|
187
|
-
end
|
|
188
|
-
else
|
|
189
|
-
# 如果没有 Web 子目录,在当前目录执行
|
|
190
|
-
require 'pindo/command/android/autobuild'
|
|
191
|
-
Pindo::Command::Android::Autobuild::run(args_temp)
|
|
192
|
-
end
|
|
144
|
+
# 主执行流程
|
|
145
|
+
def do_work
|
|
146
|
+
# 准备构建
|
|
147
|
+
prepare_build
|
|
193
148
|
|
|
194
|
-
|
|
149
|
+
# 执行构建
|
|
150
|
+
execute_build
|
|
195
151
|
|
|
196
|
-
#
|
|
197
|
-
@output_path =
|
|
152
|
+
# 查找输出文件
|
|
153
|
+
@output_path = find_output
|
|
198
154
|
|
|
199
|
-
update_progress(100, "HTML 构建成功")
|
|
200
155
|
{
|
|
201
156
|
success: true,
|
|
202
|
-
platform:
|
|
157
|
+
platform: @platform,
|
|
203
158
|
output: @output_path
|
|
204
159
|
}
|
|
205
160
|
end
|
|
206
161
|
|
|
207
|
-
#
|
|
208
|
-
def find_ipa_output_path
|
|
209
|
-
# 记录查找前的时间,用于过滤旧文件
|
|
210
|
-
start_time = @started_at || Time.now - 60
|
|
211
|
-
|
|
212
|
-
# 使用配置中的搜索路径
|
|
213
|
-
search_paths = TaskConfig::BUILD_OUTPUT_PATTERNS[:ipa].map do |pattern|
|
|
214
|
-
File.join(@project_path, pattern)
|
|
215
|
-
end
|
|
216
|
-
|
|
217
|
-
ipa_files = []
|
|
218
|
-
search_paths.each do |pattern|
|
|
219
|
-
files = Dir.glob(pattern)
|
|
220
|
-
# 过滤出在构建开始后创建或修改的文件
|
|
221
|
-
recent_files = files.select { |f| File.mtime(f) >= start_time }
|
|
222
|
-
ipa_files.concat(recent_files)
|
|
223
|
-
end
|
|
162
|
+
# ========== 子类必须实现的抽象方法 ==========
|
|
224
163
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
ipa_files.concat(Dir.glob(pattern))
|
|
229
|
-
end
|
|
230
|
-
end
|
|
231
|
-
|
|
232
|
-
# 返回最新的 IPA 文件
|
|
233
|
-
if ipa_files.any?
|
|
234
|
-
latest_ipa = ipa_files.max_by { |f| File.mtime(f) }
|
|
235
|
-
puts " 找到 IPA 文件: #{latest_ipa}"
|
|
236
|
-
latest_ipa
|
|
237
|
-
else
|
|
238
|
-
puts " 警告: 未找到 IPA 文件"
|
|
239
|
-
nil
|
|
240
|
-
end
|
|
164
|
+
# 构建任务名称
|
|
165
|
+
def build_task_name
|
|
166
|
+
raise NotImplementedError, "子类必须实现 build_task_name 方法"
|
|
241
167
|
end
|
|
242
168
|
|
|
243
|
-
#
|
|
244
|
-
def
|
|
245
|
-
|
|
246
|
-
start_time = @started_at || Time.now - 60
|
|
247
|
-
|
|
248
|
-
# 使用配置中的搜索路径
|
|
249
|
-
search_paths = []
|
|
250
|
-
search_paths.concat(TaskConfig::BUILD_OUTPUT_PATTERNS[:apk].map { |p| File.join(@project_path, p) })
|
|
251
|
-
search_paths.concat(TaskConfig::BUILD_OUTPUT_PATTERNS[:aab].map { |p| File.join(@project_path, p) })
|
|
252
|
-
|
|
253
|
-
package_files = []
|
|
254
|
-
search_paths.each do |pattern|
|
|
255
|
-
files = Dir.glob(pattern)
|
|
256
|
-
# 过滤出在构建开始后创建或修改的文件
|
|
257
|
-
recent_files = files.select { |f| File.mtime(f) >= start_time }
|
|
258
|
-
package_files.concat(recent_files)
|
|
259
|
-
end
|
|
260
|
-
|
|
261
|
-
if package_files.empty?
|
|
262
|
-
# 如果没有找到新文件,查找最近的包文件
|
|
263
|
-
search_paths.each do |pattern|
|
|
264
|
-
package_files.concat(Dir.glob(pattern))
|
|
265
|
-
end
|
|
266
|
-
end
|
|
267
|
-
|
|
268
|
-
# 过滤掉测试包和未签名包
|
|
269
|
-
package_files.reject! do |f|
|
|
270
|
-
basename = File.basename(f).downcase
|
|
271
|
-
TaskConfig::EXCLUDED_PATTERNS.any? { |pattern| basename.include?(pattern) }
|
|
272
|
-
end
|
|
273
|
-
|
|
274
|
-
# 返回最新的包文件(优先 AAB,其次 APK)
|
|
275
|
-
if package_files.any?
|
|
276
|
-
# 分类文件
|
|
277
|
-
aab_files = package_files.select { |f| f.end_with?(".aab") }
|
|
278
|
-
apk_files = package_files.select { |f| f.end_with?(".apk") }
|
|
279
|
-
|
|
280
|
-
# 优先返回 AAB 文件
|
|
281
|
-
latest_package = if aab_files.any?
|
|
282
|
-
aab_files.max_by { |f| File.mtime(f) }
|
|
283
|
-
elsif apk_files.any?
|
|
284
|
-
apk_files.max_by { |f| File.mtime(f) }
|
|
285
|
-
else
|
|
286
|
-
package_files.max_by { |f| File.mtime(f) }
|
|
287
|
-
end
|
|
288
|
-
|
|
289
|
-
puts " 找到 Android 包文件: #{latest_package}"
|
|
290
|
-
latest_package
|
|
291
|
-
else
|
|
292
|
-
puts " 警告: 未找到 APK/AAB 文件"
|
|
293
|
-
nil
|
|
294
|
-
end
|
|
169
|
+
# 准备构建环境
|
|
170
|
+
def prepare_build
|
|
171
|
+
raise NotImplementedError, "子类必须实现 prepare_build 方法"
|
|
295
172
|
end
|
|
296
173
|
|
|
297
|
-
#
|
|
298
|
-
def
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
# 可能的 Web 构建输出位置(通常是文件夹)
|
|
303
|
-
search_paths = [
|
|
304
|
-
File.join(@project_path, "build", "web"),
|
|
305
|
-
File.join(@project_path, "build", "webgl"),
|
|
306
|
-
File.join(@project_path, "output", "web"),
|
|
307
|
-
File.join(@project_path, "output", "webgl"),
|
|
308
|
-
File.join(@project_path, "GoodPlatform", "Web"),
|
|
309
|
-
File.join(@project_path, "GoodPlatform", "WebGL"),
|
|
310
|
-
File.join(@project_path, "Build", "WebGL"),
|
|
311
|
-
File.join(@project_path, "dist"),
|
|
312
|
-
File.join(@project_path, "public")
|
|
313
|
-
]
|
|
314
|
-
|
|
315
|
-
# 查找存在且最近修改的文件夹
|
|
316
|
-
web_dirs = search_paths.select do |path|
|
|
317
|
-
File.directory?(path) && File.mtime(path) >= start_time
|
|
318
|
-
end
|
|
319
|
-
|
|
320
|
-
if web_dirs.empty?
|
|
321
|
-
# 如果没有找到新文件夹,查找包含 index.html 的文件夹
|
|
322
|
-
web_dirs = search_paths.select do |path|
|
|
323
|
-
File.directory?(path) && File.exist?(File.join(path, "index.html"))
|
|
324
|
-
end
|
|
325
|
-
end
|
|
326
|
-
|
|
327
|
-
# 如果还是没找到,查找 zip 文件
|
|
328
|
-
if web_dirs.empty?
|
|
329
|
-
zip_patterns = [
|
|
330
|
-
File.join(@project_path, "build", "**", "*web*.zip"),
|
|
331
|
-
File.join(@project_path, "output", "**", "*web*.zip"),
|
|
332
|
-
File.join(@project_path, "**", "*webgl*.zip")
|
|
333
|
-
]
|
|
334
|
-
|
|
335
|
-
zip_files = []
|
|
336
|
-
zip_patterns.each do |pattern|
|
|
337
|
-
files = Dir.glob(pattern)
|
|
338
|
-
recent_files = files.select { |f| File.mtime(f) >= start_time }
|
|
339
|
-
zip_files.concat(recent_files)
|
|
340
|
-
end
|
|
341
|
-
|
|
342
|
-
if zip_files.any?
|
|
343
|
-
latest_zip = zip_files.max_by { |f| File.mtime(f) }
|
|
344
|
-
puts " 找到 Web 压缩包: #{latest_zip}"
|
|
345
|
-
return latest_zip
|
|
346
|
-
end
|
|
347
|
-
end
|
|
174
|
+
# 执行构建
|
|
175
|
+
def execute_build
|
|
176
|
+
raise NotImplementedError, "子类必须实现 execute_build 方法"
|
|
177
|
+
end
|
|
348
178
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
puts " 找到 Web 输出目录: #{latest_dir}"
|
|
353
|
-
latest_dir
|
|
354
|
-
else
|
|
355
|
-
puts " 警告: 未找到 Web 输出文件或目录"
|
|
356
|
-
nil
|
|
357
|
-
end
|
|
179
|
+
# 查找输出文件
|
|
180
|
+
def find_output
|
|
181
|
+
raise NotImplementedError, "子类必须实现 find_output 方法"
|
|
358
182
|
end
|
|
359
183
|
end
|
|
360
184
|
end
|
|
361
|
-
end
|
|
185
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
require_relative '../pindo_task'
|
|
2
|
+
require 'pindo/module/build/git_repo_helper'
|
|
3
|
+
|
|
4
|
+
module Pindo
|
|
5
|
+
module TaskSystem
|
|
6
|
+
# Git 标签任务
|
|
7
|
+
# 检查并创建 Git 标签
|
|
8
|
+
class GitTagTask < PindoTask
|
|
9
|
+
attr_reader :project_path
|
|
10
|
+
|
|
11
|
+
def self.task_type
|
|
12
|
+
:git_tag
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# 重试配置
|
|
16
|
+
def self.default_retry_mode
|
|
17
|
+
RetryMode::IMMEDIATE # 立即重试
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.default_retry_count
|
|
21
|
+
2 # 可以重试 2 次
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.default_retry_delay
|
|
25
|
+
5 # 默认延迟 5 秒
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# 初始化 Git 标签任务
|
|
29
|
+
# @param project_path [String] 项目路径
|
|
30
|
+
# @param options [Hash] 选项
|
|
31
|
+
def initialize(project_path, options = {})
|
|
32
|
+
@project_path = project_path
|
|
33
|
+
|
|
34
|
+
super("Git 标签检查", options)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def validate
|
|
38
|
+
# 验证项目路径是否存在
|
|
39
|
+
unless @project_path && Dir.exist?(@project_path)
|
|
40
|
+
@error = "项目路径不存在:#{@project_path}"
|
|
41
|
+
return false
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
true
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
protected
|
|
48
|
+
|
|
49
|
+
def do_work
|
|
50
|
+
git_repo_helper = Pindo::GitRepoHelper.share_instance
|
|
51
|
+
|
|
52
|
+
# 检查是否需要打标签
|
|
53
|
+
is_need_add_tag, tag_action_params = git_repo_helper.check_is_need_add_tag?(@project_path)
|
|
54
|
+
|
|
55
|
+
if is_need_add_tag
|
|
56
|
+
# 直接调用 GitRepoHelper 创建标签
|
|
57
|
+
git_repo_helper.create_and_push_tag(
|
|
58
|
+
project_dir: @project_path,
|
|
59
|
+
mode: 'minor',
|
|
60
|
+
force_retag: tag_action_params&.include?('--retag') || false,
|
|
61
|
+
custom_tag: nil,
|
|
62
|
+
release_branch: 'master'
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
{
|
|
66
|
+
success: true,
|
|
67
|
+
tag_added: true,
|
|
68
|
+
tag_params: tag_action_params
|
|
69
|
+
}
|
|
70
|
+
else
|
|
71
|
+
{
|
|
72
|
+
success: true,
|
|
73
|
+
tag_added: false,
|
|
74
|
+
message: "无需添加 Git 标签"
|
|
75
|
+
}
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|