ci(ios): use Tahoe runner for Xcode 26.2 GM #14
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: iOS Release | |
| on: | |
| push: | |
| tags: | |
| - 'v*' | |
| concurrency: | |
| group: ios-release-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| release: | |
| name: Build & Upload to TestFlight | |
| runs-on: nscloud-macos-tahoe-arm64-6x14 | |
| timeout-minutes: 60 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Select latest Xcode | |
| run: | | |
| LATEST=$(ls -d /Applications/Xcode_*.app 2>/dev/null | grep -iv beta | sort -V | tail -1) | |
| if [ -n "$LATEST" ]; then | |
| sudo xcode-select -s "$LATEST" | |
| fi | |
| xcodebuild -version | |
| - uses: actions/setup-java@v4 | |
| with: | |
| distribution: temurin | |
| java-version: 23 | |
| - uses: gradle/actions/setup-gradle@v4 | |
| - name: Import signing certificate | |
| env: | |
| APPLE_CERTIFICATE_BASE64: ${{ secrets.APPLE_CERTIFICATE_BASE64 }} | |
| APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} | |
| run: | | |
| CERTIFICATE_PATH="$RUNNER_TEMP/certificate.p12" | |
| KEYCHAIN_PATH="$RUNNER_TEMP/signing.keychain-db" | |
| KEYCHAIN_PASSWORD="$(openssl rand -base64 32)" | |
| echo -n "$APPLE_CERTIFICATE_BASE64" | base64 --decode -o "$CERTIFICATE_PATH" | |
| security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
| security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH" | |
| security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
| security import "$CERTIFICATE_PATH" \ | |
| -P "$APPLE_CERTIFICATE_PASSWORD" \ | |
| -A \ | |
| -t cert \ | |
| -f pkcs12 \ | |
| -k "$KEYCHAIN_PATH" | |
| security set-key-partition-list \ | |
| -S apple-tool:,apple: \ | |
| -k "$KEYCHAIN_PASSWORD" \ | |
| "$KEYCHAIN_PATH" | |
| security list-keychains -d user -s "$KEYCHAIN_PATH" login.keychain-db | |
| - name: Import provisioning profile | |
| env: | |
| APPLE_PROVISIONING_PROFILE_BASE64: ${{ secrets.APPLE_PROVISIONING_PROFILE_BASE64 }} | |
| run: | | |
| PROFILE_PATH="$RUNNER_TEMP/profile.mobileprovision" | |
| echo -n "$APPLE_PROVISIONING_PROFILE_BASE64" | base64 --decode -o "$PROFILE_PATH" | |
| mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles | |
| PROFILE_UUID=$(/usr/libexec/PlistBuddy -c "Print UUID" /dev/stdin <<< \ | |
| "$(security cms -D -i "$PROFILE_PATH")") | |
| cp "$PROFILE_PATH" ~/Library/MobileDevice/Provisioning\ Profiles/"$PROFILE_UUID".mobileprovision | |
| echo "PROVISIONING_PROFILE_UUID=$PROFILE_UUID" >> "$GITHUB_ENV" | |
| - name: Set up App Store Connect API key | |
| env: | |
| APP_STORE_CONNECT_API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }} | |
| APP_STORE_CONNECT_API_KEY_BASE64: ${{ secrets.APP_STORE_CONNECT_API_KEY_BASE64 }} | |
| run: | | |
| mkdir -p ~/.private_keys | |
| echo -n "$APP_STORE_CONNECT_API_KEY_BASE64" | base64 --decode \ | |
| -o ~/.private_keys/AuthKey_"$APP_STORE_CONNECT_API_KEY_ID".p8 | |
| - name: Extract version from tag | |
| run: | | |
| TAG="${GITHUB_REF#refs/tags/v}" | |
| echo "MARKETING_VERSION=$TAG" >> "$GITHUB_ENV" | |
| echo "CURRENT_PROJECT_VERSION=$GITHUB_RUN_NUMBER" >> "$GITHUB_ENV" | |
| echo "Building version $TAG ($GITHUB_RUN_NUMBER)" | |
| - name: Build archive | |
| run: | | |
| xcodebuild archive \ | |
| -project app/ios/FareBot.xcodeproj \ | |
| -scheme FareBot \ | |
| -configuration Release \ | |
| -destination 'generic/platform=iOS' \ | |
| -archivePath "$RUNNER_TEMP/FareBot.xcarchive" \ | |
| MARKETING_VERSION="$MARKETING_VERSION" \ | |
| CURRENT_PROJECT_VERSION="$CURRENT_PROJECT_VERSION" \ | |
| CODE_SIGN_STYLE=Manual \ | |
| CODE_SIGN_IDENTITY="Apple Distribution" \ | |
| DEVELOPMENT_TEAM=ZJ9GEQ36AH \ | |
| PROVISIONING_PROFILE_SPECIFIER="$PROVISIONING_PROFILE_UUID" | |
| - name: Export & upload to App Store Connect | |
| 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 }} | |
| run: | | |
| EXPORT_PLIST="$RUNNER_TEMP/ExportOptions.plist" | |
| cat > "$EXPORT_PLIST" <<-PLIST | |
| <?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-connect</string> | |
| <key>teamID</key> | |
| <string>ZJ9GEQ36AH</string> | |
| <key>signingStyle</key> | |
| <string>manual</string> | |
| <key>signingCertificate</key> | |
| <string>Apple Distribution</string> | |
| <key>provisioningProfiles</key> | |
| <dict> | |
| <key>com.codebutler.farebot</key> | |
| <string>$PROVISIONING_PROFILE_UUID</string> | |
| </dict> | |
| <key>uploadSymbols</key> | |
| <true/> | |
| <key>destination</key> | |
| <string>upload</string> | |
| </dict> | |
| </plist> | |
| PLIST | |
| xcodebuild -exportArchive \ | |
| -archivePath "$RUNNER_TEMP/FareBot.xcarchive" \ | |
| -exportPath "$RUNNER_TEMP/export" \ | |
| -exportOptionsPlist "$EXPORT_PLIST" \ | |
| -authenticationKeyPath ~/.private_keys/AuthKey_"$APP_STORE_CONNECT_API_KEY_ID".p8 \ | |
| -authenticationKeyID "$APP_STORE_CONNECT_API_KEY_ID" \ | |
| -authenticationKeyIssuerID "$APP_STORE_CONNECT_ISSUER_ID" | |
| - name: Install fastlane | |
| run: brew install fastlane | |
| - name: Distribute to TestFlight testers | |
| 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 }} | |
| run: | | |
| API_KEY_JSON="$RUNNER_TEMP/api_key.json" | |
| P8_CONTENTS=$(cat ~/.private_keys/AuthKey_"$APP_STORE_CONNECT_API_KEY_ID".p8) | |
| jq -n \ | |
| --arg key_id "$APP_STORE_CONNECT_API_KEY_ID" \ | |
| --arg issuer_id "$APP_STORE_CONNECT_ISSUER_ID" \ | |
| --arg key "$P8_CONTENTS" \ | |
| '{key_id: $key_id, issuer_id: $issuer_id, key: $key, in_house: false}' \ | |
| > "$API_KEY_JSON" | |
| fastlane pilot distribute \ | |
| --api_key_path "$API_KEY_JSON" \ | |
| --app_platform ios \ | |
| --app_identifier com.codebutler.farebot \ | |
| --distribute_external true \ | |
| --notify_external_testers true \ | |
| --build_number "$CURRENT_PROJECT_VERSION" \ | |
| --skip_waiting_for_build_processing false \ | |
| --changelog "Build $MARKETING_VERSION ($CURRENT_PROJECT_VERSION)" | |
| - name: Cleanup keychain | |
| if: always() | |
| run: | | |
| KEYCHAIN_PATH="$RUNNER_TEMP/signing.keychain-db" | |
| if [ -f "$KEYCHAIN_PATH" ]; then | |
| security delete-keychain "$KEYCHAIN_PATH" | |
| fi |