mirror of
https://github.com/react/react-native.git
synced 2026-09-28 13:23:09 +08:00
Run Android E2E with ARM64 APKs (#58092)
Summary: Build only the `arm64-v8a` Android ABI for dry-run CI artifacts and run the ARM64 RNTester and template-app APKs on an API 35 `google_apis` x86_64 emulator using the system images built-in NDK translation support. This also makes the Maestro emulator API level and target configurable, logs the device ABI/native-bridge configuration, and updates local RNTester artifact selection to use the ARM64 split. Release and nightly publication builds continue to build all supported Android ABIs. ## Changelog: [INTERNAL] [CHANGED] - Run Android E2E tests with ARM64 APKs through NDK translation. Pull Request resolved: https://github.com/react/react-native/pull/58092 Test Plan: - `node --check .github/workflow-scripts/maestro-android.js` — passed. - `node --check scripts/release-testing/test-release-local.js` — passed. - Parsed all modified YAML files with the `yaml` Node package — passed. - `./node_modules/.bin/prettier --check <modified files>` — passed. - `git diff --check HEAD~3..HEAD` — passed. - `actionlint` reported only existing repository metadata warnings for the custom `4-core-ubuntu` label and the missing description in the local `yarn-install` action. - `yarn test .github/workflow-scripts/__tests__/maestro-android-test.js --runInBand` could not start because the local dependency tree is missing `flow-parser`; restoring dependencies was blocked by HTTP 503 responses from the npm registry. - The draft CI run should validate ARM64 APK installation, Hermes startup, and the complete Maestro suites through `libndk_translation.so`. Reviewed By: Abbondanzo Differential Revision: D117195078 Pulled By: cortinico fbshipit-source-id: a78f2127f04e80c3b5ca4c95d2024dffb92ff122
This commit is contained in:
committed by
meta-codesync[bot]
parent
3f9cc72309
commit
25ebffd1f7
@@ -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
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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 || '<empty>'}`);
|
||||
}
|
||||
}
|
||||
|
||||
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'});
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -203,9 +203,7 @@ function downloadArtifact(
|
||||
exec(command, {stdio: 'inherit'});
|
||||
}
|
||||
|
||||
async function artifactURLForRNTesterAPK(
|
||||
emulatorArch /*: string */,
|
||||
) /*: Promise<string> */ {
|
||||
async function artifactURLForRNTesterAPK() /*: Promise<string> */ {
|
||||
return getArtifactURL('rntester-debug');
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user