Skip to content

Commit

Permalink
Typing scripts used for test-e2e-local (facebook#42610)
Browse files Browse the repository at this point in the history
Summary:

Changelog: [Internal] Adding more typing to internal scripts used by test-e2e-local

Reviewed By: NickGerleman

Differential Revision: D52988733
  • Loading branch information
lunaleaps authored and facebook-github-bot committed Jan 24, 2024
1 parent 7803bf3 commit 6f3aafa
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 71 deletions.
46 changes: 31 additions & 15 deletions packages/react-native/scripts/hermes/hermes-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/

Expand All @@ -14,6 +15,10 @@ const fs = require('fs');
const os = require('os');
const path = require('path');

/*::
type BuildType = 'dry-run' | 'release' | 'nightly' | 'prealpha';
*/

const SDKS_DIR = path.normalize(path.join(__dirname, '..', '..', 'sdks'));
const HERMES_DIR = path.join(SDKS_DIR, 'hermes');
const HERMES_TAG_FILE_PATH = path.join(SDKS_DIR, '.hermesversion');
Expand All @@ -34,11 +39,15 @@ const MACOS_IMPORT_HERMESC_PATH = path.join(
* @param args Array of arguments pass to the command.
* @param options child process options.
*/
function delegateSync(command, args, options) {
function delegateSync(
command /*: string */,
args /*: (Array<string> | child_process$spawnSyncOpts) */,
options /*: ?child_process$spawnSyncOpts */,
) {
return spawnSync(command, args, {stdio: 'inherit', ...options});
}

function readHermesTag() {
function readHermesTag() /*: string */ {
if (fs.existsSync(HERMES_TAG_FILE_PATH)) {
const data = fs
.readFileSync(HERMES_TAG_FILE_PATH, {
Expand All @@ -57,7 +66,7 @@ function readHermesTag() {
return 'main';
}

function setHermesTag(hermesTag) {
function setHermesTag(hermesTag /*: string */) {
if (readHermesTag() === hermesTag) {
// No need to update.
return;
Expand All @@ -70,15 +79,15 @@ function setHermesTag(hermesTag) {
console.log('Hermes tag has been updated. Please commit your changes.');
}

function getHermesTagSHA(hermesTag) {
function getHermesTagSHA(hermesTag /*: string */) /*: string */ {
return execSync(
`git ls-remote https://github.com/facebook/hermes ${hermesTag} | cut -f 1`,
)
.toString()
.trim();
}

function getHermesTarballDownloadPath(hermesTag) {
function getHermesTarballDownloadPath(hermesTag /*: string */) /*: string */ {
const hermesTagSHA = getHermesTagSHA(hermesTag);
return path.join(HERMES_TARBALL_DOWNLOAD_DIR, `hermes-${hermesTagSHA}.tgz`);
}
Expand Down Expand Up @@ -184,11 +193,13 @@ function isTestingAgainstLocalHermesTarball() {
return 'HERMES_ENGINE_TARBALL_PATH' in process.env;
}

function shouldBuildHermesFromSource(isInCI) {
function shouldBuildHermesFromSource(isInCI /*: boolean */) /*: boolean */ {
return !isTestingAgainstLocalHermesTarball() && isInCI;
}

function shouldUsePrebuiltHermesC(platform) {
function shouldUsePrebuiltHermesC(
platform /*: 'macos' | 'windows' */,
) /*: boolean */ {
if (platform === 'macos') {
return fs.existsSync(MACOS_HERMESC_PATH);
}
Expand All @@ -212,7 +223,9 @@ set_target_properties(native-hermesc PROPERTIES
}
}

function getHermesPrebuiltArtifactsTarballName(buildType) {
function getHermesPrebuiltArtifactsTarballName(
buildType /*: string */,
) /*: string */ {
if (!buildType) {
throw Error('Did not specify build type.');
}
Expand All @@ -222,17 +235,20 @@ function getHermesPrebuiltArtifactsTarballName(buildType) {
/**
* Creates a tarball with the contents of the supplied directory.
*/
function createTarballFromDirectory(directory, filename) {
function createTarballFromDirectory(
directory /*: string */,
filename /*: string */,
) {
const args = ['-C', directory, '-czvf', filename, '.'];
delegateSync('tar', args);
}

function createHermesPrebuiltArtifactsTarball(
hermesDir,
buildType,
tarballOutputDir,
excludeDebugSymbols,
) {
hermesDir /*: string */,
buildType /*: string */,
tarballOutputDir /*: string */,
excludeDebugSymbols /*: boolean */,
) /*: string */ {
validateHermesFrameworksExist(path.join(hermesDir, 'destroot'));

if (!fs.existsSync(tarballOutputDir)) {
Expand Down Expand Up @@ -282,7 +298,7 @@ function createHermesPrebuiltArtifactsTarball(
return tarballFilename;
}

function validateHermesFrameworksExist(destrootDir) {
function validateHermesFrameworksExist(destrootDir /*: string */) {
if (
!fs.existsSync(
path.join(destrootDir, 'Library/Frameworks/macosx/hermes.framework'),
Expand Down
32 changes: 22 additions & 10 deletions scripts/release-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/

Expand All @@ -14,7 +15,11 @@ const {
} = require('../packages/react-native/scripts/hermes/hermes-utils');
const {echo, env, exec, exit, popd, pushd, test} = require('shelljs');

function generateAndroidArtifacts(releaseVersion) {
/*::
type BuildType = 'dry-run' | 'release' | 'nightly' | 'prealpha';
*/

function generateAndroidArtifacts(releaseVersion /*: string */) {
// -------- Generating Android Artifacts
echo('Generating Android artifacts inside /tmp/maven-local');
if (exec('./gradlew publishAllToMavenTempLocal').code) {
Expand Down Expand Up @@ -52,10 +57,15 @@ function generateAndroidArtifacts(releaseVersion) {
});
}

function publishAndroidArtifactsToMaven(releaseVersion, buildType) {
function publishAndroidArtifactsToMaven(
releaseVersion /*: string */,
buildType /*: BuildType */,
) {
// -------- Publish every artifact to Maven Central
// The GPG key is base64 encoded on CircleCI and then decoded here
// $FlowFixMe[prop-missing]
let buff = Buffer.from(env.ORG_GRADLE_PROJECT_SIGNING_KEY_ENCODED, 'base64');
// $FlowFixMe[prop-missing]
env.ORG_GRADLE_PROJECT_SIGNING_KEY = buff.toString('ascii');

// We want to gate ourselves against accidentally publishing a 1.x or a 1000.x on
Expand All @@ -76,7 +86,9 @@ function publishAndroidArtifactsToMaven(releaseVersion, buildType) {
const isSnapshot = buildType === 'nightly' || buildType === 'prealpha';
// -------- For nightly releases, we only need to publish the snapshot to Sonatype snapshot repo.
if (
exec('./gradlew publishAllToSonatype -PisSnapshot=' + isSnapshot).code
exec(
'./gradlew publishAllToSonatype -PisSnapshot=' + isSnapshot.toString(),
).code
) {
echo('Failed to publish artifacts to Sonatype (Maven Central)');
exit(1);
Expand All @@ -87,11 +99,11 @@ function publishAndroidArtifactsToMaven(releaseVersion, buildType) {
}

function generateiOSArtifacts(
jsiFolder,
hermesCoreSourceFolder,
buildType,
targetFolder,
) {
jsiFolder /*: string */,
hermesCoreSourceFolder /*: string */,
buildType /*: 'Debug' | string */,
targetFolder /*: string */,
) /*: string */ {
pushd(`${hermesCoreSourceFolder}`);

//Generating iOS Artifacts
Expand All @@ -115,7 +127,7 @@ function generateiOSArtifacts(
return tarballOutputPath;
}

function failIfTagExists(version, buildType) {
function failIfTagExists(version /*: string */, buildType /*: BuildType */) {
// When dry-run in stable branch, the tag already exists.
// We are bypassing the tag-existence check when in a dry-run to have the CI pass
if (buildType === 'dry-run') {
Expand All @@ -130,7 +142,7 @@ function failIfTagExists(version, buildType) {
}
}

function checkIfTagExists(version) {
function checkIfTagExists(version /*: string */) {
const {code, stdout} = exec('git tag -l', {silent: true});
if (code !== 0) {
throw new Error('Failed to retrieve the list of tags');
Expand Down
1 change: 1 addition & 0 deletions scripts/test-e2e-local-clean.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/

Expand Down
56 changes: 37 additions & 19 deletions scripts/test-e2e-local.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/

Expand All @@ -28,6 +29,10 @@ const path = require('path');
const {cd, exec, popd, pushd, pwd, sed} = require('shelljs');
const yargs = require('yargs');

/* ::
type Unwrap<T> = T extends Promise<infer U> ? U : T;
*/

const argv = yargs
.option('t', {
alias: 'target',
Expand Down Expand Up @@ -59,17 +64,20 @@ const argv = yargs
* - @circleCIArtifacts manager object to manage all the download of CircleCIArtifacts. If null, it will fallback not to use them.
* - @onReleaseBranch whether we are on a release branch or not
*/
async function testRNTesterIOS(circleCIArtifacts, onReleaseBranch) {
async function testRNTesterIOS(
circleCIArtifacts /*: Unwrap<ReturnType<typeof setupCircleCIArtifacts>> */,
onReleaseBranch /*: boolean */,
) {
console.info(
`We're going to test the ${
argv.hermes ? 'Hermes' : 'JSC'
argv.hermes === true ? 'Hermes' : 'JSC'
} version of RNTester iOS with the new Architecture enabled`,
);

// remember that for this to be successful
// you should have run bundle install once
// in your local setup
if (argv.hermes && circleCIArtifacts != null) {
if (argv.hermes === true && circleCIArtifacts != null) {
const hermesURL = await circleCIArtifacts.artifactURLHermesDebug();
const hermesPath = path.join(
circleCIArtifacts.baseTmpPath(),
Expand All @@ -84,14 +92,14 @@ async function testRNTesterIOS(circleCIArtifacts, onReleaseBranch) {
} else {
exec(
`USE_HERMES=${
argv.hermes ? 1 : 0
} CI=${onReleaseBranch} RCT_NEW_ARCH_ENABLED=1 bundle exec pod install --ansi`,
argv.hermes === true ? 1 : 0
} CI=${onReleaseBranch.toString()} RCT_NEW_ARCH_ENABLED=1 bundle exec pod install --ansi`,
);
}

// if everything succeeded so far, we can launch Metro and the app
// start the Metro server in a separate window
launchPackagerInSeparateWindow(pwd());
launchPackagerInSeparateWindow(pwd().toString());

// launch the app on iOS simulator
exec('npx react-native run-ios --scheme RNTester --simulator "iPhone 14"');
Expand All @@ -103,17 +111,19 @@ async function testRNTesterIOS(circleCIArtifacts, onReleaseBranch) {
* Parameters:
* - @circleCIArtifacts manager object to manage all the download of CircleCIArtifacts. If null, it will fallback not to use them.
*/
async function testRNTesterAndroid(circleCIArtifacts) {
async function testRNTesterAndroid(
circleCIArtifacts /*: Unwrap<ReturnType<typeof setupCircleCIArtifacts>> */,
) {
maybeLaunchAndroidEmulator();

console.info(
`We're going to test the ${
argv.hermes ? 'Hermes' : 'JSC'
argv.hermes === true ? 'Hermes' : 'JSC'
} version of RNTester Android with the new Architecture enabled`,
);

// Start the Metro server so it will be ready if the app can be built and installed successfully.
launchPackagerInSeparateWindow(pwd());
launchPackagerInSeparateWindow(pwd().toString());

// Wait for the Android Emulator to be properly loaded and bootstrapped
exec(
Expand All @@ -127,9 +137,10 @@ async function testRNTesterAndroid(circleCIArtifacts) {
);

const emulatorArch = exec('adb shell getprop ro.product.cpu.abi').trim();
const rntesterAPKURL = argv.hermes
? await circleCIArtifacts.artifactURLForHermesRNTesterAPK(emulatorArch)
: await circleCIArtifacts.artifactURLForJSCRNTesterAPK(emulatorArch);
const rntesterAPKURL =
argv.hermes === true
? await circleCIArtifacts.artifactURLForHermesRNTesterAPK(emulatorArch)
: await circleCIArtifacts.artifactURLForJSCRNTesterAPK(emulatorArch);

console.info('Start Downloading APK');
circleCIArtifacts.downloadArtifact(rntesterAPKURL, downloadPath);
Expand All @@ -138,7 +149,7 @@ async function testRNTesterAndroid(circleCIArtifacts) {
} else {
exec(
`../../gradlew :packages:rn-tester:android:app:${
argv.hermes ? 'installHermesDebug' : 'installJscDebug'
argv.hermes === true ? 'installHermesDebug' : 'installJscDebug'
} --quiet`,
);
}
Expand All @@ -161,7 +172,10 @@ async function testRNTesterAndroid(circleCIArtifacts) {
* - @circleCIArtifacts manager object to manage all the download of CircleCIArtifacts. If null, it will fallback not to use them.
* - @onReleaseBranch whether we are on a release branch or not
*/
async function testRNTester(circleCIArtifacts, onReleaseBranch) {
async function testRNTester(
circleCIArtifacts /*:Unwrap<ReturnType<typeof setupCircleCIArtifacts>> */,
onReleaseBranch /*: boolean */,
) {
// FIXME: make sure that the commands retains colors
// (--ansi) doesn't always work
// see also https://github.com/shelljs/shelljs/issues/86
Expand All @@ -177,7 +191,9 @@ async function testRNTester(circleCIArtifacts, onReleaseBranch) {

// === RNTestProject === //

async function testRNTestProject(circleCIArtifacts) {
async function testRNTestProject(
circleCIArtifacts /*: Unwrap<ReturnType<typeof setupCircleCIArtifacts>> */,
) {
console.info("We're going to test a fresh new RN project");

// create the local npm package to feed the CLI
Expand All @@ -195,7 +211,7 @@ async function testRNTestProject(circleCIArtifacts) {
const buildType = 'dry-run';

// Prepare some variables for later use
const repoRoot = pwd();
const repoRoot = pwd().toString();
const reactNativePackagePath = `${repoRoot}/packages/react-native`;
const localNodeTGZPath = `${reactNativePackagePath}/react-native-${releaseVersion}.tgz`;

Expand Down Expand Up @@ -239,7 +255,7 @@ async function testRNTestProject(circleCIArtifacts) {
);

// Update gradle properties to set Hermes as false
if (!argv.hermes) {
if (argv.hermes == null) {
sed(
'-i',
'hermesEnabled=true',
Expand All @@ -254,7 +270,7 @@ async function testRNTestProject(circleCIArtifacts) {
exec('bundle install');
exec(
`HERMES_ENGINE_TARBALL_PATH=${hermesPath} USE_HERMES=${
argv.hermes ? 1 : 0
argv.hermes === true ? 1 : 0
} bundle exec pod install --ansi`,
);

Expand Down Expand Up @@ -286,7 +302,8 @@ async function main() {
const onReleaseBranch = branchName.endsWith('-stable');

let circleCIArtifacts = await setupCircleCIArtifacts(
argv.circleciToken,
// $FlowIgnoreError[prop-missing]
argv.circleCIToken,
branchName,
);

Expand All @@ -297,4 +314,5 @@ async function main() {
}
}

// $FlowIgnoreError[unused-promise]
main();
Loading

0 comments on commit 6f3aafa

Please sign in to comment.