diff --git a/.github/actions/build-android/action.yml b/.github/actions/build-android/action.yml index da5a2a5ec71a..7db3ac273067 100644 --- a/.github/actions/build-android/action.yml +++ b/.github/actions/build-android/action.yml @@ -52,8 +52,10 @@ runs: shell: bash run: | if [[ "${{ inputs.release-type }}" == "dry-run" ]]; then - # dry-run: we only build ARM64 to save time/resources. For release/nightlies the default is to build all archs. - export ORG_GRADLE_PROJECT_reactNativeArchitectures="arm64-v8a,x86" # x86 is required for E2E testing + # dry-run: we only build ARM64 to save time/resources. Android E2E + # runs this APK on an x86_64 API 35 image using NDK translation. + # For release/nightlies the default is to build all architectures. + export ORG_GRADLE_PROJECT_reactNativeArchitectures="arm64-v8a" export HERMES_PREBUILT_FLAG="ORG_GRADLE_PROJECT_react.internal.useHermesNightly=true" TASKS="publishAllToMavenTempLocal build" elif [[ "${{ inputs.release-type }}" == "nightly" ]]; then diff --git a/.github/actions/maestro-android/action.yml b/.github/actions/maestro-android/action.yml index 8962e2894392..58a7351da64d 100644 --- a/.github/actions/maestro-android/action.yml +++ b/.github/actions/maestro-android/action.yml @@ -26,6 +26,14 @@ inputs: required: false default: x86 description: The architecture of the emulator to run + emulator-api-level: + required: false + default: '24' + description: The Android API level of the emulator to run + emulator-target: + required: false + default: default + description: The Android system image target to use test-state-path: required: false default: /tmp/maestro-android-state/results.json @@ -60,7 +68,8 @@ runs: id: run-tests uses: reactivecircus/android-emulator-runner@v2 with: - api-level: 24 + api-level: ${{ inputs.emulator-api-level }} + target: ${{ inputs.emulator-target }} arch: ${{ inputs.emulator-arch }} ram-size: '8192M' heap-size: '4096M' diff --git a/.github/workflow-scripts/maestro-android.js b/.github/workflow-scripts/maestro-android.js index e871325998ba..7b2365512ef2 100644 --- a/.github/workflow-scripts/maestro-android.js +++ b/.github/workflow-scripts/maestro-android.js @@ -29,6 +29,22 @@ const MAESTRO_LOG_DIRECTORY = '/tmp/MaestroLogs'; const DIAGNOSTIC_COMMAND_TIMEOUT = 15000; const STATE_VERSION = 1; +function logAndroidAbiConfiguration() { + const properties = [ + 'ro.product.cpu.abi', + 'ro.product.cpu.abilist', + 'ro.dalvik.vm.native.bridge', + ]; + + console.info('Android ABI configuration:'); + for (const property of properties) { + const value = childProcess + .execFileSync('adb', ['shell', 'getprop', property], {encoding: 'utf8'}) + .trim(); + console.info(`- ${property}: ${value || ''}`); + } +} + function collectFlows(flowPath) { if (!fs.existsSync(flowPath) || !fs.lstatSync(flowPath).isDirectory()) { return [flowPath]; @@ -279,6 +295,8 @@ async function main(args = process.argv.slice(2)) { console.info(`TEST_STATE_PATH: ${statePath}`); console.info('==============================\n'); + logAndroidAbiConfiguration(); + console.info('Install app'); childProcess.execSync(`adb install ${appPath}`, {stdio: 'ignore'}); diff --git a/.github/workflows/e2e-android-rntester.yml b/.github/workflows/e2e-android-rntester.yml index b6b08b2f68b4..dca0ae68ced4 100644 --- a/.github/workflows/e2e-android-rntester.yml +++ b/.github/workflows/e2e-android-rntester.yml @@ -45,7 +45,7 @@ jobs: continue-on-error: true uses: actions/download-artifact@v7 with: - name: e2e_android_rntester_state_${{ matrix.flavor }}_x86_NewArch + name: e2e_android_rntester_state_${{ matrix.flavor }}_arm64-v8a_NewArch path: /tmp/maestro-android-state - name: Check for unfinished E2E flows id: test-state @@ -64,15 +64,18 @@ jobs: uses: ./.github/actions/maestro-android timeout-minutes: 90 with: - app-path: ./packages/rn-tester/android/app/build/outputs/apk/${{ matrix.flavor }}/app-x86-${{ matrix.flavor }}.apk + app-path: ./packages/rn-tester/android/app/build/outputs/apk/${{ matrix.flavor }}/app-arm64-v8a-${{ matrix.flavor }}.apk app-id: com.facebook.react.uiapp maestro-flow: ./packages/rn-tester/.maestro flavor: ${{ matrix.flavor }} + emulator-api-level: '35' + emulator-target: google_apis + emulator-arch: x86_64 - name: Store per-flow test state if: always() uses: actions/upload-artifact@v6 with: - name: e2e_android_rntester_state_${{ matrix.flavor }}_x86_NewArch + name: e2e_android_rntester_state_${{ matrix.flavor }}_arm64-v8a_NewArch overwrite: true if-no-files-found: warn path: /tmp/maestro-android-state/results.json diff --git a/.github/workflows/e2e-android-templateapp.yml b/.github/workflows/e2e-android-templateapp.yml index f7b010114bfc..7ef8b94bd14a 100644 --- a/.github/workflows/e2e-android-templateapp.yml +++ b/.github/workflows/e2e-android-templateapp.yml @@ -74,14 +74,14 @@ jobs: # Build cd android CAPITALIZED_FLAVOR=$(echo "${{ matrix.flavor }}" | awk '{print toupper(substr($0, 1, 1)) substr($0, 2)}') - ./gradlew assemble$CAPITALIZED_FLAVOR --no-daemon -PreactNativeArchitectures=x86 + ./gradlew assemble$CAPITALIZED_FLAVOR --no-daemon -PreactNativeArchitectures=arm64-v8a - name: Download previous per-flow test state if: ${{ inputs.retry-attempt > 0 }} continue-on-error: true uses: actions/download-artifact@v7 with: - name: e2e_android_templateapp_state_${{ matrix.flavor }}_x86_NewArch + name: e2e_android_templateapp_state_${{ matrix.flavor }}_arm64-v8a_NewArch path: /tmp/maestro-android-state - name: Check for unfinished E2E flows id: test-state @@ -106,11 +106,14 @@ jobs: install-java: 'false' flavor: ${{ matrix.flavor }} working-directory: /tmp/RNTestProject + emulator-api-level: '35' + emulator-target: google_apis + emulator-arch: x86_64 - name: Store per-flow test state if: always() uses: actions/upload-artifact@v6 with: - name: e2e_android_templateapp_state_${{ matrix.flavor }}_x86_NewArch + name: e2e_android_templateapp_state_${{ matrix.flavor }}_arm64-v8a_NewArch overwrite: true if-no-files-found: warn path: /tmp/maestro-android-state/results.json diff --git a/scripts/release-testing/test-release-local.js b/scripts/release-testing/test-release-local.js index ab77fe84bb21..5fc820005b40 100644 --- a/scripts/release-testing/test-release-local.js +++ b/scripts/release-testing/test-release-local.js @@ -155,18 +155,15 @@ async function testRNTesterAndroid( if (ciArtifacts != null) { const downloadPath = path.join(ciArtifacts.baseTmpPath(), 'rntester.zip'); - const emulatorArch = exec('adb shell getprop ro.product.cpu.abi').trim(); - // Github Actions zips all the APKs in a single archive console.info('Start Downloading APK'); - const rntesterAPKURL = - await ciArtifacts.artifactURLForRNTesterAPK(emulatorArch); + const rntesterAPKURL = await ciArtifacts.artifactURLForRNTesterAPK(); ciArtifacts.downloadArtifact(rntesterAPKURL, downloadPath); const unzipFolder = path.join(ciArtifacts.baseTmpPath(), 'rntester-apks'); exec(`rm -rf ${unzipFolder}`); exec(`unzip ${downloadPath} -d ${unzipFolder}`); - let apkPath = path.join(unzipFolder, `app-${emulatorArch}-debug.apk`); + const apkPath = path.join(unzipFolder, 'app-arm64-v8a-debug.apk'); exec(`adb install ${apkPath}`); } else { diff --git a/scripts/release-testing/utils/github-actions-utils.js b/scripts/release-testing/utils/github-actions-utils.js index 343736592226..7a173c102a89 100644 --- a/scripts/release-testing/utils/github-actions-utils.js +++ b/scripts/release-testing/utils/github-actions-utils.js @@ -203,9 +203,7 @@ function downloadArtifact( exec(command, {stdio: 'inherit'}); } -async function artifactURLForRNTesterAPK( - emulatorArch /*: string */, -) /*: Promise */ { +async function artifactURLForRNTesterAPK() /*: Promise */ { return getArtifactURL('rntester-debug'); }