Port changes in the release testing script from the release branch (#45174)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45174

As per title, this port bck to main the changes we made in the release testing script.

## Changelog:
[Internal] - Update release testing script to work with the new template

Reviewed By: blakef

Differential Revision: D59054045

fbshipit-source-id: 0e93c2db94499407845b4fb2c98c8b44310e770f
This commit is contained in:
Riccardo Cipolleschi 2024-06-27 04:11:44 -07:00 committed by Facebook GitHub Bot
parent cf8d3f8007
commit 119ab33036
3 changed files with 75 additions and 36 deletions

View File

@ -11,6 +11,8 @@
'use strict'; 'use strict';
/*:: import type {ProjectInfo} from '../utils/monorepo'; */
const {retry} = require('../circleci/retry'); const {retry} = require('../circleci/retry');
const {REPO_ROOT} = require('../consts'); const {REPO_ROOT} = require('../consts');
const {getPackages} = require('../utils/monorepo'); const {getPackages} = require('../utils/monorepo');
@ -22,12 +24,12 @@ const {
const {parseArgs} = require('@pkgjs/parseargs'); const {parseArgs} = require('@pkgjs/parseargs');
const chalk = require('chalk'); const chalk = require('chalk');
const {execSync} = require('child_process'); const {execSync} = require('child_process');
const fs = require('fs');
const path = require('path'); const path = require('path');
const config = { const config = {
options: { options: {
projectName: {type: 'string'}, projectName: {type: 'string'},
templatePath: {type: 'string'},
directory: {type: 'string'}, directory: {type: 'string'},
verbose: {type: 'boolean', default: false}, verbose: {type: 'boolean', default: false},
help: {type: 'boolean'}, help: {type: 'boolean'},
@ -56,10 +58,10 @@ async function main() {
should not be committed. should not be committed.
Options: Options:
--projectName The name of the new React Native project. --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.
--directory The absolute path to the target project directory. --pathToLocalReactNative The absolute path to the local react-native package.
--verbose Print additional output. Default: false. --verbose Print additional output. Default: false.
`); `);
return; return;
} }
@ -74,10 +76,10 @@ async function main() {
async function initNewProjectFromSource( async function initNewProjectFromSource(
{ {
projectName, projectName,
templatePath,
directory, directory,
pathToLocalReactNative = null,
verbose = false, verbose = false,
} /*: {projectName: string, templatePath: string, directory: string, verbose?: boolean} */, } /*: {projectName: string, directory: string, pathToLocalReactNative?: ?string, verbose?: boolean} */,
) { ) {
console.log('Starting local npm proxy (Verdaccio)'); console.log('Starting local npm proxy (Verdaccio)');
const verdaccioPid = setupVerdaccio(); const verdaccioPid = setupVerdaccio();
@ -117,9 +119,9 @@ async function initNewProjectFromSource(
console.log('Running react-native init without install'); console.log('Running react-native init without install');
execSync( execSync(
`node ./packages/react-native/cli.js init ${projectName} \ `npx @react-native-community/cli@next init ${projectName} \
--directory ${directory} \ --directory ${directory} \
--template ${templatePath} \ --version 0.75.0-rc.2 \
--verbose \ --verbose \
--pm npm \ --pm npm \
--skip-install`, --skip-install`,
@ -131,6 +133,9 @@ async function initNewProjectFromSource(
); );
console.log('\nDone ✅'); console.log('\nDone ✅');
_updateScopedPackages(packages, directory);
_updateReactNativeInTemplateIfNeeded(pathToLocalReactNative, directory);
console.log('Installing project dependencies'); console.log('Installing project dependencies');
await installProjectUsingProxy(directory); await installProjectUsingProxy(directory);
console.log('Done ✅'); console.log('Done ✅');
@ -169,6 +174,61 @@ async function installProjectUsingProxy(cwd /*: string */) {
} }
} }
function _updateScopedPackages(
packages /*: ProjectInfo */,
directory /*: string */,
) {
console.log(
'Updating the scoped packagesto match the version published in Verdaccio',
);
// Packages are updated in a lockstep and all with the same version.
// Pick the version from the first package
const version = packages[Object.keys(packages)[0]].packageJson.version;
// Update scoped packages which starts with @react-native
const appPackageJsonPath = path.join(directory, 'package.json');
const appPackageJson = JSON.parse(
fs.readFileSync(appPackageJsonPath, 'utf8'),
);
for (const [key, _] of Object.entries(appPackageJson.dependencies)) {
if (key.startsWith('@react-native')) {
appPackageJson.dependencies[key] = version;
}
}
for (const [key, _] of Object.entries(appPackageJson.devDependencies)) {
if (key.startsWith('@react-native')) {
appPackageJson.devDependencies[key] = version;
}
}
fs.writeFileSync(appPackageJsonPath, JSON.stringify(appPackageJson, null, 2));
console.log('Done ✅');
}
function _updateReactNativeInTemplateIfNeeded(
pathToLocalReactNative /*: ?string */,
directory /*: string */,
) {
if (pathToLocalReactNative != null) {
console.log('Updating the template version to local react-native');
// Update template version.
const appPackageJsonPath = path.join(directory, 'package.json');
const appPackageJson = JSON.parse(
fs.readFileSync(appPackageJsonPath, 'utf8'),
);
appPackageJson.dependencies['react-native'] =
`file:${pathToLocalReactNative}`;
fs.writeFileSync(
appPackageJsonPath,
JSON.stringify(appPackageJson, null, 2),
);
console.log('Done ✅');
}
}
module.exports = { module.exports = {
initNewProjectFromSource, initNewProjectFromSource,
}; };

View File

@ -24,7 +24,6 @@ const {
launchPackagerInSeparateWindow, launchPackagerInSeparateWindow,
maybeLaunchAndroidEmulator, maybeLaunchAndroidEmulator,
prepareArtifacts, prepareArtifacts,
setupCircleCIArtifacts,
setupGHAArtifacts, setupGHAArtifacts,
} = require('./utils/testing-utils'); } = require('./utils/testing-utils');
const chalk = require('chalk'); const chalk = require('chalk');
@ -78,7 +77,7 @@ const argv = yargs
* - @onReleaseBranch whether we are on a release branch or not * - @onReleaseBranch whether we are on a release branch or not
*/ */
async function testRNTesterIOS( async function testRNTesterIOS(
ciArtifacts /*: Unwrap<ReturnType<typeof setupCircleCIArtifacts>> */, ciArtifacts /*: Unwrap<ReturnType<typeof setupGHAArtifacts>> */,
onReleaseBranch /*: boolean */, onReleaseBranch /*: boolean */,
) { ) {
console.info( console.info(
@ -130,7 +129,7 @@ async function testRNTesterIOS(
* - @circleCIArtifacts manager object to manage all the download of CircleCIArtifacts. If null, it will fallback not to use them. * - @circleCIArtifacts manager object to manage all the download of CircleCIArtifacts. If null, it will fallback not to use them.
*/ */
async function testRNTesterAndroid( async function testRNTesterAndroid(
ciArtifacts /*: Unwrap<ReturnType<typeof setupCircleCIArtifacts>> */, ciArtifacts /*: Unwrap<ReturnType<typeof setupGHAArtifacts>> */,
) { ) {
maybeLaunchAndroidEmulator(); maybeLaunchAndroidEmulator();
@ -206,7 +205,7 @@ async function testRNTesterAndroid(
* - @onReleaseBranch whether we are on a release branch or not * - @onReleaseBranch whether we are on a release branch or not
*/ */
async function testRNTester( async function testRNTester(
circleCIArtifacts /*:Unwrap<ReturnType<typeof setupCircleCIArtifacts>> */, circleCIArtifacts /*:Unwrap<ReturnType<typeof setupGHAArtifacts>> */,
onReleaseBranch /*: boolean */, onReleaseBranch /*: boolean */,
) { ) {
// FIXME: make sure that the commands retains colors // FIXME: make sure that the commands retains colors
@ -225,7 +224,7 @@ async function testRNTester(
// === RNTestProject === // // === RNTestProject === //
async function testRNTestProject( async function testRNTestProject(
ciArtifacts /*: Unwrap<ReturnType<typeof setupCircleCIArtifacts>> */, ciArtifacts /*: Unwrap<ReturnType<typeof setupGHAArtifacts>> */,
) { ) {
console.info("We're going to test a fresh new RN project"); console.info("We're going to test a fresh new RN project");
@ -244,11 +243,6 @@ async function testRNTestProject(
const buildType = 'dry-run'; const buildType = 'dry-run';
const reactNativePackagePath = `${REPO_ROOT}/packages/react-native`; const reactNativePackagePath = `${REPO_ROOT}/packages/react-native`;
const templateRepoFolder = '/tmp/template';
const pathToTemplate = path.join(templateRepoFolder, 'template');
// Cleanup template clone folder
exec(`rm -rf ${templateRepoFolder}`);
const localNodeTGZPath = `${reactNativePackagePath}/react-native-${releaseVersion}.tgz`; const localNodeTGZPath = `${reactNativePackagePath}/react-native-${releaseVersion}.tgz`;
const mavenLocalPath = const mavenLocalPath =
@ -286,21 +280,6 @@ async function testRNTestProject(
} }
} }
// Cloning the template repo
// TODO: handle versioning of the template to make sure that we are downloading the right version of
// the template, given a specific React Native version
exec(
`git clone https://github.com/react-native-community/template ${templateRepoFolder} --depth=1`,
);
// Update template version.
const appPackageJsonPath = path.join(pathToTemplate, 'package.json');
const appPackageJson = JSON.parse(
fs.readFileSync(appPackageJsonPath, 'utf8'),
);
appPackageJson.dependencies['react-native'] = `file:${newLocalNodeTGZ}`;
fs.writeFileSync(appPackageJsonPath, JSON.stringify(appPackageJson, null, 2));
pushd('/tmp/'); pushd('/tmp/');
debug('Creating RNTestProject from template'); debug('Creating RNTestProject from template');
@ -311,7 +290,7 @@ async function testRNTestProject(
await initNewProjectFromSource({ await initNewProjectFromSource({
projectName: 'RNTestProject', projectName: 'RNTestProject',
directory: '/tmp/RNTestProject', directory: '/tmp/RNTestProject',
templatePath: templateRepoFolder, pathToLocalReactNative: newLocalNodeTGZ,
}); });
cd('RNTestProject'); cd('RNTestProject');

View File

@ -42,7 +42,7 @@ export type PackageInfo = {
packageJson: PackageJson, packageJson: PackageJson,
}; };
type ProjectInfo = { export type ProjectInfo = {
[packageName: string]: PackageInfo, [packageName: string]: PackageInfo,
}; };
*/ */