LighthouseApp/sign_and_notarize.sh
speakeloudest 75d4c48e41
Some checks failed
Build Windows / build (push) Has been cancelled
feat: 源码提交
2025-10-19 23:30:54 -07:00

295 lines
7.2 KiB
Bash
Executable File

#!/bin/bash
# BearVPN macOS 签名、公证和打包脚本
# 作者: AI Assistant
# 日期: $(date)
set -e
# 配置变量
APP_NAME="BearVPN"
APP_VERSION="1.0.0"
DMG_NAME="${APP_NAME}-${APP_VERSION}-macOS-Signed"
APP_PATH="build/macos/Build/Products/Release/${APP_NAME}.app"
DMG_PATH="build/macos/Build/Products/Release/${DMG_NAME}.dmg"
# 签名配置
DEVELOPER_ID="Developer ID Application: Civil Rights Corps (3UR892FAP3)"
TEAM_ID="3UR892FAP3"
APPLE_ID="kieran@newlifeephrata.us"
APPLE_PASSWORD="Asd112211@"
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 日志函数
log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 检查证书
check_certificates() {
log_info "检查开发者证书..."
# 检查证书是否存在
if ! security find-certificate -a -c "Civil Rights Corps" > /dev/null 2>&1; then
log_error "未找到 Developer ID Application 证书"
log_info "请确保已安装有效的开发者证书"
exit 1
fi
log_success "找到 Developer ID Application 证书"
}
# 清理旧文件
cleanup() {
log_info "清理旧的构建文件..."
rm -rf build/macos/Build/Products/Release/*
log_success "清理完成"
}
# 构建应用
build_app() {
log_info "开始构建 macOS 应用..."
flutter build macos --release
if [ ! -d "$APP_PATH" ]; then
log_error "应用构建失败"
exit 1
fi
log_success "应用构建完成"
}
# 签名应用
sign_app() {
log_info "开始签名应用..."
# 签名应用
codesign --force --deep --sign "$DEVELOPER_ID" "$APP_PATH"
if [ $? -eq 0 ]; then
log_success "应用签名成功"
else
log_error "应用签名失败"
exit 1
fi
# 验证签名
log_info "验证应用签名..."
codesign --verify --verbose "$APP_PATH"
if [ $? -eq 0 ]; then
log_success "应用签名验证通过"
else
log_error "应用签名验证失败"
exit 1
fi
}
# 创建 DMG
create_dmg() {
log_info "开始创建 DMG 文件..."
# 使用 create-dmg 创建 DMG
create-dmg \
--volname "$APP_NAME" \
--volicon "macos/Runner/Assets.xcassets/AppIcon.appiconset/icon-256@2x.png" \
--window-pos 200 120 \
--window-size 600 400 \
--icon-size 100 \
--icon "$APP_NAME.app" 175 190 \
--hide-extension "$APP_NAME.app" \
--app-drop-link 425 190 \
--no-internet-enable \
"$DMG_PATH" \
"$APP_PATH"
if [ $? -eq 0 ]; then
log_success "DMG 文件创建成功: $DMG_PATH"
else
log_error "DMG 文件创建失败"
exit 1
fi
}
# 签名 DMG
sign_dmg() {
log_info "开始签名 DMG 文件..."
# 签名 DMG
codesign --force --sign "$DEVELOPER_ID" "$DMG_PATH"
if [ $? -eq 0 ]; then
log_success "DMG 签名成功"
else
log_error "DMG 签名失败"
exit 1
fi
# 验证 DMG 签名
log_info "验证 DMG 签名..."
codesign --verify --verbose "$DMG_PATH"
if [ $? -eq 0 ]; then
log_success "DMG 签名验证通过"
else
log_error "DMG 签名验证失败"
exit 1
fi
}
# 公证应用
notarize_app() {
log_info "开始公证应用..."
# 创建 ZIP 文件用于公证
ZIP_PATH="build/macos/Build/Products/Release/${APP_NAME}-${APP_VERSION}.zip"
ditto -c -k --keepParent "$APP_PATH" "$ZIP_PATH"
log_info "上传应用进行公证..."
log_warning "请确保您已生成应用专用密码:"
log_warning "1. 访问 https://appleid.apple.com"
log_warning "2. 登录您的 Apple ID"
log_warning "3. 在'安全'部分生成应用专用密码"
log_warning "4. 使用该密码进行公证"
# 上传进行公证
xcrun notarytool submit "$ZIP_PATH" \
--apple-id "$APPLE_ID" \
--team-id "$TEAM_ID" \
--wait
if [ $? -eq 0 ]; then
log_success "应用公证成功"
# 装订公证票据
log_info "装订公证票据到应用..."
xcrun stapler staple "$APP_PATH"
if [ $? -eq 0 ]; then
log_success "公证票据装订成功"
else
log_warning "公证票据装订失败,但应用已公证"
fi
else
log_error "应用公证失败"
log_info "请检查 Apple ID 和应用专用密码是否正确"
exit 1
fi
# 清理 ZIP 文件
rm -f "$ZIP_PATH"
}
# 公证 DMG
notarize_dmg() {
log_info "开始公证 DMG..."
# 上传 DMG 进行公证
xcrun notarytool submit "$DMG_PATH" \
--apple-id "$APPLE_ID" \
--team-id "$TEAM_ID" \
--wait
if [ $? -eq 0 ]; then
log_success "DMG 公证成功"
# 装订公证票据
log_info "装订公证票据到 DMG..."
xcrun stapler staple "$DMG_PATH"
if [ $? -eq 0 ]; then
log_success "DMG 公证票据装订成功"
else
log_warning "DMG 公证票据装订失败,但 DMG 已公证"
fi
else
log_error "DMG 公证失败"
log_info "请检查 Apple ID 和应用专用密码是否正确"
exit 1
fi
}
# 验证最终结果
verify_final() {
log_info "验证最终结果..."
# 检查文件大小
APP_SIZE=$(du -h "$APP_PATH" | cut -f1)
DMG_SIZE=$(du -h "$DMG_PATH" | cut -f1)
log_info "应用大小: $APP_SIZE"
log_info "DMG 大小: $DMG_SIZE"
# 检查签名状态
log_info "应用签名状态:"
codesign -dv "$APP_PATH" 2>&1 | grep -E "(Authority|TeamIdentifier|BundleId)"
log_info "DMG 签名状态:"
codesign -dv "$DMG_PATH" 2>&1 | grep -E "(Authority|TeamIdentifier)"
# 检查公证状态
log_info "应用公证状态:"
xcrun stapler validate "$APP_PATH"
log_info "DMG 公证状态:"
xcrun stapler validate "$DMG_PATH"
}
# 显示结果
show_result() {
log_success "=========================================="
log_success "签名、公证和打包完成!"
log_success "=========================================="
log_info "应用名称: $APP_NAME"
log_info "版本: $APP_VERSION"
log_info "签名应用: $APP_PATH"
log_info "签名 DMG: $DMG_PATH"
log_info "开发者: $DEVELOPER_ID"
log_success "=========================================="
log_info "现在可以安全地分发给用户"
log_info "用户安装时不会看到安全警告"
log_info "应用已通过 Apple 公证,可在任何 Mac 上运行"
log_success "=========================================="
}
# 主函数
main() {
log_info "开始 BearVPN macOS 签名、公证和打包流程..."
log_info "=========================================="
check_certificates
cleanup
build_app
sign_app
notarize_app
create_dmg
sign_dmg
notarize_dmg
verify_final
show_result
log_success "所有操作完成!"
}
# 运行主函数
main "$@"