From 495319fe1f679d85730bb84fb5f82d9197754722 Mon Sep 17 00:00:00 2001 From: 7418 <7418@openclaw.ai> Date: Fri, 27 Feb 2026 16:06:54 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20macOS=20=E7=83=AD=E6=9B=B4=E6=96=B0=20co?= =?UTF-8?q?de=20signature=20=E6=A0=A1=E9=AA=8C=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因:CI 上没有 Apple Developer 证书,electron-builder 跳过签名, 生成完全未签名的 .app。electron-updater 的 ShipIt 进程在应用更新时 校验 code signature,未签名的 app 被拒绝: "Code signature did not pass validation: 代码未能满足指定的代码要求" 修复: 1. scripts/after-pack.js — 在所有文件修改(better-sqlite3 替换) 完成后,对 macOS .app 执行 ad-hoc 签名(codesign --force --deep -s -)。 Ad-hoc 签名不需要证书,但能通过 ShipIt 的基本校验。 如果将来配置了真实证书,electron-builder 的签名步骤会覆盖 ad-hoc。 2. .github/workflows/build.yml — macOS 构建添加 CSC_IDENTITY_AUTO_DISCOVERY=false,防止 electron-builder 尝试查找不存在的证书时产生不可预期的行为。 Co-Authored-By: Claude Opus 4.6 --- .github/workflows/build.yml | 1 + scripts/after-pack.js | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ec5e556..dbeb01d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -63,6 +63,7 @@ jobs: - name: Package for macOS (x64 + arm64) env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CSC_IDENTITY_AUTO_DISCOVERY: "false" run: npx electron-builder --mac --config electron-builder.yml --publish always build-linux: diff --git a/scripts/after-pack.js b/scripts/after-pack.js index 1fc721b..130e07f 100644 --- a/scripts/after-pack.js +++ b/scripts/after-pack.js @@ -118,4 +118,33 @@ module.exports = async function afterPack(context) { } } } + + // Step 4: Ad-hoc code sign on macOS for auto-update compatibility. + // electron-updater's ShipIt process validates code signatures when applying + // updates. Without at least an ad-hoc signature, the update fails with: + // "Code signature did not pass validation: 代码未能满足指定的代码要求" + // Ad-hoc signing (codesign -s -) creates a valid local signature without + // requiring an Apple Developer certificate. + // This runs AFTER all file modifications (better-sqlite3 replacement above) + // so the signature covers the final app state. If a real certificate is + // available, electron-builder's signing step will override this. + if (platform === 'mac') { + const appName = context.packager.appInfo.productFilename; + const appPath = path.join(appOutDir, `${appName}.app`); + + if (fs.existsSync(appPath)) { + console.log(`[afterPack] Ad-hoc signing ${appPath} for auto-update compatibility...`); + try { + execSync(`codesign --force --deep -s - "${appPath}"`, { + stdio: 'inherit', + timeout: 120000, + }); + console.log('[afterPack] Ad-hoc signing completed successfully'); + } catch (err) { + console.warn('[afterPack] Ad-hoc signing failed (non-fatal):', err.message); + } + } else { + console.warn(`[afterPack] macOS app not found at ${appPath}, skipping ad-hoc signing`); + } + } };