Remove bump-all-updated-packages script (#43534)

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

This is no longer used after switching to the new release workflow, which uses the newer and less error-prone `set-version` script.

Changelog: [Internal]

Reviewed By: cortinico

Differential Revision: D55027122

fbshipit-source-id: faa8cfd2af9b54fab611b108df162793c5768695
This commit is contained in:
Alex Hunt
2024-03-20 14:40:54 +00:00
committed by Alex Hunt
parent 8b5d650e60
commit d66bb7f853
11 changed files with 1 additions and 786 deletions
-1
View File
@@ -14,7 +14,6 @@
"android": "cd packages/rn-tester && npm run android",
"build-android": "./gradlew :packages:react-native:ReactAndroid:build",
"build": "node ./scripts/build/build.js",
"bump-all-updated-packages": "node ./scripts/monorepo/bump-all-updated-packages",
"clang-format": "clang-format -i --glob=*/**/*.{h,cpp,m,mm}",
"clean": "node ./scripts/build/clean.js",
"flow-check": "flow check",
-21
View File
@@ -10,7 +10,6 @@
const {
applyPackageVersions,
getNpmInfo,
getPackageVersionStrByTag,
getVersionsBySpec,
publishPackage,
} = require('../npm-utils');
@@ -73,26 +72,6 @@ describe('npm-utils', () => {
});
});
describe('getPackageVersionStrByTag', () => {
it('should return package version string', () => {
execMock.mockImplementationOnce(() => ({code: 0, stdout: '0.34.2 \n'}));
const versionStr = getPackageVersionStrByTag('my-package', 'next');
expect(versionStr).toBe('0.34.2');
});
it('should throw error when invalid result', () => {
execMock.mockImplementationOnce(() => ({
code: 1,
stderr: 'Some error message',
}));
expect(() => {
getPackageVersionStrByTag('my-package', 'next');
}).toThrow(
"Failed to run 'npm view my-package@next version'\nSome error message",
);
});
});
describe('publishPackage', () => {
it('should run publish command', () => {
publishPackage(
@@ -1,174 +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
* @oncall react-native
*/
const mockPackages = [
{
packageManifest: {
name: '@react-native/packageA',
version: 'local-version',
dependencies: {},
devDependencies: {},
},
packageAbsolutePath: '/some/place/packageA',
packageRelativePathFromRoot: './place/packageA',
},
{
packageManifest: {
name: '@react-native/not_published',
version: 'local-version',
dependencies: {'@react-native/packageA': 'local-version'},
},
packageAbsolutePath: '/some/place/not_published',
packageRelativePathFromRoot: './place/not_published',
},
{
packageManifest: {
name: '@react-native/packageB',
version: 'local-version',
dependencies: {'@react-native/packageA': 'local-version'},
},
packageAbsolutePath: '/some/place/packageB',
packageRelativePathFromRoot: './place/packageB',
},
{
packageManifest: {
name: '@react-native/packageC',
version: 'local-version',
devDependencies: {'@react-native/packageE': 'local-version'},
},
packageAbsolutePath: '/some/place/packageC',
packageRelativePathFromRoot: './place/packageC',
},
{
packageManifest: {
name: '@react-native/packageD',
version: 'local-version',
dependencies: {
'@react-native/packageA': 'local-version',
'@react-native/packageC': 'local-version',
},
},
packageAbsolutePath: '/some/place/packageD',
packageRelativePathFromRoot: './place/packageD',
},
{
packageManifest: {name: '@react-native/packageE', version: 'local-version'},
packageAbsolutePath: '/some/place/packageE',
packageRelativePathFromRoot: './place/packageE',
},
{
packageManifest: {
name: '@react-native/packageF',
version: 'local-version',
dependencies: {
'@react-native/packageB': 'local-version',
},
devDependencies: {
'@react-native/packageD': 'local-version',
},
},
packageAbsolutePath: '/some/place/packageF',
packageRelativePathFromRoot: './place/packageF',
},
{
packageManifest: {
name: '@react-native/packageP',
version: 'local-version',
private: true,
dependencies: {},
devDependencies: {},
},
packageAbsolutePath: '/some/place/packageP',
packageRelativePathFromRoot: './place/packageP',
},
{
packageManifest: {
name: 'react-native',
version: 'local-version',
private: true,
dependencies: {
'@react-native/packageA': 'local-version',
'@react-native/packageB': 'local-version',
'@react-native/packageC': 'local-version',
},
devDependencies: {
'@react-native/packageD': 'local-version',
'@react-native/packageE': 'local-version',
'@react-native/packageF': 'local-version',
},
},
packageAbsolutePath: '/some/place/react-native',
packageRelativePathFromRoot: './place/react-native',
},
];
function expectedPackageA(newVersion) {
return {
name: '@react-native/packageA',
version: newVersion,
dependencies: {},
devDependencies: {},
};
}
function expectedPackageB(newVersion) {
return {
name: '@react-native/packageB',
version: newVersion,
dependencies: {'@react-native/packageA': newVersion},
};
}
function expectedPackageC(newVersion) {
return {
name: '@react-native/packageC',
version: newVersion,
devDependencies: {'@react-native/packageE': newVersion},
};
}
function expectedPackageD(newVersion) {
return {
name: '@react-native/packageD',
version: newVersion,
dependencies: {
'@react-native/packageA': newVersion,
'@react-native/packageC': newVersion,
},
};
}
function expectedPackageE(newVersion) {
return {name: '@react-native/packageE', version: newVersion};
}
function expectedPackageF(newVersion) {
return {
name: '@react-native/packageF',
version: newVersion,
dependencies: {
'@react-native/packageB': newVersion,
},
devDependencies: {
'@react-native/packageD': newVersion,
},
};
}
const expectedPackages = {
'@react-native/packageA': expectedPackageA,
'@react-native/packageB': expectedPackageB,
'@react-native/packageC': expectedPackageC,
'@react-native/packageD': expectedPackageD,
'@react-native/packageE': expectedPackageE,
'@react-native/packageF': expectedPackageF,
};
module.exports = {
mockPackages,
expectedPackages,
};
@@ -1,36 +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
*/
const bumpPackageVersion = require('../bump-all-updated-packages/bump-package-version');
const {writeFileSync} = require('fs');
const path = require('path');
jest.mock('fs', () => ({
writeFileSync: jest.fn(),
readFileSync: jest.fn(() => '{}'),
}));
describe('bumpPackageVersionTest', () => {
it('updates patch version of the package', () => {
const mockedPackageLocation = '~/packages/assets';
const mockedPackageManifest = {
name: '@react-native/test',
version: '1.2.3',
};
bumpPackageVersion(mockedPackageLocation, mockedPackageManifest);
expect(writeFileSync).toHaveBeenCalledWith(
path.join(mockedPackageLocation, 'package.json'),
JSON.stringify({...mockedPackageManifest, version: '1.2.4'}, null, 2) +
'\n',
'utf-8',
);
});
});
-135
View File
@@ -1,135 +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.
*
* @flow
* @format
* @oncall react_native
*/
/*::
import type {PackageJson} from '../utils/monorepo';
*/
const {getPackages} = require('../utils/monorepo');
const {readFileSync, writeFileSync} = require('fs');
const path = require('path');
const ROOT_LOCATION = path.join(__dirname, '..', '..');
const TEMPLATE_LOCATION = path.join(
ROOT_LOCATION,
'packages',
'react-native',
'template',
);
const readJSONFile = (pathToFile /*: string */) /*: PackageJson */ =>
JSON.parse(readFileSync(pathToFile, 'utf-8'));
const checkIfShouldUpdateDependencyPackageVersion = (
consumerPackageAbsolutePath /*: string */,
updatedPackageName /*: string */,
updatedPackageVersion /*: string */,
) => {
const consumerPackageManifestPath = path.join(
consumerPackageAbsolutePath,
'package.json',
);
const consumerPackageManifest = readJSONFile(consumerPackageManifestPath);
const dependencyVersion =
consumerPackageManifest.dependencies?.[updatedPackageName];
if (dependencyVersion && dependencyVersion !== '*') {
const updatedDependencyVersion = dependencyVersion.startsWith('^')
? `^${updatedPackageVersion}`
: updatedPackageVersion;
if (updatedDependencyVersion !== dependencyVersion) {
console.log(
`\uD83D\uDCA1 ${consumerPackageManifest.name} was updated: now using version ${updatedPackageVersion} of ${updatedPackageName}`,
);
const updatedPackageManifest = {
...consumerPackageManifest,
dependencies: {
...consumerPackageManifest.dependencies,
[updatedPackageName]: updatedDependencyVersion,
},
};
writeFileSync(
consumerPackageManifestPath,
JSON.stringify(updatedPackageManifest, null, 2) + '\n',
'utf-8',
);
}
}
const devDependencyVersion =
consumerPackageManifest.devDependencies?.[updatedPackageName];
if (devDependencyVersion && devDependencyVersion !== '*') {
const updatedDependencyVersion = devDependencyVersion.startsWith('^')
? `^${updatedPackageVersion}`
: updatedPackageVersion;
if (updatedDependencyVersion !== devDependencyVersion) {
console.log(
`\uD83D\uDCA1 ${consumerPackageManifest.name} was updated: now using version ${updatedPackageVersion} of ${updatedPackageName}`,
);
const updatedPackageManifest = {
...consumerPackageManifest,
devDependencies: {
...consumerPackageManifest.devDependencies,
[updatedPackageName]: updatedDependencyVersion,
},
};
writeFileSync(
consumerPackageManifestPath,
JSON.stringify(updatedPackageManifest, null, 2) + '\n',
'utf-8',
);
}
}
};
async function alignPackageVersions() {
const allPackages = await getPackages({
includeReactNative: true,
includePrivate: true,
});
const packagesExcludingReactNative = Object.keys(allPackages).filter(
packageName => packageName !== 'react-native',
);
for (const packageName of packagesExcludingReactNative) {
const {packageJson: packageManifest} = allPackages[packageName];
checkIfShouldUpdateDependencyPackageVersion(
ROOT_LOCATION,
packageManifest.name,
packageManifest.version,
);
checkIfShouldUpdateDependencyPackageVersion(
TEMPLATE_LOCATION,
packageManifest.name,
packageManifest.version,
);
for (const {path: pathToPackage} of Object.values(allPackages)) {
checkIfShouldUpdateDependencyPackageVersion(
pathToPackage,
packageManifest.name,
packageManifest.version,
);
}
}
}
module.exports = alignPackageVersions;
@@ -1,52 +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
*/
const {writeFileSync} = require('fs');
const path = require('path');
const getIncrementedVersion = (version, increment) =>
version
.split('.')
.map((token, index) => {
const indexOfVersionToIncrement = increment === 'minor' ? 1 : 2;
if (index === indexOfVersionToIncrement) {
return parseInt(token, 10) + 1;
}
if (index > indexOfVersionToIncrement) {
return 0;
}
return token;
})
.join('.');
const bumpPackageVersion = (
packageAbsolutePath,
packageManifest,
increment = 'patch',
) => {
const updatedVersion = getIncrementedVersion(
packageManifest.version,
increment,
);
// Not using simple `npm version patch` because it updates dependencies and yarn.lock file
writeFileSync(
path.join(packageAbsolutePath, 'package.json'),
JSON.stringify({...packageManifest, version: updatedVersion}, null, 2) +
'\n',
'utf-8',
);
return updatedVersion;
};
module.exports = bumpPackageVersion;
@@ -1,49 +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
*/
const chalk = require('chalk');
const {echo, exec} = require('shelljs');
const detectPackageUnreleasedChanges = (
packageRelativePathFromRoot,
packageName,
ROOT_LOCATION,
) => {
const hashOfLastCommitInsidePackage = exec(
`git log -n 1 --format=format:%H -- ${packageRelativePathFromRoot}`,
{cwd: ROOT_LOCATION, silent: true},
).stdout.trim();
const hashOfLastCommitThatChangedVersion = exec(
`git log -G\\"version\\": --format=format:%H -n 1 -- ${packageRelativePathFromRoot}/package.json`,
{cwd: ROOT_LOCATION, silent: true},
).stdout.trim();
if (hashOfLastCommitInsidePackage === hashOfLastCommitThatChangedVersion) {
echo(
`\uD83D\uDD0E No changes for package ${chalk.green(
packageName,
)} since last version bump`,
);
return false;
} else {
echo(`\uD83D\uDCA1 Found changes for ${chalk.yellow(packageName)}:`);
exec(
`git log --pretty=oneline ${hashOfLastCommitThatChangedVersion}..${hashOfLastCommitInsidePackage} ${packageRelativePathFromRoot}`,
{
cwd: ROOT_LOCATION,
},
);
echo();
return true;
}
};
module.exports = detectPackageUnreleasedChanges;
@@ -1,261 +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.
*
* @flow
* @format
* @oncall react_native
*/
const {REPO_ROOT} = require('../../consts');
const {getPackageVersionStrByTag} = require('../../npm-utils');
const {
isReleaseBranch,
parseVersion,
} = require('../../releases/utils/version-utils');
const {getBranchName} = require('../../scm-utils');
const {getPackages} = require('../../utils/monorepo');
const alignPackageVersions = require('../align-package-versions');
const checkForGitChanges = require('../check-for-git-changes');
const {
COMMIT_WITH_CUSTOM_MESSAGE_CHOICE,
COMMIT_WITH_GENERIC_MESSAGE_CHOICE,
GENERIC_COMMIT_MESSAGE,
NO_COMMIT_CHOICE,
PUBLISH_PACKAGES_TAG,
} = require('../constants');
const bumpPackageVersion = require('./bump-package-version');
const detectPackageUnreleasedChanges = require('./bump-utils');
const chalk = require('chalk');
const {execSync} = require('child_process');
const inquirer = require('inquirer');
const path = require('path');
const {echo, exec, exit} = require('shelljs');
const buildExecutor =
(
packageAbsolutePath /*: string */,
packageRelativePathFromRoot /*: string */,
packageManifest /*: $FlowFixMe */,
) =>
async () => {
const {name: packageName} = packageManifest;
if (packageManifest.private) {
echo(`\u23ED Skipping private package ${chalk.dim(packageName)}`);
return;
}
if (
!detectPackageUnreleasedChanges(
packageRelativePathFromRoot,
packageName,
REPO_ROOT,
)
) {
return;
}
await inquirer
.prompt([
{
type: 'list',
name: 'shouldBumpPackage',
message: `Do you want to bump ${packageName}?`,
choices: ['Yes', 'No'],
filter: val => val === 'Yes',
},
])
.then(({shouldBumpPackage}) => {
if (!shouldBumpPackage) {
echo(`Skipping bump for ${packageName}`);
return;
}
return inquirer
.prompt([
{
type: 'list',
name: 'increment',
message: 'Which version you want to increment?',
choices: ['patch', 'minor'],
},
])
.then(({increment}) => {
const updatedVersion = bumpPackageVersion(
packageAbsolutePath,
packageManifest,
increment,
);
echo(
`\u2705 Successfully bumped ${chalk.green(
packageName,
)} to ${chalk.green(updatedVersion)}`,
);
});
});
};
const main = async () => {
if (checkForGitChanges()) {
echo(
chalk.red(
'Found uncommitted changes. Please commit or stash them before running this script',
),
);
exit(1);
}
const packages = await getPackages({
includeReactNative: false,
includePrivate: true,
});
for (const pkg of Object.values(packages)) {
const executor = buildExecutor(
pkg.path,
path.relative(REPO_ROOT, pkg.path),
pkg.packageJson,
);
await executor()
.catch(() => exit(1))
.then(() => echo());
}
if (!checkForGitChanges()) {
echo('No changes have been made. Finishing the process...');
exit(0);
}
echo('Aligning new versions across monorepo...');
await alignPackageVersions();
echo(chalk.green('Done!\n'));
// Figure out the npm dist-tags we want for all monorepo packages we're bumping
const branchName = getBranchName();
const choices = [];
if (branchName === 'main') {
choices.push({name: '"nightly"', value: 'nightly', checked: true});
} else if (isReleaseBranch(branchName)) {
choices.push({
name: `"${branchName}"`,
value: branchName,
checked: true,
});
const latestVersion = getPackageVersionStrByTag('react-native', 'latest');
const {major, minor} = parseVersion(latestVersion, 'release');
choices.push({
name: '"latest"',
value: 'latest',
checked: `${major}.${minor}-stable` === branchName,
});
} else {
echo(
'You should be running `yarn bump-all-updated-packages` only from release or main branch',
);
exit(1);
}
const {tags} = await inquirer.prompt([
{
type: 'checkbox',
name: 'tags',
message: 'Select suggested npm tags.',
choices,
required: true,
},
]);
const {confirm} = await inquirer.prompt({
type: 'confirm',
name: 'confirm',
message: `Confirm these tags for *ALL* packages being bumped: ${tags
.map(t => `"${t}"`)
.join()}`,
});
if (!confirm) {
echo('Exiting without commiting...');
exit(0);
}
const tagString = '&' + tags.join('&');
await inquirer
.prompt([
{
type: 'list',
name: 'commitChoice',
message: 'Do you want to submit a commit with these changes?',
choices: [
{
name: 'Yes, with generic message',
value: COMMIT_WITH_GENERIC_MESSAGE_CHOICE,
},
{
name: 'Yes, with custom message',
value: COMMIT_WITH_CUSTOM_MESSAGE_CHOICE,
},
{
name: 'No',
value: NO_COMMIT_CHOICE,
},
],
},
])
.then(({commitChoice}) => {
switch (commitChoice) {
case NO_COMMIT_CHOICE: {
echo('Not submitting a commit, but keeping all changes');
break;
}
case COMMIT_WITH_GENERIC_MESSAGE_CHOICE: {
exec(`git commit -am "${GENERIC_COMMIT_MESSAGE}${tagString}"`, {
cwd: REPO_ROOT,
silent: true,
});
break;
}
case COMMIT_WITH_CUSTOM_MESSAGE_CHOICE: {
// exec from shelljs currently does not support interactive input
// https://github.com/shelljs/shelljs/wiki/FAQ#running-interactive-programs-with-exec
execSync('git commit -a', {cwd: REPO_ROOT, stdio: 'inherit'});
const enteredCommitMessage = exec('git log -n 1 --format=format:%B', {
cwd: REPO_ROOT,
silent: true,
}).stdout.trim();
const commitMessageWithTag =
enteredCommitMessage + `\n\n${PUBLISH_PACKAGES_TAG}${tagString}`;
exec(`git commit --amend -m "${commitMessageWithTag}"`, {
cwd: REPO_ROOT,
silent: true,
});
break;
}
default:
throw new Error('');
}
})
.then(() => echo());
echo(chalk.green('Successfully finished the process of bumping packages'));
exit(0);
};
if (require.main === module) {
// eslint-disable-next-line no-void
void main();
}
-24
View File
@@ -1,24 +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.
*
* @flow strict-local
* @format
*/
const PUBLISH_PACKAGES_TAG = '#publish-packages-to-npm';
const GENERIC_COMMIT_MESSAGE = `bumped packages versions\n\n${PUBLISH_PACKAGES_TAG}`;
const NO_COMMIT_CHOICE = 'NO_COMMIT';
const COMMIT_WITH_GENERIC_MESSAGE_CHOICE = 'COMMIT_WITH_GENERIC_MESSAGE';
const COMMIT_WITH_CUSTOM_MESSAGE_CHOICE = 'COMMIT_WITH_CUSTOM_MESSAGE';
module.exports = {
PUBLISH_PACKAGES_TAG,
GENERIC_COMMIT_MESSAGE,
NO_COMMIT_CHOICE,
COMMIT_WITH_GENERIC_MESSAGE_CHOICE,
COMMIT_WITH_CUSTOM_MESSAGE_CHOICE,
};
-32
View File
@@ -141,35 +141,6 @@ function publishPackage(
return exec(`npm publish${tagsFlag}${otpFlag}`, options);
}
function diffPackages(
packageSpecA /*: string */,
packageSpecB /*: string */,
options /*: ExecOptsSync */,
) /*: string */ {
const result = exec(
`npm diff --diff=${packageSpecA} --diff=${packageSpecB} --diff-name-only`,
options,
);
if (result.code !== 0) {
throw new Error(
`Failed to diff ${packageSpecA} and ${packageSpecB}\n${result.stderr}`,
);
}
return result.stdout;
}
function pack(packagePath /*: string */) {
const result = exec('npm pack', {
cwd: packagePath,
});
if (result.code !== 0) {
throw new Error(result.stderr);
}
}
/**
* `package` is an object form of package.json
* `dependencies` is a map of dependency to version string
@@ -272,9 +243,6 @@ function getVersionsBySpec(
module.exports = {
applyPackageVersions,
getNpmInfo,
getPackageVersionStrByTag,
getVersionsBySpec,
publishPackage,
diffPackages,
pack,
};
@@ -9,12 +9,12 @@
* @oncall react_native
*/
const {PUBLISH_PACKAGES_TAG} = require('../monorepo/constants');
const {publishPackage} = require('../npm-utils');
const {getPackages} = require('../utils/monorepo');
const {parseArgs} = require('@pkgjs/parseargs');
const {execSync} = require('child_process');
const PUBLISH_PACKAGES_TAG = '#publish-packages-to-npm';
const NPM_CONFIG_OTP = process.env.NPM_CONFIG_OTP;
const config = {