176 lines
5.0 KiB
Bash
Executable File
176 lines
5.0 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
# macOS DMG 构建和签名脚本
|
||
# 需要配置以下环境变量:
|
||
# - APPLE_ID: 您的 Apple ID
|
||
# - APPLE_PASSWORD: App 专用密码
|
||
# - TEAM_ID: 您的开发者团队 ID
|
||
# - SIGNING_IDENTITY: 代码签名身份
|
||
|
||
set -e
|
||
|
||
# 颜色输出
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
NC='\033[0m' # No Color
|
||
|
||
echo -e "${GREEN}🚀 开始构建 macOS DMG...${NC}"
|
||
|
||
# 检查必要的环境变量
|
||
if [ -z "$APPLE_ID" ]; then
|
||
echo -e "${RED}❌ 请设置 APPLE_ID 环境变量${NC}"
|
||
exit 1
|
||
fi
|
||
|
||
if [ -z "$APPLE_PASSWORD" ]; then
|
||
echo -e "${RED}❌ 请设置 APPLE_PASSWORD 环境变量(App 专用密码)${NC}"
|
||
exit 1
|
||
fi
|
||
|
||
if [ -z "$TEAM_ID" ]; then
|
||
echo -e "${RED}❌ 请设置 TEAM_ID 环境变量${NC}"
|
||
exit 1
|
||
fi
|
||
|
||
# 设置默认签名身份(如果没有设置)
|
||
if [ -z "$SIGNING_IDENTITY" ]; then
|
||
SIGNING_IDENTITY="Developer ID Application: Your Name (${TEAM_ID})"
|
||
echo -e "${YELLOW}⚠️ 使用默认签名身份: ${SIGNING_IDENTITY}${NC}"
|
||
fi
|
||
|
||
# 清理之前的构建
|
||
echo -e "${YELLOW}🧹 清理之前的构建...${NC}"
|
||
flutter clean
|
||
rm -rf build/macos/Build/Products/Release/kaer_with_panels.app
|
||
rm -rf build/macos/Build/Products/Release/kaer_with_panels.dmg
|
||
|
||
# 构建 Flutter macOS 应用
|
||
echo -e "${YELLOW}🔨 构建 Flutter macOS 应用...${NC}"
|
||
flutter build macos --release
|
||
|
||
# 检查应用是否构建成功
|
||
APP_PATH="build/macos/Build/Products/Release/BearVPN.app"
|
||
if [ ! -d "$APP_PATH" ]; then
|
||
echo -e "${RED}❌ 应用构建失败: $APP_PATH 不存在${NC}"
|
||
exit 1
|
||
fi
|
||
|
||
echo -e "${GREEN}✅ 应用构建成功: $APP_PATH${NC}"
|
||
|
||
# 代码签名
|
||
echo -e "${YELLOW}🔐 开始代码签名...${NC}"
|
||
|
||
# 签名应用
|
||
echo -e "${YELLOW}📝 签名应用...${NC}"
|
||
codesign --force --deep --sign "$SIGNING_IDENTITY" \
|
||
--options runtime \
|
||
--timestamp \
|
||
--entitlements macos/Runner/Runner.entitlements \
|
||
"$APP_PATH"
|
||
|
||
# 验证签名
|
||
echo -e "${YELLOW}🔍 验证应用签名...${NC}"
|
||
codesign --verify --verbose "$APP_PATH"
|
||
spctl --assess --verbose "$APP_PATH"
|
||
|
||
echo -e "${GREEN}✅ 应用签名成功${NC}"
|
||
|
||
# 创建 DMG
|
||
echo -e "${YELLOW}📦 创建 DMG 安装包...${NC}"
|
||
|
||
DMG_PATH="build/macos/Build/Products/Release/BearVPN.dmg"
|
||
TEMP_DMG="build/macos/Build/Products/Release/temp.dmg"
|
||
|
||
# 创建临时 DMG
|
||
hdiutil create -srcfolder "$APP_PATH" -volname "Kaer VPN" -fs HFS+ -fsargs "-c c=64,a=16,e=16" -format UDRW -size 200m "$TEMP_DMG"
|
||
|
||
# 挂载临时 DMG
|
||
MOUNT_POINT=$(hdiutil attach -readwrite -noverify -noautoopen "$TEMP_DMG" | egrep '^/dev/' | sed 1q | awk '{print $3}')
|
||
|
||
# 等待挂载完成
|
||
sleep 2
|
||
|
||
# 设置 DMG 属性
|
||
echo -e "${YELLOW}🎨 设置 DMG 属性...${NC}"
|
||
|
||
# 创建应用程序链接
|
||
ln -s /Applications "$MOUNT_POINT/Applications"
|
||
|
||
# 设置 DMG 背景和图标(可选)
|
||
# cp dmg_background.png "$MOUNT_POINT/.background/"
|
||
# cp app_icon.icns "$MOUNT_POINT/.VolumeIcon.icns"
|
||
|
||
# 设置窗口属性
|
||
osascript <<EOF
|
||
tell application "Finder"
|
||
tell disk "Kaer VPN"
|
||
open
|
||
set current view of container window to icon view
|
||
set toolbar visible of container window to false
|
||
set statusbar visible of container window to false
|
||
set the bounds of container window to {400, 100, 900, 450}
|
||
set theViewOptions to the icon view options of container window
|
||
set arrangement of theViewOptions to not arranged
|
||
set icon size of theViewOptions to 128
|
||
set background picture of theViewOptions to file ".background:dmg_background.png"
|
||
make new alias file at container window to POSIX file "/Applications" with properties {name:"Applications"}
|
||
set position of item "BearVPN.app" of container window to {150, 200}
|
||
set position of item "Applications" of container window to {350, 200}
|
||
close
|
||
open
|
||
update without registering applications
|
||
delay 2
|
||
end tell
|
||
end tell
|
||
EOF
|
||
|
||
# 卸载 DMG
|
||
hdiutil detach "$MOUNT_POINT"
|
||
|
||
# 转换为只读 DMG
|
||
hdiutil convert "$TEMP_DMG" -format UDZO -imagekey zlib-level=9 -o "$DMG_PATH"
|
||
|
||
# 清理临时文件
|
||
rm "$TEMP_DMG"
|
||
|
||
echo -e "${GREEN}✅ DMG 创建成功: $DMG_PATH${NC}"
|
||
|
||
# 签名 DMG
|
||
echo -e "${YELLOW}🔐 签名 DMG...${NC}"
|
||
INSTALLER_IDENTITY="Developer ID Installer: Your Name (${TEAM_ID})"
|
||
codesign --sign "$INSTALLER_IDENTITY" "$DMG_PATH"
|
||
|
||
# 验证 DMG 签名
|
||
codesign --verify --verbose "$DMG_PATH"
|
||
|
||
echo -e "${GREEN}✅ DMG 签名成功${NC}"
|
||
|
||
# 公证 DMG
|
||
echo -e "${YELLOW}📋 开始公证 DMG...${NC}"
|
||
|
||
# 上传到 Apple 进行公证
|
||
xcrun notarytool submit "$DMG_PATH" \
|
||
--apple-id "$APPLE_ID" \
|
||
--password "$APPLE_PASSWORD" \
|
||
--team-id "$TEAM_ID" \
|
||
--wait
|
||
|
||
echo -e "${GREEN}✅ DMG 公证成功${NC}"
|
||
|
||
# 装订公证票据
|
||
echo -e "${YELLOW}📎 装订公证票据...${NC}"
|
||
xcrun stapler staple "$DMG_PATH"
|
||
|
||
# 验证最终 DMG
|
||
echo -e "${YELLOW}🔍 验证最终 DMG...${NC}"
|
||
spctl --assess --verbose "$DMG_PATH"
|
||
|
||
echo -e "${GREEN}🎉 DMG 构建完成!${NC}"
|
||
echo -e "${GREEN}📁 文件位置: $DMG_PATH${NC}"
|
||
echo -e "${GREEN}📏 文件大小: $(du -h "$DMG_PATH" | cut -f1)${NC}"
|
||
|
||
# 显示 DMG 信息
|
||
echo -e "${YELLOW}📊 DMG 信息:${NC}"
|
||
hdiutil imageinfo "$DMG_PATH"
|