[FIX] iOS 빌드: Provisioning profile 타입 확인 및 설치 검증 로그 추가 #19
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Develop Build & Deploy | |
| on: | |
| push: | |
| branches: | |
| - develop | |
| workflow_dispatch: | |
| jobs: | |
| build-android-dev: | |
| name: Build Android Dev | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Java | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: 'temurin' | |
| java-version: '17' | |
| - name: Setup Flutter | |
| uses: subosito/flutter-action@v2 | |
| with: | |
| flutter-version: '3.24.5' | |
| channel: 'stable' | |
| - name: Get dependencies | |
| run: flutter pub get | |
| - name: Build Android APK (Dev) | |
| run: | | |
| flutter build apk --release \ | |
| --build-name=1.0.0-dev \ | |
| --build-number=${{ github.run_number }} \ | |
| --dart-define=API_ENV=dev | |
| - name: Upload APK artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: android-dev-apk | |
| path: build/app/outputs/flutter-apk/app-release.apk | |
| retention-days: 30 | |
| build-ios-dev: | |
| name: Build iOS Dev | |
| runs-on: macos-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Flutter | |
| uses: subosito/flutter-action@v2 | |
| with: | |
| flutter-version: '3.24.5' | |
| channel: 'stable' | |
| - name: Get dependencies | |
| run: flutter pub get | |
| - name: Install CocoaPods dependencies | |
| run: | | |
| cd ios | |
| pod install | |
| - name: Setup iOS Certificates and Profiles | |
| env: | |
| APPLE_CERTIFICATE_BASE64: ${{ secrets.APPLE_CERTIFICATE_BASE64 }} | |
| APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} | |
| APPLE_PROVISIONING_PROFILE_BASE64: ${{ secrets.APPLE_PROVISIONING_PROFILE_BASE64 }} | |
| run: | | |
| # Certificate와 비밀번호가 모두 제공된 경우에만 설정 시도 | |
| if [ -n "$APPLE_CERTIFICATE_BASE64" ] && [ -n "$APPLE_CERTIFICATE_PASSWORD" ]; then | |
| # Create keychain | |
| security create-keychain -p "" build.keychain || true | |
| security default-keychain -s build.keychain || true | |
| security unlock-keychain -p "" build.keychain || true | |
| security set-keychain-settings -t 3600 -u build.keychain || true | |
| # Import certificate | |
| echo "$APPLE_CERTIFICATE_BASE64" | base64 -d > certificate.p12 | |
| if ! security import certificate.p12 -k build.keychain -P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign; then | |
| echo "Certificate import failed. Will continue with provisioning profile setup." | |
| fi | |
| # Import provisioning profile (if provided) | |
| if [ -n "$APPLE_PROVISIONING_PROFILE_BASE64" ]; then | |
| echo "$APPLE_PROVISIONING_PROFILE_BASE64" | base64 -d > profile.mobileprovision | |
| # Extract UUID and other info from provisioning profile | |
| PROFILE_UUID="" | |
| PROFILE_NAME="" | |
| # Decode provisioning profile to plist | |
| TEMP_PLIST=$(mktemp) | |
| if security cms -D -i profile.mobileprovision > "$TEMP_PLIST" 2>/dev/null; then | |
| # Extract UUID using PlistBuddy | |
| PROFILE_UUID=$(/usr/libexec/PlistBuddy -c "Print UUID" "$TEMP_PLIST" 2>/dev/null) | |
| PROFILE_NAME=$(/usr/libexec/PlistBuddy -c "Print Name" "$TEMP_PLIST" 2>/dev/null) | |
| PROFILE_TYPE=$(/usr/libexec/PlistBuddy -c "Print ProvisionedDevices" "$TEMP_PLIST" 2>/dev/null | head -1 || echo "App Store") | |
| echo "Provisioning Profile Name: $PROFILE_NAME" | |
| echo "Provisioning Profile UUID: $PROFILE_UUID" | |
| # Check profile type | |
| if /usr/libexec/PlistBuddy -c "Print ProvisionedDevices" "$TEMP_PLIST" 2>/dev/null | grep -q "array"; then | |
| echo "⚠️ Profile Type: Ad Hoc or Development (has ProvisionedDevices)" | |
| else | |
| echo "✅ Profile Type: App Store Distribution (no ProvisionedDevices)" | |
| fi | |
| # Extract Bundle ID to verify | |
| APP_ID=$(/usr/libexec/PlistBuddy -c "Print Entitlements:application-identifier" "$TEMP_PLIST" 2>/dev/null | sed 's/.*\.//') | |
| echo "App Bundle ID from profile: $APP_ID" | |
| # Verify profile is for App Store | |
| PROVISIONED_DEVICES=$(/usr/libexec/PlistBuddy -c "Print ProvisionedDevices" "$TEMP_PLIST" 2>/dev/null || echo "") | |
| if [ -n "$PROVISIONED_DEVICES" ] && [ "$PROVISIONED_DEVICES" != "" ]; then | |
| echo "❌ WARNING: This profile has ProvisionedDevices, which means it's NOT an App Store Distribution profile!" | |
| echo "Archive builds require App Store Distribution profiles without ProvisionedDevices." | |
| fi | |
| fi | |
| # Install provisioning profile | |
| mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles | |
| if [ -n "$PROFILE_UUID" ]; then | |
| cp profile.mobileprovision ~/Library/MobileDevice/Provisioning\ Profiles/$PROFILE_UUID.mobileprovision | |
| echo "✅ Provisioning profile installed as: $PROFILE_UUID.mobileprovision" | |
| # Save UUID to file for later use | |
| echo "$PROFILE_UUID" > /tmp/profile_uuid.txt | |
| else | |
| echo "❌ Failed to extract UUID from provisioning profile" | |
| echo "Profile content preview:" | |
| head -20 "$TEMP_PLIST" || true | |
| rm -f "$TEMP_PLIST" | |
| exit 1 | |
| fi | |
| rm -f "$TEMP_PLIST" | |
| # Verify profile installation | |
| echo "Installed profiles:" | |
| ls -la ~/Library/MobileDevice/Provisioning\ Profiles/ | grep -i mobileprovision || echo "No profiles found" | |
| fi | |
| # Set keychain to allow codesign | |
| security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "" build.keychain || true | |
| else | |
| echo "No certificate provided. Will use automatic signing." | |
| fi | |
| - name: Build iOS IPA (Dev) | |
| run: | | |
| # Verify profile is installed | |
| echo "Checking installed provisioning profiles:" | |
| ls -la ~/Library/MobileDevice/Provisioning\ Profiles/ 2>/dev/null || echo "No profiles directory found" | |
| # Update ExportOptions with provisioning profile UUID if available | |
| if [ -f /tmp/profile_uuid.txt ]; then | |
| PROFILE_UUID=$(cat /tmp/profile_uuid.txt) | |
| echo "Using provisioning profile UUID: $PROFILE_UUID" | |
| # Verify profile file exists | |
| if [ -f ~/Library/MobileDevice/Provisioning\ Profiles/$PROFILE_UUID.mobileprovision ]; then | |
| echo "✅ Profile file exists: $PROFILE_UUID.mobileprovision" | |
| else | |
| echo "❌ Profile file NOT found: $PROFILE_UUID.mobileprovision" | |
| echo "Available profiles:" | |
| ls -la ~/Library/MobileDevice/Provisioning\ Profiles/ 2>/dev/null || true | |
| fi | |
| # Create updated ExportOptions with UUID | |
| /usr/libexec/PlistBuddy -c "Add :provisioningProfiles dict" ios/ExportOptions-dev.plist 2>/dev/null || true | |
| /usr/libexec/PlistBuddy -c "Add :provisioningProfiles:com.coby.taba string $PROFILE_UUID" ios/ExportOptions-dev.plist 2>/dev/null || \ | |
| /usr/libexec/PlistBuddy -c "Set :provisioningProfiles:com.coby.taba $PROFILE_UUID" ios/ExportOptions-dev.plist 2>/dev/null || true | |
| echo "Updated ExportOptions:" | |
| cat ios/ExportOptions-dev.plist | |
| fi | |
| # Build with verbose logging | |
| flutter build ipa --release \ | |
| --build-name=1.0.0-dev \ | |
| --build-number=${{ github.run_number }} \ | |
| --dart-define=API_ENV=dev \ | |
| --export-options-plist=ios/ExportOptions-dev.plist \ | |
| --verbose | |
| - name: Upload IPA artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ios-dev-ipa | |
| path: build/ios/ipa/*.ipa | |
| retention-days: 30 | |
| - name: Upload to TestFlight (Dev) | |
| if: success() | |
| env: | |
| APP_STORE_CONNECT_API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }} | |
| APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }} | |
| APP_STORE_CONNECT_API_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY }} | |
| run: | | |
| # Create API key file | |
| mkdir -p ~/private_keys | |
| echo "$APP_STORE_CONNECT_API_KEY" > ~/private_keys/AuthKey_$APP_STORE_CONNECT_API_KEY_ID.p8 | |
| chmod 600 ~/private_keys/AuthKey_$APP_STORE_CONNECT_API_KEY_ID.p8 | |
| # Upload using xcrun altool | |
| xcrun altool --upload-app \ | |
| --type ios \ | |
| --file build/ios/ipa/*.ipa \ | |
| --apiKey $APP_STORE_CONNECT_API_KEY_ID \ | |
| --apiIssuer $APP_STORE_CONNECT_ISSUER_ID \ | |
| --verbose | |