From bb6eb1eca31f6889608414157ed51dfdbd3f2df6 Mon Sep 17 00:00:00 2001 From: Borislav Grigorov <11405770+bsgrigorov@users.noreply.github.com> Date: Tue, 5 May 2026 15:14:26 -0700 Subject: [PATCH 1/2] chore(INFRA-3591): temp Bitrise iOS KV cache workflow + runners monitoring (POC) Co-authored-by: Cursor --- .github/actionlint.yaml | 4 + .github/workflows/run-e2e-smoke-tests-ios.yml | 17 + .github/workflows/run-e2e-workflow.yml | 35 +- .github/workflows/temp-bitrise-ios-kv.yml | 361 ++++++++++++++++++ 4 files changed, 416 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/temp-bitrise-ios-kv.yml diff --git a/.github/actionlint.yaml b/.github/actionlint.yaml index 39f1b05384f..e42ac72ab43 100644 --- a/.github/actionlint.yaml +++ b/.github/actionlint.yaml @@ -15,6 +15,10 @@ self-hosted-runner: - "ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-lg" - "ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-xl" - "low-priority" + # Bitrise GHA runner pool labels (self-hosted runner group temp-bitrise-runners) + - "bitrise_pool_name:DemoFA" + - "bitrise_pool_name:DemoFAL" + - "bitrise_pool_name:DemoFAXL" # Configuration variables in array of strings defined in your repository or # organization. `null` means disabling configuration variables check. diff --git a/.github/workflows/run-e2e-smoke-tests-ios.yml b/.github/workflows/run-e2e-smoke-tests-ios.yml index 05b82e8bf05..ebf496adb50 100644 --- a/.github/workflows/run-e2e-smoke-tests-ios.yml +++ b/.github/workflows/run-e2e-smoke-tests-ios.yml @@ -13,6 +13,11 @@ on: required: false type: string default: '' + use_bitrise_runner: + description: "Route iOS E2E jobs to Bitrise self-hosted runner group." + required: false + type: boolean + default: false permissions: contents: read @@ -35,6 +40,7 @@ jobs: changed_files: ${{ inputs.changed_files }} build_type: 'main' metamask_environment: 'qa' + use_bitrise_runner: ${{ inputs.use_bitrise_runner }} secrets: inherit swap-ios-smoke: @@ -53,6 +59,7 @@ jobs: changed_files: ${{ inputs.changed_files }} build_type: 'main' metamask_environment: 'qa' + use_bitrise_runner: ${{ inputs.use_bitrise_runner }} secrets: inherit stake-ios-smoke: @@ -89,6 +96,7 @@ jobs: changed_files: ${{ inputs.changed_files }} build_type: 'main' metamask_environment: 'qa' + use_bitrise_runner: ${{ inputs.use_bitrise_runner }} secrets: inherit wallet-platform-ios-smoke: @@ -125,6 +133,7 @@ jobs: changed_files: ${{ inputs.changed_files }} build_type: 'main' metamask_environment: 'qa' + use_bitrise_runner: ${{ inputs.use_bitrise_runner }} secrets: inherit accounts-ios-smoke: @@ -143,6 +152,7 @@ jobs: changed_files: ${{ inputs.changed_files }} build_type: 'main' metamask_environment: 'qa' + use_bitrise_runner: ${{ inputs.use_bitrise_runner }} secrets: inherit network-abstraction-ios-smoke: @@ -161,6 +171,7 @@ jobs: changed_files: ${{ inputs.changed_files }} build_type: 'main' metamask_environment: 'qa' + use_bitrise_runner: ${{ inputs.use_bitrise_runner }} secrets: inherit network-expansion-ios-smoke: @@ -179,6 +190,7 @@ jobs: changed_files: ${{ inputs.changed_files }} build_type: 'main' metamask_environment: 'qa' + use_bitrise_runner: ${{ inputs.use_bitrise_runner }} secrets: inherit prediction-market-ios-smoke: @@ -197,6 +209,7 @@ jobs: changed_files: ${{ inputs.changed_files }} build_type: 'main' metamask_environment: 'qa' + use_bitrise_runner: ${{ inputs.use_bitrise_runner }} secrets: inherit money-ios-smoke: @@ -233,6 +246,7 @@ jobs: changed_files: ${{ inputs.changed_files }} build_type: 'main' metamask_environment: 'qa' + use_bitrise_runner: ${{ inputs.use_bitrise_runner }} secrets: inherit seedless-onboarding-ios-smoke: @@ -251,6 +265,7 @@ jobs: changed_files: ${{ inputs.changed_files }} build_type: 'main' metamask_environment: 'qa' + use_bitrise_runner: ${{ inputs.use_bitrise_runner }} secrets: inherit browser-ios-smoke: @@ -269,6 +284,7 @@ jobs: changed_files: ${{ inputs.changed_files }} build_type: 'main' metamask_environment: 'qa' + use_bitrise_runner: ${{ inputs.use_bitrise_runner }} secrets: inherit snaps-ios-smoke: @@ -287,6 +303,7 @@ jobs: changed_files: ${{ inputs.changed_files }} build_type: 'main' metamask_environment: 'qa' + use_bitrise_runner: ${{ inputs.use_bitrise_runner }} secrets: inherit report-ios-smoke-tests: diff --git a/.github/workflows/run-e2e-workflow.yml b/.github/workflows/run-e2e-workflow.yml index cf7e218be2a..b24c8009f94 100644 --- a/.github/workflows/run-e2e-workflow.yml +++ b/.github/workflows/run-e2e-workflow.yml @@ -53,11 +53,16 @@ on: required: false type: string default: 'main-' + use_bitrise_runner: + description: 'Route iOS E2E jobs to Bitrise self-hosted runner group.' + required: false + type: boolean + default: false jobs: test-e2e-mobile: name: ${{ inputs.test-suite-name }} - runs-on: ${{ inputs.platform == 'ios' && 'ghcr.io/cirruslabs/macos-runner:tahoe' || 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-lg' }} + runs-on: ${{ inputs.platform == 'ios' && (inputs.use_bitrise_runner && fromJSON('{"group":"temp-bitrise-runners","labels":["bitrise_pool_name:DemoFAL"]}') || 'ghcr.io/cirruslabs/macos-runner:tahoe') || 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-lg' }} outputs: apk-target-path: ${{ steps.determine-target-paths.outputs.apk-target-path }} test-apk-target-path: ${{ steps.determine-target-paths.outputs.test-apk-target-path }} @@ -102,6 +107,34 @@ jobs: - name: Checkout uses: actions/checkout@v6 + # TEMPORARY: Bitrise runners use Vagrant (user=vagrant, HOME=/Users/vagrant). + # GitHub Actions tools hardcode /Users/runner paths, so create the symlink. + - name: Fix Vagrant environment paths (Bitrise runners) + if: ${{ inputs.use_bitrise_runner && inputs.platform == 'ios' }} + run: | + if [ -L /Users/runner ]; then + current_target="$(readlink /Users/runner)" + if [ "$current_target" = "/Users/vagrant" ]; then + echo "Symlink already correct: /Users/runner -> /Users/vagrant" + else + echo "Replacing incorrect symlink /Users/runner -> $current_target" + sudo rm /Users/runner + sudo ln -s /Users/vagrant /Users/runner + echo "Recreated symlink: /Users/runner -> /Users/vagrant" + fi + elif [ -e /Users/runner ]; then + echo "Error: /Users/runner exists but is not a symlink" + ls -ld /Users/runner + exit 1 + else + sudo ln -s /Users/vagrant /Users/runner + echo "Created symlink /Users/runner -> /Users/vagrant" + fi + mkdir -p "$HOME/hostedtoolcache" "$HOME/tmp" + echo "RUNNER_TOOL_CACHE=$HOME/hostedtoolcache" >> "$GITHUB_ENV" + echo "RUNNER_TEMP=$HOME/tmp" >> "$GITHUB_ENV" + shell: bash + - name: Restore .metamask folder uses: actions/cache@v4 with: diff --git a/.github/workflows/temp-bitrise-ios-kv.yml b/.github/workflows/temp-bitrise-ios-kv.yml new file mode 100644 index 00000000000..d2fe8754d23 --- /dev/null +++ b/.github/workflows/temp-bitrise-ios-kv.yml @@ -0,0 +1,361 @@ +name: "[TEMP] Bitrise iOS KV cache POC" + +# TEMPORARY WORKFLOW for INFRA-3591 +# Purpose: KV cache POC — GitHub Actions cache (actions/cache) for Xcode/DerivedData + iOS app on Bitrise runners. +# This workflow is not part of the CI gate and should be removed after the POC. +# +# Triggers: workflow_dispatch (Actions tab — pick branch under "Use workflow from"), +# pull_request (label bitrise-poc), and hourly schedule (:30 UTC, staggered from temp-bitrise-ios-rn.yml). + +on: + workflow_dispatch: + pull_request: + types: [ labeled, synchronize ] + schedule: + - cron: "30 * * * *" + +concurrency: + group: bitrise-ios-kv-${{ github.head_ref || github.ref }} + cancel-in-progress: true + +permissions: + contents: read + id-token: write + +jobs: + build-ios-on-bitrise: + name: Build iOS E2E App (KV cache) + if: >- + github.event_name != 'pull_request' || + (contains(github.event.pull_request.labels.*.name, 'bitrise-poc') && + !github.event.pull_request.head.repo.fork) + runs-on: + group: temp-bitrise-runners + labels: [ "bitrise_pool_name:DemoFAXL" ] + timeout-minutes: 60 + outputs: + artifacts-url: ${{ steps.set-artifacts-url.outputs.artifacts-url }} + env: + XCODE_CACHE_VERSION: 1 + IOS_APP_CACHE_VERSION: 2 + RCT_NO_LAUNCH_PACKAGER: 1 + XCODE_BUILD_SETTINGS: "COMPILER_INDEX_STORE_ENABLE=NO" + GITHUB_CI: "true" + PLATFORM: ios + METAMASK_ENVIRONMENT: qa + METAMASK_BUILD_TYPE: main + IS_TEST: true + E2E: "true" + IGNORE_BOXLOGS_DEVELOPMENT: true + CI: "true" + NODE_OPTIONS: "--max-old-space-size=8192" + BRIDGE_USE_DEV_APIS: "true" + RAMP_INTERNAL_BUILD: "true" + SEEDLESS_ONBOARDING_ENABLED: "true" + MM_NOTIFICATIONS_UI_ENABLED: "true" + MM_SECURITY_ALERTS_API_ENABLED: "true" + YARN_ENABLE_GLOBAL_CACHE: "true" + FEATURES_ANNOUNCEMENTS_ACCESS_TOKEN: ${{ secrets.FEATURES_ANNOUNCEMENTS_ACCESS_TOKEN }} + FEATURES_ANNOUNCEMENTS_SPACE_ID: ${{ secrets.FEATURES_ANNOUNCEMENTS_SPACE_ID }} + SEGMENT_WRITE_KEY_QA: ${{ secrets.SEGMENT_WRITE_KEY_QA }} + SEGMENT_PROXY_URL_QA: ${{ secrets.SEGMENT_PROXY_URL_QA }} + SEGMENT_DELETE_API_SOURCE_ID_QA: ${{ secrets.SEGMENT_DELETE_API_SOURCE_ID_QA }} + SEGMENT_REGULATIONS_ENDPOINT_QA: ${{ secrets.SEGMENT_REGULATIONS_ENDPOINT_QA }} + MM_SENTRY_DSN_TEST: ${{ secrets.MM_SENTRY_DSN_TEST }} + MM_SENTRY_AUTH_TOKEN: ${{ secrets.MM_SENTRY_AUTH_TOKEN }} + MAIN_IOS_GOOGLE_CLIENT_ID_UAT: ${{ secrets.MAIN_IOS_GOOGLE_CLIENT_ID_UAT }} + MAIN_IOS_GOOGLE_REDIRECT_URI_UAT: ${{ secrets.MAIN_IOS_GOOGLE_REDIRECT_URI_UAT }} + MAIN_ANDROID_APPLE_CLIENT_ID_UAT: ${{ secrets.MAIN_ANDROID_APPLE_CLIENT_ID_UAT }} + MAIN_ANDROID_GOOGLE_CLIENT_ID_UAT: ${{ secrets.MAIN_ANDROID_GOOGLE_CLIENT_ID_UAT }} + MAIN_ANDROID_GOOGLE_SERVER_CLIENT_ID_UAT: ${{ secrets.MAIN_ANDROID_GOOGLE_SERVER_CLIENT_ID_UAT }} + GOOGLE_SERVICES_B64_IOS: ${{ secrets.GOOGLE_SERVICES_B64_IOS }} + GOOGLE_SERVICES_B64_ANDROID: ${{ secrets.GOOGLE_SERVICES_B64_ANDROID }} + MM_INFURA_PROJECT_ID: ${{ secrets.MM_INFURA_PROJECT_ID }} + MM_PREDICT_GTM_MODAL_ENABLED: "false" + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Print runner environment diagnostics + run: | + echo "=== Runner Diagnostics ===" + echo "Runner OS: ${{ runner.os }}" + echo "Runner Arch: ${{ runner.arch }}" + echo "macOS version: $(sw_vers -productVersion)" + echo "Memory: $(sysctl -n hw.memsize | awk '{print $1/1024/1024/1024 " GB"}')" + echo "Disk free: $(df -h / | tail -1 | awk '{print $4}')" + echo "CPU cores: $(sysctl -n hw.ncpu)" + echo "=== Xcode ===" + xcode-select -p 2>/dev/null | sed "s|$HOME|~|g" || echo "No Xcode selected" + xcodebuild -version 2>/dev/null | head -2 || echo "xcodebuild not available" + echo "=== Ruby ===" + ruby --version 2>/dev/null || echo "No ruby" + echo "=== Node ===" + node --version 2>/dev/null || echo "No node" + shell: bash + + - name: Fix Vagrant environment paths + run: | + if [ -L /Users/runner ]; then + current_target="$(readlink /Users/runner)" + if [ "$current_target" = "/Users/vagrant" ]; then + echo "Symlink already correct: /Users/runner -> /Users/vagrant" + else + echo "Replacing incorrect symlink /Users/runner -> $current_target" + sudo rm /Users/runner + sudo ln -s /Users/vagrant /Users/runner + echo "Recreated symlink: /Users/runner -> /Users/vagrant" + fi + elif [ -e /Users/runner ]; then + echo "Error: /Users/runner exists but is not a symlink" + ls -ld /Users/runner + exit 1 + else + sudo ln -s /Users/vagrant /Users/runner + echo "Created symlink: /Users/runner -> /Users/vagrant" + fi + mkdir -p "$HOME/hostedtoolcache" "$HOME/tmp" + echo "RUNNER_TOOL_CACHE=$HOME/hostedtoolcache" >> "$GITHUB_ENV" + echo "RUNNER_TEMP=$HOME/tmp" >> "$GITHUB_ENV" + shell: bash + + - name: Restore Xcode derived data from branch cache + id: xcode-restore-cache + uses: actions/cache@v4 + with: + path: | + ~/Library/Developer/Xcode/DerivedData + ios/build + key: bitrise-${{ runner.os }}-xcode-${{ github.ref_name }}-${{ + env.XCODE_CACHE_VERSION }}-${{ hashFiles('ios/**/*.{h,m,mm,swift}', + 'ios/**/Podfile.lock', 'yarn.lock') }} + + - name: Restore Xcode derived data from main cache + if: ${{ steps.xcode-restore-cache.outputs.cache-hit != 'true' && github.ref_name + != 'main' }} + id: xcode-restore-cache-main + uses: actions/cache/restore@v4 + with: + path: | + ~/Library/Developer/Xcode/DerivedData + ios/build + key: bitrise-${{ runner.os }}-xcode-main-${{ env.XCODE_CACHE_VERSION }}-${{ + hashFiles('ios/**/*.{h,m,mm,swift}', 'ios/**/Podfile.lock', + 'yarn.lock') }} + + - name: Installing iOS Environment Setup + timeout-minutes: 15 + uses: ./.github/actions/setup-e2e-env + with: + platform: ios + setup-simulator: false + configure-keystores: false + + - name: Print iOS tool versions + run: | + echo "Node.js Version: $(node -v || echo 'not found')" + echo "Yarn Version: $(yarn -v || echo 'not found')" + echo "CocoaPods Version: $(pod --version || echo 'not found')" + echo "Xcode Path: $(xcode-select -p || echo 'not found')" + echo "Ruby Version: $(ruby --version || echo 'not found')" + echo "Booted iOS Simulators:" + xcrun simctl list | grep Booted || echo "No booted simulators found" + shell: bash + + - name: Clean iOS plist files + run: find ios -name "*.plist" -exec xattr -c {} \; + + - name: Restore .metamask folder + id: restore-metamask + uses: actions/cache@v4 + with: + path: .metamask + key: .metamask-${{ hashFiles('package.json', 'yarn.lock') }} + + - name: Install Foundry if cache missed + if: steps.restore-metamask.outputs.cache-hit != 'true' + run: yarn install:foundryup + + - name: Setup project dependencies with retry + uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2 + with: + timeout_minutes: 10 + max_attempts: 3 + retry_wait_seconds: 30 + command: | + echo "Setting up project..." + yarn setup:github-ci --build-ios --no-build-android + + - name: Generate current fingerprint + id: generate-fingerprint + run: | + FINGERPRINT=$(yarn fingerprint:generate) + echo "fingerprint=$FINGERPRINT" >> "$GITHUB_OUTPUT" + echo "Current fingerprint: ${FINGERPRINT}" + + - name: Restore iOS app matching fingerprint from branch cache + id: cache-restore + uses: actions/cache@v4 + with: + path: ios/build/Build/Products/Release-iphonesimulator/MetaMask.app + key: bitrise-ios-app-${{ github.ref_name }}-v${{ env.IOS_APP_CACHE_VERSION + }}-${{ steps.generate-fingerprint.outputs.fingerprint }} + + - name: Restore iOS app matching fingerprint from main cache + if: ${{ steps.cache-restore.outputs.cache-hit != 'true' && github.ref_name != + 'main' }} + id: cache-restore-main + uses: actions/cache/restore@v4 + with: + path: ios/build/Build/Products/Release-iphonesimulator/MetaMask.app + key: bitrise-ios-app-main-v${{ env.IOS_APP_CACHE_VERSION }}-${{ + steps.generate-fingerprint.outputs.fingerprint }} + + - name: Build iOS E2E App + if: ${{ steps.cache-restore.outputs.cache-hit != 'true' && + steps.cache-restore-main.outputs.cache-hit != 'true' }} + run: | + echo "Building iOS E2E App on Bitrise runner with KV cache only..." + yarn build:ios:main:e2e + shell: bash + env: + PLATFORM: ios + METAMASK_ENVIRONMENT: qa + METAMASK_BUILD_TYPE: main + IS_TEST: true + IS_SIM_BUILD: "true" + IGNORE_BOXLOGS_DEVELOPMENT: true + GITHUB_CI: "true" + CI: "true" + SEGMENT_WRITE_KEY_QA: ${{ secrets.SEGMENT_WRITE_KEY_QA }} + SEGMENT_PROXY_URL_QA: ${{ secrets.SEGMENT_PROXY_URL_QA }} + SEGMENT_DELETE_API_SOURCE_ID_QA: ${{ secrets.SEGMENT_DELETE_API_SOURCE_ID_QA }} + SEGMENT_REGULATIONS_ENDPOINT_QA: ${{ secrets.SEGMENT_REGULATIONS_ENDPOINT_QA }} + MM_SENTRY_DSN_TEST: ${{ secrets.MM_SENTRY_DSN_TEST }} + MM_SENTRY_AUTH_TOKEN: ${{ secrets.MM_SENTRY_AUTH_TOKEN }} + MAIN_IOS_GOOGLE_CLIENT_ID_UAT: ${{ secrets.MAIN_IOS_GOOGLE_CLIENT_ID_UAT }} + MAIN_IOS_GOOGLE_REDIRECT_URI_UAT: ${{ secrets.MAIN_IOS_GOOGLE_REDIRECT_URI_UAT }} + MAIN_ANDROID_APPLE_CLIENT_ID_UAT: ${{ secrets.MAIN_ANDROID_APPLE_CLIENT_ID_UAT }} + MAIN_ANDROID_GOOGLE_CLIENT_ID_UAT: ${{ secrets.MAIN_ANDROID_GOOGLE_CLIENT_ID_UAT }} + MAIN_ANDROID_GOOGLE_SERVER_CLIENT_ID_UAT: ${{ secrets.MAIN_ANDROID_GOOGLE_SERVER_CLIENT_ID_UAT }} + GOOGLE_SERVICES_B64_IOS: ${{ secrets.GOOGLE_SERVICES_B64_IOS }} + GOOGLE_SERVICES_B64_ANDROID: ${{ secrets.GOOGLE_SERVICES_B64_ANDROID }} + + - name: Repack iOS app with JS updates + if: ${{ steps.cache-restore.outputs.cache-hit == 'true' || + steps.cache-restore-main.outputs.cache-hit == 'true' }} + run: | + echo "Repacking iOS app with updated JavaScript bundle..." + yarn build:repack:ios + echo "Final app size: $(du -sh "ios/build/Build/Products/Release-iphonesimulator/MetaMask.app" | cut -f1)" + env: + PLATFORM: ios + METAMASK_ENVIRONMENT: qa + METAMASK_BUILD_TYPE: main + IS_TEST: true + E2E: "true" + IGNORE_BOXLOGS_DEVELOPMENT: true + GITHUB_CI: "true" + CI: "true" + NODE_OPTIONS: "--max-old-space-size=8192" + BRIDGE_USE_DEV_APIS: "true" + RAMP_INTERNAL_BUILD: "true" + SEEDLESS_ONBOARDING_ENABLED: "true" + MM_NOTIFICATIONS_UI_ENABLED: "true" + MM_SECURITY_ALERTS_API_ENABLED: "true" + FEATURES_ANNOUNCEMENTS_ACCESS_TOKEN: ${{ secrets.FEATURES_ANNOUNCEMENTS_ACCESS_TOKEN }} + FEATURES_ANNOUNCEMENTS_SPACE_ID: ${{ secrets.FEATURES_ANNOUNCEMENTS_SPACE_ID }} + SEGMENT_WRITE_KEY_QA: ${{ secrets.SEGMENT_WRITE_KEY_QA }} + SEGMENT_PROXY_URL_QA: ${{ secrets.SEGMENT_PROXY_URL_QA }} + SEGMENT_DELETE_API_SOURCE_ID_QA: ${{ secrets.SEGMENT_DELETE_API_SOURCE_ID_QA }} + SEGMENT_REGULATIONS_ENDPOINT_QA: ${{ secrets.SEGMENT_REGULATIONS_ENDPOINT_QA }} + MM_SENTRY_DSN_TEST: ${{ secrets.MM_SENTRY_DSN_TEST }} + MM_SENTRY_AUTH_TOKEN: ${{ secrets.MM_SENTRY_AUTH_TOKEN }} + MAIN_IOS_GOOGLE_CLIENT_ID_UAT: ${{ secrets.MAIN_IOS_GOOGLE_CLIENT_ID_UAT }} + MAIN_IOS_GOOGLE_REDIRECT_URI_UAT: ${{ secrets.MAIN_IOS_GOOGLE_REDIRECT_URI_UAT }} + MAIN_ANDROID_APPLE_CLIENT_ID_UAT: ${{ secrets.MAIN_ANDROID_APPLE_CLIENT_ID_UAT }} + MAIN_ANDROID_GOOGLE_CLIENT_ID_UAT: ${{ secrets.MAIN_ANDROID_GOOGLE_CLIENT_ID_UAT }} + MAIN_ANDROID_GOOGLE_SERVER_CLIENT_ID_UAT: ${{ secrets.MAIN_ANDROID_GOOGLE_SERVER_CLIENT_ID_UAT }} + GOOGLE_SERVICES_B64_IOS: ${{ secrets.GOOGLE_SERVICES_B64_IOS }} + GOOGLE_SERVICES_B64_ANDROID: ${{ secrets.GOOGLE_SERVICES_B64_ANDROID }} + MM_INFURA_PROJECT_ID: ${{ secrets.MM_INFURA_PROJECT_ID }} + + - name: Fix iOS bundle executable case and permissions before upload + run: | + APP_PATH="ios/build/Build/Products/Release-iphonesimulator/MetaMask.app" + BUNDLE_EXEC=$(/usr/libexec/PlistBuddy -c "Print CFBundleExecutable" "$APP_PATH/Info.plist" 2>/dev/null) + if [ -z "$BUNDLE_EXEC" ]; then + echo "Could not read CFBundleExecutable from Info.plist" + exit 1 + fi + ACTUAL_PATH=$(find "$APP_PATH" -maxdepth 1 -iname "$BUNDLE_EXEC" -type f | head -1) + if [ -z "$ACTUAL_PATH" ]; then + echo "Bundle executable not found: $BUNDLE_EXEC" + exit 1 + fi + if [ "$(basename "$ACTUAL_PATH")" != "$BUNDLE_EXEC" ]; then + mv "$ACTUAL_PATH" "$APP_PATH/${BUNDLE_EXEC}_fix" + mv "$APP_PATH/${BUNDLE_EXEC}_fix" "$APP_PATH/$BUNDLE_EXEC" + fi + chmod +x "$APP_PATH/$BUNDLE_EXEC" + shell: bash + + - name: Upload iOS APP Artifact (Simulator) + id: upload-app + uses: actions/upload-artifact@v4 + with: + name: main-qa-MetaMask.app + path: ios/build/Build/Products/Release-iphonesimulator/MetaMask.app + retention-days: 7 + if-no-files-found: error + + - name: Upload iOS Source Map + id: upload-sourcemap + if: ${{ steps.cache-restore.outputs.cache-hit == 'true' || + steps.cache-restore-main.outputs.cache-hit == 'true' }} + uses: actions/upload-artifact@v4 + with: + name: main-qa-index.js.map + path: sourcemaps/ios/index.js.map + retention-days: 7 + if-no-files-found: error + continue-on-error: true + + - name: Set Artifacts URL and Status + id: set-artifacts-url + run: | + ARTIFACTS_URL="https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" + echo "artifacts-url=${ARTIFACTS_URL}" >> "$GITHUB_OUTPUT" + echo "Artifacts available at: ${ARTIFACTS_URL}" + echo "" + echo "Upload Status Summary:" + echo "- APP (Simulator): ${{ steps.upload-app.outcome }}" + echo "- Source Map: ${{ steps.upload-sourcemap.outcome }}" + env: + GITHUB_REPOSITORY: ${{ github.repository }} + GITHUB_RUN_ID: ${{ github.run_id }} + + - name: Record build timing summary + if: always() + run: | + echo "=== Bitrise iOS KV cache — build timing summary ===" + echo "Runner platform: ${{ runner.os }}/${{ runner.arch }}" + echo "Build outcome: ${{ steps.upload-app.outcome }}" + echo "Xcode cache hit (branch): ${{ steps.xcode-restore-cache.outputs.cache-hit }}" + echo "Xcode cache hit (main): ${{ steps.xcode-restore-cache-main.outputs.cache-hit || 'N/A' }}" + echo "App cache hit (branch): ${{ steps.cache-restore.outputs.cache-hit }}" + echo "App cache hit (main): ${{ steps.cache-restore-main.outputs.cache-hit || 'N/A' }}" + echo "Cache mode: Bitrise KV cache via actions/cache only" + echo "Record CPU and memory utilization from the VM monitoring CSV for this job." + shell: bash + # e2e-smoke-tests-ios: + # name: iOS E2E Smoke Tests (Bitrise) + # permissions: + # contents: read + # id-token: write + # needs: [build-ios-on-bitrise] + # uses: ./.github/workflows/run-e2e-smoke-tests-ios.yml + # with: + # use_bitrise_runner: true + # secrets: inherit From 271011a12650df67b99f7997c88980f5863082eb Mon Sep 17 00:00:00 2001 From: Borislav Grigorov <11405770+bsgrigorov@users.noreply.github.com> Date: Tue, 5 May 2026 15:48:40 -0700 Subject: [PATCH 2/2] chore(INFRA-3591): Bitrise smoke routing fix + bump temp KV workflow actions Co-authored-by: Cursor --- .github/workflows/run-e2e-smoke-tests-ios.yml | 3 +++ .github/workflows/temp-bitrise-ios-kv.yml | 16 ++++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/.github/workflows/run-e2e-smoke-tests-ios.yml b/.github/workflows/run-e2e-smoke-tests-ios.yml index ebf496adb50..59dcfaf3bc8 100644 --- a/.github/workflows/run-e2e-smoke-tests-ios.yml +++ b/.github/workflows/run-e2e-smoke-tests-ios.yml @@ -78,6 +78,7 @@ jobs: changed_files: ${{ inputs.changed_files }} build_type: 'main' metamask_environment: 'qa' + use_bitrise_runner: ${{ inputs.use_bitrise_runner }} secrets: inherit perps-ios-smoke: @@ -115,6 +116,7 @@ jobs: changed_files: ${{ inputs.changed_files }} build_type: 'main' metamask_environment: 'qa' + use_bitrise_runner: ${{ inputs.use_bitrise_runner }} secrets: inherit identity-ios-smoke: @@ -228,6 +230,7 @@ jobs: changed_files: ${{ inputs.changed_files }} build_type: 'main' metamask_environment: 'qa' + use_bitrise_runner: ${{ inputs.use_bitrise_runner }} secrets: inherit multichain-api-ios-smoke: diff --git a/.github/workflows/temp-bitrise-ios-kv.yml b/.github/workflows/temp-bitrise-ios-kv.yml index d2fe8754d23..71a4a07d3bd 100644 --- a/.github/workflows/temp-bitrise-ios-kv.yml +++ b/.github/workflows/temp-bitrise-ios-kv.yml @@ -75,7 +75,7 @@ jobs: steps: - name: Checkout repo - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Print runner environment diagnostics run: | @@ -122,7 +122,7 @@ jobs: - name: Restore Xcode derived data from branch cache id: xcode-restore-cache - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: | ~/Library/Developer/Xcode/DerivedData @@ -135,7 +135,7 @@ jobs: if: ${{ steps.xcode-restore-cache.outputs.cache-hit != 'true' && github.ref_name != 'main' }} id: xcode-restore-cache-main - uses: actions/cache/restore@v4 + uses: actions/cache/restore@v5 with: path: | ~/Library/Developer/Xcode/DerivedData @@ -168,7 +168,7 @@ jobs: - name: Restore .metamask folder id: restore-metamask - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: .metamask key: .metamask-${{ hashFiles('package.json', 'yarn.lock') }} @@ -196,7 +196,7 @@ jobs: - name: Restore iOS app matching fingerprint from branch cache id: cache-restore - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: ios/build/Build/Products/Release-iphonesimulator/MetaMask.app key: bitrise-ios-app-${{ github.ref_name }}-v${{ env.IOS_APP_CACHE_VERSION @@ -206,7 +206,7 @@ jobs: if: ${{ steps.cache-restore.outputs.cache-hit != 'true' && github.ref_name != 'main' }} id: cache-restore-main - uses: actions/cache/restore@v4 + uses: actions/cache/restore@v5 with: path: ios/build/Build/Products/Release-iphonesimulator/MetaMask.app key: bitrise-ios-app-main-v${{ env.IOS_APP_CACHE_VERSION }}-${{ @@ -303,7 +303,7 @@ jobs: - name: Upload iOS APP Artifact (Simulator) id: upload-app - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: main-qa-MetaMask.app path: ios/build/Build/Products/Release-iphonesimulator/MetaMask.app @@ -314,7 +314,7 @@ jobs: id: upload-sourcemap if: ${{ steps.cache-restore.outputs.cache-hit == 'true' || steps.cache-restore-main.outputs.cache-hit == 'true' }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: main-qa-index.js.map path: sourcemaps/ios/index.js.map