328 lines
7.2 KiB
Bash
Executable File
328 lines
7.2 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# iOS 自动化构建脚本
|
|
# 支持开发版本和分发版本的构建
|
|
|
|
set -e
|
|
|
|
# 颜色输出
|
|
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_environment() {
|
|
log_info "检查构建环境..."
|
|
|
|
# 检查 Flutter
|
|
if ! command -v flutter &> /dev/null; then
|
|
log_error "Flutter 未安装或不在 PATH 中"
|
|
exit 1
|
|
fi
|
|
|
|
# 检查 Xcode
|
|
if ! command -v xcodebuild &> /dev/null; then
|
|
log_error "Xcode 未安装或不在 PATH 中"
|
|
exit 1
|
|
fi
|
|
|
|
# 检查必要的环境变量
|
|
if [ -z "$APPLE_ID" ] || [ -z "$TEAM_ID" ] || [ -z "$BUNDLE_ID" ]; then
|
|
log_error "请先运行: source ios_signing_config.sh"
|
|
exit 1
|
|
fi
|
|
|
|
log_success "环境检查通过"
|
|
}
|
|
|
|
# 检查证书
|
|
check_certificates() {
|
|
log_info "检查开发者证书..."
|
|
|
|
# 检查开发证书
|
|
if ! security find-identity -v -p codesigning | grep -q "iPhone Developer\|Apple Development"; then
|
|
log_error "未找到有效的开发证书"
|
|
log_info "请确保已安装开发者证书"
|
|
exit 1
|
|
fi
|
|
|
|
log_success "找到有效的开发证书"
|
|
}
|
|
|
|
# 清理构建
|
|
clean_build() {
|
|
log_info "清理之前的构建..."
|
|
|
|
flutter clean
|
|
rm -rf build/ios
|
|
rm -rf ios/build
|
|
|
|
log_success "清理完成"
|
|
}
|
|
|
|
# 获取依赖
|
|
get_dependencies() {
|
|
log_info "获取 Flutter 依赖..."
|
|
|
|
flutter pub get
|
|
|
|
log_success "依赖获取完成"
|
|
}
|
|
|
|
# 构建 iOS 应用
|
|
build_ios_app() {
|
|
local build_type=$1
|
|
local configuration=$2
|
|
|
|
log_info "开始构建 iOS 应用 (${build_type})..."
|
|
|
|
# 设置构建参数
|
|
local build_args="--release"
|
|
if [ "$build_type" = "debug" ]; then
|
|
build_args="--debug"
|
|
fi
|
|
|
|
# 构建 Flutter 应用
|
|
flutter build ios $build_args --no-codesign
|
|
|
|
# 检查构建结果
|
|
local app_path="build/ios/iphoneos/Runner.app"
|
|
if [ ! -d "$app_path" ]; then
|
|
log_error "iOS 应用构建失败: $app_path 不存在"
|
|
exit 1
|
|
fi
|
|
|
|
log_success "iOS 应用构建完成: $app_path"
|
|
}
|
|
|
|
# 签名应用
|
|
sign_app() {
|
|
local app_path=$1
|
|
local identity=$2
|
|
local provisioning_profile=$3
|
|
|
|
log_info "开始签名应用..."
|
|
|
|
# 移除旧的签名
|
|
codesign --remove-signature "$app_path"
|
|
|
|
# 签名应用
|
|
codesign --force --sign "$identity" \
|
|
--entitlements ios/Runner/Runner.entitlements \
|
|
"$app_path"
|
|
|
|
# 验证签名
|
|
codesign --verify --verbose "$app_path"
|
|
|
|
if [ $? -eq 0 ]; then
|
|
log_success "应用签名成功"
|
|
else
|
|
log_error "应用签名失败"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# 创建 IPA 文件
|
|
create_ipa() {
|
|
local app_path=$1
|
|
local ipa_path=$2
|
|
|
|
log_info "创建 IPA 文件..."
|
|
|
|
# 创建 Payload 目录
|
|
local payload_dir="build/ios/Payload"
|
|
mkdir -p "$payload_dir"
|
|
|
|
# 复制应用
|
|
cp -R "$app_path" "$payload_dir/"
|
|
|
|
# 创建 IPA
|
|
cd build/ios
|
|
zip -r "${ipa_path##*/}" Payload/
|
|
cd ../..
|
|
|
|
# 清理 Payload 目录
|
|
rm -rf "$payload_dir"
|
|
|
|
if [ -f "$ipa_path" ]; then
|
|
log_success "IPA 文件创建成功: $ipa_path"
|
|
else
|
|
log_error "IPA 文件创建失败"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# 创建 DMG 文件
|
|
create_dmg() {
|
|
local ipa_path=$1
|
|
local dmg_path=$2
|
|
|
|
log_info "创建 DMG 文件..."
|
|
|
|
# 创建临时目录
|
|
local temp_dir="build/ios/temp_dmg"
|
|
mkdir -p "$temp_dir"
|
|
|
|
# 复制 IPA 到临时目录
|
|
cp "$ipa_path" "$temp_dir/"
|
|
|
|
# 创建 DMG
|
|
hdiutil create -srcfolder "$temp_dir" \
|
|
-volname "BearVPN iOS" \
|
|
-fs HFS+ \
|
|
-format UDZO \
|
|
-imagekey zlib-level=9 \
|
|
"$dmg_path"
|
|
|
|
# 清理临时目录
|
|
rm -rf "$temp_dir"
|
|
|
|
if [ -f "$dmg_path" ]; then
|
|
log_success "DMG 文件创建成功: $dmg_path"
|
|
else
|
|
log_error "DMG 文件创建失败"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# 验证构建结果
|
|
verify_build() {
|
|
local ipa_path=$1
|
|
local dmg_path=$2
|
|
|
|
log_info "验证构建结果..."
|
|
|
|
# 检查文件大小
|
|
local ipa_size=$(du -h "$ipa_path" | cut -f1)
|
|
local dmg_size=$(du -h "$dmg_path" | cut -f1)
|
|
|
|
log_info "IPA 大小: $ipa_size"
|
|
log_info "DMG 大小: $dmg_size"
|
|
|
|
# 验证 IPA 内容
|
|
unzip -l "$ipa_path" | grep -q "Payload/Runner.app"
|
|
if [ $? -eq 0 ]; then
|
|
log_success "IPA 内容验证通过"
|
|
else
|
|
log_error "IPA 内容验证失败"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# 显示构建结果
|
|
show_result() {
|
|
local ipa_path=$1
|
|
local dmg_path=$2
|
|
|
|
log_success "=========================================="
|
|
log_success "iOS 构建完成!"
|
|
log_success "=========================================="
|
|
log_info "应用名称: $APP_NAME"
|
|
log_info "版本: $VERSION"
|
|
log_info "Bundle ID: $BUNDLE_ID"
|
|
log_info "IPA 文件: $ipa_path"
|
|
log_info "DMG 文件: $dmg_path"
|
|
log_info "开发者: $SIGNING_IDENTITY"
|
|
log_success "=========================================="
|
|
log_info "现在可以安装到设备或上传到 App Store"
|
|
log_success "=========================================="
|
|
}
|
|
|
|
# 主函数
|
|
main() {
|
|
local build_type=${1:-"release"}
|
|
|
|
log_info "开始 iOS 构建流程..."
|
|
log_info "构建类型: $build_type"
|
|
log_info "=========================================="
|
|
|
|
check_environment
|
|
check_certificates
|
|
clean_build
|
|
get_dependencies
|
|
build_ios_app "$build_type"
|
|
|
|
# 设置路径
|
|
local app_path="build/ios/iphoneos/Runner.app"
|
|
local ipa_path="$IPA_PATH"
|
|
local dmg_path="$DMG_PATH"
|
|
|
|
# 创建输出目录
|
|
mkdir -p "$(dirname "$ipa_path")"
|
|
mkdir -p "$(dirname "$dmg_path")"
|
|
|
|
# 签名应用
|
|
sign_app "$app_path" "$SIGNING_IDENTITY" ""
|
|
|
|
# 创建 IPA
|
|
create_ipa "$app_path" "$ipa_path"
|
|
|
|
# 创建 DMG
|
|
create_dmg "$ipa_path" "$dmg_path"
|
|
|
|
# 验证结果
|
|
verify_build "$ipa_path" "$dmg_path"
|
|
|
|
# 显示结果
|
|
show_result "$ipa_path" "$dmg_path"
|
|
|
|
log_success "所有操作完成!"
|
|
}
|
|
|
|
# 显示帮助信息
|
|
show_help() {
|
|
echo "iOS 自动化构建脚本"
|
|
echo ""
|
|
echo "用法: $0 [选项]"
|
|
echo ""
|
|
echo "选项:"
|
|
echo " debug 构建调试版本"
|
|
echo " release 构建发布版本 (默认)"
|
|
echo " help 显示此帮助信息"
|
|
echo ""
|
|
echo "示例:"
|
|
echo " $0 # 构建发布版本"
|
|
echo " $0 debug # 构建调试版本"
|
|
echo " $0 release # 构建发布版本"
|
|
echo ""
|
|
echo "注意: 请先运行 'source ios_signing_config.sh' 配置签名信息"
|
|
}
|
|
|
|
# 处理命令行参数
|
|
case "${1:-}" in
|
|
"help"|"-h"|"--help")
|
|
show_help
|
|
exit 0
|
|
;;
|
|
"debug"|"release")
|
|
main "$1"
|
|
;;
|
|
"")
|
|
main "release"
|
|
;;
|
|
*)
|
|
log_error "未知选项: $1"
|
|
show_help
|
|
exit 1
|
|
;;
|
|
esac
|