153 lines
4.3 KiB
Bash
Executable File
153 lines
4.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# 对已经 Developer ID 签名的 DMG 做 Apple 公证并 staple。
|
||
# 已钉票则直接退出,避免重复上传。
|
||
# notarytool --wait 有时会一直 In Progress,即使苹果已 Accepted;超时后仍尝试 staple。
|
||
set -u
|
||
|
||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||
VERSION="$(node -p "require('$ROOT_DIR/package.json').version")"
|
||
|
||
default_dmg() {
|
||
local dir dmg
|
||
for dir in \
|
||
"$ROOT_DIR/src-tauri/target/aarch64-apple-darwin/release/bundle/dmg" \
|
||
"$ROOT_DIR/src-tauri/target/x86_64-apple-darwin/release/bundle/dmg" \
|
||
"$ROOT_DIR/src-tauri/target/release/bundle/dmg"
|
||
do
|
||
dmg="$(ls -t "$dir"/OpsXShell_"${VERSION}"_*.dmg 2>/dev/null | head -n 1 || true)"
|
||
if [ -n "$dmg" ]; then
|
||
printf '%s' "$dmg"
|
||
return 0
|
||
fi
|
||
done
|
||
return 1
|
||
}
|
||
|
||
if [ -n "${1:-}" ]; then
|
||
DMG="$1"
|
||
elif ! DMG="$(default_dmg)"; then
|
||
echo "找不到 Tauri bundle 里的 DMG。请先 ./scripts/build.sh,或显式传入路径。" >&2
|
||
echo "标准位置:src-tauri/target/<triple>/release/bundle/dmg/" >&2
|
||
exit 1
|
||
fi
|
||
APPLE_ID="${APPLE_ID:-}"
|
||
TEAM_ID="${APPLE_TEAM_ID:-B8DVUUUF6W}"
|
||
WAIT_TIMEOUT="${NOTARY_WAIT_TIMEOUT:-15m}"
|
||
: "${WAIT_TIMEOUT:=15m}"
|
||
|
||
if [ ! -f "$DMG" ]; then
|
||
echo "找不到安装包:$DMG" >&2
|
||
exit 1
|
||
fi
|
||
|
||
# 挂载中的 DMG 无法 staple / validate
|
||
if hdiutil info 2>/dev/null | grep -Fq "$DMG"; then
|
||
echo "DMG 仍挂载,请先在 Finder 弹出 /Volumes 下的 OpsXShell,再重试。" >&2
|
||
hdiutil info | grep -E "image-path|/Volumes/" || true
|
||
exit 1
|
||
fi
|
||
|
||
export http_proxy="${http_proxy:-http://127.0.0.1:7897}"
|
||
export https_proxy="${https_proxy:-http://127.0.0.1:7897}"
|
||
export HTTP_PROXY="$http_proxy"
|
||
export HTTPS_PROXY="$https_proxy"
|
||
export ALL_PROXY="${ALL_PROXY:-socks5://127.0.0.1:7897}"
|
||
export no_proxy="localhost,127.0.0.1,::1"
|
||
export NO_PROXY="$no_proxy"
|
||
|
||
already_stapled() {
|
||
xcrun stapler validate "$DMG" >/dev/null 2>&1
|
||
}
|
||
|
||
try_staple() {
|
||
echo "尝试 staple(从苹果拉票据钉进 DMG,不需要专用密码)…"
|
||
if xcrun stapler staple "$DMG"; then
|
||
xcrun stapler validate "$DMG"
|
||
echo
|
||
echo "完成(已钉票):$DMG"
|
||
return 0
|
||
fi
|
||
return 1
|
||
}
|
||
|
||
if already_stapled; then
|
||
echo "这份 DMG 已经公证并 staple,不用再执行。"
|
||
echo "$DMG"
|
||
xcrun stapler validate "$DMG"
|
||
exit 0
|
||
fi
|
||
|
||
echo "尚未钉票。先看苹果是否已经公证通过(常见于 --wait 卡住)。"
|
||
if try_staple; then
|
||
exit 0
|
||
fi
|
||
|
||
if [ -z "$APPLE_ID" ]; then
|
||
APPLE_ID="$(
|
||
osascript <<'APPLESCRIPT'
|
||
tell application "System Events"
|
||
activate
|
||
set dlg to display dialog "Apple ID(开发者账号邮箱)" default answer "" with title "OpsXShell 公证" buttons {"取消", "继续"} default button "继续" cancel button "取消"
|
||
return text returned of dlg
|
||
end tell
|
||
APPLESCRIPT
|
||
)" || exit 1
|
||
fi
|
||
|
||
echo
|
||
echo "需要提交公证。请输入 App 专用密码,不要发到聊天。"
|
||
PASSWORD="$(
|
||
osascript <<'APPLESCRIPT'
|
||
tell application "System Events"
|
||
activate
|
||
set dlg to display dialog "App 专用密码(xxxx-xxxx-xxxx-xxxx)" default answer "" with hidden answer with title "OpsXShell 公证" buttons {"取消", "提交"} default button "提交" cancel button "取消"
|
||
return text returned of dlg
|
||
end tell
|
||
APPLESCRIPT
|
||
)" || {
|
||
echo "已取消。" >&2
|
||
exit 1
|
||
}
|
||
|
||
if [ -z "$PASSWORD" ] || [ -z "$APPLE_ID" ]; then
|
||
echo "未输入 Apple ID 或专用密码,已取消。" >&2
|
||
exit 1
|
||
fi
|
||
|
||
echo "正在提交 ${DMG} (最多等 ${WAIT_TIMEOUT}) …"
|
||
set +e
|
||
SUBMIT_LOG="$(mktemp)"
|
||
xcrun notarytool submit "$DMG" \
|
||
--apple-id "$APPLE_ID" \
|
||
--password "$PASSWORD" \
|
||
--team-id "$TEAM_ID" \
|
||
--wait \
|
||
--timeout "${WAIT_TIMEOUT}" | tee "$SUBMIT_LOG"
|
||
SUBMIT_STATUS="${PIPESTATUS[0]}"
|
||
set -e
|
||
|
||
SUB_ID="$(awk '/id: / { print $2; exit }' "$SUBMIT_LOG")"
|
||
rm -f "$SUBMIT_LOG"
|
||
|
||
if [ -n "$SUB_ID" ]; then
|
||
echo "提交号:$SUB_ID"
|
||
fi
|
||
|
||
if [ "$SUBMIT_STATUS" -eq 0 ]; then
|
||
echo "notarytool 报告处理结束。"
|
||
else
|
||
echo "等待超时或状态未刷新 (exit ${SUBMIT_STATUS}). 改为直接 staple。"
|
||
fi
|
||
|
||
if try_staple; then
|
||
exit 0
|
||
fi
|
||
|
||
echo >&2
|
||
echo "staple 仍失败。可等几分钟再执行本脚本(已公证则不会重新上传)。" >&2
|
||
if [ -n "${SUB_ID:-}" ]; then
|
||
echo " xcrun notarytool info $SUB_ID --apple-id \"$APPLE_ID\" --team-id \"$TEAM_ID\"" >&2
|
||
fi
|
||
echo "不要对同一份未变化的 DMG 连续第三次提交。" >&2
|
||
exit 1
|