246 строки
7.5 KiB
JavaScript
246 строки
7.5 KiB
JavaScript
/**
|
|
* 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 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 removeNewArchFlags = jest.fn();
|
|
const env = process.env;
|
|
|
|
jest
|
|
.mock('shelljs', () => ({
|
|
exec: execMock,
|
|
echo: echoMock,
|
|
exit: exitMock,
|
|
}))
|
|
.mock('./../scm-utils', () => ({
|
|
exitIfNotOnGit: command => command(),
|
|
getCurrentCommit: () => 'currentco_mmit',
|
|
isTaggedLatest: isTaggedLatestMock,
|
|
}))
|
|
.mock('path', () => ({
|
|
join: () => '../packages/react-native',
|
|
}))
|
|
.mock('fs')
|
|
.mock('./../release-utils', () => ({
|
|
generateAndroidArtifacts: jest.fn(),
|
|
publishAndroidArtifactsToMaven: publishAndroidArtifactsToMavenMock,
|
|
}))
|
|
.mock('./../set-rn-version', () => setReactNativeVersionMock)
|
|
.mock('../monorepo/get-and-update-packages')
|
|
.mock('../releases/remove-new-arch-flags', () => removeNewArchFlags);
|
|
|
|
const date = new Date('2023-04-20T23:52:39.543Z');
|
|
|
|
const publishNpm = require('../publish-npm');
|
|
let consoleError;
|
|
|
|
describe('publish-npm', () => {
|
|
beforeAll(() => {
|
|
jest.setSystemTime(date);
|
|
});
|
|
beforeEach(() => {
|
|
consoleError = console.error;
|
|
console.error = consoleErrorMock;
|
|
});
|
|
|
|
afterEach(() => {
|
|
process.env = env;
|
|
console.error = consoleError;
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.resetModules();
|
|
jest.resetAllMocks();
|
|
});
|
|
|
|
describe('publish-npm.js', () => {
|
|
it('Fails when invalid build type is passed', () => {
|
|
expect(() => publishNpm('invalid')).toThrowError(
|
|
'Unsupported build type: invalid',
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('dry-run', () => {
|
|
it('should set version and not publish', () => {
|
|
publishNpm('dry-run');
|
|
|
|
expect(removeNewArchFlags).not.toHaveBeenCalled();
|
|
expect(exitMock).toHaveBeenCalledWith(0);
|
|
expect(isTaggedLatestMock.mock.calls).toHaveLength(0);
|
|
expect(echoMock).toHaveBeenCalledWith(
|
|
'Skipping `npm publish` because --dry-run is set.',
|
|
);
|
|
expect(setReactNativeVersionMock).toBeCalledWith(
|
|
'1000.0.0-currentco',
|
|
null,
|
|
'dry-run',
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('nightly', () => {
|
|
it('should publish', () => {
|
|
execMock
|
|
.mockReturnValueOnce({stdout: '0.81.0-rc.1\n', code: 0})
|
|
.mockReturnValueOnce({code: 0});
|
|
const expectedVersion = '0.82.0-nightly-20230420-currentco';
|
|
|
|
publishNpm('nightly');
|
|
|
|
expect(removeNewArchFlags).not.toHaveBeenCalled();
|
|
expect(publishAndroidArtifactsToMavenMock).toHaveBeenCalledWith(
|
|
expectedVersion,
|
|
'nightly',
|
|
);
|
|
expect(execMock.mock.calls[0][0]).toBe(
|
|
`npm view react-native@next version`,
|
|
);
|
|
expect(execMock.mock.calls[1][0]).toBe('npm publish --tag nightly');
|
|
expect(echoMock).toHaveBeenCalledWith(
|
|
`Published to npm ${expectedVersion}`,
|
|
);
|
|
expect(exitMock).toHaveBeenCalledWith(0);
|
|
});
|
|
|
|
it('should fail to set version', () => {
|
|
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(removeNewArchFlags).not.toHaveBeenCalled();
|
|
expect(publishAndroidArtifactsToMavenMock).not.toBeCalled();
|
|
expect(execMock.mock.calls[0][0]).toBe(
|
|
`npm view react-native@next version`,
|
|
);
|
|
expect(consoleErrorMock).toHaveBeenCalledWith(
|
|
`Failed to set version number to ${expectedVersion}`,
|
|
);
|
|
expect(exitMock).toHaveBeenCalledWith(1);
|
|
});
|
|
});
|
|
|
|
describe('release', () => {
|
|
it('should fail with invalid release version', () => {
|
|
process.env.CIRCLE_TAG = '1.0.1';
|
|
expect(() => {
|
|
publishNpm('release');
|
|
}).toThrow('Version 1.0.1 is not valid for Release');
|
|
expect(publishAndroidArtifactsToMavenMock).not.toBeCalled();
|
|
});
|
|
|
|
it('should publish non-latest', () => {
|
|
execMock.mockReturnValueOnce({code: 0});
|
|
isTaggedLatestMock.mockReturnValueOnce(false);
|
|
process.env.CIRCLE_TAG = '0.81.1';
|
|
process.env.NPM_CONFIG_OTP = 'otp';
|
|
|
|
publishNpm('release');
|
|
|
|
expect(removeNewArchFlags).not.toHaveBeenCalled();
|
|
const expectedVersion = '0.81.1';
|
|
expect(publishAndroidArtifactsToMavenMock).toHaveBeenCalledWith(
|
|
expectedVersion,
|
|
'release',
|
|
);
|
|
expect(execMock).toHaveBeenCalledWith(
|
|
`npm publish --tag 0.81-stable --otp otp`,
|
|
{cwd: '../packages/react-native'},
|
|
);
|
|
expect(echoMock).toHaveBeenCalledWith(
|
|
`Published to npm ${expectedVersion}`,
|
|
);
|
|
expect(exitMock).toHaveBeenCalledWith(0);
|
|
expect(execMock.mock.calls).toHaveLength(1);
|
|
});
|
|
|
|
it('should publish latest stable', () => {
|
|
execMock.mockReturnValueOnce({code: 0});
|
|
isTaggedLatestMock.mockReturnValueOnce(true);
|
|
process.env.CIRCLE_TAG = '0.81.1';
|
|
process.env.NPM_CONFIG_OTP = 'otp';
|
|
|
|
publishNpm('release');
|
|
|
|
expect(removeNewArchFlags).not.toHaveBeenCalled();
|
|
const expectedVersion = '0.81.1';
|
|
expect(publishAndroidArtifactsToMavenMock).toHaveBeenCalledWith(
|
|
expectedVersion,
|
|
'release',
|
|
);
|
|
expect(execMock).toHaveBeenCalledWith(
|
|
`npm publish --tag latest --otp ${process.env.NPM_CONFIG_OTP}`,
|
|
{cwd: '../packages/react-native'},
|
|
);
|
|
expect(echoMock).toHaveBeenCalledWith(
|
|
`Published to npm ${expectedVersion}`,
|
|
);
|
|
expect(exitMock).toHaveBeenCalledWith(0);
|
|
expect(execMock.mock.calls).toHaveLength(1);
|
|
});
|
|
|
|
it('should fail to publish latest stable', () => {
|
|
execMock.mockReturnValueOnce({code: 1});
|
|
isTaggedLatestMock.mockReturnValueOnce(true);
|
|
process.env.CIRCLE_TAG = '0.81.1';
|
|
process.env.NPM_CONFIG_OTP = 'otp';
|
|
|
|
publishNpm('release');
|
|
|
|
expect(removeNewArchFlags).not.toHaveBeenCalled();
|
|
const expectedVersion = '0.81.1';
|
|
expect(publishAndroidArtifactsToMavenMock).toHaveBeenCalledWith(
|
|
expectedVersion,
|
|
'release',
|
|
);
|
|
expect(execMock).toHaveBeenCalledWith(
|
|
`npm publish --tag latest --otp ${process.env.NPM_CONFIG_OTP}`,
|
|
{cwd: '../packages/react-native'},
|
|
);
|
|
expect(echoMock).toHaveBeenCalledWith(`Failed to publish package to npm`);
|
|
expect(exitMock).toHaveBeenCalledWith(1);
|
|
expect(execMock.mock.calls).toHaveLength(1);
|
|
});
|
|
|
|
it('should publish next', () => {
|
|
execMock.mockReturnValueOnce({code: 0});
|
|
isTaggedLatestMock.mockReturnValueOnce(true);
|
|
process.env.CIRCLE_TAG = '0.81.0-rc.4';
|
|
process.env.NPM_CONFIG_OTP = 'otp';
|
|
|
|
publishNpm('release');
|
|
|
|
expect(removeNewArchFlags).not.toHaveBeenCalled();
|
|
const expectedVersion = '0.81.0-rc.4';
|
|
expect(publishAndroidArtifactsToMavenMock).toHaveBeenCalledWith(
|
|
expectedVersion,
|
|
'release',
|
|
);
|
|
expect(execMock).toHaveBeenCalledWith(
|
|
`npm publish --tag next --otp ${process.env.NPM_CONFIG_OTP}`,
|
|
{cwd: '../packages/react-native'},
|
|
);
|
|
expect(echoMock).toHaveBeenCalledWith(
|
|
`Published to npm ${expectedVersion}`,
|
|
);
|
|
expect(exitMock).toHaveBeenCalledWith(0);
|
|
expect(execMock.mock.calls).toHaveLength(1);
|
|
});
|
|
});
|
|
});
|