chore: 保存工作副本——客户端授权新契约(双端点/验签/令牌/周检)与桌面会话可靠性改进
This commit is contained in:
1 parent
f71eef0eba
commit
ae6093c9b3
163 files changed
+4911
-2494
No files matched your search
+16
-3
@@ -176,10 +176,23 @@ esac
|
||||
node scripts/release-preflight.mjs "$RELEASE_PLATFORM"
|
||||
|
||||
log "构建原生安装包"
|
||||
TAURI_ARGS=(--ci --target "$RUST_TARGET")
|
||||
CODESIGN_WRAP_DIR=""
|
||||
if [ "$RELEASE_PLATFORM" = "macos" ]; then
|
||||
npx tauri build --ci --target "$RUST_TARGET" --bundles app,dmg
|
||||
else
|
||||
npx tauri build --ci --target "$RUST_TARGET"
|
||||
TAURI_ARGS+=(--bundles app,dmg)
|
||||
CODESIGN_WRAP_DIR="$(mktemp -d "${TMPDIR:-/tmp}/opsx-codesign.XXXXXX")"
|
||||
cp "$ROOT_DIR/scripts/macos-codesign-wrapper.sh" "$CODESIGN_WRAP_DIR/codesign"
|
||||
chmod +x "$CODESIGN_WRAP_DIR/codesign"
|
||||
export PATH="$CODESIGN_WRAP_DIR:$PATH"
|
||||
log "macOS 签名使用 HTTP 时间戳(可用 CODESIGN_USE_SYSTEM_TIMESTAMP=1 关闭)"
|
||||
fi
|
||||
if [ -f "$ROOT_DIR/src-tauri/tauri.signing.conf.json" ]; then
|
||||
TAURI_ARGS+=(--config src-tauri/tauri.signing.conf.json)
|
||||
log "使用 src-tauri/tauri.signing.conf.json 签名"
|
||||
fi
|
||||
npx tauri build "${TAURI_ARGS[@]}"
|
||||
if [ -n "$CODESIGN_WRAP_DIR" ]; then
|
||||
rm -rf "$CODESIGN_WRAP_DIR"
|
||||
fi
|
||||
|
||||
BUNDLE_ROOT="${CARGO_TARGET_DIR:-$ROOT_DIR/src-tauri/target}/$RUST_TARGET/release/bundle"
|
||||
|
||||
Executable
+38
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env bash
|
||||
# Tauri 默认 `codesign --timestamp` 走 timestamp.apple.com:443。
|
||||
# 部分网络(含仅开 HTTP 代理、443 不通)会报 “The timestamp service is not available.”
|
||||
# 构建时把本脚本以 `codesign` 之名放进 PATH,改为 RFC 3161 HTTP 时间戳。
|
||||
# 关闭:CODESIGN_USE_SYSTEM_TIMESTAMP=1
|
||||
set -euo pipefail
|
||||
REAL="/usr/bin/codesign"
|
||||
TS="${APPLE_TIMESTAMP_URL:-http://timestamp.apple.com/ts01}"
|
||||
|
||||
if [ "${CODESIGN_USE_SYSTEM_TIMESTAMP:-}" = "1" ]; then
|
||||
exec "$REAL" "$@"
|
||||
fi
|
||||
|
||||
signing=0
|
||||
for a in "$@"; do
|
||||
case "$a" in
|
||||
--sign|-s) signing=1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ "$signing" -eq 0 ]; then
|
||||
exec "$REAL" "$@"
|
||||
fi
|
||||
|
||||
new=()
|
||||
found=0
|
||||
for a in "$@"; do
|
||||
if [ "$a" = "--timestamp" ] || [[ "$a" == --timestamp=* ]]; then
|
||||
new+=("--timestamp=$TS")
|
||||
found=1
|
||||
else
|
||||
new+=("$a")
|
||||
fi
|
||||
done
|
||||
if [ "$found" -eq 0 ]; then
|
||||
new+=("--timestamp=$TS")
|
||||
fi
|
||||
exec "$REAL" "${new[@]}"
|
||||
Executable
+129
@@ -0,0 +1,129 @@
|
||||
#!/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")"
|
||||
DMG="${1:-$ROOT_DIR/release/v$VERSION/macos-arm64/OpsXShell_${VERSION}_aarch64.dmg}"
|
||||
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
|
||||
+1
-1
@@ -137,7 +137,7 @@ def release_body(version: str, repo: str, assets: list[Path]) -> str:
|
||||
"### macOS 安装",
|
||||
"",
|
||||
"1. 打开 DMG,将 OpsXShell 拖入 Applications。",
|
||||
"2. 当前公开包为 ad-hoc 开发签名且尚未 Apple 公证;首次启动如被 Gatekeeper 拦截,请在 Finder 中右键应用并选择“打开”。",
|
||||
"2. 已 Developer ID 签名并公证、staple 的包可直接打开。若仍提示无法验证,请确认下载的是钉票后的 DMG,或在 Finder 右键应用选择“打开”。",
|
||||
"",
|
||||
"### 完整性校验",
|
||||
"",
|
||||
|
||||
Reference in new issue
Block a user