Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-sync with internal repository #37831

Merged
merged 1 commit into from
Jun 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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 >>
Expand Down
47 changes: 46 additions & 1 deletion scripts/__tests__/npm-utils-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => ({
Expand All @@ -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'}));
Expand Down
39 changes: 20 additions & 19 deletions scripts/__tests__/publish-npm-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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(() => {
Expand All @@ -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(() => {
Expand All @@ -58,27 +68,25 @@ describe('publish-npm', () => {

describe('dry-run', () => {
it('should set version and not publish', () => {
execMock.mockReturnValueOnce({code: 0});

publishNpm('dry-run');

expect(exitMock).toHaveBeenCalledWith(0);
expect(isTaggedLatestMock.mock.calls).toHaveLength(0);
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);
});
});

describe('nightly', () => {
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';

Expand All @@ -91,37 +99,30 @@ 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');

expect(publishAndroidArtifactsToMavenMock).not.toBeCalled();
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);
});
});

Expand Down
56 changes: 28 additions & 28 deletions scripts/__tests__/set-rn-version-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
}))
Expand All @@ -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' ||
Expand All @@ -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',
Expand All @@ -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(exitMock.mock.calls[0][0]).toBe(0);
expect(execMock.mock.calls[0][0]).toBe(
`node scripts/set-rn-template-version.js ${version}`,
);
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(updateTemplatePackageMock).toHaveBeenCalledWith({
'@react-native/package-a': '0.81.0-nightly-29282302-abcd1234',
'react-native': version,
});
});

it('should set release version', () => {
Expand All @@ -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',
Expand All @@ -137,21 +141,18 @@ 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} `,
);
});

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',
Expand All @@ -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/',
Expand Down
28 changes: 28 additions & 0 deletions scripts/npm-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down