Files
root a9af6c634c
Backend CI / Backend (push) Successful in 13m6s
Deployment Config CI / Deployment Config (push) Successful in 17s
Frontend CI / Frontend (push) Successful in 2m24s
chore(desktop-client): add macOS code-signing and notarization scaffolding
- Move the build config out of package.json into electron-builder.yml so
  the mac block can carry hardenedRuntime, entitlements, universal arch,
  and usage-description Info.plist keys. Drop identity:null (which
  forces unsigned builds) and let CSC_NAME or the keychain decide.
- Add entitlements plist files and three helper scripts: sign-setup.sh
  (one-time keychain prep with notarytool store-credentials),
  sign-mac.sh (sign + notarize + staple, supports keychain or CI env
  vars), and ci-import-cert.sh (CI keychain bootstrap).
- Ignore .env.signing so local credentials don't sneak into the repo,
  and pin @emnapi/{core,runtime} as devDependencies so universal builds
  resolve them deterministically.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 16:02:14 +08:00

106 lines
4.6 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# 一次性签名环境配置:检查证书 + 录入 Apple ID 凭证 + 写入 .env.signing
# 用法: pnpm sign:setup
set -euo pipefail
cd "$(dirname "$0")/.."
KEYCHAIN_PROFILE="GeoRanklySign"
ENV_FILE=".env.signing"
R=$'\033[31m'; G=$'\033[32m'; Y=$'\033[33m'; B=$'\033[1m'; N=$'\033[0m'
ok() { echo " ${G}${N} $1"; }
fail() { echo " ${R}${N} $1"; }
warn() { echo " ${Y}!${N} $1"; }
hr() { echo ""; echo "${B}── $1 ──${N}"; }
# ── 1. Xcode CLT ────────────────────────────────────────────────
hr "1/3 检查 Xcode Command Line Tools"
if xcode-select -p >/dev/null 2>&1; then
ok "已安装:$(xcode-select -p)"
else
fail "未安装"
echo " 请在终端运行 ${B}xcode-select --install${N},弹窗装好后再来"
exit 1
fi
# ── 2. Developer ID 证书 ────────────────────────────────────────
hr "2/3 检查 Developer ID Application 证书"
IDENTITIES=$(security find-identity -v -p codesigning | grep "Developer ID Application" || true)
if [ -z "$IDENTITIES" ]; then
fail "钥匙串里没找到 Developer ID Application 证书"
cat <<EOF
${B}申请步骤(一次性,约 10 分钟):${N}
${Y}1.${N} 浏览器登录 https://developer.apple.com/account/resources/certificates
${Y}2.${N} 点 ${B}+${N} 新建证书 → 选 ${B}Developer ID Application${N} → Continue
${Y}3.${N} 它要你上传 CSR,按下面方法生成:
打开 macOS ${B}钥匙串访问.app${N}
菜单栏 → 钥匙串访问 → 证书助理 → ${B}从证书颁发机构请求证书…${N}
邮箱填你的 Apple ID,常用名随意,选 ${B}存储到磁盘${N},保存为 .certSigningRequest
${Y}4.${N} 把这个 .certSigningRequest 上传,下载得到 ${B}developerID_application.cer${N}
${Y}5.${N} 双击 .cer,导入到 ${B}登录${N} 钥匙串
${Y}6.${N} 重新运行 ${B}pnpm sign:setup${N}
EOF
exit 1
fi
# 多张证书时取第一张
IDENTITY_LINE=$(echo "$IDENTITIES" | head -n1)
IDENTITY_NAME=$(echo "$IDENTITY_LINE" | sed -E 's/.*"(Developer ID Application: [^"]+)".*/\1/')
# CSC_NAME 必须去掉 "Developer ID Application: " 前缀,否则 electron-builder 会拒绝
CSC_NAME_VALUE=$(echo "$IDENTITY_NAME" | sed -E 's/^Developer ID Application: //')
TEAM_ID=$(echo "$IDENTITY_NAME" | sed -E 's/.*\(([A-Z0-9]+)\).*/\1/')
ok "找到证书:${B}$IDENTITY_NAME${N}"
ok "Team ID${B}$TEAM_ID${N}"
if [ "$(echo "$IDENTITIES" | wc -l | tr -d ' ')" -gt 1 ]; then
warn "钥匙串里有多张 Developer ID 证书,本脚本默认用上面这一张"
fi
# ── 3. Apple ID 凭证(公证用)─────────────────────────────────────
hr "3/3 录入 Apple ID 凭证(用于公证 notarize"
NEED_CREDENTIALS=1
if security find-generic-password -s "com.apple.gke.notary.tool.saved-creds" -a "$KEYCHAIN_PROFILE" >/dev/null 2>&1; then
ok "钥匙串里已有 profile$KEYCHAIN_PROFILE"
read -r -p " 是否重新录入?(y/N): " RECONFIG
[[ "${RECONFIG:-n}" =~ ^[Yy]$ ]] || NEED_CREDENTIALS=0
fi
if [ "$NEED_CREDENTIALS" = "1" ]; then
echo ""
echo " 需要 ${B}Apple ID 邮箱${N} + ${B}App 专用密码${N}(不是登录密码!)"
echo " 生成 App 专用密码: https://appleid.apple.com → 登录与安全 → App 专用密码 → +"
echo ""
read -r -p " Apple ID 邮箱: " APPLE_ID
read -r -s -p " App 专用密码 (xxxx-xxxx-xxxx-xxxx): " APPLE_PWD
echo ""
if ! xcrun notarytool store-credentials "$KEYCHAIN_PROFILE" \
--apple-id "$APPLE_ID" \
--team-id "$TEAM_ID" \
--password "$APPLE_PWD" >/dev/null; then
fail "凭证录入失败,常见原因:密码格式错(需带短横线),或 Team ID 不匹配"
exit 1
fi
ok "凭证已存入钥匙串(profile: ${KEYCHAIN_PROFILE}"
fi
# ── 写入 .env.signing ───────────────────────────────────────────
cat > "$ENV_FILE" <<EOF
# Auto-generated by scripts/sign-setup.sh — DO NOT COMMIT
# 让 electron-builder 自动选用钥匙串里的证书
# 注意:CSC_NAME 不能带 "Developer ID Application:" 前缀
CSC_NAME="$CSC_NAME_VALUE"
APPLE_TEAM_ID="$TEAM_ID"
NOTARY_KEYCHAIN_PROFILE="$KEYCHAIN_PROFILE"
EOF
ok "写入 ${B}apps/desktop-client/$ENV_FILE${N}"
echo ""
echo "${G}${B}━━━ 配置完成 ━━━${N}"
echo " 下一步:运行 ${B}pnpm sign:mac${N} 一键打包 + 签名 + 公证"