pindo 5.20.9 → 5.20.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.
- checksums.yaml +4 -4
- data/lib/pindo/base/git_handler.rb +3 -3
- data/lib/pindo/command/ios/autobuild.rb +7 -1
- data/lib/pindo/command/ios/cert.rb +1 -0
- data/lib/pindo/module/cert/mode/base_cert_operator.rb +26 -0
- data/lib/pindo/module/cert/mode/custom_git_cert_operator.rb +1 -1
- data/lib/pindo/module/cert/mode/custom_https_cert_operator.rb +6 -3
- data/lib/pindo/module/cert/mode/match_git_cert_operator.rb +27 -2
- data/lib/pindo/module/task/model/build/ios_build_dev_task.rb +4 -1
- data/lib/pindo/module/task/model/git/git_tag_task.rb +41 -3
- data/lib/pindo/module/xcode/xcode_build_config.rb +11 -4
- data/lib/pindo/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ae50b918737d06a03fee40e06d31c3833762cabcbbf7425cf9b09da950dc3246
|
|
4
|
+
data.tar.gz: 38373f9ab3fd41bb20e31a56d171afce72b3a93610e583a2e191f013319363cf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f3af21bb72d61fe617aa675afcdec5c00041c8c570983ea362b66c517f7e15eaa352e67bec268d90e59e350a6143a42eecdfd04682a4647baab312b58596583b
|
|
7
|
+
data.tar.gz: ca8b7b1f91b3a26b8a35a9d5182998ed868b767dad52936419460f637f2c7183a96132bf354da33a3a3d2ec348a93b245101c40750b0c6316dda2dcaa841b175
|
|
@@ -375,10 +375,10 @@ module Pindo
|
|
|
375
375
|
if local_branch_exists?(local_repo_dir:local_repo_dir, branch:new_branch)
|
|
376
376
|
git!(%W(-C #{local_repo_dir} checkout #{new_branch}))
|
|
377
377
|
else
|
|
378
|
-
if
|
|
379
|
-
git!(%W(-C #{local_repo_dir} checkout -b #{new_branch}))
|
|
378
|
+
if remote_branch_exists?(local_repo_dir:local_repo_dir, branch:new_branch)
|
|
379
|
+
git!(%W(-C #{local_repo_dir} checkout -b #{new_branch} origin/#{new_branch}))
|
|
380
380
|
else
|
|
381
|
-
|
|
381
|
+
git!(%W(-C #{local_repo_dir} checkout -b #{new_branch}))
|
|
382
382
|
end
|
|
383
383
|
end
|
|
384
384
|
git!(%W(-C #{local_repo_dir} branch --set-upstream-to=origin/#{new_branch} #{new_branch}))
|
|
@@ -119,6 +119,10 @@ module Pindo
|
|
|
119
119
|
# 保存参数到实例变量
|
|
120
120
|
@args_conf = @options[:conf]
|
|
121
121
|
@args_bundle_id = @options[:bundleid]
|
|
122
|
+
|
|
123
|
+
# 用户显式指定的 Bundle ID(@args_bundle_id 会在 resolve_bundle_id! 中被回填,
|
|
124
|
+
# 这里单独留一份原始值,用于判断是否覆盖工作流名推导出的 Bundle ID)
|
|
125
|
+
@explicit_bundle_id = @options[:bundleid]
|
|
122
126
|
@build_type = @options[:build_type] || 'dev'
|
|
123
127
|
|
|
124
128
|
# 标准化构建类型(dev -> development, release -> appstore)
|
|
@@ -331,7 +335,9 @@ module Pindo
|
|
|
331
335
|
|
|
332
336
|
build_options = {
|
|
333
337
|
project_path: ios_project_path,
|
|
334
|
-
|
|
338
|
+
# 仅传用户显式指定的值:非空时覆盖工作流名推导出的 Bundle ID,
|
|
339
|
+
# 为空时构建任务保持原有的工作流推导行为
|
|
340
|
+
bundle_id: @explicit_bundle_id,
|
|
335
341
|
app_info_obj: config[:app_info_obj],
|
|
336
342
|
workflow_info: config[:workflow_info],
|
|
337
343
|
# Git 版本参数
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require 'open3'
|
|
1
2
|
require 'pindo/module/xcode/xcode_build_helper'
|
|
2
3
|
|
|
3
4
|
module Pindo
|
|
@@ -59,6 +60,21 @@ module Pindo
|
|
|
59
60
|
config_parser
|
|
60
61
|
end
|
|
61
62
|
|
|
63
|
+
# 检查证书是否已安装到 Keychain
|
|
64
|
+
#
|
|
65
|
+
# fastlane 的 CertChecker.installed? 会先联网安装 Apple 中间证书(WWDR / Developer ID),
|
|
66
|
+
# 使用的是无重试的 curl -f,Apple CDN 偶发 403 时会抛出 FastlaneError 中断整个证书流程。
|
|
67
|
+
# 这里捕获该异常并降级为不联网的本地签名身份比对。
|
|
68
|
+
#
|
|
69
|
+
# @param cert_path [String] 证书文件路径
|
|
70
|
+
# @return [Boolean] 证书是否已安装
|
|
71
|
+
def certificate_installed?(cert_path)
|
|
72
|
+
FastlaneCore::CertChecker.installed?(cert_path, in_keychain: nil)
|
|
73
|
+
rescue FastlaneCore::Interface::FastlaneError => e
|
|
74
|
+
Funlog.instance.fancyinfo_error("安装 Apple 中间证书失败(#{e.message}),改用本地签名身份比对")
|
|
75
|
+
local_identity_installed?(cert_path)
|
|
76
|
+
end
|
|
77
|
+
|
|
62
78
|
# 验证并保存证书信息
|
|
63
79
|
#
|
|
64
80
|
# 验证证书信息非空,保存到全局配置,提取 Team ID
|
|
@@ -320,6 +336,16 @@ module Pindo
|
|
|
320
336
|
# 私有辅助方法
|
|
321
337
|
# ========================================
|
|
322
338
|
|
|
339
|
+
# 不联网检查证书是否已在本地代码签名身份中
|
|
340
|
+
#
|
|
341
|
+
# @param cert_path [String] 证书文件路径
|
|
342
|
+
# @return [Boolean] 证书是否已安装
|
|
343
|
+
def local_identity_installed?(cert_path)
|
|
344
|
+
fingerprint = FastlaneCore::CertChecker.sha1_fingerprint(cert_path)
|
|
345
|
+
identities, _stderr, _status = Open3.capture3("security", "find-identity", "-v", "-p", "codesigning")
|
|
346
|
+
identities.include?(fingerprint)
|
|
347
|
+
end
|
|
348
|
+
|
|
323
349
|
# 配置项目级签名设置
|
|
324
350
|
def configure_project_level_signing(project, cert_type, platform_type)
|
|
325
351
|
signing_identity = determine_signing_identity(cert_type, platform_type)
|
|
@@ -204,7 +204,7 @@ module Pindo
|
|
|
204
204
|
if Pindo::CertHelper.isMac?
|
|
205
205
|
|
|
206
206
|
keychain_name = "login.keychain"
|
|
207
|
-
if
|
|
207
|
+
if certificate_installed?(cert_path)
|
|
208
208
|
Funlog.instance.fancyinfo_success("证书#{File.basename(cert_path)}已安装,无需重复安装!")
|
|
209
209
|
else
|
|
210
210
|
|
|
@@ -90,7 +90,7 @@ module Pindo
|
|
|
90
90
|
end
|
|
91
91
|
|
|
92
92
|
# HTTPS 模式不支持创建证书
|
|
93
|
-
def create_and_install_certs(apple_id:, bundle_id_array:, cert_type:, platform_type:)
|
|
93
|
+
def create_and_install_certs(apple_id:, bundle_id_array:, cert_type:, platform_type:, project_dir: nil)
|
|
94
94
|
raise_unsupported_error("创建证书")
|
|
95
95
|
end
|
|
96
96
|
|
|
@@ -388,7 +388,7 @@ module Pindo
|
|
|
388
388
|
keychain_name = "login.keychain"
|
|
389
389
|
|
|
390
390
|
# 检查证书是否已安装
|
|
391
|
-
if
|
|
391
|
+
if certificate_installed?(cert_path)
|
|
392
392
|
Funlog.instance.fancyinfo_success("证书已安装") if debug_mode?
|
|
393
393
|
else
|
|
394
394
|
# 获取 Keychain 密码
|
|
@@ -564,7 +564,10 @@ module Pindo
|
|
|
564
564
|
|
|
565
565
|
# 抛出不支持的操作错误
|
|
566
566
|
def raise_unsupported_error(operation)
|
|
567
|
-
raise Informative, "CustomHttpsCertOperator (HTTPS 模式) 不支持 #{operation} 操作。HTTPS
|
|
567
|
+
raise Informative, "CustomHttpsCertOperator (HTTPS 模式) 不支持 #{operation} 操作。HTTPS 模式仅支持获取和安装已有证书。\n" \
|
|
568
|
+
"如需创建证书,请使用:\n" \
|
|
569
|
+
" pindo ios cert --renew --match\n" \
|
|
570
|
+
"或:pindo ios cert --renew --cert-mode=match --storage=git"
|
|
568
571
|
end
|
|
569
572
|
end
|
|
570
573
|
end
|
|
@@ -51,7 +51,7 @@ module Pindo
|
|
|
51
51
|
# 这是 fastlane 内部使用的参数,在 App Store Connect API v3.8.0 中已弃用
|
|
52
52
|
# 该警告不影响功能,fastlane 会自动处理兼容性
|
|
53
53
|
# 参考:https://docs.fastlane.tools/actions/match/#managed-capabilities
|
|
54
|
-
|
|
54
|
+
run_match(config)
|
|
55
55
|
|
|
56
56
|
# 从环境变量中读取 match 创建的证书信息(内部方法)
|
|
57
57
|
provisioning_info_array = extract_provisioning_info_from_match_env(
|
|
@@ -97,7 +97,7 @@ module Pindo
|
|
|
97
97
|
config = FastlaneCore::Configuration.create(Match::Options.available_options, values)
|
|
98
98
|
|
|
99
99
|
# 从 Git 获取证书(只读模式)
|
|
100
|
-
|
|
100
|
+
run_match(config)
|
|
101
101
|
|
|
102
102
|
# 从环境变量中读取 match 获取的证书信息(内部方法)
|
|
103
103
|
provisioning_info_array = extract_provisioning_info_from_match_env(
|
|
@@ -124,6 +124,31 @@ module Pindo
|
|
|
124
124
|
# Match 特定逻辑:高度自包含
|
|
125
125
|
# ========================================
|
|
126
126
|
|
|
127
|
+
# 运行 fastlane match(禁用 Git hooks)
|
|
128
|
+
#
|
|
129
|
+
# match 会用固定信息提交证书仓库(如 "[fastlane] Updated development and platform ios"),
|
|
130
|
+
# 该信息不符合 Conventional Commits 规范,被 commit-msg 校验 hook 拒绝后
|
|
131
|
+
# 新证书无法推回远端仓库,只能安装到本地。
|
|
132
|
+
# 这里通过 GIT_CONFIG_* 把 core.hooksPath 指向 /dev/null,让 match 的 git 子进程跳过所有 hook。
|
|
133
|
+
#
|
|
134
|
+
# @param config [FastlaneCore::Configuration] match 配置
|
|
135
|
+
def run_match(config)
|
|
136
|
+
index = ENV['GIT_CONFIG_COUNT'].to_i
|
|
137
|
+
saved_env = {
|
|
138
|
+
'GIT_CONFIG_COUNT' => ENV['GIT_CONFIG_COUNT'],
|
|
139
|
+
"GIT_CONFIG_KEY_#{index}" => ENV["GIT_CONFIG_KEY_#{index}"],
|
|
140
|
+
"GIT_CONFIG_VALUE_#{index}" => ENV["GIT_CONFIG_VALUE_#{index}"]
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
ENV["GIT_CONFIG_KEY_#{index}"] = 'core.hooksPath'
|
|
144
|
+
ENV["GIT_CONFIG_VALUE_#{index}"] = '/dev/null'
|
|
145
|
+
ENV['GIT_CONFIG_COUNT'] = (index + 1).to_s
|
|
146
|
+
|
|
147
|
+
Match::Runner.new.run(config)
|
|
148
|
+
ensure
|
|
149
|
+
saved_env.each { |key, value| ENV[key] = value } if saved_env
|
|
150
|
+
end
|
|
151
|
+
|
|
127
152
|
# 构建 fastlane match 配置参数
|
|
128
153
|
#
|
|
129
154
|
# @param apple_id [String] Apple ID
|
|
@@ -134,12 +134,15 @@ module Pindo
|
|
|
134
134
|
|
|
135
135
|
puts "\n使用工作流配置更新 iOS 项目:"
|
|
136
136
|
puts " Workflow Package Name: #{workflow_packname}"
|
|
137
|
+
puts " 指定的 Bundle ID: #{@bundle_id}" if @bundle_id && !@bundle_id.to_s.strip.empty?
|
|
137
138
|
|
|
138
139
|
# 更新 Display Name、Bundle ID、URL Schemes 和 JPS 快捷操作
|
|
140
|
+
# bundle_id 显式传入时优先于工作流名推导,避免 --bundleid 被工作流配置覆盖
|
|
139
141
|
Pindo::XcodeBuildConfig.update_project_with_workflow(
|
|
140
142
|
project_dir: @project_path,
|
|
141
143
|
workflow_packname: workflow_packname,
|
|
142
|
-
project_id: project_id
|
|
144
|
+
project_id: project_id,
|
|
145
|
+
bundle_id: @bundle_id
|
|
143
146
|
)
|
|
144
147
|
|
|
145
148
|
# 下载并替换 Icon,优先使用 packageProjectIcon,为空则回退到 projectIcon
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require 'pindo/module/task/model/git_task'
|
|
2
|
+
require 'pindo/base/executable'
|
|
2
3
|
require 'pindo/base/git_handler'
|
|
3
4
|
require 'pindo/module/source_files_guard'
|
|
4
5
|
require 'pindo/module/utils/git_repo_helper'
|
|
@@ -133,13 +134,20 @@ module Pindo
|
|
|
133
134
|
|
|
134
135
|
# 只提交 autobuild 明确注入的源码文件,避免把 Pods、DerivedData 等构建产物带入发布提交。
|
|
135
136
|
def commit_build_changes(root_dir)
|
|
136
|
-
guard_paths =
|
|
137
|
+
guard_paths = reject_ignored_paths(
|
|
137
138
|
root_dir,
|
|
138
|
-
|
|
139
|
+
existing_guard_paths(
|
|
140
|
+
root_dir,
|
|
141
|
+
Pindo::BuildSourceFilesGuard.for_project(@project_path)
|
|
142
|
+
)
|
|
139
143
|
)
|
|
140
144
|
return false if guard_paths.empty?
|
|
141
145
|
|
|
142
|
-
|
|
146
|
+
# -f 是必需的:文件已跟踪、但父目录名匹配 .gitignore 规则时(如本仓库的 build/ 规则
|
|
147
|
+
# 命中 module/task/model/build),普通 add 仍会以非零码退出,让打 tag 整体失败。
|
|
148
|
+
# 危险的「未跟踪 + 被忽略」路径已由 reject_ignored_paths 剔除,此处剩下的都应当提交,
|
|
149
|
+
# -f 只是绕过 advice,不会多纳入任何文件。
|
|
150
|
+
Pindo::GitHandler.git!(git_command(root_dir, 'add', '-f', '--', *guard_paths))
|
|
143
151
|
staged_files = Pindo::GitHandler.git!(
|
|
144
152
|
git_command(root_dir, 'diff', '--cached', '--name-only', '--', *guard_paths)
|
|
145
153
|
).lines.map(&:strip).reject(&:empty?)
|
|
@@ -167,6 +175,36 @@ module Pindo
|
|
|
167
175
|
end.uniq
|
|
168
176
|
end
|
|
169
177
|
|
|
178
|
+
# 剔除被 .gitignore 忽略且尚未跟踪的路径。
|
|
179
|
+
#
|
|
180
|
+
# Unity 工程把导出的平台工程目录(GoodPlatform/iOS 等)整体写进 .gitignore,
|
|
181
|
+
# 其中的 project.pbxproj / Info.plist / AppIcon.appiconset 会命中 guard 清单,
|
|
182
|
+
# 但 git add 遇到「被忽略且未跟踪」的路径会以非零码退出,直接让打 tag 任务失败。
|
|
183
|
+
# git check-ignore 不报告已在 index 中的文件,因此已入库的文件仍会照常提交。
|
|
184
|
+
def reject_ignored_paths(root_dir, relative_paths)
|
|
185
|
+
return relative_paths if relative_paths.empty?
|
|
186
|
+
|
|
187
|
+
# check-ignore 不接受 --literal-pathspecs(会以 "pathspec magic not supported" 退出 128),
|
|
188
|
+
# 故不能复用 git_command,这里单独拼参数。
|
|
189
|
+
# core.quotePath=false 是必需的:默认会把中文等非 ASCII 路径转义成 "\344\270\255" 形式,
|
|
190
|
+
# 与输入路径对不上,下面的差集就减不掉,过滤会静默失效。
|
|
191
|
+
output, status = Executable.capture_command(
|
|
192
|
+
'git',
|
|
193
|
+
['-C', root_dir, '-c', 'core.quotePath=false', 'check-ignore', '--', *relative_paths],
|
|
194
|
+
capture: :out
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
# 退出码 1 表示没有任何路径被忽略;其余非零码(如 128)说明命令本身出错,
|
|
198
|
+
# 此时不做过滤,保持原有行为把问题暴露给后续的 git add
|
|
199
|
+
return relative_paths unless status.success?
|
|
200
|
+
|
|
201
|
+
ignored = output.lines.map(&:strip).reject(&:empty?)
|
|
202
|
+
return relative_paths if ignored.empty?
|
|
203
|
+
|
|
204
|
+
Funlog.instance.fancyinfo_warning("以下构建注入文件被 .gitignore 忽略,跳过提交: #{ignored.join(', ')}")
|
|
205
|
+
relative_paths - ignored
|
|
206
|
+
end
|
|
207
|
+
|
|
170
208
|
def git_command(root_dir, command, *arguments)
|
|
171
209
|
['--literal-pathspecs', '-C', root_dir, command, *arguments]
|
|
172
210
|
end
|
|
@@ -18,17 +18,23 @@ module Pindo
|
|
|
18
18
|
# @param project_dir [String] iOS项目目录路径
|
|
19
19
|
# @param workflow_packname [String] 工作流的名称(如:"Test Demo")
|
|
20
20
|
# @param project_id [String] JPS项目ID(可选,用于添加快捷操作)
|
|
21
|
+
# @param bundle_id [String] 显式指定的 Bundle ID(可选,来自 --bundleid)
|
|
21
22
|
# @return [Boolean] 是否成功更新
|
|
22
|
-
def self.update_project_with_workflow(project_dir: nil, workflow_packname: nil, project_id: nil)
|
|
23
|
+
def self.update_project_with_workflow(project_dir: nil, workflow_packname: nil, project_id: nil, bundle_id: nil)
|
|
23
24
|
raise ArgumentError, "项目目录不能为空" if project_dir.nil?
|
|
24
25
|
raise ArgumentError, "Workflow Package Name不能为空" if workflow_packname.nil?
|
|
25
26
|
|
|
26
27
|
# 生成各种值
|
|
27
28
|
display_name = workflow_packname.gsub(/[^a-zA-Z0-9\s]/, '').gsub(/\s+/, '')
|
|
28
|
-
bundle_id_suffix = workflow_packname.gsub(/[^a-zA-Z0-9]/, '').downcase
|
|
29
|
-
final_bundle_id = "com.heroneverdie101.#{bundle_id_suffix}"
|
|
30
29
|
package_scheme = workflow_packname.gsub(/[^a-zA-Z0-9]/, '').downcase
|
|
31
30
|
|
|
31
|
+
# Bundle ID 优先使用显式传入的值(--bundleid),未传时按工作流名推导。
|
|
32
|
+
# 通配符(如 com.example.*)不能作为工程的 PRODUCT_BUNDLE_IDENTIFIER,
|
|
33
|
+
# 与 BaseCertOperator#configure_target_build_settings 的处理保持一致,退回推导值。
|
|
34
|
+
explicit_bundle_id = bundle_id.to_s.strip
|
|
35
|
+
use_explicit_bundle_id = !explicit_bundle_id.empty? && !explicit_bundle_id.include?("*")
|
|
36
|
+
final_bundle_id = use_explicit_bundle_id ? explicit_bundle_id : "com.heroneverdie101.#{package_scheme}"
|
|
37
|
+
|
|
32
38
|
project_fullname = Dir.glob(File.join(project_dir, "/*.xcodeproj")).max_by {|f| File.mtime(f)}
|
|
33
39
|
return false if project_fullname.nil?
|
|
34
40
|
|
|
@@ -124,7 +130,8 @@ module Pindo
|
|
|
124
130
|
end
|
|
125
131
|
|
|
126
132
|
puts " ✓ Display Name 已更新为: #{display_name}"
|
|
127
|
-
|
|
133
|
+
bundle_id_source = use_explicit_bundle_id ? "--bundleid" : "工作流名称"
|
|
134
|
+
puts " ✓ Bundle ID 已更新为: #{final_bundle_id} (来源: #{bundle_id_source})"
|
|
128
135
|
return true
|
|
129
136
|
end
|
|
130
137
|
|
data/lib/pindo/version.rb
CHANGED