From 4eed12b7df5d9731e556b77d701c87dcf91d3a1f Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Fri, 27 Oct 2023 07:25:02 -0700 Subject: [PATCH] Fix RNTestProject testing on Android (#41172) Summary: While releasing RN 0.73.0-RC3, we relaized that the e2e test script was bugged for Android when used to test RNTestProject with the `-c` option. There were 2 problems: - The downloaded maven-local was not actually used because it doesn't work with a zip. (We were always downloading a version from Maven) - The versions of React Native between maven-local and the locally packaged React Native were different. This change fixes the script by: - Downloading maven-local - Unzipping maven-local and passing the new folder to the Android app - Downloading the React Native version that has been packaged in CI By unzipping maven-local and using the unzipped folder, we make sure that Android is actually using the local repository. By downloading both the packaged react native and the maven-local from the same CI workflow, we ensure that the versions are aligned. This also speeds-up further the Android testing. While running this change, we also moved the `pod install` step inside the `if (iOS)` branch, so we do not install Cocoapods if we need to test Android. ## Changelog: [Internal] - Fix Android E2E test script when downloading artefacts from CI Pull Request resolved: https://github.com/facebook/react-native/pull/41172 Test Plan: Tested locally on both main and 0.73-stable, on both Android and iOS Reviewed By: cortinico Differential Revision: D50651448 Pulled By: cipolleschi fbshipit-source-id: 70a9ed19072119d19c5388e8a4309d7333a08e13 --- scripts/circle-ci-artifacts-utils.js | 19 ++++++++- scripts/test-e2e-local.js | 60 +++++++++------------------- scripts/testing-utils.js | 9 ++++- 3 files changed, 43 insertions(+), 45 deletions(-) diff --git a/scripts/circle-ci-artifacts-utils.js b/scripts/circle-ci-artifacts-utils.js index 5d7f9e2b09bf8b..fb23b68df49d97 100644 --- a/scripts/circle-ci-artifacts-utils.js +++ b/scripts/circle-ci-artifacts-utils.js @@ -128,8 +128,11 @@ async function _findUrlForJob(jobName, artifactPath) { _throwIfJobIsUnsuccessful(job); const artifacts = await _getJobsArtifacts(job.job_number); - return artifacts.find(artifact => artifact.path.indexOf(artifactPath) > -1) - .url; + let artifact = artifacts.find(a => a.path.indexOf(artifactPath) > -1); + if (!artifact) { + throw new Error(`I could not find the artifact with path ${artifactPath}`); + } + return artifact.url; } function _throwIfJobIsNull(job) { @@ -156,6 +159,17 @@ async function artifactURLForMavenLocal() { return _findUrlForJob('build_npm_package', 'maven-local.zip'); } +async function artifactURLForReactNative() { + let shortCommit = exec('git rev-parse HEAD', {silent: true}) + .toString() + .trim() + .slice(0, 9); + return _findUrlForJob( + 'build_npm_package', + `react-native-1000.0.0-${shortCommit}.tgz`, + ); +} + async function artifactURLForHermesRNTesterAPK(emulatorArch) { return _findUrlForJob( 'test_android', @@ -182,5 +196,6 @@ module.exports = { artifactURLForHermesRNTesterAPK, artifactURLForMavenLocal, artifactURLHermesDebug, + artifactURLForReactNative, baseTmpPath, }; diff --git a/scripts/test-e2e-local.js b/scripts/test-e2e-local.js index 3346c59e144167..510a914ff23069 100644 --- a/scripts/test-e2e-local.js +++ b/scripts/test-e2e-local.js @@ -20,7 +20,6 @@ const {exec, pushd, popd, pwd, cd, sed} = require('shelljs'); const updateTemplatePackage = require('./update-template-package'); const yargs = require('yargs'); const path = require('path'); -const fs = require('fs'); const { checkPackagerRunning, @@ -189,15 +188,12 @@ async function testRNTestProject(circleCIArtifacts) { // in local testing, 1000.0.0 mean we are on main, every other case means we are // working on a release version const buildType = baseVersion !== '1000.0.0' ? 'release' : 'dry-run'; + const shortCommit = exec('git rev-parse HEAD', {silent: true}) + .toString() + .trim() + .slice(0, 9); - // we need to add the unique timestamp to avoid npm/yarn to use some local caches - const dateIdentifier = new Date() - .toISOString() - .slice(0, -8) - .replace(/[-:]/g, '') - .replace(/[T]/g, '-'); - - const releaseVersion = `${baseVersion}-${dateIdentifier}`; + const releaseVersion = `1000.0.0-${shortCommit}`; // Prepare some variables for later use const repoRoot = pwd(); @@ -206,7 +202,7 @@ async function testRNTestProject(circleCIArtifacts) { const mavenLocalPath = circleCIArtifacts != null - ? path.join(circleCIArtifacts.baseTmpPath(), 'maven-local.zip') + ? path.join(circleCIArtifacts.baseTmpPath(), 'maven-local') : '/private/tmp/maven-local'; const hermesPath = await prepareArtifacts( circleCIArtifacts, @@ -218,30 +214,13 @@ async function testRNTestProject(circleCIArtifacts) { ); updateTemplatePackage({ - 'react-native': `file:${localNodeTGZPath}`, + 'react-native': `file://${localNodeTGZPath}`, }); - // create locally the node module - exec('npm pack --pack-destination ', {cwd: reactNativePackagePath}); - - // node pack does not creates a version of React Native with the right name on main. - // Let's add some defensive programming checks: - if (!fs.existsSync(localNodeTGZPath)) { - const tarfile = fs - .readdirSync(reactNativePackagePath) - .find(name => name.startsWith('react-native-') && name.endsWith('.tgz')); - if (!tarfile) { - throw new Error("Couldn't find a zipped version of react-native"); - } - exec( - `cp ${path.join(reactNativePackagePath, tarfile)} ${localNodeTGZPath}`, - ); - } - pushd('/tmp/'); // need to avoid the pod install step - we'll do it later exec( - `node ${reactNativePackagePath}/cli.js init RNTestProject --template ${localNodeTGZPath} --skip-install`, + `node ${reactNativePackagePath}/cli.js init RNTestProject --template ${reactNativePackagePath} --skip-install`, ); cd('RNTestProject'); @@ -249,7 +228,7 @@ async function testRNTestProject(circleCIArtifacts) { // need to do this here so that Android will be properly setup either way exec( - `echo "react.internal.mavenLocalRepo=${mavenLocalPath}" >> android/gradle.properties`, + `echo "react.internal.mavenLocalRepo=${mavenLocalPath}/tmp/maven-local" >> android/gradle.properties`, ); // Update gradle properties to set Hermes as false @@ -262,18 +241,17 @@ async function testRNTestProject(circleCIArtifacts) { ); } - // doing the pod install here so that it's easier to play around RNTestProject - cd('ios'); - exec('bundle install'); - exec( - `HERMES_ENGINE_TARBALL_PATH=${hermesPath} USE_HERMES=${ - argv.hermes ? 1 : 0 - } bundle exec pod install --ansi`, - ); - - cd('..'); - if (argv.platform === 'iOS') { + // doing the pod install here so that it's easier to play around RNTestProject + cd('ios'); + exec('bundle install'); + exec( + `HERMES_ENGINE_TARBALL_PATH=${hermesPath} USE_HERMES=${ + argv.hermes ? 1 : 0 + } bundle exec pod install --ansi`, + ); + + cd('..'); exec('yarn ios'); } else { // android diff --git a/scripts/testing-utils.js b/scripts/testing-utils.js index af996674de5d79..c2b18342ba92ac 100644 --- a/scripts/testing-utils.js +++ b/scripts/testing-utils.js @@ -170,16 +170,21 @@ async function downloadArtifactsFromCircleCI( ) { const mavenLocalURL = await circleCIArtifacts.artifactURLForMavenLocal(); const hermesURL = await circleCIArtifacts.artifactURLHermesDebug(); + const reactNativeURL = await circleCIArtifacts.artifactURLForReactNative(); const hermesPath = path.join( circleCIArtifacts.baseTmpPath(), 'hermes-ios-debug.tar.gz', ); - console.info('[Download] Maven Local Artifacts'); - circleCIArtifacts.downloadArtifact(mavenLocalURL, mavenLocalPath); + console.info(`[Download] Maven Local Artifacts from ${mavenLocalURL}`); + const mavenLocalZipPath = `${mavenLocalPath}.zip`; + circleCIArtifacts.downloadArtifact(mavenLocalURL, mavenLocalZipPath); + exec(`unzip -oq ${mavenLocalZipPath} -d ${mavenLocalPath}`); console.info('[Download] Hermes'); circleCIArtifacts.downloadArtifact(hermesURL, hermesPath); + console.info(`[Download] React Native from ${reactNativeURL}`); + circleCIArtifacts.downloadArtifact(reactNativeURL, localNodeTGZPath); return hermesPath; }