mirror of
https://github.com/facebook/react-native.git
synced 2024-11-21 22:10:14 +00:00
Update test-e2e-local to use source monorepo packages for RNTestProject (#42899)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/42899 Updates the `test-e2e-local` script to bootstrap `/tmp/RNTestProject/` using the currently checked out repository as the source of truth for all monorepo packages (previously we only did this for the `react-native` package). This enables release testers to validate a release **before** physically publishing new dependency versions via `yarn bump-all-updated-packages`. We are able to reuse the `scripts/template/initialize.js` script that is currently used for E2E validation in CI. This sets up a local Verdaccio server during project install. NOTE: The time taken for `Build packages` + Verdaccio isn't ideal, I may explore a way to reuse the published package state in a future diff. Until then, this extra time (~1 min) will still be much less pain than the `bump-all-updated-packages` + commit process loop. Changelog: [Internal] - Update test-e2e-local to use source monorepo packages for RNTestProject Reviewed By: lunaleaps Differential Revision: D53484510 fbshipit-source-id: 600a8a3257a4947d7738ab9d908d6549c38545e6
This commit is contained in:
parent
15700626cc
commit
e4135e9be5
@ -360,7 +360,7 @@ jobs:
|
||||
command: |
|
||||
REPO_ROOT=$(pwd)
|
||||
node ./scripts/releases/update-template-package.js "{\"react-native\":\"file:$REPO_ROOT/build/$(cat build/react-native-package-version)\"}"
|
||||
node ./scripts/template/initialize.js --projectName $PROJECT_NAME --templatePath "$REPO_ROOT/packages/react-native" --directory "/tmp/$PROJECT_NAME"
|
||||
node ./scripts/template/initialize.js --projectName $PROJECT_NAME --templatePath "$REPO_ROOT/packages/react-native" --directory "/tmp/$PROJECT_NAME" --verbose
|
||||
- with_gradle_cache:
|
||||
steps:
|
||||
- run:
|
||||
@ -458,7 +458,7 @@ jobs:
|
||||
PACKAGE=$(cat build/react-native-package-version)
|
||||
PATH_TO_PACKAGE="$REPO_ROOT/build/$PACKAGE"
|
||||
node ./scripts/releases/update-template-package.js "{\"react-native\":\"file:$PATH_TO_PACKAGE\"}"
|
||||
node ./scripts/template/initialize.js --projectName $PROJECT_NAME --templatePath "$REPO_ROOT/packages/react-native" --directory "/tmp/$PROJECT_NAME"
|
||||
node ./scripts/template/initialize.js --projectName $PROJECT_NAME --templatePath "$REPO_ROOT/packages/react-native" --directory "/tmp/$PROJECT_NAME" --verbose
|
||||
- with_xcodebuild_cache:
|
||||
podfile_lock_path: << parameters.podfile_lock_path >>
|
||||
pods_build_folder: << parameters.pods_build_folder >>
|
||||
|
@ -29,6 +29,7 @@
|
||||
* - an option to uninstall the apps (RNTester, RNTestProject) from emulators
|
||||
*/
|
||||
|
||||
const {VERDACCIO_STORAGE_PATH} = require('../template/setup-verdaccio');
|
||||
const {isPackagerRunning} = require('./utils/testing-utils');
|
||||
const {exec, exit} = require('shelljs');
|
||||
|
||||
@ -61,6 +62,9 @@ exec('rm -rf packages/rn-tester/Pods');
|
||||
console.info('\n** Removing the RNTestProject folder **\n');
|
||||
exec('rm -rf /tmp/RNTestProject');
|
||||
|
||||
console.info('\n** Removing Verdaccio storage directory **\n');
|
||||
exec(`rm -rf ${VERDACCIO_STORAGE_PATH}`);
|
||||
|
||||
// final clean up
|
||||
console.info('\n** Final git level wipe **\n');
|
||||
// clean unstaged changes from git
|
||||
|
@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
const updateTemplatePackage = require('../releases/update-template-package');
|
||||
const {initNewProjectFromSource} = require('../template/initialize');
|
||||
const {
|
||||
checkPackagerRunning,
|
||||
launchPackagerInSeparateWindow,
|
||||
@ -25,6 +26,7 @@ const {
|
||||
prepareArtifacts,
|
||||
setupCircleCIArtifacts,
|
||||
} = require('./utils/testing-utils');
|
||||
const debug = require('debug')('test-e2e-local');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const {cd, exec, popd, pushd, pwd, sed} = require('shelljs');
|
||||
@ -34,6 +36,8 @@ const yargs = require('yargs');
|
||||
type Unwrap<T> = T extends Promise<infer U> ? U : T;
|
||||
*/
|
||||
|
||||
const REPO_ROOT = path.resolve(__dirname, '../..');
|
||||
|
||||
const argv = yargs
|
||||
.option('t', {
|
||||
alias: 'target',
|
||||
@ -211,9 +215,7 @@ async function testRNTestProject(
|
||||
const releaseVersion = `1000.0.0-${shortCommit}`;
|
||||
const buildType = 'dry-run';
|
||||
|
||||
// Prepare some variables for later use
|
||||
const repoRoot = pwd().toString();
|
||||
const reactNativePackagePath = `${repoRoot}/packages/react-native`;
|
||||
const reactNativePackagePath = `${REPO_ROOT}/packages/react-native`;
|
||||
const localNodeTGZPath = `${reactNativePackagePath}/react-native-${releaseVersion}.tgz`;
|
||||
|
||||
const mavenLocalPath =
|
||||
@ -256,13 +258,16 @@ async function testRNTestProject(
|
||||
});
|
||||
|
||||
pushd('/tmp/');
|
||||
// need to avoid the pod install step - we'll do it later
|
||||
exec(
|
||||
`node ${reactNativePackagePath}/cli.js init RNTestProject --template ${reactNativePackagePath} --skip-install`,
|
||||
);
|
||||
|
||||
debug('Creating RNTestProject from template');
|
||||
|
||||
await initNewProjectFromSource({
|
||||
projectName: 'RNTestProject',
|
||||
directory: '/tmp/RNTestProject',
|
||||
templatePath: reactNativePackagePath,
|
||||
});
|
||||
|
||||
cd('RNTestProject');
|
||||
exec('yarn install');
|
||||
|
||||
// When using CircleCI artifacts, the CI will zip maven local into a
|
||||
// /tmp/maven-local subfolder struct.
|
||||
@ -336,5 +341,7 @@ async function main() {
|
||||
}
|
||||
}
|
||||
|
||||
// $FlowIgnoreError[unused-promise]
|
||||
main();
|
||||
if (require.main === module) {
|
||||
// eslint-disable-next-line no-void
|
||||
void main();
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
*/
|
||||
|
||||
const forEachPackage = require('./monorepo/for-each-package');
|
||||
const setupVerdaccio = require('./template/setup-verdaccio');
|
||||
const {setupVerdaccio} = require('./template/setup-verdaccio');
|
||||
const tryExecNTimes = require('./try-n-times');
|
||||
const {execFileSync, spawn} = require('child_process');
|
||||
const fs = require('fs');
|
||||
|
@ -13,26 +13,31 @@
|
||||
|
||||
const {retry} = require('../circleci/retry');
|
||||
const forEachPackage = require('../monorepo/for-each-package');
|
||||
const setupVerdaccio = require('./setup-verdaccio');
|
||||
const {
|
||||
VERDACCIO_SERVER_URL,
|
||||
VERDACCIO_STORAGE_PATH,
|
||||
setupVerdaccio,
|
||||
} = require('./setup-verdaccio');
|
||||
const {parseArgs} = require('@pkgjs/parseargs');
|
||||
const chalk = require('chalk');
|
||||
const {execSync} = require('child_process');
|
||||
const path = require('path');
|
||||
|
||||
const REPO_ROOT = path.resolve(__dirname, '../..');
|
||||
const NPM_REGISTRY_SERVER = 'http://localhost:4873';
|
||||
|
||||
const config = {
|
||||
options: {
|
||||
projectName: {type: 'string'},
|
||||
templatePath: {type: 'string'},
|
||||
directory: {type: 'string'},
|
||||
verbose: {type: 'boolean', default: false},
|
||||
help: {type: 'boolean'},
|
||||
},
|
||||
};
|
||||
|
||||
async function main() {
|
||||
const {
|
||||
values: {help, projectName, templatePath, directory},
|
||||
values: {help, ...options},
|
||||
} = parseArgs(config);
|
||||
|
||||
if (help) {
|
||||
@ -55,94 +60,119 @@ async function main() {
|
||||
--projectName The name of the new React Native project.
|
||||
--templatePath The absolute path to the folder containing the template.
|
||||
--directory The absolute path to the target project directory.
|
||||
--verbose Print additional output. Default: false.
|
||||
`);
|
||||
return;
|
||||
}
|
||||
|
||||
const VERDACCIO_PID = setupVerdaccio();
|
||||
await initNewProjectFromSource(options);
|
||||
}
|
||||
|
||||
async function initNewProjectFromSource(
|
||||
{
|
||||
projectName,
|
||||
templatePath,
|
||||
directory,
|
||||
verbose = false,
|
||||
} /*: {projectName: string, templatePath: string, directory: string, verbose?: boolean} */,
|
||||
) {
|
||||
console.log('Starting local npm proxy (Verdaccio)');
|
||||
const verdaccioPid = setupVerdaccio();
|
||||
console.log('Done ✅');
|
||||
|
||||
try {
|
||||
process.stdout.write('Bootstrapped Verdaccio \u2705\n');
|
||||
|
||||
process.stdout.write('Building packages...\n');
|
||||
execSync('node ./scripts/build/build.js', {
|
||||
cwd: REPO_ROOT,
|
||||
stdio: [process.stdin, process.stdout, process.stderr],
|
||||
stdio: 'inherit',
|
||||
});
|
||||
console.log('\nDone ✅');
|
||||
|
||||
process.stdout.write('Starting to publish every package...\n');
|
||||
console.log('Publishing packages to local npm proxy\n');
|
||||
forEachPackage(
|
||||
(packageAbsolutePath, packageRelativePathFromRoot, packageManifest) => {
|
||||
if (packageManifest.private) {
|
||||
return;
|
||||
}
|
||||
|
||||
const desc = `${packageManifest.name} (${packageRelativePathFromRoot})`;
|
||||
process.stdout.write(
|
||||
`${desc} ${chalk.dim('.').repeat(Math.max(0, 72 - desc.length))} `,
|
||||
);
|
||||
execSync(
|
||||
`npm publish --registry ${NPM_REGISTRY_SERVER} --access public`,
|
||||
`npm publish --registry ${VERDACCIO_SERVER_URL} --access public`,
|
||||
{
|
||||
cwd: packageAbsolutePath,
|
||||
stdio: [process.stdin, process.stdout, process.stderr],
|
||||
stdio: verbose ? 'inherit' : [process.stderr],
|
||||
},
|
||||
);
|
||||
|
||||
process.stdout.write(
|
||||
`Published ${packageManifest.name} to proxy \u2705\n`,
|
||||
);
|
||||
process.stdout.write(chalk.reset.inverse.bold.green(' DONE ') + '\n');
|
||||
},
|
||||
);
|
||||
console.log('\nDone ✅');
|
||||
|
||||
process.stdout.write('Published every package \u2705\n');
|
||||
|
||||
console.log('Running react-native init without install');
|
||||
execSync(
|
||||
`node cli.js init ${projectName} \
|
||||
`node ./packages/react-native/cli.js init ${projectName} \
|
||||
--directory ${directory} \
|
||||
--template ${templatePath} \
|
||||
--verbose \
|
||||
--skip-install \
|
||||
--yarn-config-options npmRegistryServer="${NPM_REGISTRY_SERVER}"`,
|
||||
--yarn-config-options npmRegistryServer="${VERDACCIO_SERVER_URL}"`,
|
||||
{
|
||||
cwd: `${REPO_ROOT}/packages/react-native`,
|
||||
stdio: [process.stdin, process.stdout, process.stderr],
|
||||
// Avoid loading packages/react-native/react-native.config.js
|
||||
cwd: REPO_ROOT,
|
||||
stdio: verbose ? 'inherit' : [process.stderr],
|
||||
},
|
||||
);
|
||||
process.stdout.write('Completed initialization of template app \u2705\n');
|
||||
console.log('\nDone ✅');
|
||||
|
||||
process.stdout.write('Installing dependencies in template app folder...\n');
|
||||
const options = {
|
||||
cwd: directory,
|
||||
stdio: [process.stdin, process.stdout, process.stderr],
|
||||
};
|
||||
|
||||
execSync(
|
||||
`yarn config set npmRegistryServer "${NPM_REGISTRY_SERVER}"`,
|
||||
options,
|
||||
);
|
||||
|
||||
execSync(
|
||||
'yarn config set unsafeHttpWhitelist --json \'["localhost"]\'',
|
||||
options,
|
||||
);
|
||||
|
||||
const success = await retry('yarn', options, 3, 500, ['install']);
|
||||
|
||||
if (!success) {
|
||||
process.stdout.write(
|
||||
'Failed to install dependencies in template app folder.',
|
||||
);
|
||||
throw new Error('Failed to install dependencies in template app folder.');
|
||||
}
|
||||
|
||||
process.stdout.write('Installed dependencies via Yarn \u2705\n');
|
||||
console.log('Installing project dependencies');
|
||||
await runYarnUsingProxy(directory);
|
||||
console.log('Done ✅');
|
||||
} catch (e) {
|
||||
console.log('Failed ❌');
|
||||
throw e;
|
||||
} finally {
|
||||
process.stdout.write(`Killing verdaccio. PID — ${VERDACCIO_PID}...\n`);
|
||||
execSync(`kill -9 ${VERDACCIO_PID}`);
|
||||
process.stdout.write('Killed Verdaccio process \u2705\n');
|
||||
console.log(`Cleanup: Killing Verdaccio process (PID: ${verdaccioPid})`);
|
||||
execSync(`kill -9 ${verdaccioPid}`);
|
||||
console.log('Done ✅');
|
||||
|
||||
console.log('Cleanup: Removing Verdaccio storage directory');
|
||||
execSync(`rm -rf ${VERDACCIO_STORAGE_PATH}`);
|
||||
console.log('Done ✅');
|
||||
|
||||
// TODO(huntie): Fix memory leak from `spawn` in `setupVerdaccio` (above
|
||||
// kill command does not wait for kill success).
|
||||
process.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
async function runYarnUsingProxy(cwd /*: string */) {
|
||||
const execOptions = {
|
||||
cwd,
|
||||
stdio: 'inherit',
|
||||
};
|
||||
execSync(
|
||||
`yarn config set npmRegistryServer "${VERDACCIO_SERVER_URL}"`,
|
||||
execOptions,
|
||||
);
|
||||
execSync(
|
||||
'yarn config set unsafeHttpWhitelist --json \'["localhost"]\'',
|
||||
execOptions,
|
||||
);
|
||||
|
||||
// TODO(huntie): Review pre-existing retry limit
|
||||
const success = await retry('yarn', execOptions, 3, 500, ['install']);
|
||||
|
||||
if (!success) {
|
||||
throw new Error('Failed to install project dependencies');
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
initNewProjectFromSource,
|
||||
};
|
||||
|
||||
if (require.main === module) {
|
||||
// eslint-disable-next-line no-void
|
||||
void main();
|
||||
|
@ -48,4 +48,8 @@ function setupVerdaccio() /*: number */ {
|
||||
return verdaccioProcess.pid;
|
||||
}
|
||||
|
||||
module.exports = setupVerdaccio;
|
||||
module.exports = {
|
||||
setupVerdaccio,
|
||||
VERDACCIO_SERVER_URL,
|
||||
VERDACCIO_STORAGE_PATH,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user