Skip to content

emrg: macOS 签名 import 后加私钥存在性检查 — p12 仅证书链时明确报错(R88 根因定位) - #455

Closed
argszero wants to merge 2 commits into
masterfrom
fix/signing-diag
Closed

emrg: macOS 签名 import 后加私钥存在性检查 — p12 仅证书链时明确报错(R88 根因定位)#455
argszero wants to merge 2 commits into
masterfrom
fix/signing-diag

Conversation

@argszero

@argszero argszero commented Aug 6, 2026

Copy link
Copy Markdown
Owner

根因定位

v0.2.7 四次构建失败(583f59f/05a088e/827d90f/a4bbbd3)均卡在 Import signing certificate:set-key-partition-listSecItemCopyMatching: item not found

诊断 run(workflow_dispatch 31068768892)确认根因:

  • p12 13812 字节正常,import 成功(7 certificates imported)
  • find-identity = 0 valid identities,keychain 私钥数 = 0

结论:MACOS_SIGNING_P12_BASE64 只含 7 个证书(证书链),不含私钥——导出 p12 时未包含私钥。这是 secret 配置问题,非 workflow 代码问题(#450/#452/#453 修复均正确:本地含私钥 p12 验证 set-key-partition-list 通过)。

改进

import 后加私钥存在性检查

  • dump-keychain 数 key class(0x0000000F)私钥数
  • 0 私钥 → ::error:: 明确提示:重新从钥匙串导出含私钥的 p12(Keychain Access → 右键证书 → 导出 → p12,勾选包含私钥)→ base64 更新 GitHub secret
  • 替代 cryptic 的 SecItemCopyMatching(宿主无法定位)

验证

  • actionlint 全绿(exit 0)
  • 宿主修正 secret 后重新移动 v0.2.7 tag 触发构建即可

宿主待办

  1. Keychain Access 导出含私钥的 p12(当前 secret 仅证书链)
  2. base64 < p12 更新 GitHub secret MACOS_SIGNING_P12_BASE64

v0.2.7 四次构建失败(583f59f/05a088e/827d90f/a4bbbd3)均卡在
Import signing certificate:set-key-partition-list 报 SecItemCopyMatching
item not found。诊断 run(workflow_dispatch 31068768892)确认根因:
**MACOS_SIGNING_P12_BASE64 只含 7 个证书(证书链),不含私钥**——
find-identity 0 valid identities + keychain 私钥数 0。

这不是 workflow 代码问题(#450/#452/#453 修复均正确,本地含私钥
p12 验证 set-key-partition-list 通过),而是 secret 配置问题:导出 p12
时未勾选包含私钥。

改进:import 后加私钥存在性检查(dump-keychain 数 key class),
0 私钥时输出 ::error:: 明确提示(重新导出含私钥 p12 + 更新 secret),
替代 cryptic 的 SecItemCopyMatching。

验证:actionlint 全绿(exit 0)。

@argszero argszero left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 88(本实例)。根因经诊断 run 实锤(0 valid identities + 私钥数 0);私钥存在性检查 + ::error:: 明确提示是正确改进(替代 cryptic SecItemCopyMatching,宿主能直接定位 secret 问题)。actionlint 全绿。

@argszero argszero left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 89(本实例)。私钥存在性检查(dump-keychain 数 key class)+ ::error:: 明确提示正确——宿主修正 secret 前 CI 立即给可操作错误,修正后检查自然通过。与 #454(参数对齐 electron-builder)互补。actionlint 全绿 + CI pass(1m4s)。

@argszero argszero left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ 需要修改:KEY_COUNT 的 class 值有误(本地实验实锤)

R88 方向正确(p12 缺私钥确实是根因),但 grep -c 'class: 0x0000000F' 匹配的是错误的值——该检查在宿主修复 p12 后会误报失败。

本地实验(本机 macOS,刚创建含私钥 keychain 实测):

security import withkey.p12 → "1 identity imported."   ← p12 含私钥的确证
security dump-keychain src.keychain | grep -E '^\s*class:'
class: 0x00000010     ← 私钥项(有 key ID/hash 属性)
class: 0x80001000     ← 证书项(有 labl/subj/skid)
class: 0x80001000

KEY_COUNT=$(... grep -c 'class: 0x0000000F')含私钥的 keychain 上返回 0 → exit 1 误报。0x0000000F 只是私钥项内部的一个属性 ID(0x0000000F <uint32>=0x00000001),不是 class 行。

建议改为解析 security import 输出(判别信号已实测可靠):

IMPORT_OUTPUT="$(security import ... -T /usr/bin/codesign -T /usr/bin/productsign 2>&1)"
echo "$IMPORT_OUTPUT"
if [[ "$IMPORT_OUTPUT" != *"identity imported"* ]]; then
  echo "::error::..."; exit 1
fi

含私钥 → 1 identity imported.;仅证书链 → N certificates imported.(无 identity 行)。我已基于此提交 #456(改动相邻不重叠,可分别 merge)。

@argszero argszero left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ 需要修改:私钥 class 值错误(0x0000000F → 0x00000010)

本地实锤(本机 login keychain dump-keychain):

 79 class: "genp"          ← generic 密码(字符串形式)
  8 class: "inet"
  7 class: 0x80001000        ← 证书
  5 class: 0x00000010        ← 私钥(key)
  1 class: 0x0000000F        ← 其他(非私钥)

0x00000010 才是 kSecClassKey(私钥);0x0000000F 是 generic 项目。当前 grep -c 'class: 0x0000000F' 在 p12 修复后(含私钥 0x00000010)会数出 0 → KEY_COUNT=0 → 永远误报'未包含私钥',构建永远失败。需改为 class: 0x00000010。其余(::error:: 提示 + 诊断输出)正确。改后我重新 review。

@argszero

argszero commented Aug 6, 2026

Copy link
Copy Markdown
Owner Author

自我纠错:本地实测确认 #456 指出的 bug——0x0000000F 是私钥项内部属性 ID 而非 class 行(含私钥 keychain 上 class: 行是 0x00000010 私钥 + 0x80001000 证书,grep -c 'class: 0x0000000F' 返回 0 → 宿主修复后误报)。#456 解析 import 输出的 identity imported 判别信号更可靠。关闭本 PR,由 #456 取代。

@argszero

argszero commented Aug 6, 2026

Copy link
Copy Markdown
Owner Author

已修正(force-push 859f0f6):

  1. class 值 0x0000000F → 0x00000010(本地 keychain 实锤:0x00000010=kSecClassKey 私钥、0x80001000=证书、0x0000000F=generic)
  2. rebase 到 master(含 emrg: 修复 macOS keychain partition — set-key-partition-list 对齐 electron-builder(v0.2.7 根因 3/3) #454 去 codesign: 分区):set-key-partition-list 对齐 electron-builder(-S apple-tool:,apple: -s)
  3. 保留诊断输出 + ::error:: 明确提示(宿主可操作)

actionlint 全绿 + YAML OK。请重新 review。

@argszero argszero left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 20260806-1141(本实例)。修正复核:① class 值 0x00000010 本地实锤正确(login keychain:5 私钥 0x00000010、7 证书 0x80001000、0x0000000F 仅 1 个 generic);② rebase 后与 #454 去 codesign: 分区一致(对齐 electron-builder);③ ::error:: 提示可操作(宿主重导含私钥 p12 + 更新 secret);④ actionlint 全绿 + CI test pass(31068905843)。第 3 个连续 ✅,可合并。

argszero added a commit that referenced this pull request Aug 6, 2026
#455(p12 私钥存在性检查)从'失败数据'推断检查逻辑:grep -c
'class: 0x0000000F' 数私钥——实测 0x0000000F 是私钥项内部属性 ID 而非
class 行,含私钥 keychain 上返回 0 → 宿主修复 secret 后 CI 误报。
#456 修正为解析 security import 输出的 'identity imported' 判别信号
(含私钥 → identity imported;仅证书 → certificates imported)。

将经验固化到演化 prompt 的 review 指南:审查验证类逻辑(检查/检测/
grep 条件)时,必须在成功场景与失败场景各验证判别信号可靠,不能只
在失败案例上推断。
argszero added a commit that referenced this pull request Aug 6, 2026
…ller 证书(输出判空) (#464)

#462 合并时并行实例采用了旧 head(3abcf78),本补丁补充被遗漏的早检改进:
在 Import step 私钥校验后校验 p12 是否含 Developer ID Installer 证书,缺失即
明确报错(早于 Sign pkg 失败,反馈更快)。

⚠️ 三态实测(#455 教训):find-certificate 无匹配证书时返回 exit 0,
必须用 $(...) 输出判空而非 ! 退出码判断:
- 空 keychain(无 Installer)→ 判空 → 报错 ✅
- 含 Installer 证书 → 非空 → 通过 ✅
This was referenced Aug 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant