Files
crowd-funder-from-jason/scripts/build-ios.sh
Matthew Raymer 974d33b322 Document environment variable precedence and API configuration scheme
Add comprehensive documentation explaining the order of precedence for
environment variables in TimeSafari project. Covers shell script overrides,
platform-specific configurations, .env file usage, and API alignment between
claim and partner APIs. Includes troubleshooting guide and best practices
for maintaining consistent environment configuration across development,
test, and production environments.
2025-08-05 11:51:48 +00:00

449 lines
13 KiB
Bash
Executable File

#!/bin/bash
# build-ios.sh
# Author: Matthew Raymer
# Description: iOS build script for TimeSafari application
# Date: 2025-07-11
# Exit on any error
set -e
# Source common utilities
source "$(dirname "$0")/common.sh"
# Default values
BUILD_MODE="development"
BUILD_TYPE="debug"
OPEN_STUDIO=false
BUILD_IPA=false
BUILD_APP=false
CLEAN_ONLY=false
SYNC_ONLY=false
ASSETS_ONLY=false
DEPLOY_APP=false
AUTO_RUN=false
CUSTOM_API_IP=""
# Function to print iOS-specific usage
print_ios_usage() {
echo "Usage: $0 [options]"
echo ""
echo "iOS Build Options:"
echo " --dev, --development Build for development environment"
echo " --test Build for testing environment"
echo " --prod, --production Build for production environment"
echo " --debug Build debug app (default)"
echo " --release Build release app"
echo " --studio Open Xcode after build"
echo " --ipa Build IPA file"
echo " --app Build app bundle"
echo " --clean Clean build artifacts only"
echo " --sync Sync Capacitor only"
echo " --assets Generate assets only"
echo " --deploy Deploy app to connected device"
echo " --auto-run Auto-run app after build"
echo " --api-ip <ip> Custom IP address for claim API (uses Capacitor default)"
echo ""
echo "Common Options:"
echo " -h, --help Show this help message"
echo " -v, --verbose Enable verbose logging"
echo ""
echo "Examples:"
echo " $0 --dev --studio # Development build + open Xcode"
echo " $0 --prod --ipa # Production IPA build"
echo " $0 --test --app # Testing app build"
echo " $0 --test --auto-run # Test build + auto-run"
echo " $0 --clean # Clean only"
echo " $0 --sync # Sync only"
echo " $0 --deploy # Build and deploy to device"
echo " $0 --dev # Dev build with Capacitor default"
echo " $0 --dev --api-ip 192.168.1.100 # Dev build with custom API IP"
echo ""
}
# Function to parse iOS-specific arguments
parse_ios_args() {
local args=("$@")
local i=0
while [ $i -lt ${#args[@]} ]; do
local arg="${args[$i]}"
case $arg in
--dev|--development)
BUILD_MODE="development"
;;
--test)
BUILD_MODE="test"
;;
--prod|--production)
BUILD_MODE="production"
;;
--debug)
BUILD_TYPE="debug"
;;
--release)
BUILD_TYPE="release"
;;
--studio)
OPEN_STUDIO=true
;;
--ipa)
BUILD_IPA=true
;;
--app)
BUILD_APP=true
;;
--clean)
CLEAN_ONLY=true
;;
--sync)
SYNC_ONLY=true
;;
--assets)
ASSETS_ONLY=true
;;
--deploy)
DEPLOY_APP=true
;;
--auto-run)
AUTO_RUN=true
;;
--api-ip)
if [ $((i + 1)) -lt ${#args[@]} ]; then
CUSTOM_API_IP="${args[$((i + 1))]}"
i=$((i + 1)) # Skip the next argument
else
log_error "Error: --api-ip requires an IP address"
exit 1
fi
;;
--api-ip=*)
CUSTOM_API_IP="${arg#*=}"
;;
-h|--help)
print_ios_usage
exit 0
;;
-v|--verbose)
set -x
;;
*)
log_warn "Unknown argument: $arg"
;;
esac
i=$((i + 1))
done
}
# Function to validate iOS environment
validate_ios_environment() {
log_info "Validating iOS build environment..."
# Check for Xcode
if ! command -v xcodebuild &> /dev/null; then
log_error "Xcode not found. Please install Xcode and command line tools."
exit 1
fi
# Check for iOS Simulator
if ! command -v xcrun &> /dev/null; then
log_error "Xcode command line tools not found. Please install with: xcode-select --install"
exit 1
fi
# Check for Capacitor
if ! command -v npx &> /dev/null; then
log_error "npx not found. Please install Node.js and npm."
exit 1
fi
# Check for iOS platform
if [ ! -d "ios" ]; then
log_error "iOS platform not found. Please run: npx cap add ios"
exit 1
fi
log_success "iOS build environment validated"
}
# Function to check iOS resources
check_ios_resources() {
log_info "Checking iOS resources..."
# Check for required assets
if [ ! -f "assets/icon.png" ]; then
log_warning "App icon not found at assets/icon.png"
fi
if [ ! -f "assets/splash.png" ]; then
log_warning "Splash screen not found at assets/splash.png"
fi
# Check for iOS-specific files
if [ ! -f "ios/App/App/Info.plist" ]; then
log_warning "Info.plist not found"
fi
if [ ! -f "ios/App/App/AppDelegate.swift" ]; then
log_warning "AppDelegate.swift not found"
fi
log_success "iOS resource check completed"
}
# Function to clean iOS build
clean_ios_build() {
log_info "Cleaning iOS build artifacts..."
# Clean Xcode build (temporary output directory)
if [ -d "ios/App/build" ]; then
rm -rf ios/App/build/
log_debug "Cleaned ios/App/build/"
fi
# Clean DerivedData
if [ -d "ios/App/DerivedData" ]; then
rm -rf ios/App/DerivedData/
log_debug "Cleaned ios/App/DerivedData/"
fi
# Clean Capacitor (using npm script instead of invalid cap clean command)
npm run clean:ios || true
log_success "iOS build cleaned"
}
# Function to build iOS app
build_ios_app() {
local build_config=""
local scheme="App"
local destination=""
if [ "$BUILD_TYPE" = "debug" ]; then
build_config="Debug"
destination="platform=iOS Simulator,name=iPhone 15 Pro"
else
build_config="Release"
destination="platform=iOS,id=auto"
fi
log_info "Building iOS app (${build_config})..."
cd ios/App
# Build the app
xcodebuild -workspace App.xcworkspace \
-scheme "$scheme" \
-configuration "$build_config" \
-destination "$destination" \
build \
CODE_SIGN_IDENTITY="" \
CODE_SIGNING_REQUIRED=NO \
CODE_SIGNING_ALLOWED=NO
cd ../..
log_success "iOS app built successfully"
}
# Function to deploy to device
deploy_ios_app() {
log_info "Deploy-app mode: building app and deploying to device"
# Check for connected device
local devices=$(xcrun devicectl list devices --json | grep -c '"state":"booted"' || echo "0")
if [ "$devices" -eq 0 ]; then
log_error "No iOS device connected. Please connect a device and try again."
exit 1
fi
# Build app for device
BUILD_TYPE="debug"
build_ios_app
# Get device ID
local device_id=$(xcrun devicectl list devices --json | grep -o '"identifier":"[^"]*"' | head -1 | cut -d'"' -f4)
if [ -z "$device_id" ]; then
log_error "Could not find device ID. Please ensure device is connected and unlocked."
exit 1
fi
# Install app on device
log_info "Installing app on device..."
xcrun devicectl device install app --device "$device_id" ios/App/build/Debug-iphoneos/App.app
log_success "iOS app deployed successfully to device!"
log_info "You can now run the app with: npx cap run ios"
}
# Function to auto-run iOS app
auto_run_ios_app() {
log_step "Auto-running iOS app..."
# Check if we're in debug mode (simulator) or release mode (device)
if [ "$BUILD_TYPE" = "debug" ]; then
log_info "Launching iOS Simulator and installing app"
safe_execute "Launching app" "npx cap run ios" || {
log_error "Failed to launch iOS app on simulator"
return 1
}
else
log_info "Building and installing on real device"
# For release builds, we need to use a different approach
# since npx cap run ios is primarily for simulators
log_warn "Auto-run for release builds requires manual device setup"
log_info "Please use Xcode to run the app on your device"
return 1
fi
log_success "iOS app launched successfully!"
}
# Parse command line arguments
parse_ios_args "$@"
# Print build header
print_header "TimeSafari iOS Build Process"
log_info "Starting iOS build process at $(date)"
log_info "Build mode: $BUILD_MODE"
log_info "Build type: $BUILD_TYPE"
# Setup environment for Capacitor build
setup_build_env "capacitor"
# Override API servers for iOS development when custom IP is specified
if [ "$BUILD_MODE" = "development" ] && [ -n "$CUSTOM_API_IP" ]; then
# Use custom IP for physical device development
export VITE_DEFAULT_ENDORSER_API_SERVER="http://${CUSTOM_API_IP}:3000"
export VITE_DEFAULT_PARTNER_API_SERVER="http://${CUSTOM_API_IP}:3000"
log_info "iOS development mode: Using custom IP ${CUSTOM_API_IP} for physical device"
fi
# Setup application directories
setup_app_directories
# Load environment from .env file if it exists
load_env_file ".env"
# Validate iOS environment
validate_ios_environment
# Handle clean-only mode
if [ "$CLEAN_ONLY" = true ]; then
log_info "Clean-only mode: cleaning build artifacts"
clean_ios_build
safe_execute "Cleaning dist directory" "clean_build_artifacts dist" || exit 1
log_success "Clean completed successfully!"
exit 0
fi
# Handle sync-only mode
if [ "$SYNC_ONLY" = true ]; then
log_info "Sync-only mode: syncing with Capacitor"
safe_execute "Syncing with Capacitor" "npx cap sync ios" || exit 6
log_success "Sync completed successfully!"
exit 0
fi
# Handle assets-only mode
if [ "$ASSETS_ONLY" = true ]; then
log_info "Assets-only mode: generating assets"
safe_execute "Generating assets" "npx capacitor-assets generate --ios" || exit 7
log_success "Assets generation completed successfully!"
exit 0
fi
# Handle deploy-app mode
if [ "$DEPLOY_APP" = true ]; then
deploy_ios_app
exit 0
fi
# Step 1: Check iOS resources
check_ios_resources
# Step 2: Clean iOS build
safe_execute "Cleaning iOS build" "clean_ios_build" || exit 1
# Step 3: Clean dist directory
log_info "Cleaning dist directory..."
clean_build_artifacts "dist"
# Step 4: Build Capacitor version with mode
if [ "$BUILD_MODE" = "development" ]; then
safe_execute "Building Capacitor version (development)" "npm run build:capacitor" || exit 3
elif [ "$BUILD_MODE" = "test" ]; then
safe_execute "Building Capacitor version (test)" "npm run build:capacitor -- --mode test" || exit 3
elif [ "$BUILD_MODE" = "production" ]; then
safe_execute "Building Capacitor version (production)" "npm run build:capacitor -- --mode production" || exit 3
fi
# Step 5: Sync with Capacitor
safe_execute "Syncing with Capacitor" "npx cap sync ios" || exit 6
# Step 6: Generate assets
safe_execute "Generating assets" "npx capacitor-assets generate --ios" || exit 7
# Step 7: Build iOS app
safe_execute "Building iOS app" "build_ios_app" || exit 5
# Step 8: Build IPA/App if requested
if [ "$BUILD_IPA" = true ]; then
log_info "Building IPA package..."
cd ios/App
xcodebuild -workspace App.xcworkspace \
-scheme App \
-configuration Release \
-archivePath build/App.xcarchive \
archive \
CODE_SIGN_IDENTITY="" \
CODE_SIGNING_REQUIRED=NO \
CODE_SIGNING_ALLOWED=NO
xcodebuild -exportArchive \
-archivePath build/App.xcarchive \
-exportPath build/ \
-exportOptionsPlist exportOptions.plist
cd ../..
log_success "IPA package built successfully"
fi
if [ "$BUILD_APP" = true ]; then
log_info "Building app bundle..."
# App bundle is already built in step 7
log_success "App bundle built successfully"
fi
# Step 9: Auto-run app if requested
if [ "$AUTO_RUN" = true ]; then
safe_execute "Auto-running iOS app" "auto_run_ios_app" || exit 9
fi
# Step 10: Open Xcode if requested
if [ "$OPEN_STUDIO" = true ]; then
safe_execute "Opening Xcode" "npx cap open ios" || exit 8
fi
# Print build summary
log_success "iOS build completed successfully!"
log_info "Build mode: $BUILD_MODE"
log_info "Build type: $BUILD_TYPE"
if [ "$BUILD_IPA" = true ]; then
log_info "IPA build: completed"
fi
if [ "$BUILD_APP" = true ]; then
log_info "App build: completed"
fi
if [ "$AUTO_RUN" = true ]; then
log_info "Auto-run: completed"
fi
if [ "$OPEN_STUDIO" = true ]; then
log_info "Xcode: opened"
fi
print_footer "iOS Build"
# Exit with success
exit 0