multi: fork to redwallet #56
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 Release and Upload to TestFlight (iOS) | |
| on: | |
| push: | |
| branches: | |
| - master | |
| pull_request: | |
| types: [opened, reopened, synchronize, labeled] | |
| branches: | |
| - master | |
| workflow_dispatch: | |
| jobs: | |
| build: | |
| runs-on: macos-26 | |
| timeout-minutes: 180 | |
| outputs: | |
| new_build_number: ${{ steps.generate_build_number.outputs.build_number }} | |
| project_version: ${{ steps.determine_marketing_version.outputs.project_version }} | |
| ipa_output_path: ${{ steps.build_app.outputs.ipa_output_path }} | |
| latest_commit_message: ${{ steps.get_latest_commit_details.outputs.commit_message }} | |
| branch_name: ${{ steps.get_latest_commit_details.outputs.branch_name }} | |
| env: | |
| APPLE_ID: ${{ secrets.APPLE_ID }} | |
| MATCH_READONLY: "true" | |
| steps: | |
| - name: Checkout Project | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| fetch-depth: 0 # Ensures the full Git history is | |
| - name: Ensure Correct Branch | |
| if: github.ref != 'refs/heads/master' | |
| run: | | |
| if [ -n "${GITHUB_HEAD_REF}" ]; then | |
| git fetch origin ${GITHUB_HEAD_REF}:${GITHUB_HEAD_REF} | |
| git checkout ${GITHUB_HEAD_REF} | |
| else | |
| git fetch origin ${GITHUB_REF##*/}:${GITHUB_REF##*/} | |
| git checkout ${GITHUB_REF##*/} | |
| fi | |
| echo "Checked out branch: $(git rev-parse --abbrev-ref HEAD)" | |
| - name: Get Latest Commit Details | |
| id: get_latest_commit_details | |
| run: | | |
| # Check if we are in a detached HEAD state | |
| if [ "$(git rev-parse --abbrev-ref HEAD)" == "HEAD" ]; then | |
| CURRENT_BRANCH=$(git show-ref --head -s HEAD | xargs -I {} git branch --contains {} | grep -v "detached" | head -n 1 | sed 's/^[* ]*//') | |
| else | |
| CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) | |
| fi | |
| LATEST_COMMIT_MESSAGE=$(git log -1 --pretty=format:"%s") | |
| echo "CURRENT_BRANCH=${CURRENT_BRANCH}" >> $GITHUB_ENV | |
| echo "LATEST_COMMIT_MESSAGE=${LATEST_COMMIT_MESSAGE}" >> $GITHUB_ENV | |
| echo "branch_name=${CURRENT_BRANCH}" >> $GITHUB_OUTPUT | |
| echo "commit_message=${LATEST_COMMIT_MESSAGE}" >> $GITHUB_OUTPUT | |
| - name: Print Commit Details | |
| run: | | |
| echo "Commit Message: ${{ env.LATEST_COMMIT_MESSAGE }}" | |
| echo "Branch Name: ${{ env.CURRENT_BRANCH }}" | |
| - name: Specify Node.js Version | |
| uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 | |
| with: | |
| node-version: 24 | |
| cache: 'npm' | |
| cache-dependency-path: package-lock.json | |
| - uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd # v1 | |
| with: | |
| xcode-version: latest | |
| - name: Setup Xcode Path | |
| run: | | |
| echo -e "\033[1;34m==================== XCODE SETUP DEBUG ====================\033[0m" | |
| echo -e "\033[1;36mSystem Information:\033[0m" | |
| echo " macOS Version: $(sw_vers -productVersion)" | |
| echo " macOS Build: $(sw_vers -buildVersion)" | |
| echo " Architecture: $(uname -m)" | |
| echo -e "\033[1;36mAvailable Xcode Installations:\033[0m" | |
| find /Applications -name "Xcode*.app" -type d 2>/dev/null | while read -r xcode_path; do | |
| if [ -d "$xcode_path/Contents/Developer" ]; then | |
| echo " Found: $xcode_path" | |
| version=$("$xcode_path/Contents/Developer/usr/bin/xcodebuild" -version 2>/dev/null | head -1 || echo "Version unavailable") | |
| echo " Version: $version" | |
| fi | |
| done | |
| echo -e "\033[1;36mCurrent Xcode Configuration:\033[0m" | |
| echo " Before xcode-select: $(xcode-select -p 2>/dev/null || echo 'Not set')" | |
| # Ensure we're using the correct Xcode installation | |
| sudo xcode-select -s /Applications/Xcode.app | |
| echo " After xcode-select: $(xcode-select -p)" | |
| echo " Xcode Version: $(xcodebuild -version)" | |
| echo " Xcode Build Version: $(xcodebuild -version | tail -1)" | |
| echo -e "\033[1;36mSDK Information:\033[0m" | |
| echo " Available SDKs:" | |
| xcodebuild -showsdks | grep -E "(iOS|watchOS|macOS)" | head -10 | |
| echo -e "\033[1;34m========================================================\033[0m" | |
| - name: Install Simulator Runtimes (iOS & watchOS) | |
| run: | | |
| echo -e "\033[1;34m============ SIMULATOR RUNTIME SETUP DEBUG ============\033[0m" | |
| echo -e "\033[1;33mNote: Installing runtimes for debugging purposes - release builds use physical device targets\033[0m" | |
| echo -e "\033[1;36mInitial Runtime Analysis:\033[0m" | |
| echo " All available runtimes:" | |
| xcrun simctl list runtimes | cat -n | |
| echo -e "\033[1;36mRuntime Summary:\033[0m" | |
| echo " iOS Runtimes:" | |
| xcrun simctl list runtimes | grep "iOS" | while read -r line; do | |
| echo " $line" | |
| done | |
| echo " watchOS Runtimes:" | |
| xcrun simctl list runtimes | grep "watchOS" | while read -r line; do | |
| echo " $line" | |
| done | |
| echo -e "\033[1;33mChecking iOS Runtime Requirements (17+):\033[0m" | |
| if ! xcrun simctl list runtimes | grep -Eq "iOS (1[7-9]|[2-9][0-9])"; then | |
| echo -e "\033[1;31m No iOS 17+ runtime found - installing...\033[0m" | |
| echo " Downloading iOS platform..." | |
| xcodebuild -downloadPlatform iOS | |
| echo -e "\033[1;32m iOS platform download completed\033[0m" | |
| else | |
| echo -e "\033[1;32m iOS 17+ runtime already present\033[0m" | |
| xcrun simctl list runtimes | grep -E "iOS (1[7-9]|[2-9][0-9])" | while read -r line; do | |
| echo " Found: $line" | |
| done | |
| fi | |
| echo -e "\033[1;33mChecking watchOS Runtime Requirements (11+):\033[0m" | |
| if ! xcrun simctl list runtimes | grep -Eq "watchOS (1[1-9]|[2-9][0-9])"; then | |
| echo -e "\033[1;31m No watchOS 11+ runtime found - installing...\033[0m" | |
| echo " Downloading watchOS platform..." | |
| xcodebuild -downloadPlatform watchOS | |
| echo -e "\033[1;32m watchOS platform download completed\033[0m" | |
| else | |
| echo -e "\033[1;32m watchOS 11+ runtime already present\033[0m" | |
| xcrun simctl list runtimes | grep -E "watchOS (1[1-9]|[2-9][0-9])" | while read -r line; do | |
| echo " Found: $line" | |
| done | |
| fi | |
| echo -e "\033[1;36mFinal Runtime Analysis:\033[0m" | |
| echo " All runtimes after installation:" | |
| xcrun simctl list runtimes | cat -n | |
| echo -e "\033[1;36mDevice Analysis & Setup:\033[0m" | |
| echo " Current iOS devices:" | |
| xcrun simctl list devices iOS | cat -n | |
| echo -e "\033[1;33mChecking for available iPhone simulators:\033[0m" | |
| IPHONE_COUNT=$(xcrun simctl list devices iOS | grep -c "iPhone" || echo "0") | |
| echo " iPhone simulators found: $IPHONE_COUNT" | |
| if [ "$IPHONE_COUNT" -eq "0" ]; then | |
| echo -e "\033[1;31m No iPhone simulators found - creating one...\033[0m" | |
| # Get the latest iOS runtime available | |
| echo " Finding latest iOS runtime:" | |
| LATEST_IOS=$(xcrun simctl list runtimes | grep "iOS" | tail -1 | sed 's/.*iOS \([0-9.]*\).*/\1/') | |
| echo " Latest iOS version detected: $LATEST_IOS" | |
| if [ -n "$LATEST_IOS" ]; then | |
| RUNTIME_ID="com.apple.CoreSimulator.SimRuntime.iOS-${LATEST_IOS//./-}" | |
| DEVICE_TYPE="com.apple.CoreSimulator.SimDeviceType.iPhone-15" | |
| echo " Creating iPhone 15 simulator:" | |
| echo " Device Type: $DEVICE_TYPE" | |
| echo " Runtime ID: $RUNTIME_ID" | |
| if xcrun simctl create "iPhone 15" "$DEVICE_TYPE" "$RUNTIME_ID"; then | |
| echo -e "\033[1;32m Successfully created iPhone 15 with iOS $LATEST_IOS\033[0m" | |
| else | |
| echo -e "\033[1;33m Failed to create iPhone 15, trying iPhone 14...\033[0m" | |
| xcrun simctl create "iPhone 14" "com.apple.CoreSimulator.SimDeviceType.iPhone-14" "$RUNTIME_ID" || echo -e "\033[1;31m Failed to create any iPhone simulator\033[0m" | |
| fi | |
| else | |
| echo -e "\033[1;31m No iOS runtime available for device creation\033[0m" | |
| fi | |
| else | |
| echo -e "\033[1;32m iPhone simulators already available\033[0m" | |
| fi | |
| echo -e "\033[1;36mFinal Device Status:\033[0m" | |
| echo " All iOS devices:" | |
| xcrun simctl list devices iOS | cat -n | |
| echo -e "\033[1;36mDevice Type Analysis:\033[0m" | |
| echo " Available device types:" | |
| xcrun simctl list devicetypes | grep -i iphone | head -5 | |
| echo -e "\033[1;34m======================================================\033[0m" | |
| - name: Set Up Ruby | |
| uses: ruby/setup-ruby@v1 | |
| with: | |
| ruby-version: 3.4.8 | |
| - name: System Debug Information | |
| run: | | |
| echo -e "\033[1;34m================ SYSTEM DEBUG INFORMATION ================\033[0m" | |
| echo -e "\033[1;36mSystem Overview:\033[0m" | |
| echo " Hostname: $(hostname)" | |
| echo " User: $(whoami)" | |
| echo " Home: $HOME" | |
| echo " Shell: $SHELL" | |
| echo " PATH (first 5 entries):" | |
| echo "$PATH" | tr ':' '\n' | head -5 | sed 's/^/ /' | |
| echo -e "\033[1;36mDisk Space:\033[0m" | |
| df -h / | tail -1 | awk '{print " Available: " $4 " (" $5 " used)"}' | |
| echo -e "\033[1;36mMemory:\033[0m" | |
| vm_stat | grep "Pages free" | awk '{print " Free Pages: " $3}' | |
| echo -e "\033[1;36mPackage Managers:\033[0m" | |
| echo " Bundle version: $(bundle --version 2>/dev/null || echo 'Not available')" | |
| echo " NPM version: $(npm --version 2>/dev/null || echo 'Not available')" | |
| echo " CocoaPods version: $(pod --version 2>/dev/null || echo 'Not available')" | |
| echo -e "\033[1;36mEnvironment Variables (Build-related):\033[0m" | |
| env | grep -E "(GITHUB_|CI|RUNNER_|PROJECT_|NEW_BUILD)" | sort | head -10 | |
| echo -e "\033[1;34m========================================================\033[0m" | |
| - name: Install Dependencies with Bundler | |
| run: | | |
| bundle config path vendor/bundle | |
| bundle install --jobs 4 --retry 3 --quiet | |
| - name: Set default network | |
| run: ./scripts/set-network.sh signet | |
| - name: Install Node Modules | |
| run: npm ci --omit=dev --yes | |
| - name: Install CocoaPods Dependencies | |
| run: | | |
| bundle exec fastlane ios install_pods | |
| echo "CocoaPods dependencies installed successfully" | |
| - name: Generate Build Number Based on Timestamp | |
| id: generate_build_number | |
| run: | | |
| NEW_BUILD_NUMBER=$(date +%s) | |
| echo "NEW_BUILD_NUMBER=$NEW_BUILD_NUMBER" >> $GITHUB_ENV | |
| echo "build_number=$NEW_BUILD_NUMBER" >> $GITHUB_OUTPUT | |
| - name: Set Build Number | |
| run: bundle exec fastlane ios increment_build_number_lane | |
| - name: Determine Marketing Version | |
| id: determine_marketing_version | |
| run: | | |
| MARKETING_VERSION=$(grep MARKETING_VERSION BlueWallet.xcodeproj/project.pbxproj | awk -F '= ' '{print $2}' | tr -d ' ;' | head -1) | |
| echo "PROJECT_VERSION=$MARKETING_VERSION" >> $GITHUB_ENV | |
| echo "project_version=$MARKETING_VERSION" >> $GITHUB_OUTPUT | |
| working-directory: ios | |
| - name: Set Up Git Authentication | |
| env: | |
| ACCESS_TOKEN: ${{ secrets.GIT_ACCESS_TOKEN }} | |
| run: | | |
| git config --global credential.helper 'cache --timeout=3600' | |
| git config --global http.https://github.com/.extraheader "AUTHORIZATION: basic $(echo -n x-access-token:${ACCESS_TOKEN} | base64)" | |
| - name: Create Temporary Keychain | |
| run: bundle exec fastlane ios create_temp_keychain | |
| env: | |
| KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} | |
| - name: Setup Provisioning Profiles | |
| env: | |
| MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} | |
| GIT_ACCESS_TOKEN: ${{ secrets.GIT_ACCESS_TOKEN }} | |
| GIT_URL: ${{ secrets.GIT_URL }} | |
| ITC_TEAM_ID: ${{ secrets.ITC_TEAM_ID }} | |
| ITC_TEAM_NAME: ${{ secrets.ITC_TEAM_NAME }} | |
| KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} | |
| run: | | |
| bundle exec fastlane ios setup_provisioning_profiles | |
| - name: Build App (unsigned, non-master) | |
| if: github.ref != 'refs/heads/master' && github.ref != 'refs/heads/2025-12-03-redwallet' | |
| run: | | |
| cd ios && pod install | |
| mkdir -p build_logs | |
| xcodebuild -workspace BlueWallet.xcworkspace \ | |
| -scheme BlueWallet \ | |
| -configuration Release \ | |
| -sdk iphonesimulator \ | |
| -destination 'generic/platform=iOS Simulator' \ | |
| -derivedDataPath build \ | |
| CODE_SIGNING_ALLOWED=NO \ | |
| build 2>&1 | tee build_logs/xcodebuild.log | |
| - name: Upload unsigned app as artifact | |
| if: github.ref != 'refs/heads/master' && github.ref != 'refs/heads/2025-12-03-redwallet' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: BlueWallet-unsigned-simulator | |
| path: ios/build/Build/Products/Release-iphonesimulator/BlueWallet.app | |
| retention-days: 7 | |
| if-no-files-found: error | |
| - name: Upload build logs (non-master) | |
| if: always() && github.ref != 'refs/heads/master' && github.ref != 'refs/heads/2025-12-03-redwallet' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: build_logs_pr | |
| path: ios/build_logs/xcodebuild.log | |
| retention-days: 7 | |
| if-no-files-found: error | |
| - name: Build App | |
| id: build_app | |
| run: | | |
| echo -e "\033[1;34m==================== BUILD APP DEBUG ====================\033[0m" | |
| echo -e "\033[1;36mPre-Build Environment Check:\033[0m" | |
| echo " Working Directory: $(pwd)" | |
| echo " iOS Directory Contents:" | |
| ls -la ios/ || echo -e "\033[1;31m iOS directory not found\033[0m" | |
| echo -e "\033[1;36mBuild Configuration:\033[0m" | |
| echo " PROJECT_VERSION: ${PROJECT_VERSION:-'Not set'}" | |
| echo " NEW_BUILD_NUMBER: ${NEW_BUILD_NUMBER:-'Not set'}" | |
| echo " Build Type: Release (App Store)" | |
| echo -e "\033[1;33mXcode Project Analysis:\033[0m" | |
| if [ -f "ios/BlueWallet.xcworkspace" ]; then | |
| echo -e "\033[1;32m Workspace found: ios/BlueWallet.xcworkspace\033[0m" | |
| else | |
| echo -e "\033[1;31m Workspace missing: ios/BlueWallet.xcworkspace\033[0m" | |
| fi | |
| if [ -f "ios/export_options.plist" ]; then | |
| echo -e "\033[1;32m Export options found: ios/export_options.plist\033[0m" | |
| echo " Export options content:" | |
| cat ios/export_options.plist | head -20 | |
| else | |
| echo -e "\033[1;31m Export options missing: ios/export_options.plist\033[0m" | |
| fi | |
| echo -e "\033[1;33mAvailable Build Destinations:\033[0m" | |
| if [ -f "ios/BlueWallet.xcworkspace" ]; then | |
| xcodebuild -workspace ios/BlueWallet.xcworkspace -scheme BlueWallet -showdestinations 2>/dev/null | head -20 || echo -e "\033[1;31m Failed to get destinations\033[0m" | |
| fi | |
| echo -e "\033[1;35mStarting Fastlane Build (Release Mode):\033[0m" | |
| bundle exec fastlane ios build_app_lane | |
| echo -e "\033[1;36mPost-Build IPA Analysis:\033[0m" | |
| echo " Searching for IPA files..." | |
| find ./ios -name "*.ipa" -type f 2>/dev/null | while read -r ipa; do | |
| echo " Found IPA: $ipa" | |
| echo " Size: $(ls -lh "$ipa" | awk '{print $5}')" | |
| echo " Modified: $(ls -l "$ipa" | awk '{print $6, $7, $8}')" | |
| done | |
| # Ensure IPA path is set for subsequent steps | |
| if [ -f "./ios/build/ipa_path.txt" ]; then | |
| IPA_PATH=$(cat ./ios/build/ipa_path.txt) | |
| echo -e "\033[1;32m IPA path from file: $IPA_PATH\033[0m" | |
| echo "IPA_OUTPUT_PATH=$IPA_PATH" >> $GITHUB_ENV | |
| echo "ipa_output_path=$IPA_PATH" >> $GITHUB_OUTPUT | |
| else | |
| echo -e "\033[1;33m ipa_path.txt not found, searching manually...\033[0m" | |
| IPA_PATH=$(find ./ios -name "*.ipa" | head -n 1) | |
| if [ -n "$IPA_PATH" ]; then | |
| echo -e "\033[1;32m IPA found manually: $IPA_PATH\033[0m" | |
| echo "IPA_OUTPUT_PATH=$IPA_PATH" >> $GITHUB_ENV | |
| echo "ipa_output_path=$IPA_PATH" >> $GITHUB_OUTPUT | |
| else | |
| echo -e "\033[1;31m No IPA file found anywhere\033[0m" | |
| echo -e "\033[1;33m Directory structure for debugging:\033[0m" | |
| find ./ios -type f -name "*.xcarchive" -o -name "*.ipa" -o -name "build_logs" 2>/dev/null || echo " No build artifacts found" | |
| exit 1 | |
| fi | |
| fi | |
| echo -e "\033[1;32mBuild Summary:\033[0m" | |
| echo " Final IPA Path: ${IPA_OUTPUT_PATH:-'Not set'}" | |
| if [ -n "${IPA_OUTPUT_PATH}" ] && [ -f "${IPA_OUTPUT_PATH}" ]; then | |
| echo -e "\033[1;32m IPA file exists and is ready for release\033[0m" | |
| echo " File info: $(ls -lh "${IPA_OUTPUT_PATH}")" | |
| fi | |
| echo -e "\033[1;34m========================================================\033[0m" | |
| - name: Debug Build Failure | |
| if: failure() | |
| run: | | |
| echo -e "\033[1;31m================== BUILD FAILURE DEBUG ==================\033[0m" | |
| echo -e "\033[1;31mBuild failure analysis initiated...\033[0m" | |
| echo -e "\033[1;36mProject Structure Analysis:\033[0m" | |
| echo " iOS directory contents:" | |
| ls -la ios/ 2>/dev/null || echo -e "\033[1;31m iOS directory not accessible\033[0m" | |
| echo " Build directory contents:" | |
| if [ -d "ios/build" ]; then | |
| find ios/build -type f -name "*.log" -o -name "*.ipa" -o -name "*.xcarchive" | head -10 | |
| else | |
| echo -e "\033[1;31m ios/build directory does not exist\033[0m" | |
| fi | |
| echo -e "\033[1;36mBuild Logs Analysis:\033[0m" | |
| if [ -d "ios/build_logs" ]; then | |
| echo " Build logs directory contents:" | |
| ls -la ios/build_logs/ | head -10 | |
| echo " Recent log files (last 50 lines each):" | |
| find ios/build_logs -name "*.log" -type f | head -3 | while read -r logfile; do | |
| echo " === $logfile ===" | |
| tail -50 "$logfile" 2>/dev/null | head -20 | |
| echo " === End of $logfile ===" | |
| done | |
| else | |
| echo -e "\033[1;31m No build logs directory found\033[0m" | |
| fi | |
| echo -e "\033[1;36mXcode Build System Analysis:\033[0m" | |
| echo " Recent archives:" | |
| find ~/Library/Developer/Xcode/Archives -name "*.xcarchive" -type d 2>/dev/null | tail -3 || echo " No archives found" | |
| echo " Derived data contents:" | |
| find ~/Library/Developer/Xcode/DerivedData -maxdepth 2 -name "*BlueWallet*" 2>/dev/null | head -5 || echo " No derived data found" | |
| echo -e "\033[1;36mFinal Simulator State:\033[0m" | |
| echo " Available runtimes:" | |
| xcrun simctl list runtimes | grep -E "(iOS|watchOS)" | tail -5 | |
| echo " Available devices:" | |
| xcrun simctl list devices iOS | head -10 | |
| echo -e "\033[1;36mSystem State:\033[0m" | |
| echo " Disk space:" | |
| df -h / | tail -1 | |
| echo " Memory usage:" | |
| vm_stat | grep -E "(Pages free|Pages active)" | head -2 | |
| echo -e "\033[1;31m========================================================\033[0m" | |
| - name: Upload Bugsnag Sourcemaps | |
| if: success() | |
| run: bundle exec fastlane ios upload_bugsnag_sourcemaps | |
| env: | |
| BUGSNAG_API_KEY: ${{ secrets.BUGSNAG_API_KEY }} | |
| BUGSNAG_RELEASE_STAGE: production | |
| PROJECT_VERSION: ${{ env.PROJECT_VERSION }} | |
| NEW_BUILD_NUMBER: ${{ env.NEW_BUILD_NUMBER }} | |
| - name: Upload Build Logs | |
| if: always() | |
| uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6 | |
| with: | |
| name: build_logs | |
| path: ./ios/build_logs/ | |
| retention-days: 7 | |
| if-no-files-found: warn | |
| - name: Verify IPA File Before Upload | |
| run: | | |
| echo "Checking IPA file at: $IPA_OUTPUT_PATH" | |
| if [ -f "$IPA_OUTPUT_PATH" ]; then | |
| echo "✅ IPA file exists" | |
| ls -la "$IPA_OUTPUT_PATH" | |
| else | |
| echo "❌ IPA file not found at: $IPA_OUTPUT_PATH" | |
| echo "Current directory contents:" | |
| find ./ios -name "*.ipa" | |
| exit 1 | |
| fi | |
| - name: Upload IPA as Artifact | |
| if: success() | |
| uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6 | |
| with: | |
| name: BlueWallet_IPA | |
| path: ${{ env.IPA_OUTPUT_PATH }} | |
| retention-days: 7 | |
| - name: Delete Temporary Keychain | |
| if: always() | |
| run: bundle exec fastlane ios delete_temp_keychain | |
| testflight-upload: | |
| needs: build | |
| runs-on: macos-26 | |
| if: github.event_name == 'push' || contains(github.event.pull_request.labels.*.name, 'testflight') | |
| env: | |
| APPLE_ID: ${{ secrets.APPLE_ID }} | |
| NEW_BUILD_NUMBER: ${{ needs.build.outputs.new_build_number }} | |
| PROJECT_VERSION: ${{ needs.build.outputs.project_version }} | |
| LATEST_COMMIT_MESSAGE: ${{ needs.build.outputs.latest_commit_message }} | |
| BRANCH_NAME: ${{ needs.build.outputs.branch_name }} | |
| steps: | |
| - name: Checkout Project | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - name: Set Up Ruby | |
| uses: ruby/setup-ruby@v1 | |
| with: | |
| ruby-version: 3.4.8 | |
| - name: Install Dependencies with Bundler | |
| run: | | |
| bundle config path vendor/bundle | |
| bundle install --jobs 4 --retry 3 --quiet | |
| - name: Download IPA from Artifact | |
| uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5 | |
| with: | |
| name: BlueWallet_IPA | |
| path: ./ | |
| - name: Create App Store Connect API Key JSON | |
| run: echo '${{ secrets.APP_STORE_CONNECT_API_KEY_CONTENT }}' > ./appstore_api_key.json | |
| - name: Set IPA Path Environment Variable | |
| run: echo "IPA_OUTPUT_PATH=$(pwd)/BlueWallet_${{ needs.build.outputs.project_version }}_${{ needs.build.outputs.new_build_number }}.ipa" >> $GITHUB_ENV | |
| - name: Verify IPA Path Before Upload | |
| run: | | |
| if [ ! -f "$IPA_OUTPUT_PATH" ]; then | |
| echo "❌ IPA file not found at path: $IPA_OUTPUT_PATH" | |
| ls -la $(pwd) | |
| exit 1 | |
| else | |
| echo "✅ Found IPA at: $IPA_OUTPUT_PATH" | |
| fi | |
| - name: Print Environment Variables for Debugging | |
| run: | | |
| echo "LATEST_COMMIT_MESSAGE: $LATEST_COMMIT_MESSAGE" | |
| echo "BRANCH_NAME: $BRANCH_NAME" | |
| echo "PROJECT_VERSION: $PROJECT_VERSION" | |
| echo "NEW_BUILD_NUMBER: $NEW_BUILD_NUMBER" | |
| echo "IPA_OUTPUT_PATH: $IPA_OUTPUT_PATH" | |
| - name: Upload to TestFlight | |
| run: bundle exec fastlane ios upload_to_testflight_lane | |
| env: | |
| APP_STORE_CONNECT_API_KEY_PATH: $(pwd)/appstore_api_key.p8 | |
| MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} | |
| GIT_ACCESS_TOKEN: ${{ secrets.GIT_ACCESS_TOKEN }} | |
| GIT_URL: ${{ secrets.GIT_URL }} | |
| ITC_TEAM_ID: ${{ secrets.ITC_TEAM_ID }} | |
| ITC_TEAM_NAME: ${{ secrets.ITC_TEAM_NAME }} | |
| APP_STORE_CONNECT_API_KEY_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_KEY_ID }} | |
| APP_STORE_CONNECT_API_KEY_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ISSUER_ID }} | |
| KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} | |
| - name: Post PR Comment | |
| if: success() && github.event_name == 'pull_request' | |
| uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7 | |
| env: | |
| BUILD_NUMBER: ${{ needs.build.outputs.new_build_number }} | |
| PROJECT_VERSION: ${{ needs.build.outputs.project_version }} | |
| LATEST_COMMIT_MESSAGE: ${{ needs.build.outputs.latest_commit_message }} | |
| with: | |
| script: | | |
| const buildNumber = process.env.BUILD_NUMBER; | |
| const version = process.env.PROJECT_VERSION; | |
| const message = `✅ Build ${version} (${buildNumber}) has been uploaded to TestFlight and will be available for testing soon.`; | |
| const prNumber = context.payload.pull_request.number; | |
| const repo = context.repo; | |
| github.rest.issues.createComment({ | |
| ...repo, | |
| issue_number: prNumber, | |
| body: message, | |
| }); |