#!/bin/zsh set -e SCRIPT_DIR=${0:a:h} cd "$SCRIPT_DIR" source .env function sediment() { if [[ "$OSTYPE" == "darwin"* ]]; then sed -i '' "$@" else sed -i "$@" fi } # 絶対パスに変換 REPO_DIR="$SCRIPT_DIR/../repos/social-app" APP_NAME="Aiat" WORKSPACE="$REPO_DIR/ios/${APP_NAME}.xcworkspace" SCHEME="$APP_NAME" BUILD_DIR="$REPO_DIR/build" MOBILEPROVISION="$SCRIPT_DIR/store.mobileprovision" ASSETS_DIR="$SCRIPT_DIR/assets" echo "Running iOS preview workflow..." cd "$REPO_DIR" # 0. Environment Setup (Fix Node Version) export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm echo "Checking Node version..." if command -v nvm >/dev/null; then nvm use 22 || nvm use 20 || echo "Warning: Could not switch to Node 22/20. Current: $(node -v)" else echo "nvm not found, using system node: $(node -v)" fi # 1. Install dependencies echo "1. Installing dependencies (yarn)..." yarn install # 1.5. Copy assets echo "1.5. Copying assets..." if [ -d "$ASSETS_DIR" ]; then cp -rf "$ASSETS_DIR/"* "$REPO_DIR/assets/" echo "✅ Copied all assets (including logo.png, logo-1024.png)" else echo "⚠️ Warning: $ASSETS_DIR not found" fi function cleanup_build { # 1.8. Update package.json version (prevent App Store version conflict) echo "1.8. Updating package.json version..." if [ -n "$APP_VERSION" ]; then PACKAGE_JSON="$REPO_DIR/package.json" # Use node to update version in package.json node -e " const fs = require('fs'); const pkg = JSON.parse(fs.readFileSync('$PACKAGE_JSON', 'utf8')); pkg.version = '$APP_VERSION'; fs.writeFileSync('$PACKAGE_JSON', JSON.stringify(pkg, null, 2) + '\n'); " echo " ✅ Set version to $APP_VERSION" else echo " ⚠️ APP_VERSION not set in .env" fi # 1.9. Update buildNumber (CFBundleVersion) with current timestamp echo "1.9. Updating buildNumber..." local build_number=$(date +%y%m%d%H%M%S) CONFIG_FILE="$REPO_DIR/app.config.js" sediment "s/buildNumber: '[0-9]*'/buildNumber: '${build_number}'/" "$CONFIG_FILE" echo " ✅ Set buildNumber to $build_number" # 2. Prebuild (Generate ios directory) echo "2. Running Expo Prebuild..." # Clean old ios folder to remove old entitlements/AppClip targets rm -rf ios npx expo prebuild --platform ios --clean # 3. CocoaPods echo "3. Installing CocoaPods..." # Ensure PATH includes Homebrew ruby gems if needed export PATH="/opt/homebrew/lib/ruby/gems/3.4.0/bin:$PATH" cd ios pod install cd .. # 4. Signing (Automated) echo "4. Configuring Xcode Signing..." XCODE_PROJ="ios/${APP_NAME}.xcodeproj" if [ ! -d "$XCODE_PROJ" ]; then XCODE_PROJ=$(find ios -name "*.xcodeproj" | head -n 1) fi PBXPROJ="$XCODE_PROJ/project.pbxproj" # Set DEVELOPMENT_TEAM in pbxproj if [ -n "$DEVELOPMENT_TEAM" ]; then echo " Setting DEVELOPMENT_TEAM=$DEVELOPMENT_TEAM" sediment "s/PRODUCT_BUNDLE_IDENTIFIER = /DEVELOPMENT_TEAM = $DEVELOPMENT_TEAM; PRODUCT_BUNDLE_IDENTIFIER = /g" "$PBXPROJ" sediment "s/DEVELOPMENT_TEAM = \"\";/DEVELOPMENT_TEAM = $DEVELOPMENT_TEAM;/g" "$PBXPROJ" sediment "s/DEVELOPMENT_TEAM = ;/DEVELOPMENT_TEAM = $DEVELOPMENT_TEAM;/g" "$PBXPROJ" fi # Create/Update entitlements file with App Group ENTITLEMENTS_FILE="ios/${APP_NAME}/${APP_NAME}.entitlements" if [ -n "$APP_GROUP" ]; then echo " Setting APP_GROUP=$APP_GROUP" cat > "$ENTITLEMENTS_FILE" << EOF aps-environment production com.apple.security.application-groups ${APP_GROUP} EOF if ! grep -q "CODE_SIGN_ENTITLEMENTS" "$PBXPROJ"; then sediment "s/DEVELOPMENT_TEAM = $DEVELOPMENT_TEAM;/DEVELOPMENT_TEAM = $DEVELOPMENT_TEAM; CODE_SIGN_ENTITLEMENTS = ${APP_NAME}\\/${APP_NAME}.entitlements;/g" "$PBXPROJ" fi fi echo "✅ Signing configured automatically" # (Old manual step - commented out) # open "$XCODE_PROJ" # read } case $1 in i) cleanup_build ;; esac echo "Building $APP_NAME for App Store upload..." # ビルドディレクトリ作成 mkdir -p "$BUILD_DIR" # アーカイブ(詳細ログ出力) xcodebuild -workspace "$WORKSPACE" \ -scheme "$SCHEME" \ -configuration Release \ -archivePath "$BUILD_DIR/${APP_NAME}.xcarchive" \ -allowProvisioningUpdates \ DEVELOPMENT_TEAM="$DEVELOPMENT_TEAM" \ archive 2>&1 | tee "$BUILD_DIR/build.log" # アーカイブ成功確認 if [ ! -d "$BUILD_DIR/${APP_NAME}.xcarchive" ]; then echo "Error: Archive failed. Check $BUILD_DIR/build.log for details" exit 1 fi cd "$BUILD_DIR" # IPA作成 rm -rf Payload ${APP_NAME}.ipa mkdir -p Payload cp -R ${APP_NAME}.xcarchive/Products/Applications/${APP_NAME}.app Payload/ # store.mobileprovisionの存在確認とコピー # https://developer.apple.com/account/resources/profiles/list if [ ! -f "$MOBILEPROVISION" ]; then echo "Error: store.mobileprovision not found at $MOBILEPROVISION" exit 1 fi cp "$MOBILEPROVISION" Payload/${APP_NAME}.app/embedded.mobileprovision # entitlements抽出 security cms -D -i Payload/${APP_NAME}.app/embedded.mobileprovision > /tmp/profile.plist /usr/libexec/PlistBuddy -x -c "Print :Entitlements" /tmp/profile.plist > /tmp/entitlements.plist # 署名 CERT="$IOS_CERTIFICATE_NAME" # Frameworksディレクトリが存在する場合のみ署名 if [ -d "Payload/${APP_NAME}.app/Frameworks" ]; then for framework in Payload/${APP_NAME}.app/Frameworks/*.framework; do if [ -e "$framework" ]; then echo "Signing $framework" codesign -f -s "$CERT" "$framework" fi done fi # アプリ本体に署名 codesign -f -s "$CERT" --entitlements /tmp/entitlements.plist Payload/${APP_NAME}.app # IPA作成 zip -r ${APP_NAME}.ipa Payload # アップロード xcrun altool --upload-app -f ${APP_NAME}.ipa -t ios -u "${APP_MAIL}" -p "${APP_KEYCHAIN}" echo "Upload complete: ${APP_NAME}.ipa"