Skip to content

Commit

Permalink
Fix RNTestProject testing on Android (#41172)
Browse files Browse the repository at this point in the history
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: #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
  • Loading branch information
cipolleschi authored and facebook-github-bot committed Oct 27, 2023
1 parent 3648886 commit 4eed12b
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 45 deletions.
19 changes: 17 additions & 2 deletions scripts/circle-ci-artifacts-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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',
Expand All @@ -182,5 +196,6 @@ module.exports = {
artifactURLForHermesRNTesterAPK,
artifactURLForMavenLocal,
artifactURLHermesDebug,
artifactURLForReactNative,
baseTmpPath,
};
60 changes: 19 additions & 41 deletions scripts/test-e2e-local.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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();
Expand All @@ -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,
Expand All @@ -218,38 +214,21 @@ 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');
exec('yarn install');

// 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
Expand All @@ -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
Expand Down
9 changes: 7 additions & 2 deletions scripts/testing-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down

0 comments on commit 4eed12b

Please sign in to comment.