a9af6c634c
- 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>
106 lines
4.6 KiB
Bash
Executable File
106 lines
4.6 KiB
Bash
Executable File
#!/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} 一键打包 + 签名 + 公证"
|