feat: 修改hidialog弹窗位置,增加macos dmg打包配置
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 820 KiB |
Executable
+136
@@ -0,0 +1,136 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# ╔═══════════════════════════════════════════════════════════════════════════╗
|
||||
# ║ HiFastVPN macOS DMG 打包脚本 ║
|
||||
# ║ ║
|
||||
# ║ 使用方法: ║
|
||||
# ║ 1. 确保已经运行 sign_and_notarize.sh 生成签名的 .app ║
|
||||
# ║ 2. chmod +x build_dmg.sh ║
|
||||
# ║ 3. ./build_dmg.sh ║
|
||||
# ╚═══════════════════════════════════════════════════════════════════════════╝
|
||||
|
||||
# ======================== 路径配置 ========================
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
|
||||
APP_PATH="${PROJECT_DIR}/build/macos/Build/Products/Release/HiFastVPN.app"
|
||||
BACKGROUND_IMAGE="${SCRIPT_DIR}/assets/dmg_bg.png"
|
||||
|
||||
# ======================== 提取版本号 ========================
|
||||
echo "╔═══════════════════════════════════════════════════════════════════╗"
|
||||
echo "║ HiFastVPN macOS DMG 打包脚本 ║"
|
||||
echo "╚═══════════════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
|
||||
PUBSPEC_PATH="${PROJECT_DIR}/pubspec.yaml"
|
||||
if [ ! -f "${PUBSPEC_PATH}" ]; then
|
||||
echo "❌ 错误: 找不到 pubspec.yaml"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VERSION=$(grep "^version:" "${PUBSPEC_PATH}" | sed 's/version: *//' | tr -d ' ')
|
||||
if [ -z "${VERSION}" ]; then
|
||||
echo "❌ 错误: 无法提取版本号"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "📦 版本号: ${VERSION}"
|
||||
echo "📁 项目目录: ${PROJECT_DIR}"
|
||||
echo "📦 应用路径: ${APP_PATH}"
|
||||
echo "🖼️ 背景图: ${BACKGROUND_IMAGE}"
|
||||
echo ""
|
||||
|
||||
# ======================== 检查依赖 ========================
|
||||
if ! command -v create-dmg >/dev/null 2>&1; then
|
||||
echo "❌ 错误: create-dmg 未安装(brew install create-dmg)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d "${APP_PATH}" ]; then
|
||||
echo "❌ 错误: HiFastVPN.app 不存在"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "${BACKGROUND_IMAGE}" ]; then
|
||||
echo "❌ 错误: 背景图不存在"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ======================== 校验背景图尺寸 ========================
|
||||
BG_INFO=$(sips -g pixelWidth -g pixelHeight "${BACKGROUND_IMAGE}")
|
||||
BG_W=$(echo "$BG_INFO" | awk '/pixelWidth/ {print $2}')
|
||||
BG_H=$(echo "$BG_INFO" | awk '/pixelHeight/ {print $2}')
|
||||
|
||||
if [ "$BG_W" != "1200" ] || [ "$BG_H" != "800" ]; then
|
||||
echo "❌ 背景图必须是 1200x800,当前是 ${BG_W}x${BG_H}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ======================== 输出目录 ========================
|
||||
OUTPUT_DIR="${PROJECT_DIR}/dist/${VERSION}"
|
||||
mkdir -p "${OUTPUT_DIR}"
|
||||
|
||||
DMG_NAME="HiFastVPN-${VERSION}.dmg"
|
||||
DMG_PATH="${OUTPUT_DIR}/${DMG_NAME}"
|
||||
|
||||
echo "📂 输出目录: ${OUTPUT_DIR}"
|
||||
echo "💿 DMG 文件: ${DMG_NAME}"
|
||||
echo ""
|
||||
|
||||
rm -f "${DMG_PATH}"
|
||||
|
||||
# ======================== 创建 DMG ========================
|
||||
echo "💿 开始创建 DMG..."
|
||||
echo ""
|
||||
|
||||
TEMP_DIR=$(mktemp -d)
|
||||
cp -R "${APP_PATH}" "${TEMP_DIR}/"
|
||||
|
||||
# ======================== Finder 坐标(左上原点,中心点对齐) ========================
|
||||
# 背景:1200 × 800
|
||||
# HiFastVPN.app 中心:左 228, 上 418, 尺寸 168×168
|
||||
APP_CENTER_X=236
|
||||
APP_CENTER_Y=432
|
||||
APP_ICON_SIZE=152
|
||||
APP_X=$((APP_CENTER_X + APP_ICON_SIZE / 2)) # 左上角坐标
|
||||
APP_Y=$((APP_CENTER_Y + APP_ICON_SIZE / 2))
|
||||
|
||||
# Applications 图标中心:左 742, 上 372, 尺寸 259×259
|
||||
DROP_CENTER_X=742
|
||||
DROP_CENTER_Y=372
|
||||
DROP_ICON_SIZE=259
|
||||
DROP_X=$((DROP_CENTER_X + DROP_ICON_SIZE / 2))
|
||||
DROP_Y=$((DROP_CENTER_Y + DROP_ICON_SIZE / 2))
|
||||
|
||||
# ======================== 打包 ========================
|
||||
create-dmg \
|
||||
--volname "HiFastVPN Installation" \
|
||||
--background "${BACKGROUND_IMAGE}" \
|
||||
--window-size 1200 800 \
|
||||
--icon-size "${APP_ICON_SIZE}" \
|
||||
--icon "HiFastVPN.app" "${APP_X}" "${APP_Y}" \
|
||||
--app-drop-link "${DROP_X}" "${DROP_Y}" \
|
||||
--hide-extension "HiFastVPN.app" \
|
||||
--no-internet-enable \
|
||||
"${DMG_PATH}" \
|
||||
"${TEMP_DIR}"
|
||||
|
||||
# 清理临时目录
|
||||
rm -rf "${TEMP_DIR}"
|
||||
|
||||
# ======================== 完成 ========================
|
||||
echo ""
|
||||
echo "╔═══════════════════════════════════════════════════════════════════╗"
|
||||
echo "║ 🎉 DMG 创建完成! ║"
|
||||
echo "╚═══════════════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
echo "输出文件:"
|
||||
echo " 💿 ${DMG_PATH}"
|
||||
echo ""
|
||||
echo "📝 注意事项:"
|
||||
echo " • DMG 已保存到 dist/${VERSION}/ 目录"
|
||||
echo " • 图标和 Applications 已按设计稿中心点对齐"
|
||||
echo " • 此 DMG 包含已签名和公证的 .app"
|
||||
echo " • 可以直接分发给用户使用"
|
||||
echo ""
|
||||
Executable
+233
@@ -0,0 +1,233 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# ╔═══════════════════════════════════════════════════════════════════════════╗
|
||||
# ║ HiFastVPN macOS 签名和公证脚本 ║
|
||||
# ║ ║
|
||||
# ║ 使用方法: ║
|
||||
# ║ 1. 修改下面的配置变量 ║
|
||||
# ║ 2. chmod +x sign_and_notarize.sh ║
|
||||
# ║ 3. ./sign_and_notarize.sh ║
|
||||
# ╚═══════════════════════════════════════════════════════════════════════════╝
|
||||
|
||||
# ======================== 配置变量(请修改这里)========================
|
||||
SIGNING_IDENTITY="Developer ID Application: TAW TRADERS SDN. BHD. (NJRRF427XB)"
|
||||
APPLE_ID="speakeloudest@gmail.com"
|
||||
APP_PASSWORD="lvry-umfn-pqgz-lnwk" # App-specific password
|
||||
TEAM_ID="NJRRF427XB"
|
||||
|
||||
# 路径配置
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
APP_PATH="${PROJECT_DIR}/hi-client/build/macos/Build/Products/Release/HiFastVPN.app"
|
||||
ENTITLEMENTS="${PROJECT_DIR}/hi-client/macos/Runner/Release.entitlements"
|
||||
OUTPUT_DIR="${PROJECT_DIR}/dist"
|
||||
# =====================================================================
|
||||
|
||||
echo "╔═══════════════════════════════════════════════════════════════════╗"
|
||||
echo "║ HiFastVPN macOS 签名和公证脚本 ║"
|
||||
echo "╚═══════════════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
echo "📁 项目目录: ${PROJECT_DIR}"
|
||||
echo "📦 应用路径: ${APP_PATH}"
|
||||
echo "📄 Entitlements: ${ENTITLEMENTS}"
|
||||
echo ""
|
||||
|
||||
# 检查 .app 是否存在
|
||||
if [ ! -d "${APP_PATH}" ]; then
|
||||
echo "❌ 错误: ${APP_PATH} 不存在"
|
||||
echo "请先运行: flutter build macos --release"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 检查 entitlements 是否存在
|
||||
if [ ! -f "${ENTITLEMENTS}" ]; then
|
||||
echo "❌ 错误: ${ENTITLEMENTS} 不存在"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 创建输出目录
|
||||
mkdir -p "${OUTPUT_DIR}"
|
||||
|
||||
# ======================== Step 1: 清理 ========================
|
||||
echo ""
|
||||
echo "🧹 Step 1: 清理多余文件..."
|
||||
|
||||
# 删除 .DS_Store
|
||||
find "${APP_PATH}" -name ".DS_Store" -delete 2>/dev/null || true
|
||||
find "${APP_PATH}" -name "*.bak" -delete 2>/dev/null || true
|
||||
|
||||
# 删除 Headers 目录和符号链接
|
||||
find "${APP_PATH}/Contents/Frameworks" -type l -name "Headers" -delete 2>/dev/null || true
|
||||
find "${APP_PATH}/Contents/Frameworks" -type d -name "Headers" -exec rm -rf {} + 2>/dev/null || true
|
||||
|
||||
# 删除 Modules 目录
|
||||
find "${APP_PATH}/Contents/Frameworks" -type d -name "Modules" -exec rm -rf {} + 2>/dev/null || true
|
||||
|
||||
# 删除 PrivateHeaders
|
||||
find "${APP_PATH}/Contents/Frameworks" -name "PrivateHeaders" -exec rm -rf {} + 2>/dev/null || true
|
||||
|
||||
echo " ✅ 清理完成"
|
||||
|
||||
# ======================== Step 2: 移除现有签名 ========================
|
||||
echo ""
|
||||
echo "🗑️ Step 2: 移除现有签名..."
|
||||
|
||||
# 移除所有签名(忽略错误)
|
||||
find "${APP_PATH}" -name "*.dylib" -exec codesign --remove-signature {} \; 2>/dev/null || true
|
||||
find "${APP_PATH}" -name "*.framework" -exec codesign --remove-signature {} \; 2>/dev/null || true
|
||||
codesign --remove-signature "${APP_PATH}" 2>/dev/null || true
|
||||
|
||||
echo " ✅ 移除签名完成"
|
||||
|
||||
# ======================== Step 3: 签名 dylib 文件 ========================
|
||||
echo ""
|
||||
echo "🔐 Step 3: 签名 dylib 文件..."
|
||||
|
||||
find "${APP_PATH}" -name "*.dylib" -print0 | while IFS= read -r -d '' dylib; do
|
||||
echo " → $(basename "$dylib")"
|
||||
codesign --force --sign "${SIGNING_IDENTITY}" \
|
||||
--options runtime \
|
||||
--timestamp \
|
||||
"$dylib"
|
||||
done
|
||||
|
||||
echo " ✅ dylib 签名完成"
|
||||
|
||||
# ======================== Step 4: 签名 Framework ========================
|
||||
echo ""
|
||||
echo "🔐 Step 4: 签名 Framework..."
|
||||
|
||||
# 签名所有 framework(使用 --deep 确保内部资源被正确处理)
|
||||
for fw in "${APP_PATH}"/Contents/Frameworks/*.framework; do
|
||||
if [ -d "$fw" ]; then
|
||||
fw_name=$(basename "$fw")
|
||||
echo " → ${fw_name}"
|
||||
|
||||
# 使用 --deep 签名 framework,这样会自动处理内部的资源
|
||||
codesign --force --sign "${SIGNING_IDENTITY}" \
|
||||
--options runtime \
|
||||
--timestamp \
|
||||
"$fw"
|
||||
fi
|
||||
done
|
||||
|
||||
echo " ✅ Framework 签名完成"
|
||||
|
||||
# ======================== Step 5: 签名主应用 ========================
|
||||
echo ""
|
||||
echo "🔐 Step 5: 签名主应用..."
|
||||
|
||||
codesign --force --sign "${SIGNING_IDENTITY}" \
|
||||
--options runtime \
|
||||
--entitlements "${ENTITLEMENTS}" \
|
||||
--timestamp \
|
||||
"${APP_PATH}"
|
||||
|
||||
echo " ✅ 主应用签名完成"
|
||||
|
||||
# ======================== Step 6: 验证签名 ========================
|
||||
echo ""
|
||||
echo "✅ Step 6: 验证签名..."
|
||||
|
||||
if codesign --verify --deep --strict --verbose=2 "${APP_PATH}" 2>&1; then
|
||||
echo " ✅ 签名验证通过!"
|
||||
else
|
||||
echo " ❌ 签名验证失败!"
|
||||
echo ""
|
||||
echo "详细错误信息:"
|
||||
codesign --verify --deep --strict --verbose=4 "${APP_PATH}" 2>&1
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ======================== Step 7: 创建 ZIP ========================
|
||||
echo ""
|
||||
echo "📦 Step 7: 创建 ZIP..."
|
||||
|
||||
ZIP_PATH="${OUTPUT_DIR}/HiFastVPN.zip"
|
||||
rm -f "${ZIP_PATH}"
|
||||
ditto -c -k --keepParent "${APP_PATH}" "${ZIP_PATH}"
|
||||
|
||||
echo " ✅ ZIP 创建完成: ${ZIP_PATH}"
|
||||
|
||||
# ======================== Step 8: 公证 ========================
|
||||
echo ""
|
||||
echo "📤 Step 8: 提交公证..."
|
||||
echo " (这可能需要几分钟时间...)"
|
||||
|
||||
xcrun notarytool submit "${ZIP_PATH}" \
|
||||
--apple-id "${APPLE_ID}" \
|
||||
--password "${APP_PASSWORD}" \
|
||||
--team-id "${TEAM_ID}" \
|
||||
--wait
|
||||
|
||||
echo " ✅ 公证完成"
|
||||
|
||||
# ======================== Step 9: Staple ========================
|
||||
echo ""
|
||||
echo "📎 Step 9: Staple..."
|
||||
|
||||
xcrun stapler staple "${APP_PATH}"
|
||||
|
||||
echo " ✅ Staple 完成"
|
||||
|
||||
# ======================== Step 10: 最终验证 ========================
|
||||
echo ""
|
||||
echo "🔍 Step 10: 最终验证..."
|
||||
|
||||
echo ""
|
||||
echo "--- codesign --verify ---"
|
||||
codesign --verify --deep --strict "${APP_PATH}" && echo "✅ codesign 验证通过"
|
||||
|
||||
echo ""
|
||||
echo "--- xcrun stapler validate ---"
|
||||
xcrun stapler validate "${APP_PATH}"
|
||||
|
||||
echo ""
|
||||
echo "--- spctl -a -t execute ---"
|
||||
spctl -a -t execute -vv "${APP_PATH}"
|
||||
|
||||
# ======================== Step 11: 创建 DMG ========================
|
||||
echo ""
|
||||
echo "💿 Step 11: 创建 DMG..."
|
||||
|
||||
DMG_PATH="${OUTPUT_DIR}/HiFastVPN.dmg"
|
||||
rm -f "${DMG_PATH}"
|
||||
|
||||
# 使用 hdiutil 创建简单的 DMG
|
||||
hdiutil create -volname "HiFastVPN" -srcfolder "${APP_PATH}" -ov -format UDZO "${DMG_PATH}"
|
||||
|
||||
# 签名 DMG
|
||||
# echo " 签名 DMG..."
|
||||
# codesign --force --sign "${SIGNING_IDENTITY}" --timestamp "${DMG_PATH}"
|
||||
|
||||
# 公证 DMG
|
||||
echo " 公证 DMG..."
|
||||
xcrun notarytool submit "${DMG_PATH}" \
|
||||
--apple-id "${APPLE_ID}" \
|
||||
--password "${APP_PASSWORD}" \
|
||||
--team-id "${TEAM_ID}" \
|
||||
--wait
|
||||
|
||||
# Staple DMG
|
||||
echo " Staple DMG..."
|
||||
xcrun stapler staple "${DMG_PATH}"
|
||||
|
||||
echo " ✅ DMG 创建完成: ${DMG_PATH}"
|
||||
|
||||
# ======================== 完成 ========================
|
||||
echo ""
|
||||
echo "╔═══════════════════════════════════════════════════════════════════╗"
|
||||
echo "║ 🎉 全部完成! ║"
|
||||
echo "╚═══════════════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
echo "输出文件:"
|
||||
echo " 📦 ${APP_PATH}"
|
||||
echo " 📦 ${ZIP_PATH}"
|
||||
echo " 💿 ${DMG_PATH}"
|
||||
echo ""
|
||||
echo "⚠️ 重要提示:"
|
||||
echo " 发给用户的应该是 DMG 文件,不是 ZIP 或 .app"
|
||||
echo " DMG 已经签名和公证,用户打开后不会被 Gatekeeper 拦截"
|
||||
echo ""
|
||||
|
||||
Reference in New Issue
Block a user