This repository was archived by the owner on Jan 14, 2026. It is now read-only.
Build & Publish to App Store #13
Workflow file for this run
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: Build & Publish to App Store | |
| on: | |
| push: | |
| tags: | |
| - 'v*.*.*' # Triggers on version tags like v1.0.0 | |
| workflow_dispatch: | |
| jobs: | |
| publish-ios: | |
| runs-on: macos-latest | |
| defaults: | |
| run: | |
| working-directory: ./object_detect_test | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Flutter | |
| uses: subosito/flutter-action@v2 | |
| with: | |
| channel: stable | |
| cache: true | |
| - name: Install Flutter dependencies | |
| run: flutter pub get | |
| - name: Update CocoaPods repo | |
| run: | | |
| cd ios | |
| pod repo update | |
| cd .. | |
| - name: Setup Xcode | |
| uses: maxim-lobanov/setup-xcode@v1 | |
| with: | |
| xcode-version: latest-stable | |
| - name: Setup App Store Connect API Key | |
| env: | |
| API_KEY_BASE64: ${{ secrets.APP_STORE_CONNECT_API_KEY_BASE64 }} | |
| API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }} | |
| API_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_ISSUER_ID }} | |
| run: | | |
| mkdir -p ~/private_keys | |
| echo "$API_KEY_BASE64" | base64 --decode > ~/private_keys/AuthKey_$API_KEY_ID.p8 | |
| chmod 600 ~/private_keys/AuthKey_$API_KEY_ID.p8 | |
| - name: Import Distribution Certificate | |
| env: | |
| CERTIFICATE_BASE64: ${{ secrets.IOS_DISTRIBUTION_CERTIFICATE_BASE64 }} | |
| CERTIFICATE_PASSWORD: ${{ secrets.IOS_CERTIFICATE_PASSWORD }} | |
| run: | | |
| # Create keychain | |
| KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db | |
| KEYCHAIN_PASSWORD=$(openssl rand -base64 32) | |
| security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH | |
| security set-keychain-settings -lut 21600 $KEYCHAIN_PATH | |
| security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH | |
| # Import certificate | |
| CERTIFICATE_PATH=$RUNNER_TEMP/certificate.p12 | |
| echo "$CERTIFICATE_BASE64" | base64 --decode > $CERTIFICATE_PATH | |
| security import $CERTIFICATE_PATH \ | |
| -P "$CERTIFICATE_PASSWORD" \ | |
| -A \ | |
| -t cert \ | |
| -f pkcs12 \ | |
| -k $KEYCHAIN_PATH | |
| security list-keychain -d user -s $KEYCHAIN_PATH | |
| security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH | |
| - name: Import App Store Provisioning Profile | |
| env: | |
| PROVISIONING_PROFILE_BASE64: ${{ secrets.IOS_APPSTORE_PROVISIONING_PROFILE_BASE64 }} | |
| run: | | |
| PP_PATH=$RUNNER_TEMP/profile.mobileprovision | |
| echo "$PROVISIONING_PROFILE_BASE64" | base64 --decode > $PP_PATH | |
| mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles | |
| cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles/ | |
| - name: Create ExportOptions.plist for App Store | |
| env: | |
| TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} | |
| BUNDLE_ID: ${{ secrets.IOS_BUNDLE_ID }} | |
| PROVISIONING_PROFILE_NAME: ${{ secrets.IOS_APPSTORE_PROVISIONING_PROFILE_NAME }} | |
| run: | | |
| cat > ios/ExportOptions.plist << EOF | |
| <?xml version="1.0" encoding="UTF-8"?> | |
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
| <plist version="1.0"> | |
| <dict> | |
| <key>method</key> | |
| <string>app-store</string> | |
| <key>teamID</key> | |
| <string>$TEAM_ID</string> | |
| <key>uploadSymbols</key> | |
| <true/> | |
| <key>uploadBitcode</key> | |
| <false/> | |
| <key>signingStyle</key> | |
| <string>manual</string> | |
| <key>provisioningProfiles</key> | |
| <dict> | |
| <key>$BUNDLE_ID</key> | |
| <string>$PROVISIONING_PROFILE_NAME</string> | |
| </dict> | |
| </dict> | |
| </plist> | |
| EOF | |
| - name: Build IPA for App Store | |
| run: | | |
| flutter build ipa --release \ | |
| --export-options-plist=ios/ExportOptions.plist | |
| - name: Upload to App Store Connect using Transporter | |
| env: | |
| API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }} | |
| API_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_ISSUER_ID }} | |
| run: | | |
| # Transporter uses the API key from the private_keys folder | |
| xcrun iTMSTransporter -m upload \ | |
| -f build/ios/ipa/*.ipa \ | |
| -k ~/private_keys/AuthKey_$API_KEY_ID.p8 \ | |
| -i $API_KEY_ID \ | |
| -u $API_ISSUER_ID \ | |
| -t Signiant | |
| - name: Wait for Processing (Optional) | |
| env: | |
| API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }} | |
| API_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_ISSUER_ID }} | |
| run: | | |
| echo "Build uploaded! Check App Store Connect for processing status." | |
| echo "You can monitor at: https://appstoreconnect.apple.com" | |
| - name: Upload IPA as Artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: appstore-release-ipa | |
| path: build/ios/ipa/*.ipa | |
| retention-days: 30 | |
| - name: Cleanup | |
| if: always() | |
| run: | | |
| security delete-keychain $RUNNER_TEMP/app-signing.keychain-db || true | |
| rm -rf ~/private_keys || true | |
| rm -f ~/Library/MobileDevice/Provisioning\ Profiles/*.mobileprovision || true |