Skip to content

Commit

Permalink
set unified version (facebook#42776)
Browse files Browse the repository at this point in the history
Summary:

Changelog: [Internal] set all monorepo packages (including react-native) to one version and update all inter-dependencies (including the template)

Reviewed By: huntie

Differential Revision: D53251917
  • Loading branch information
lunaleaps authored and facebook-github-bot committed Feb 1, 2024
1 parent 6a8a28b commit 18906ea
Show file tree
Hide file tree
Showing 11 changed files with 335 additions and 23 deletions.
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ module.exports = {
'<rootDir>/packages/react-native/jest/ReactNativeInternalFeatureFlagsMock.js',
},
moduleFileExtensions: ['fb.js'].concat(defaults.moduleFileExtensions),
modulePathIgnorePatterns: ['scripts/.*/__fixtures__/'],
unmockedModulePathPatterns: [
'node_modules/react/',
'packages/react-native/Libraries/Renderer',
Expand Down
50 changes: 28 additions & 22 deletions scripts/monorepo/for-each-package.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,56 +4,62 @@
* 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 {readdirSync, readFileSync} = require('fs');
const path = require('path');

const ROOT_LOCATION = path.join(__dirname, '..', '..');
const PACKAGES_LOCATION = path.join(ROOT_LOCATION, 'packages');
const REPO_ROOT = path.join(path.dirname(__filename), '..', '..');
const PACKAGES_LOCATION = path.join(REPO_ROOT, 'packages');

const DEFAULT_OPTIONS = {includeReactNative: false};
const DEFAULT_OPTIONS /*: Options */ = {includeReactNative: false};

/*::
type PackageJSON = {
name: string,
private?: ?boolean,
version: string,
dependencies: {[string]: string},
devDependencies: {[string]: string},
...
};
type Options = {
includeReactNative?: ?boolean,
};
*/

/**
* Function, which returns an array of all directories inside specified location
*
* @param {string} source Path to directory, where this should be executed
* @returns {string[]} List of directories names
*/
const getDirectories = source =>
const getDirectories = (source /*: string */) /*: Array<string> */ =>
readdirSync(source, {withFileTypes: true})
.filter(file => file.isDirectory())
.map(directory => directory.name);

/**
* @callback forEachPackageCallback
* @param {string} packageAbsolutePath
* @param {string} packageRelativePathFromRoot
* @param {Object} packageManifest
*/

.map(directory => directory.name.toString());
/**
* Iterate through every package inside /packages (ignoring react-native) and call provided callback for each of them
*
* @param {forEachPackageCallback} callback The callback which will be called for each package
* @param {{includeReactNative: (boolean|undefined)}} [options={}] description
*/
const forEachPackage = (callback, options = DEFAULT_OPTIONS) => {
const forEachPackage = (
callback /*: (string, string, PackageJSON) => void */,
options /*: Options */ = DEFAULT_OPTIONS,
) => {
const {includeReactNative} = options;

// We filter react-native package on purpose, so that no CI's script will be executed for this package in future
// Unless includeReactNative options is provided
const packagesDirectories = getDirectories(PACKAGES_LOCATION).filter(
directoryName => directoryName !== 'react-native' || includeReactNative,
directoryName =>
directoryName !== 'react-native' || includeReactNative === true,
);

packagesDirectories.forEach(packageDirectory => {
const packageAbsolutePath = path.join(PACKAGES_LOCATION, packageDirectory);
const packageRelativePathFromRoot = path.join('packages', packageDirectory);

const packageManifest = JSON.parse(
readFileSync(path.join(packageAbsolutePath, 'package.json')),
readFileSync(path.join(packageAbsolutePath, 'package.json')).toString(),
);

callback(packageAbsolutePath, packageRelativePathFromRoot, packageManifest);
Expand Down
2 changes: 1 addition & 1 deletion scripts/monorepo/get-and-update-packages.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ type PackageMetadata = {|
* is an object that contains the absolute path to the package and the packageJson.
*/
function getPackagesToPublish() /*: PackageMap */ {
let packages = {};
let packages /*: PackageMap */ = {};

forEachPackage(
(packageAbsolutePath, packageRelativePathFromRoot, packageManifest) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "@monorepo/pkg-a",
"version": "0.0.1",
"description": "@monorepo/pkg-a",
"dependencies": {
"@monorepo/pkg-b": "0.0.1",
"@monorepo/other": "0.0.1"
},
"devDependencies": {
"@monorepo/pkg-c": "0.0.1"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "@monorepo/pkg-b",
"version": "0.0.2",
"description": "@monorepo/pkg-b",
"dependencies": {
"@monorepo/pkg-c": "0.0.1",
"metro-config": "^0.80.3",
"metro-runtime": "^0.80.3"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "@monorepo/pkg-c",
"version": "0.0.3",
"description": "@monorepo/pkg-c",
"dependencies": {
"metro-config": "^0.80.3",
"metro-runtime": "^0.80.3"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "react-native",
"version": "0.0.0",
"description": "fake react native package",
"dependencies": {
"@monorepo/pkg-a": "0.0.1",
"@monorepo/pkg-b": "0.0.1",
"@monorepo/pkg-c": "0.0.1",
"metro-config": "^0.80.3",
"metro-runtime": "^0.80.3"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "react-native-test-template",
"version": "0.0.1",
"private": true,
"dependencies": {
"react": "18.2.0",
"react-native": "0.0.0"
},
"devDependencies": {
"@monorepo/pkg-a": "0.0.1",
"@monorepo/pkg-c": "0.0.0",
"@types/react": "^18.2.6",
"@types/react-test-renderer": "^18.0.0"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`setVersion updates all public packages to version: monorepo-pkg-a 1`] = `
"{
\\"name\\": \\"@monorepo/pkg-a\\",
\\"version\\": \\"0.80.0\\",
\\"description\\": \\"@monorepo/pkg-a\\",
\\"dependencies\\": {
\\"@monorepo/pkg-b\\": \\"0.80.0\\",
\\"@monorepo/other\\": \\"0.0.1\\"
},
\\"devDependencies\\": {
\\"@monorepo/pkg-c\\": \\"0.80.0\\"
}
}
"
`;

exports[`setVersion updates all public packages to version: monorepo-pkg-b 1`] = `
"{
\\"name\\": \\"@monorepo/pkg-b\\",
\\"version\\": \\"0.80.0\\",
\\"description\\": \\"@monorepo/pkg-b\\",
\\"dependencies\\": {
\\"@monorepo/pkg-c\\": \\"0.80.0\\",
\\"metro-config\\": \\"^0.80.3\\",
\\"metro-runtime\\": \\"^0.80.3\\"
}
}
"
`;

exports[`setVersion updates all public packages to version: monorepo-pkg-c 1`] = `
"{
\\"name\\": \\"@monorepo/pkg-c\\",
\\"version\\": \\"0.80.0\\",
\\"description\\": \\"@monorepo/pkg-c\\",
\\"dependencies\\": {
\\"metro-config\\": \\"^0.80.3\\",
\\"metro-runtime\\": \\"^0.80.3\\"
}
}
"
`;

exports[`setVersion updates all public packages to version: react-native 1`] = `
"{
\\"name\\": \\"react-native\\",
\\"version\\": \\"0.80.0\\",
\\"description\\": \\"fake react native package\\",
\\"dependencies\\": {
\\"@monorepo/pkg-a\\": \\"0.80.0\\",
\\"@monorepo/pkg-b\\": \\"0.80.0\\",
\\"@monorepo/pkg-c\\": \\"0.80.0\\",
\\"metro-config\\": \\"^0.80.3\\",
\\"metro-runtime\\": \\"^0.80.3\\"
}
}
"
`;

exports[`setVersion updates all public packages to version: template 1`] = `
"{
\\"name\\": \\"react-native-test-template\\",
\\"version\\": \\"0.0.1\\",
\\"private\\": true,
\\"dependencies\\": {
\\"react\\": \\"18.2.0\\",
\\"react-native\\": \\"0.80.0\\"
},
\\"devDependencies\\": {
\\"@monorepo/pkg-a\\": \\"0.80.0\\",
\\"@monorepo/pkg-c\\": \\"0.80.0\\",
\\"@types/react\\": \\"^18.2.6\\",
\\"@types/react-test-renderer\\": \\"^18.0.0\\"
}
}
"
`;
46 changes: 46 additions & 0 deletions scripts/releases/set-version/__tests__/set-version-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* 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
*/

const setVersion = require('../index');
const path = require('path');

describe('setVersion', () => {
beforeAll(() => {
jest.mock('path', () => {
// $FlowIgnore[underconstrained-implicit-instantiation]
const originalPath = jest.requireActual('path');
return {
...originalPath,
dirname: () => originalPath.join(__dirname, '__fixtures__/two/levels'),
};
});

jest.mock('fs', () => {
// $FlowIgnore[underconstrained-implicit-instantiation]
const originalFs = jest.requireActual('fs');

return {
...originalFs,
writeFileSync: (packagePath, content) => {
expect(content).toMatchSnapshot(
path.basename(path.join(packagePath, '..')),
);
},
};
});
});
test('updates all public packages to version', () => {
setVersion('0.80.0');
});
afterAll(() => {
jest.unmock('path');
jest.unmock('fs');
});
});
Loading

0 comments on commit 18906ea

Please sign in to comment.