#!/bin/bash # 手动公证脚本 # 作者: Collins set -e # 配置变量 APP_NAME="BearVPN" APP_VERSION="1.0.0" APP_PATH="build/macos/Build/Products/Release/${APP_NAME}.app" DMG_PATH="build/macos/Build/Products/Release/${APP_NAME}-${APP_VERSION}-macOS-Signed.dmg" # 颜色输出 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_files() { if [ ! -d "$APP_PATH" ]; then log_error "应用文件不存在: $APP_PATH" exit 1 fi if [ ! -f "$DMG_PATH" ]; then log_error "DMG 文件不存在: $DMG_PATH" exit 1 fi log_success "找到应用和 DMG 文件" } # 创建 ZIP 文件 create_zip() { log_info "创建 ZIP 文件用于公证..." ZIP_PATH="build/macos/Build/Products/Release/${APP_NAME}-${APP_VERSION}.zip" ditto -c -k --keepParent "$APP_PATH" "$ZIP_PATH" log_success "ZIP 文件创建完成: $ZIP_PATH" } # 手动公证应用 notarize_app_manual() { log_info "开始手动公证应用..." # 创建 ZIP 文件 create_zip ZIP_PATH="build/macos/Build/Products/Release/${APP_NAME}-${APP_VERSION}.zip" log_warning "请按照以下步骤进行手动公证:" echo "" log_info "1. 打开浏览器,访问:https://developer.apple.com/account/resources/certificates/list" log_info "2. 登录您的 Apple Developer 账户" log_info "3. 点击左侧菜单的 'Services' > 'Notarization'" log_info "4. 点击 'Upload' 按钮" log_info "5. 选择文件:$ZIP_PATH" log_info "6. 等待公证完成(通常需要几分钟)" echo "" read -p "按回车键继续,当公证完成后..." # 检查公证状态 log_info "检查公证状态..." xcrun stapler validate "$APP_PATH" 2>/dev/null || log_warning "应用尚未公证或公证失败" } # 手动公证 DMG notarize_dmg_manual() { log_info "开始手动公证 DMG..." log_warning "请按照以下步骤进行手动公证:" echo "" log_info "1. 打开浏览器,访问:https://developer.apple.com/account/resources/certificates/list" log_info "2. 登录您的 Apple Developer 账户" log_info "3. 点击左侧菜单的 'Services' > 'Notarization'" log_info "4. 点击 'Upload' 按钮" log_info "5. 选择文件:$DMG_PATH" log_info "6. 等待公证完成(通常需要几分钟)" echo "" read -p "按回车键继续,当公证完成后..." # 检查公证状态 log_info "检查公证状态..." xcrun stapler validate "$DMG_PATH" 2>/dev/null || log_warning "DMG 尚未公证或公证失败" } # 装订公证票据 staple_tickets() { log_info "装订公证票据..." # 装订应用 log_info "装订应用公证票据..." xcrun stapler staple "$APP_PATH" 2>/dev/null || log_warning "应用公证票据装订失败" # 装订 DMG log_info "装订 DMG 公证票据..." xcrun stapler staple "$DMG_PATH" 2>/dev/null || log_warning "DMG 公证票据装订失败" } # 验证最终结果 verify_result() { log_info "验证最终结果..." # 检查应用签名 log_info "应用签名状态:" codesign -dv "$APP_PATH" 2>&1 | grep -E "(Authority|TeamIdentifier|BundleId)" || true # 检查 DMG 签名 log_info "DMG 签名状态:" codesign -dv "$DMG_PATH" 2>&1 | grep -E "(Authority|TeamIdentifier)" || true # 检查公证状态 log_info "应用公证状态:" xcrun stapler validate "$APP_PATH" 2>/dev/null && log_success "应用已公证" || log_warning "应用未公证" log_info "DMG 公证状态:" xcrun stapler validate "$DMG_PATH" 2>/dev/null && log_success "DMG 已公证" || log_warning "DMG 未公证" } # 显示结果 show_result() { log_success "==========================================" log_success "手动公证完成!" log_success "==========================================" log_info "应用: $APP_PATH" log_info "DMG: $DMG_PATH" log_success "==========================================" log_info "现在应用已通过 Apple 公证" log_info "可以在任何 Mac 上安全运行" log_success "==========================================" } # 主函数 main() { log_info "开始 BearVPN macOS 手动公证流程..." log_info "==========================================" check_files notarize_app_manual notarize_dmg_manual staple_tickets verify_result show_result log_success "手动公证完成!" } # 运行主函数 main "$@"