Re-sync with internal repository (#37831)

Co-authored-by: Facebook Community Bot <6422482+facebook-github-bot@users.noreply.github.com>
This commit is contained in:
Facebook Community Bot 2023-06-12 14:34:52 -07:00 коммит произвёл GitHub
Родитель a300a35f28
Коммит 2eba6ab5ac
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
11 изменённых файлов: 237 добавлений и 114 удалений

Просмотреть файл

@ -795,7 +795,7 @@ jobs:
name: Create Android template project
command: |
REPO_ROOT=$(pwd)
node ./scripts/set-rn-template-version.js "file:$REPO_ROOT/build/$(cat build/react-native-package-version)"
node ./scripts/update-template-package.js "{\"react-native\":\"file:$REPO_ROOT/build/$(cat build/react-native-package-version)\"}"
node ./scripts/template/initialize.js --reactNativeRootPath $REPO_ROOT --templateName $PROJECT_NAME --templateConfigPath "$REPO_ROOT/packages/react-native" --directory "/tmp/$PROJECT_NAME"
- run:
name: Build the template application for << parameters.flavor >> with Architecture set to << parameters.architecture >>, and using the << parameters.jsengine>> JS engine.
@ -879,7 +879,7 @@ jobs:
REPO_ROOT=$(pwd)
PACKAGE=$(cat build/react-native-package-version)
PATH_TO_PACKAGE="$REPO_ROOT/build/$PACKAGE"
node ./scripts/set-rn-template-version.js "file:$PATH_TO_PACKAGE"
node ./scripts/update-template-package.js "{\"react-native\":\"file:$PATH_TO_PACKAGE\"}"
node ./scripts/template/initialize.js --reactNativeRootPath $REPO_ROOT --templateName $PROJECT_NAME --templateConfigPath "$REPO_ROOT/packages/react-native" --directory "/tmp/$PROJECT_NAME"
- run:
name: Install iOS dependencies - Configuration << parameters.flavor >>; New Architecture << parameters.architecture >>; JS Engine << parameters.jsengine>>; Flipper << parameters.flipper >>

Просмотреть файл

@ -7,7 +7,11 @@
* @format
*/
const {getPackageVersionStrByTag, publishPackage} = require('../npm-utils');
const {
applyPackageVersions,
getPackageVersionStrByTag,
publishPackage,
} = require('../npm-utils');
const execMock = jest.fn();
jest.mock('shelljs', () => ({
@ -20,6 +24,47 @@ describe('npm-utils', () => {
jest.resetAllMocks();
});
describe('applyPackageVersions', () => {
it('should replace package.json with dependencies', () => {
const originalPackageJson = {
name: 'my-package',
dependencies: {
'my-dependency-a': 'nightly',
'my-dependency-b': '^1.2.3',
},
devDependencies: {
'my-dev-dependency-a': 'nightly',
'my-dev-dependency-b': '^1.2.3',
},
someOtherField: {
'my-dependency-a': 'should-be-untouched',
},
};
const dependencies = {
'my-dependency-a': '0.72.0-nightly-shortcommit',
'my-dev-dependency-a': 'updated-version',
'my-non-existant-dep': 'some-version',
};
const package = applyPackageVersions(originalPackageJson, dependencies);
expect(package).toEqual({
name: 'my-package',
dependencies: {
'my-dependency-a': '0.72.0-nightly-shortcommit',
'my-dependency-b': '^1.2.3',
},
devDependencies: {
'my-dev-dependency-a': 'updated-version',
'my-dev-dependency-b': '^1.2.3',
},
someOtherField: {
'my-dependency-a': 'should-be-untouched',
},
});
});
});
describe('getPackageVersionStrByTag', () => {
it('should return package version string', () => {
execMock.mockImplementationOnce(() => ({code: 0, stdout: '0.34.2 \n'}));

Просмотреть файл

@ -10,7 +10,9 @@
const execMock = jest.fn();
const echoMock = jest.fn();
const exitMock = jest.fn();
const consoleErrorMock = jest.fn();
const isTaggedLatestMock = jest.fn();
const setReactNativeVersionMock = jest.fn();
const publishAndroidArtifactsToMavenMock = jest.fn();
const env = process.env;
@ -33,11 +35,13 @@ jest
generateAndroidArtifacts: jest.fn(),
publishAndroidArtifactsToMaven: publishAndroidArtifactsToMavenMock,
}))
.mock('./../set-rn-version', () => setReactNativeVersionMock)
.mock('../monorepo/get-and-update-nightlies');
const date = new Date('2023-04-20T23:52:39.543Z');
const publishNpm = require('../publish-npm');
let consoleError;
describe('publish-npm', () => {
beforeAll(() => {
@ -47,8 +51,14 @@ describe('publish-npm', () => {
afterAll(() => {
jest.useRealTimers();
});
beforeEach(() => {
consoleError = console.error;
console.error = consoleErrorMock;
});
afterEach(() => {
process.env = env;
console.error = consoleError;
});
afterEach(() => {
@ -58,8 +68,6 @@ describe('publish-npm', () => {
describe('dry-run', () => {
it('should set version and not publish', () => {
execMock.mockReturnValueOnce({code: 0});
publishNpm('dry-run');
expect(exitMock).toHaveBeenCalledWith(0);
@ -67,10 +75,11 @@ describe('publish-npm', () => {
expect(echoMock).toHaveBeenCalledWith(
'Skipping `npm publish` because --dry-run is set.',
);
expect(execMock).toHaveBeenCalledWith(
'node scripts/set-rn-version.js --to-version 1000.0.0-currentco --build-type dry-run',
expect(setReactNativeVersionMock).toBeCalledWith(
'1000.0.0-currentco',
null,
'dry-run',
);
expect(execMock.mock.calls).toHaveLength(1);
});
});
@ -78,7 +87,6 @@ describe('publish-npm', () => {
it('should publish', () => {
execMock
.mockReturnValueOnce({stdout: '0.81.0-rc.1\n', code: 0})
.mockReturnValueOnce({code: 0})
.mockReturnValueOnce({code: 0});
const expectedVersion = '0.82.0-nightly-20230420-currentco';
@ -91,22 +99,19 @@ describe('publish-npm', () => {
expect(execMock.mock.calls[0][0]).toBe(
`npm view react-native@next version`,
);
expect(execMock.mock.calls[1][0]).toBe(
`node scripts/set-rn-version.js --to-version ${expectedVersion} --build-type nightly`,
);
expect(execMock.mock.calls[2][0]).toBe('npm publish --tag nightly');
expect(execMock.mock.calls[1][0]).toBe('npm publish --tag nightly');
expect(echoMock).toHaveBeenCalledWith(
`Published to npm ${expectedVersion}`,
);
expect(exitMock).toHaveBeenCalledWith(0);
expect(execMock.mock.calls).toHaveLength(3);
});
it('should fail to set version', () => {
execMock
.mockReturnValueOnce({stdout: '0.81.0-rc.1\n', code: 0})
.mockReturnValueOnce({code: 1});
execMock.mockReturnValueOnce({stdout: '0.81.0-rc.1\n', code: 0});
const expectedVersion = '0.82.0-nightly-20230420-currentco';
setReactNativeVersionMock.mockImplementation(() => {
throw new Error('something went wrong');
});
publishNpm('nightly');
@ -114,14 +119,10 @@ describe('publish-npm', () => {
expect(execMock.mock.calls[0][0]).toBe(
`npm view react-native@next version`,
);
expect(execMock.mock.calls[1][0]).toBe(
`node scripts/set-rn-version.js --to-version ${expectedVersion} --build-type nightly`,
);
expect(echoMock).toHaveBeenCalledWith(
expect(consoleErrorMock).toHaveBeenCalledWith(
`Failed to set version number to ${expectedVersion}`,
);
expect(exitMock).toHaveBeenCalledWith(1);
expect(execMock.mock.calls).toHaveLength(2);
});
});

Просмотреть файл

@ -9,19 +9,19 @@
const execMock = jest.fn();
const echoMock = jest.fn();
const exitMock = jest.fn();
const catMock = jest.fn();
const sedMock = jest.fn();
const writeFileSyncMock = jest.fn();
const updateTemplatePackageMock = jest.fn();
jest
.mock('shelljs', () => ({
exec: execMock,
echo: echoMock,
exit: exitMock,
cat: catMock,
sed: sedMock,
}))
.mock('./../update-template-package', () => updateTemplatePackageMock)
.mock('./../scm-utils', () => ({
saveFiles: jest.fn(),
}))
@ -45,7 +45,7 @@ describe('set-rn-version', () => {
it('should set nightly version', () => {
catMock.mockImplementation(path => {
if (path === 'packages/react-native/package.json') {
return '{"name": "myPackage", "version": 2}';
return '{"name": "myPackage", "version": 2, "dependencies": {"@react-native/package-a": "nightly", "@react-native/package-b": "^0.73.0"}}';
} else if (
path === 'scripts/versiontemplates/ReactNativeVersion.java.template' ||
path === 'scripts/versiontemplates/RCTVersion.m.template' ||
@ -58,13 +58,14 @@ describe('set-rn-version', () => {
}
});
execMock
.mockReturnValueOnce({code: 0})
.mockReturnValueOnce({stdout: 'line1\nline2\nline3\n'});
execMock.mockReturnValueOnce({stdout: 'line1\nline2\nline3\n'});
sedMock.mockReturnValueOnce({code: 0});
const version = '0.81.0-nightly-29282302-abcd1234';
setReactNativeVersion(version, 'nightly');
const nightlyVersions = {
'@react-native/package-a': version,
};
setReactNativeVersion(version, nightlyVersions, 'nightly');
expect(sedMock).toHaveBeenCalledWith(
'-i',
@ -91,14 +92,19 @@ describe('set-rn-version', () => {
expect(writeFileSyncMock.mock.calls[4][0]).toBe(
'packages/react-native/package.json',
);
expect(writeFileSyncMock.mock.calls[4][1]).toBe(
`{\n "name": "myPackage",\n "version": "${version}"\n}`,
);
expect(writeFileSyncMock.mock.calls[4][1]).toBe(`{
"name": "myPackage",
"version": "${version}",
"dependencies": {
"@react-native/package-a": "0.81.0-nightly-29282302-abcd1234",
"@react-native/package-b": "^0.73.0"
}
}`);
expect(exitMock.mock.calls[0][0]).toBe(0);
expect(execMock.mock.calls[0][0]).toBe(
`node scripts/set-rn-template-version.js ${version}`,
);
expect(updateTemplatePackageMock).toHaveBeenCalledWith({
'@react-native/package-a': '0.81.0-nightly-29282302-abcd1234',
'react-native': version,
});
});
it('should set release version', () => {
@ -109,13 +115,11 @@ describe('set-rn-version', () => {
return 'exports.version = {major: ${major}, minor: ${minor}, patch: ${patch}, prerelease: ${prerelease}}';
});
execMock
.mockReturnValueOnce({code: 0})
.mockReturnValueOnce({stdout: 'line1\nline2\nline3\n'});
execMock.mockReturnValueOnce({stdout: 'line1\nline2\nline3\n'});
sedMock.mockReturnValueOnce({code: 0});
const version = '0.81.0';
setReactNativeVersion(version, 'release');
setReactNativeVersion(version, null, 'release');
expect(sedMock).toHaveBeenCalledWith(
'-i',
@ -137,11 +141,10 @@ describe('set-rn-version', () => {
`{\n "name": "myPackage",\n "version": "${version}"\n}`,
);
expect(exitMock.mock.calls[0][0]).toBe(0);
expect(updateTemplatePackageMock).toHaveBeenCalledWith({
'react-native': version,
});
expect(execMock.mock.calls[0][0]).toBe(
`node scripts/set-rn-template-version.js ${version}`,
);
expect(execMock.mock.calls[1][0]).toBe(
`diff -r ./rn-set-version/ . | grep '^[>]' | grep -c ${version} `,
);
});
@ -149,9 +152,7 @@ describe('set-rn-version', () => {
it('should fail validation', () => {
catMock.mockReturnValue('{}');
execMock
.mockReturnValueOnce({code: 0})
.mockReturnValueOnce({stdout: 'line1\nline2\n'});
execMock.mockReturnValueOnce({stdout: 'line1\nline2\n'});
sedMock.mockReturnValueOnce({code: 0});
const filesToValidate = [
'packages/react-native/package.json',
@ -160,9 +161,8 @@ describe('set-rn-version', () => {
];
const version = '0.81.0';
setReactNativeVersion(version, 'release');
setReactNativeVersion(version, null, 'release');
expect(exitMock).toHaveBeenCalledWith(0);
expect(echoMock).toHaveBeenNthCalledWith(
1,
'The tmp versioning folder is ./rn-set-version/',

Просмотреть файл

@ -56,7 +56,35 @@ function pack(packagePath) {
}
}
/**
* `package` is an object form of package.json
* `dependencies` is a map of dependency to version string
*
* This replaces both dependencies and devDependencies in package.json
*/
function applyPackageVersions(originalPackageJson, packageVersions) {
const packageJson = {...originalPackageJson};
for (const name of Object.keys(packageVersions)) {
if (
packageJson.dependencies != null &&
packageJson.dependencies[name] != null
) {
packageJson.dependencies[name] = packageVersions[name];
}
if (
packageJson.devDependencies != null &&
packageJson.devDependencies[name] != null
) {
packageJson.devDependencies[name] = packageVersions[name];
}
}
return packageJson;
}
module.exports = {
applyPackageVersions,
getPackageVersionStrByTag,
publishPackage,
diffPackages,

Просмотреть файл

@ -9,7 +9,7 @@
'use strict';
const {exec, echo, exit} = require('shelljs');
const {echo, exit} = require('shelljs');
const {parseVersion} = require('./version-utils');
const {getPackageVersionStrByTag, publishPackage} = require('./npm-utils');
const {
@ -18,6 +18,7 @@ const {
isTaggedLatest,
} = require('./scm-utils');
const getAndUpdateNightlies = require('./monorepo/get-and-update-nightlies');
const setReactNativeVersion = require('./set-rn-version');
const {
generateAndroidArtifacts,
publishAndroidArtifactsToMaven,
@ -134,25 +135,24 @@ function getNpmInfo(buildType) {
function publishNpm(buildType) {
const {version, tag} = getNpmInfo(buildType);
// Set version number in various files (package.json, gradle.properties etc)
// For non-nightly, non-dry-run, CircleCI job `prepare_package_for_release` does this
// Here we update the react-native package and template package with the right versions
// For releases, CircleCI job `prepare_package_for_release` handles this
if (buildType === 'nightly' || buildType === 'dry-run') {
// Sets the version for package/react-native
if (
exec(
`node scripts/set-rn-version.js --to-version ${version} --build-type ${buildType}`,
).code
) {
echo(`Failed to set version number to ${version}`);
// Publish monorepo nightlies if there are updates, returns nightly versions for each
const monorepoNightlyVersions =
buildType === 'nightly' ? getAndUpdateNightlies(version) : null;
try {
// Update the react-native and template packages with the react-native version
// and nightly versions of monorepo deps
setReactNativeVersion(version, monorepoNightlyVersions, buildType);
} catch (e) {
console.error(`Failed to set version number to ${version}`);
console.error(e);
return exit(1);
}
}
// set and publish the relevant monorepo packages
if (buildType === 'nightly') {
getAndUpdateNightlies(version);
}
generateAndroidArtifacts(version);
// Write version number to the build folder

Просмотреть файл

@ -64,7 +64,7 @@ try {
}
describe('Create react-native package');
if (exec('node ./scripts/set-rn-version.js --version 1000.0.0').code) {
if (exec('node ./scripts/set-rn-version.js --to-version 1000.0.0').code) {
echo('Failed to set version and update package.json ready for release');
exitCode = 1;
throw Error(exitCode);

Просмотреть файл

@ -1,33 +0,0 @@
/**
* 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 fs = require('fs');
const path = require('path');
const version = process.argv[2];
if (!version) {
console.error('Please provide a react-native version.');
process.exit(1);
}
const jsonPath = path.join(
__dirname,
'../packages/react-native/template/package.json',
);
let templatePackageJson = require(jsonPath);
templatePackageJson.dependencies['react-native'] = version;
fs.writeFileSync(
jsonPath,
JSON.stringify(templatePackageJson, null, 2) + '\n',
'utf-8',
);

Просмотреть файл

@ -16,6 +16,8 @@ const {cat, echo, exec, exit, sed} = require('shelljs');
const yargs = require('yargs');
const {parseVersion, validateBuildType} = require('./version-utils');
const {saveFiles} = require('./scm-utils');
const updateTemplatePackage = require('./update-template-package');
const {applyPackageVersions} = require('./npm-utils');
/**
* This script updates relevant React Native files with supplied version:
@ -31,13 +33,31 @@ if (require.main === module) {
type: 'string',
required: true,
})
.option('d', {
alias: 'dependency-versions',
type: 'string',
describe:
'JSON string of package versions. Ex. "{"react-native":"0.64.1"}"',
default: null,
})
.coerce('d', dependencyVersions => {
if (dependencyVersions == null) {
return null;
}
return JSON.parse(dependencyVersions);
})
.option('b', {
alias: 'build-type',
type: 'string',
required: true,
}).argv;
setReactNativeVersion(argv.toVersion, argv.buildType);
setReactNativeVersion(
argv.toVersion,
argv.dependencyVersions,
argv.buildType,
);
exit(0);
}
function setSource({major, minor, patch, prerelease}) {
@ -108,8 +128,15 @@ function setGradle({version}) {
}
}
function setPackage({version}) {
const packageJson = JSON.parse(cat('packages/react-native/package.json'));
function setPackage({version}, dependencyVersions) {
const originalPackageJson = JSON.parse(
cat('packages/react-native/package.json'),
);
const packageJson =
dependencyVersions != null
? applyPackageVersions(originalPackageJson, dependencyVersions)
: originalPackageJson;
packageJson.version = version;
fs.writeFileSync(
@ -119,15 +146,7 @@ function setPackage({version}) {
);
}
function setTemplatePackage({version}) {
const result = exec(`node scripts/set-rn-template-version.js ${version}`);
if (result.code) {
echo("Failed to update React Native template's version of React Native");
throw result.stderr;
}
}
function setReactNativeVersion(argVersion, buildType) {
function setReactNativeVersion(argVersion, dependencyVersions, buildType) {
validateBuildType(buildType);
const version = parseVersion(argVersion, buildType);
@ -145,8 +164,14 @@ function setReactNativeVersion(argVersion, buildType) {
saveFiles(tmpVersioningFolder);
setSource(version);
setPackage(version);
setTemplatePackage(version);
setPackage(version, dependencyVersions);
const templateDependencyVersions = {
'react-native': version.version,
...(dependencyVersions != null ? dependencyVersions : {}),
};
updateTemplatePackage(templateDependencyVersions);
setGradle(version);
// Validate changes
@ -170,7 +195,7 @@ function setReactNativeVersion(argVersion, buildType) {
echo(`These files already had version ${version.version} set.`);
}
return exit(0);
return;
}
module.exports = setReactNativeVersion;

Просмотреть файл

@ -17,6 +17,7 @@
*/
const {exec, exit, pushd, popd, pwd, cd, cp} = require('shelljs');
const updateTemplatePackage = require('../scripts/update-template-package');
const yargs = require('yargs');
const fs = require('fs');
@ -208,7 +209,9 @@ if (argv.target === 'RNTester') {
);
const localNodeTGZPath = `${reactNativePackagePath}/react-native-${releaseVersion}.tgz`;
exec(`node scripts/set-rn-template-version.js "file:${localNodeTGZPath}"`);
updateTemplatePackage({
'react-native': `file:${localNodeTGZPath}`,
});
// create locally the node module
exec('npm pack', {cwd: reactNativePackagePath});

Просмотреть файл

@ -0,0 +1,54 @@
/**
* 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 fs = require('fs');
const path = require('path');
const {applyPackageVersions} = require('./npm-utils');
/**
* Updates the react-native template package.json with
* dependencies in `dependencyMap`.
*
* `dependencyMap` is a dict of package name to its version
* ex. {"react-native": "0.23.0", "other-dep": "nightly"}
*/
function updateTemplatePackage(dependencyMap) {
const jsonPath = path.join(
__dirname,
'../packages/react-native/template/package.json',
);
const templatePackageJson = require(jsonPath);
const updatedPackageJson = applyPackageVersions(
templatePackageJson,
dependencyMap,
);
fs.writeFileSync(
jsonPath,
JSON.stringify(updatedPackageJson, null, 2) + '\n',
'utf-8',
);
}
if (require.main === module) {
const dependencyMapStr = process.argv[2];
if (!dependencyMapStr) {
console.error(
'Please provide a json string of package name and their version. Ex. \'{"packageName":"0.23.0"}\'',
);
process.exit(1);
}
updateTemplatePackage(JSON.parse(dependencyMapStr));
}
module.exports = updateTemplatePackage;