#!/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" # 颜色输出 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 # 显示签名信息 log_info "签名信息:" codesign -dv --verbose=4 "$APP_PATH" } # 创建 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 } # 验证最终结果 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)" } # 显示结果 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_success "==========================================" } # 主函数 main() { log_info "开始 BearVPN macOS 签名和打包流程..." log_info "==========================================" check_certificates cleanup build_app sign_app create_dmg sign_dmg verify_final show_result log_success "所有操作完成!" } # 运行主函数 main "$@"