Build iOS #53
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 iOS | |
| on: | |
| workflow_dispatch: | |
| env: | |
| NODE_ENV: production | |
| APP_ENV: production | |
| jobs: | |
| build-ios: | |
| runs-on: macos-15 | |
| steps: | |
| - name: π Setup repo | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: π§ Setup Xcode | |
| uses: maxim-lobanov/setup-xcode@v1 | |
| with: | |
| xcode-version: '16.4' | |
| - name: π Setup distribution certificate | |
| uses: apple-actions/import-codesign-certs@v2 | |
| with: | |
| create-keychain: true | |
| keychain-password: ${{ secrets.APPLE_KEYCHAIN_PASSWORD }} | |
| p12-file-base64: ${{ secrets.APPLE_DISTRIBUTION_CERT_BASE64 }} | |
| p12-password: ${{ secrets.APPLE_DISTRIBUTION_CERT_PASS }} | |
| - name: π Setup development certificate | |
| uses: apple-actions/import-codesign-certs@v2 | |
| with: | |
| create-keychain: false | |
| keychain-password: ${{ secrets.APPLE_KEYCHAIN_PASSWORD }} | |
| p12-file-base64: ${{ secrets.APPLE_DEVELOPMENT_CERT_BASE64 }} | |
| p12-password: ${{ secrets.APPLE_DEVELOPMENT_CERT_PASS }} | |
| - name: π Setup App Store Connect API Key | |
| env: | |
| APP_STORE_CONNECT_API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }} | |
| APP_STORE_CONNECT_API_KEY_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ISSUER_ID }} | |
| APP_STORE_CONNECT_API_KEY_BASE64: ${{ secrets.APP_STORE_CONNECT_API_KEY_BASE64 }} | |
| run: | | |
| # Create API key directory | |
| mkdir -p ~/.appstoreconnect/private_keys | |
| # Decode base64 and create API key file | |
| echo "$APP_STORE_CONNECT_API_KEY_BASE64" | base64 --decode > ~/.appstoreconnect/private_keys/AuthKey_$APP_STORE_CONNECT_API_KEY_ID.p8 | |
| # Set permissions | |
| chmod 600 ~/.appstoreconnect/private_keys/AuthKey_$APP_STORE_CONNECT_API_KEY_ID.p8 | |
| - name: π Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 24 | |
| - name: π¦ Setup Rust | |
| uses: dtolnay/rust-toolchain@master | |
| with: | |
| toolchain: nightly-2025-08-14 | |
| components: clippy,rustfmt | |
| targets: aarch64-apple-ios,aarch64-apple-ios-sim | |
| - name: π§ Install Expo CLI | |
| run: npm install -g --include=dev @expo/cli@latest | |
| - name: π§ Install patch-package | |
| run: npm install -g --include=dev patch-package@latest | |
| - name: π¦ Install nodeThread dependencies | |
| run: cd nodejs-assets/nodejs-project && npm install --force --include=dev && cd .. && cd .. | |
| - name: π¦ Install main dependencies | |
| run: npm install --force --include=dev | |
| - name: π¦ Build nodeThread | |
| run: npm run buildNodeThread | |
| - name: π Prebuild | |
| run: | | |
| npm run prebuild:ci:ios | |
| - name: π± Build and Archive iOS App | |
| run: | | |
| cd ios | |
| xcodebuild \ | |
| -workspace Filen.xcworkspace \ | |
| -scheme Filen \ | |
| -configuration Release \ | |
| -destination generic/platform=iOS \ | |
| -archivePath $RUNNER_TEMP/Filen.xcarchive \ | |
| -authenticationKeyPath ~/.appstoreconnect/private_keys/AuthKey_${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}.p8 \ | |
| -authenticationKeyID ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }} \ | |
| -authenticationKeyIssuerID ${{ secrets.APP_STORE_CONNECT_API_KEY_ISSUER_ID }} \ | |
| -allowProvisioningUpdates \ | |
| -allowProvisioningDeviceRegistration \ | |
| CODE_SIGN_STYLE=Automatic \ | |
| DEVELOPMENT_TEAM=${{ secrets.APPLE_TEAM_ID }} \ | |
| archive | |
| - name: π± Export IPA | |
| run: | | |
| # Create export options plist for automatic signing | |
| cat > $RUNNER_TEMP/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>${{ secrets.APPLE_TEAM_ID }}</string> | |
| <key>uploadBitcode</key> | |
| <false/> | |
| <key>uploadSymbols</key> | |
| <true/> | |
| <key>compileBitcode</key> | |
| <false/> | |
| <key>manageAppVersionAndBuildNumber</key> | |
| <false/> | |
| <key>signingStyle</key> | |
| <string>automatic</string> | |
| </dict> | |
| </plist> | |
| EOF | |
| # Export IPA with automatic signing | |
| xcodebuild \ | |
| -exportArchive \ | |
| -archivePath $RUNNER_TEMP/Filen.xcarchive \ | |
| -exportOptionsPlist $RUNNER_TEMP/ExportOptions.plist \ | |
| -exportPath $RUNNER_TEMP/ \ | |
| -authenticationKeyPath ~/.appstoreconnect/private_keys/AuthKey_${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}.p8 \ | |
| -authenticationKeyID ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }} \ | |
| -authenticationKeyIssuerID ${{ secrets.APP_STORE_CONNECT_API_KEY_ISSUER_ID }} \ | |
| -allowProvisioningUpdates | |
| - name: π§Ή Cleanup | |
| if: always() | |
| run: | | |
| # Remove API key | |
| rm -rf ~/.appstoreconnect | |
| # Clear Xcode derived data and caches | |
| rm -rf ~/Library/Developer/Xcode/DerivedData | |
| rm -rf ~/Library/Caches/com.apple.dt.Xcode | |
| # Clear provisioning profiles downloaded by the action | |
| rm -rf ~/Library/MobileDevice/Provisioning\ Profiles | |
| # Clear any temporary keychains that might have been created | |
| security list-keychains | grep -E "(temp|build|ci|apple-actions|signing_temp|temp)" | xargs -I {} security delete-keychain {} 2>/dev/null || true | |
| # Reset keychain list to default | |
| security list-keychains -d user -s login.keychain | |
| - name: π€ Upload iOS Archive | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ios-archive-${{ github.run_number }} | |
| path: ${{ runner.temp }}/Filen.xcarchive | |
| retention-days: 90 | |
| - name: π€ Upload iOS IPA | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ios-ipa-${{ github.run_number }} | |
| path: ${{ runner.temp }}/*.ipa | |
| retention-days: 90 | |
| - name: π Upload to TestFlight | |
| uses: apple-actions/upload-testflight-build@v3 | |
| with: | |
| app-path: ${{ runner.temp }}/Filen.ipa | |
| issuer-id: ${{ secrets.APP_STORE_CONNECT_API_KEY_ISSUER_ID }} | |
| api-key-id: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }} | |
| api-private-key: ${{ secrets.APP_STORE_CONNECT_API_KEY }} | |
| - name: π Build Summary | |
| run: | | |
| echo "## π iOS Build Complete!" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### π± Built artifacts:" >> $GITHUB_STEP_SUMMARY | |
| if [ -d "$RUNNER_TEMP/Filen.xcarchive" ]; then | |
| echo "- β iOS Archive (.xcarchive)" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| if ls $RUNNER_TEMP/*.ipa 1> /dev/null 2>&1; then | |
| IPA_FILE=$(ls $RUNNER_TEMP/*.ipa | head -n 1) | |
| IPA_SIZE=$(du -h "$IPA_FILE" | cut -f1) | |
| IPA_NAME=$(basename "$IPA_FILE") | |
| echo "- β iOS IPA: $IPA_NAME (${IPA_SIZE})" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### π TestFlight Upload Complete!" >> $GITHUB_STEP_SUMMARY | |
| echo "- β Build uploaded to App Store Connect internal beta track" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### π¦ Download artifacts from the Actions tab above" >> $GITHUB_STEP_SUMMARY | |
| echo "### π Build #${{ github.run_number }}" >> $GITHUB_STEP_SUMMARY |