forked from jsnbuchanan/crowd-funder-for-time-pwa
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.
449 lines
13 KiB
Bash
Executable File
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 |