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';
/*:: import type {ProjectInfo} from '../utils/monorepo'; */
const {retry} = require('../circleci/retry');
const {REPO_ROOT} = require('../consts');
const {getPackages} = require('../utils/monorepo');
@ -22,12 +24,12 @@ const {
const {parseArgs} = require('@pkgjs/parseargs');
const chalk = require('chalk');
const {execSync} = require('child_process');
const fs = require('fs');
const path = require('path');
const config = {
options: {
projectName: {type: 'string'},
templatePath: {type: 'string'},
directory: {type: 'string'},
verbose: {type: 'boolean', default: false},
help: {type: 'boolean'},
@ -57,8 +59,8 @@ async function main() {
Options:
--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.
--pathToLocalReactNative The absolute path to the local react-native package.
--verbose Print additional output. Default: false.
`);
return;
@ -74,10 +76,10 @@ async function main() {
async function initNewProjectFromSource(
{
projectName,
templatePath,
directory,
pathToLocalReactNative = null,
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)');
const verdaccioPid = setupVerdaccio();
@ -117,9 +119,9 @@ async function initNewProjectFromSource(
console.log('Running react-native init without install');
execSync(
`node ./packages/react-native/cli.js init ${projectName} \
`npx @react-native-community/cli@next init ${projectName} \
--directory ${directory} \
--template ${templatePath} \
--version 0.75.0-rc.2 \
--verbose \
--pm npm \
--skip-install`,
@ -131,6 +133,9 @@ async function initNewProjectFromSource(
);
console.log('\nDone ✅');
_updateScopedPackages(packages, directory);
_updateReactNativeInTemplateIfNeeded(pathToLocalReactNative, directory);
console.log('Installing project dependencies');
await installProjectUsingProxy(directory);
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 = {
initNewProjectFromSource,
};

View File

@ -24,7 +24,6 @@ const {
launchPackagerInSeparateWindow,
maybeLaunchAndroidEmulator,
prepareArtifacts,
setupCircleCIArtifacts,
setupGHAArtifacts,
} = require('./utils/testing-utils');
const chalk = require('chalk');
@ -78,7 +77,7 @@ const argv = yargs
* - @onReleaseBranch whether we are on a release branch or not
*/
async function testRNTesterIOS(
ciArtifacts /*: Unwrap<ReturnType<typeof setupCircleCIArtifacts>> */,
ciArtifacts /*: Unwrap<ReturnType<typeof setupGHAArtifacts>> */,
onReleaseBranch /*: boolean */,
) {
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.
*/
async function testRNTesterAndroid(
ciArtifacts /*: Unwrap<ReturnType<typeof setupCircleCIArtifacts>> */,
ciArtifacts /*: Unwrap<ReturnType<typeof setupGHAArtifacts>> */,
) {
maybeLaunchAndroidEmulator();
@ -206,7 +205,7 @@ async function testRNTesterAndroid(
* - @onReleaseBranch whether we are on a release branch or not
*/
async function testRNTester(
circleCIArtifacts /*:Unwrap<ReturnType<typeof setupCircleCIArtifacts>> */,
circleCIArtifacts /*:Unwrap<ReturnType<typeof setupGHAArtifacts>> */,
onReleaseBranch /*: boolean */,
) {
// FIXME: make sure that the commands retains colors
@ -225,7 +224,7 @@ async function testRNTester(
// === RNTestProject === //
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");
@ -244,11 +243,6 @@ async function testRNTestProject(
const buildType = 'dry-run';
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 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/');
debug('Creating RNTestProject from template');
@ -311,7 +290,7 @@ async function testRNTestProject(
await initNewProjectFromSource({
projectName: 'RNTestProject',
directory: '/tmp/RNTestProject',
templatePath: templateRepoFolder,
pathToLocalReactNative: newLocalNodeTGZ,
});
cd('RNTestProject');

View File

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