mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
infra(e2e): rework local E2E script (#34513)
Summary: This is a long time coming effort to improve the situation around the local e2e script that in the release crew: the current bash-based script is quirky at best, and what you end up generating as a sample project is not really a true sample project. This is where this PR comes in: it migrates the flow from `./scripts/test-manual-e2e.sh` to `yarn test-e2e-local <options>`. Here's the current shape of the options: ```sh Options: --help Show help [boolean] --version Show version number [boolean] -t, --target [choices: "RNTester", "RNTestProject"] [default: "RNTester"] -p, --platform [choices: "iOS", "Android"] [default: "iOS"] -h, --hermes [boolean] [default: true] ``` The idea is to change it so that you can just run the script, and it will do that one specific thing "well", without the tester needing to do anything aside from actually testing the app once it's open. Some of the key changes: * tries to stick to the patterns of the other established *.js based scripts, in terms of tooling and approach (and even refactor parts that can be shared with other scripts) - like the android artifacts generation * no need to start the android emulator on the side * no need to start Metro on the side * RNTester iOS will open up on the simulator (no Xcode open that then you need to press) Things that still need work: * see the #fixme and #todo in comments * because we rely on exec, the output sent back is not formatted/shaped correctly so it's a bit more noisy/chaotic - but can't handle it right now because the package we use doesn't allow it - see https://github.com/shelljs/shelljs/issues/86 ## Changelog <!-- Help reviewers and the release process by writing your own changelog entry. For an example, see: https://reactnative.dev/contributing/changelogs-in-pull-requests --> [Internal] [Changed] - Migrate bash E2E local testing script to new JS based command Pull Request resolved: https://github.com/facebook/react-native/pull/34513 Test Plan: To test the script, you can run it passing the options showed above; this is the current situation: * RNTester iOS Hermes ✅ * RNTester Android Hermes ✅ * RNTester iOS JSC ✅ * RNTester Android JSC ✅ * RNTestProject Android Hermes ✅ * RNTestProject iOS Hermes ✅ * RNTestProject Android JSC ✅ * RNTestProject iOS JSC ✅ Reviewed By: cortinico Differential Revision: D39814692 Pulled By: cortinico fbshipit-source-id: d4791798aaad764c6a3757269b7636f847ccf2ca
This commit is contained in:
committed by
Facebook GitHub Bot
parent
540ae39487
commit
97f5ef05e6
+3
-1
@@ -38,7 +38,7 @@
|
||||
"rn-get-polyfills.js",
|
||||
"scripts/compose-source-maps.js",
|
||||
"scripts/find-node-for-xcode.sh",
|
||||
"scripts/generate-artifacts.js",
|
||||
"scripts/generate-codegen-artifacts.js",
|
||||
"scripts/generate-provider-cli.js",
|
||||
"scripts/generate-specs-cli.js",
|
||||
"scripts/codegen/codegen-utils.js",
|
||||
@@ -95,6 +95,8 @@
|
||||
"test-android-instrumentation": "yarn run docker-build-android && yarn run test-android-run-instrumentation",
|
||||
"test-android-unit": "yarn run docker-build-android && yarn run test-android-run-unit",
|
||||
"test-android-e2e": "yarn run docker-build-android && yarn run test-android-run-e2e",
|
||||
"test-e2e-local": "node ./scripts/test-e2e-local.js",
|
||||
"test-e2e-local-clean": "node ./scripts/test-e2e-local-clean.js",
|
||||
"test-ios": "./scripts/objc-test.sh test",
|
||||
"test-typescript": "dtslint types"
|
||||
},
|
||||
|
||||
@@ -361,7 +361,7 @@ class CodegenUtilsTests < Test::Unit::TestCase
|
||||
assert_equal(Pod::Executable.executed_commands, [
|
||||
{
|
||||
"command" => "node",
|
||||
"arguments"=> ["~/app/ios/../node_modules/react-native/scripts/generate-artifacts.js",
|
||||
"arguments"=> ["~/app/ios/../node_modules/react-native/scripts/generate-codegen-artifacts.js",
|
||||
"-p", "~/app",
|
||||
"-o", Pod::Config.instance.installation_root,
|
||||
"-e", "false",
|
||||
|
||||
@@ -201,8 +201,8 @@ class CodegenUtils
|
||||
end
|
||||
|
||||
# Generate input files for in-app libaraies which will be used to check if the script needs to be run.
|
||||
# TODO: Ideally, we generate the input_files list from generate-artifacts.js and read the result here.
|
||||
# Or, generate this podspec in generate-artifacts.js as well.
|
||||
# TODO: Ideally, we generate the input_files list from generate-codegen-artifacts.js and read the result here.
|
||||
# Or, generate this podspec in generate-codegen-artifacts.js as well.
|
||||
app_package_path = File.join(app_path, 'package.json')
|
||||
app_codegen_config = codegen_utils.get_codegen_config_from_file(app_package_path, config_key)
|
||||
input_files = codegen_utils.get_list_of_js_specs(app_codegen_config, app_path)
|
||||
@@ -270,7 +270,7 @@ class CodegenUtils
|
||||
out = Pod::Executable.execute_command(
|
||||
'node',
|
||||
[
|
||||
"#{relative_installation_root}/#{react_native_path}/scripts/generate-artifacts.js",
|
||||
"#{relative_installation_root}/#{react_native_path}/scripts/generate-codegen-artifacts.js",
|
||||
"-p", "#{app_path}",
|
||||
"-o", Pod::Config.instance.installation_root,
|
||||
"-e", "#{fabric_enabled}",
|
||||
|
||||
+7
-60
@@ -31,14 +31,17 @@
|
||||
* * or otherwise `{major}.{minor}-stable`
|
||||
*/
|
||||
|
||||
const {exec, echo, exit, env, test} = require('shelljs');
|
||||
const {exec, echo, exit} = require('shelljs');
|
||||
const {parseVersion} = require('./version-utils');
|
||||
const {
|
||||
exitIfNotOnGit,
|
||||
getCurrentCommit,
|
||||
isTaggedLatest,
|
||||
saveFiles,
|
||||
} = require('./scm-utils');
|
||||
const {
|
||||
generateAndroidArtifacts,
|
||||
saveFilesToRestore,
|
||||
} = require('./release-utils');
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
const path = require('path');
|
||||
@@ -72,22 +75,7 @@ const dryRunBuild = argv.dryRun;
|
||||
const includeHermes = argv.includeHermes;
|
||||
const isCommitly = nightlyBuild || dryRunBuild;
|
||||
|
||||
const filesToSaveAndRestore = [
|
||||
'template/Gemfile',
|
||||
'template/_ruby-version',
|
||||
'template/package.json',
|
||||
'.ruby-version',
|
||||
'Gemfile.lock',
|
||||
'Gemfile',
|
||||
'package.json',
|
||||
'ReactAndroid/gradle.properties',
|
||||
'Libraries/Core/ReactNativeVersion.js',
|
||||
'React/Base/RCTVersion.m',
|
||||
'ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java',
|
||||
'ReactCommon/cxxreact/ReactNativeVersion.h',
|
||||
];
|
||||
|
||||
saveFiles(filesToSaveAndRestore, tmpPublishingFolder);
|
||||
saveFilesToRestore(tmpPublishingFolder);
|
||||
|
||||
if (includeHermes) {
|
||||
const HERMES_INSTALL_LOCATION = 'sdks';
|
||||
@@ -195,48 +183,7 @@ if (isCommitly) {
|
||||
}
|
||||
}
|
||||
|
||||
// -------- Generating Android Artifacts
|
||||
env.REACT_NATIVE_SKIP_PREFAB = true;
|
||||
if (exec('./gradlew :ReactAndroid:installArchives').code) {
|
||||
echo('Could not generate artifacts');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// -------- Generating the Hermes Engine Artifacts
|
||||
env.REACT_NATIVE_HERMES_SKIP_PREFAB = true;
|
||||
if (exec('./gradlew :ReactAndroid:hermes-engine:installArchives').code) {
|
||||
echo('Could not generate artifacts');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
echo('Generated artifacts for Maven');
|
||||
|
||||
let artifacts = [
|
||||
'.module',
|
||||
'.pom',
|
||||
'-debug.aar',
|
||||
'-release.aar',
|
||||
'-debug-sources.jar',
|
||||
'-release-sources.jar',
|
||||
].map(suffix => {
|
||||
return `react-native-${releaseVersion}${suffix}`;
|
||||
});
|
||||
|
||||
artifacts.forEach(name => {
|
||||
if (
|
||||
!test(
|
||||
'-e',
|
||||
`./android/com/facebook/react/react-native/${releaseVersion}/${name}`,
|
||||
)
|
||||
) {
|
||||
echo(
|
||||
`Failing as expected file: \n\
|
||||
android/com/facebook/react/react-native/${releaseVersion}/${name}\n\
|
||||
was not correctly generated.`,
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
});
|
||||
generateAndroidArtifacts(releaseVersion, tmpPublishingFolder);
|
||||
|
||||
if (dryRunBuild) {
|
||||
echo('Skipping `npm publish` because --dry-run is set.');
|
||||
|
||||
@@ -100,7 +100,7 @@ generateCodegenArtifactsFromSchema () {
|
||||
generateArtifacts () {
|
||||
describe "Generating codegen artifacts"
|
||||
pushd "$RCT_SCRIPT_RN_DIR" >/dev/null || exit 1
|
||||
"$NODE_BINARY" "scripts/generate-artifacts.js" --path "$RCT_SCRIPT_APP_PATH" --outputPath "$TEMP_OUTPUT_DIR" --fabricEnabled "$RCT_SCRIPT_FABRIC_ENABLED" --configFileDir "$RCT_SCRIPT_CONFIG_FILE_DIR" --nodeBinary "$NODE_BINARY"
|
||||
"$NODE_BINARY" "scripts/generate-codegen-artifacts.js" --path "$RCT_SCRIPT_APP_PATH" --outputPath "$TEMP_OUTPUT_DIR" --fabricEnabled "$RCT_SCRIPT_FABRIC_ENABLED" --configFileDir "$RCT_SCRIPT_CONFIG_FILE_DIR" --nodeBinary "$NODE_BINARY"
|
||||
popd >/dev/null || exit 1
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const {exec, echo, exit, test, env} = require('shelljs');
|
||||
const {revertFiles, saveFiles} = require('./scm-utils');
|
||||
|
||||
function saveFilesToRestore(tmpPublishingFolder) {
|
||||
const filesToSaveAndRestore = [
|
||||
'template/Gemfile',
|
||||
'template/_ruby-version',
|
||||
'template/package.json',
|
||||
'.ruby-version',
|
||||
'Gemfile.lock',
|
||||
'Gemfile',
|
||||
'package.json',
|
||||
'ReactAndroid/gradle.properties',
|
||||
'Libraries/Core/ReactNativeVersion.js',
|
||||
'React/Base/RCTVersion.m',
|
||||
'ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java',
|
||||
'ReactCommon/cxxreact/ReactNativeVersion.h',
|
||||
];
|
||||
|
||||
saveFiles(filesToSaveAndRestore, tmpPublishingFolder);
|
||||
}
|
||||
|
||||
function generateAndroidArtifacts(releaseVersion, tmpPublishingFolder) {
|
||||
// -------- Generating Android Artifacts
|
||||
env.REACT_NATIVE_SKIP_PREFAB = true;
|
||||
if (exec('./gradlew :ReactAndroid:installArchives').code) {
|
||||
echo('Could not generate artifacts');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// -------- Generating the Hermes Engine Artifacts
|
||||
env.REACT_NATIVE_HERMES_SKIP_PREFAB = true;
|
||||
if (exec('./gradlew :ReactAndroid:hermes-engine:installArchives').code) {
|
||||
echo('Could not generate artifacts');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// undo uncommenting javadoc setting
|
||||
revertFiles(['ReactAndroid/gradle.properties'], tmpPublishingFolder);
|
||||
|
||||
echo('Generated artifacts for Maven');
|
||||
|
||||
let artifacts = [
|
||||
'.module',
|
||||
'.pom',
|
||||
'-debug.aar',
|
||||
'-release.aar',
|
||||
'-debug-sources.jar',
|
||||
'-release-sources.jar',
|
||||
].map(suffix => {
|
||||
return `react-native-${releaseVersion}${suffix}`;
|
||||
});
|
||||
|
||||
artifacts.forEach(name => {
|
||||
if (
|
||||
!test(
|
||||
'-e',
|
||||
`./android/com/facebook/react/react-native/${releaseVersion}/${name}`,
|
||||
)
|
||||
) {
|
||||
echo(
|
||||
`Failing as expected file: \n\
|
||||
android/com/facebook/react/react-native/${releaseVersion}/${name}\n\
|
||||
was not correctly generated.`,
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
generateAndroidArtifacts,
|
||||
saveFilesToRestore,
|
||||
};
|
||||
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/*
|
||||
* This script, paired with test-e2e-local.js, is the full suite of
|
||||
* tooling needed for a successful local testing experience.
|
||||
* This script is an helper to clean up the environment fully
|
||||
* before running the test suite.
|
||||
*
|
||||
* You should use this when switching between branches.
|
||||
*
|
||||
* It will:
|
||||
* - clean up node modules
|
||||
* - clean up the build folder (derived data, gradlew cleanAll)
|
||||
* - clean up the pods folder for RNTester (pod install) (and Podfile.lock too)
|
||||
* - kill all packagers
|
||||
* - remove RNTestProject folder
|
||||
*
|
||||
* an improvements to consider:
|
||||
* - an option to uninstall the apps (RNTester, RNTestProject) from emulators
|
||||
*/
|
||||
|
||||
const {exec, exit} = require('shelljs');
|
||||
|
||||
const {isPackagerRunning} = require('./testing-utils');
|
||||
|
||||
console.info('\n** Starting the clean up process **\n');
|
||||
|
||||
// let's check if Metro is already running, if it is let's kill it and start fresh
|
||||
if (isPackagerRunning() === 'running') {
|
||||
exec("lsof -i :8081 | grep LISTEN | /usr/bin/awk '{print $2}' | xargs kill");
|
||||
console.info('\n** Killed Metro **\n');
|
||||
}
|
||||
|
||||
// Android
|
||||
console.info('\n** Cleaning Gradle build artifacts **\n');
|
||||
exec('./gradlew cleanAll');
|
||||
|
||||
// iOS
|
||||
console.info('\n** Nuking the derived data folder **\n');
|
||||
exec('rm -rf ~/Library/Developer/Xcode/DerivedData');
|
||||
|
||||
// RNTester Pods
|
||||
console.info('\n** Removing the RNTester Pods **\n');
|
||||
exec('rm -rf packages/rn-tester/Pods');
|
||||
|
||||
// I'm not sure we want to also remove the lock file
|
||||
// exec('rm -rf packages/rn-tester/Podfile.lock');
|
||||
|
||||
// RNTestProject
|
||||
console.info('\n** Removing the RNTestProject folder **\n');
|
||||
exec('rm -rf /tmp/RNTestProject');
|
||||
|
||||
// final clean up
|
||||
console.info('\n** Final git level wipe **\n');
|
||||
// clean unstaged changes from git
|
||||
exec('git checkout -- .');
|
||||
// remove all the untracked files
|
||||
exec('git clean -fdx');
|
||||
|
||||
console.info(
|
||||
'\n** Clean up process completed\nPlease remember to run yarn install if you are planning to test again\n',
|
||||
);
|
||||
exit(0);
|
||||
@@ -0,0 +1,205 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/*
|
||||
* This script is a re-interpretation of the old test-manual.e2e.sh script.
|
||||
* the idea is to provide a better DX for the manual testing.
|
||||
* It's using Javascript over Bash for consistency with the rest of the recent scripts
|
||||
* and to make it more accessible for other devs to play around with.
|
||||
*/
|
||||
|
||||
const {exec, exit, pushd, popd, pwd, cd} = require('shelljs');
|
||||
const yargs = require('yargs');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
|
||||
const {
|
||||
launchAndroidEmulator,
|
||||
isPackagerRunning,
|
||||
launchPackagerInSeparateWindow,
|
||||
} = require('./testing-utils');
|
||||
|
||||
const {
|
||||
generateAndroidArtifacts,
|
||||
saveFilesToRestore,
|
||||
} = require('./release-utils');
|
||||
|
||||
const argv = yargs
|
||||
.option('t', {
|
||||
alias: 'target',
|
||||
default: 'RNTester',
|
||||
choices: ['RNTester', 'RNTestProject'],
|
||||
})
|
||||
.option('p', {
|
||||
alias: 'platform',
|
||||
default: 'iOS',
|
||||
choices: ['iOS', 'Android'],
|
||||
})
|
||||
.option('h', {
|
||||
alias: 'hermes',
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
}).argv;
|
||||
|
||||
/*
|
||||
* see the test-local-e2e.js script for clean up process
|
||||
*/
|
||||
|
||||
// command order: we ask the user to select if they want to test RN tester
|
||||
// or RNTestProject
|
||||
|
||||
// if they select RN tester, we ask if iOS or Android, and then we run the tests
|
||||
// if they select RNTestProject, we run the RNTestProject test
|
||||
|
||||
// let's check if Metro is already running, if it is let's kill it and start fresh
|
||||
if (isPackagerRunning() === 'running') {
|
||||
exec("lsof -i :8081 | grep LISTEN | /usr/bin/awk '{print $2}' | xargs kill");
|
||||
}
|
||||
|
||||
if (argv.target === 'RNTester') {
|
||||
// FIXME: make sure that the commands retains colors
|
||||
// (--ansi) doesn't always work
|
||||
// see also https://github.com/shelljs/shelljs/issues/86
|
||||
|
||||
if (argv.platform === 'iOS') {
|
||||
console.info(
|
||||
`We're going to test the ${
|
||||
argv.hermes ? 'Hermes' : 'JSC'
|
||||
} version of RNTester iOS`,
|
||||
);
|
||||
exec(
|
||||
`cd packages/rn-tester && USE_HERMES=${
|
||||
argv.hermes ? 1 : 0
|
||||
} 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();
|
||||
|
||||
// launch the app on iOS simulator
|
||||
pushd('packages/rn-tester');
|
||||
exec('npx react-native run-ios --scheme RNTester');
|
||||
popd();
|
||||
} else {
|
||||
// we do the android path here
|
||||
|
||||
launchAndroidEmulator();
|
||||
|
||||
console.info(
|
||||
`We're going to test the ${
|
||||
argv.hermes ? 'Hermes' : 'JSC'
|
||||
} version of RNTester Android`,
|
||||
);
|
||||
exec(
|
||||
`./gradlew :packages:rn-tester:android:app:${
|
||||
argv.hermes ? 'installHermesDebug' : 'installJscDebug'
|
||||
} --quiet`,
|
||||
);
|
||||
|
||||
// launch the app on Android simulator
|
||||
// TODO: we should find a way to make it work like for iOS, via npx react-native run-android
|
||||
// currently, that fails with an error.
|
||||
|
||||
// if everything succeeded so far, we can launch Metro and the app
|
||||
// start the Metro server in a separate window
|
||||
launchPackagerInSeparateWindow();
|
||||
// just to make sure that the Android up won't have troubles finding the Metro server
|
||||
exec('adb reverse tcp:8081 tcp:8081');
|
||||
// launch the app
|
||||
exec(
|
||||
'adb shell am start -n com.facebook.react.uiapp/com.facebook.react.uiapp.RNTesterActivity',
|
||||
);
|
||||
}
|
||||
} else {
|
||||
console.info("We're going to test a fresh new RN project");
|
||||
|
||||
// create the local npm package to feed the CLI
|
||||
|
||||
// base setup required (specular to publish-npm.js)
|
||||
const tmpPublishingFolder = fs.mkdtempSync(
|
||||
path.join(os.tmpdir(), 'rn-publish-'),
|
||||
);
|
||||
console.info(`The temp publishing folder is ${tmpPublishingFolder}`);
|
||||
|
||||
saveFilesToRestore(tmpPublishingFolder);
|
||||
|
||||
// we need to add the unique timestamp to avoid npm/yarn to use some local caches
|
||||
const baseVersion = require('../package.json').version;
|
||||
|
||||
const dateIdentifier = new Date()
|
||||
.toISOString()
|
||||
.slice(0, -8)
|
||||
.replace(/[-:]/g, '')
|
||||
.replace(/[T]/g, '-');
|
||||
|
||||
const releaseVersion = `${baseVersion}-${dateIdentifier}`;
|
||||
|
||||
// this is needed to generate the Android artifacts correctly
|
||||
exec(`node scripts/set-rn-version.js --to-version ${releaseVersion}`).code;
|
||||
|
||||
// Generate native files (Android only for now)
|
||||
generateAndroidArtifacts(releaseVersion, tmpPublishingFolder);
|
||||
|
||||
// create locally the node module
|
||||
exec('npm pack');
|
||||
|
||||
const localNodeTGZPath = `${pwd()}/react-native-${releaseVersion}.tgz`;
|
||||
exec(`node scripts/set-rn-template-version.js "file:${localNodeTGZPath}"`);
|
||||
|
||||
const repoRoot = pwd();
|
||||
|
||||
pushd('/tmp/');
|
||||
// need to avoid the pod install step because it will fail! (see above)
|
||||
exec(
|
||||
`node ${repoRoot}/cli.js init RNTestProject --template ${repoRoot} --skip-install`,
|
||||
);
|
||||
|
||||
cd('RNTestProject');
|
||||
exec('yarn install');
|
||||
|
||||
if (argv.platform === 'iOS') {
|
||||
// if we want iOS, we need to do pod install - but with a trick
|
||||
cd('ios');
|
||||
exec('bundle install');
|
||||
|
||||
// TODO: we should be able to also use HERMES_ENGINE_TARBALL_PATH
|
||||
// if we can make RNTester step generate it already so that it gets reused
|
||||
|
||||
// need to discern if it's main branch or release branch
|
||||
if (baseVersion === '1000.0.0') {
|
||||
// main branch
|
||||
exec(`USE_HERMES=${argv.hermes ? 1 : 0} bundle exec pod install --ansi`);
|
||||
} else {
|
||||
// TODO: to test this, I need to apply changes on top of a release branch
|
||||
// a release branch
|
||||
// copy over the .hermesversion file from react-native core into the RNTestProject
|
||||
exec(`cp -f ${repoRoot}/sdks/.hermesversion .`);
|
||||
exec(
|
||||
`CI=true USE_HERMES=${
|
||||
argv.hermes ? 1 : 0
|
||||
} bundle exec pod install --ansi`,
|
||||
);
|
||||
}
|
||||
cd('..');
|
||||
exec('yarn ios');
|
||||
} else {
|
||||
// android
|
||||
exec('yarn android');
|
||||
}
|
||||
popd();
|
||||
|
||||
// just cleaning up the temp folder, the rest is done by the test clean script
|
||||
exec(`rm -rf ${tmpPublishingFolder}`);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const {exec} = require('shelljs');
|
||||
const os = require('os');
|
||||
const {spawn} = require('node:child_process');
|
||||
|
||||
/*
|
||||
* Android related utils - leverages android tooling
|
||||
*/
|
||||
|
||||
// this code is taken from the CLI repo, slightly readapted to our needs
|
||||
// here's the reference folder:
|
||||
// https://github.com/react-native-community/cli/blob/main/packages/cli-platform-android/src/commands/runAndroid
|
||||
|
||||
const emulatorCommand = process.env.ANDROID_HOME
|
||||
? `${process.env.ANDROID_HOME}/emulator/emulator`
|
||||
: 'emulator';
|
||||
|
||||
const getEmulators = () => {
|
||||
const emulatorsOutput = exec(`${emulatorCommand} -list-avds`).stdout;
|
||||
return emulatorsOutput.split(os.EOL).filter(name => name !== '');
|
||||
};
|
||||
|
||||
const launchEmulator = emulatorName => {
|
||||
// we need both options 'cause reasons:
|
||||
// from docs: "When using the detached option to start a long-running process, the process will not stay running in the background after the parent exits unless it is provided with a stdio configuration that is not connected to the parent. If the parent's stdio is inherited, the child will remain attached to the controlling terminal."
|
||||
// here: https://nodejs.org/api/child_process.html#optionsdetached
|
||||
|
||||
const cp = spawn(emulatorCommand, [`@${emulatorName}`], {
|
||||
detached: true,
|
||||
stdio: 'ignore',
|
||||
});
|
||||
|
||||
cp.unref();
|
||||
};
|
||||
|
||||
function tryLaunchEmulator() {
|
||||
const emulators = getEmulators();
|
||||
if (emulators.length > 0) {
|
||||
try {
|
||||
launchEmulator(emulators[0]);
|
||||
|
||||
return {success: true};
|
||||
} catch (error) {
|
||||
return {success: false, error};
|
||||
}
|
||||
}
|
||||
return {
|
||||
success: false,
|
||||
error: 'No emulators found as an output of `emulator -list-avds`',
|
||||
};
|
||||
}
|
||||
|
||||
function launchAndroidEmulator() {
|
||||
const result = tryLaunchEmulator();
|
||||
if (result.success) {
|
||||
console.info('Successfully launched emulator.');
|
||||
} else {
|
||||
console.error(`Failed to launch emulator. Reason: ${result.error || ''}.`);
|
||||
console.warn(
|
||||
'Please launch an emulator manually or connect a device. Otherwise app may fail to launch.',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* iOS related utils - leverages xcodebuild
|
||||
*/
|
||||
|
||||
/*
|
||||
* Metro related utils
|
||||
*/
|
||||
|
||||
// inspired by CLI again https://github.com/react-native-community/cli/blob/main/packages/cli-tools/src/isPackagerRunning.ts
|
||||
|
||||
function isPackagerRunning(
|
||||
packagerPort = process.env.RCT_METRO_PORT || '8081',
|
||||
) {
|
||||
try {
|
||||
const status = exec(`curl http://localhost:${packagerPort}/status`, {
|
||||
silent: true,
|
||||
}).stdout;
|
||||
|
||||
return status === 'packager-status:running' ? 'running' : 'unrecognized';
|
||||
} catch (_error) {
|
||||
return 'not_running';
|
||||
}
|
||||
}
|
||||
|
||||
// this is a very limited implementation of how this should work
|
||||
// literally, this is macos only
|
||||
// a more robust implementation can be found here:
|
||||
// https://github.com/react-native-community/cli/blob/7c003f2b1d9d80ec5c167614ba533a004272c685/packages/cli-platform-android/src/commands/runAndroid/index.ts#L195
|
||||
function launchPackagerInSeparateWindow() {
|
||||
exec("open -a 'Terminal' ./scripts/packager.sh");
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
launchAndroidEmulator,
|
||||
isPackagerRunning,
|
||||
launchPackagerInSeparateWindow,
|
||||
};
|
||||
@@ -28,7 +28,7 @@ git = "https://github.com/facebook/hermes.git"
|
||||
if ENV.has_key?('HERMES_ENGINE_TARBALL_PATH')
|
||||
Pod::UI.puts '[Hermes] Using pre-built Hermes binaries from local path.' if Object.const_defined?("Pod::UI")
|
||||
source[:http] = "file://#{ENV['HERMES_ENGINE_TARBALL_PATH']}"
|
||||
elsif version == '1000.0.0' || version.start_with?('0.0.0-')
|
||||
elsif version.include? '1000.0.0'
|
||||
Pod::UI.puts '[Hermes] Installing hermes-engine may take a while, building Hermes from source...'.yellow if Object.const_defined?("Pod::UI")
|
||||
source[:git] = git
|
||||
source[:commit] = `git ls-remote https://github.com/facebook/hermes main | cut -f 1`.strip
|
||||
|
||||
Reference in New Issue
Block a user