Skip to content

Commit 7819fef

Browse files
lunaleapsfacebook-github-bot
authored andcommitted
Refactor to npm-utils (facebook#37555)
Summary: Pull Request resolved: facebook#37555 Changelog: [Internal] Refactor some npm commands and centralize in npm-utils. For now, centralize `getPackageVersionStrByTag` and `publishPackage` and update: 1. `publish-npm` to use utilities. This is how we publish `react-native` for commitlies, releases, and nightlies 2. Update `find-and-publish-all-bumped-packages.js` where we publish our monorepo dependencies Reviewed By: cortinico, hoxyq Differential Revision: D46131120 fbshipit-source-id: e6020058eb94b4f8d95068b8cd87cc765711be5b
1 parent be8af22 commit 7819fef

File tree

5 files changed

+114
-26
lines changed

5 files changed

+114
-26
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @format
8+
*/
9+
10+
const {getPackageVersionStrByTag, publishPackage} = require('../npm-utils');
11+
12+
const execMock = jest.fn();
13+
jest.mock('shelljs', () => ({
14+
exec: execMock,
15+
}));
16+
17+
describe('npm-utils', () => {
18+
beforeEach(() => {
19+
jest.resetModules();
20+
jest.resetAllMocks();
21+
});
22+
23+
describe('getPackageVersionStrByTag', () => {
24+
it('should return package version string', () => {
25+
execMock.mockImplementationOnce(() => ({code: 0, stdout: '0.34.2 \n'}));
26+
const versionStr = getPackageVersionStrByTag('my-package', 'next');
27+
expect(versionStr).toBe('0.34.2');
28+
});
29+
it('should throw error when invalid result', () => {
30+
execMock.mockImplementationOnce(() => ({
31+
code: 1,
32+
stderr: 'Some error message',
33+
}));
34+
35+
expect(() => {
36+
getPackageVersionStrByTag('my-package', 'next');
37+
}).toThrow('Failed to get next version from npm\nSome error message');
38+
});
39+
});
40+
41+
describe('publishPackage', () => {
42+
it('should run publish command', () => {
43+
publishPackage(
44+
'path/to/my-package',
45+
{tag: 'latest', otp: 'otp'},
46+
{silent: true, cwd: 'i/expect/this/to/be/overriden'},
47+
);
48+
expect(execMock).toHaveBeenCalledWith(
49+
'npm publish --tag latest --otp otp',
50+
{silent: true, cwd: 'path/to/my-package'},
51+
);
52+
});
53+
54+
it('should run publish command when no execOptions', () => {
55+
publishPackage('path/to/my-package', {tag: 'latest', otp: 'otp'});
56+
expect(execMock).toHaveBeenCalledWith(
57+
'npm publish --tag latest --otp otp',
58+
{cwd: 'path/to/my-package'},
59+
);
60+
});
61+
});
62+
});

scripts/__tests__/publish-npm-test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ describe('publish-npm', () => {
8888
true,
8989
);
9090
expect(execMock.mock.calls[0][0]).toBe(
91-
`npm view react-native dist-tags.next`,
91+
`npm view react-native@next version`,
9292
);
9393
expect(execMock.mock.calls[1][0]).toBe(
9494
`node scripts/set-rn-version.js --to-version ${expectedVersion} --build-type nightly`,
@@ -111,7 +111,7 @@ describe('publish-npm', () => {
111111

112112
expect(publishAndroidArtifactsToMavenMock).not.toBeCalled();
113113
expect(execMock.mock.calls[0][0]).toBe(
114-
`npm view react-native dist-tags.next`,
114+
`npm view react-native@next version`,
115115
);
116116
expect(execMock.mock.calls[1][0]).toBe(
117117
`node scripts/set-rn-version.js --to-version ${expectedVersion} --build-type nightly`,

scripts/monorepo/find-and-publish-all-bumped-packages.js

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -101,19 +101,12 @@ const findAndPublishAllBumpedPackages = () => {
101101
);
102102
}
103103

104-
const npmOTPFlag = NPM_CONFIG_OTP ? `--otp ${NPM_CONFIG_OTP}` : '';
105-
106-
const {status, stderr} = spawnSync('npm', ['publish', `${npmOTPFlag}`], {
107-
cwd: packageAbsolutePath,
108-
shell: true,
109-
stdio: 'pipe',
110-
encoding: 'utf-8',
111-
});
112-
if (status !== 0) {
104+
const result = publishPackage(packageAbsolutePath, {otp: NPM_CONFIG_OTP});
105+
if (result.code !== 0) {
113106
console.log(
114-
`\u274c Failed to publish version ${nextVersion} of ${packageManifest.name}. npm publish exited with code ${status}:`,
107+
`\u274c Failed to publish version ${nextVersion} of ${packageManifest.name}. npm publish exited with code ${result.code}:`,
115108
);
116-
console.log(stderr);
109+
console.log(result.stderr);
117110

118111
process.exit(1);
119112
} else {

scripts/npm-utils.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @format
8+
*/
9+
10+
'use strict';
11+
12+
const {exec} = require('shelljs');
13+
14+
function getPackageVersionStrByTag(packageName, tag) {
15+
const result = exec(`npm view ${packageName}@${tag} version`);
16+
17+
if (result.code) {
18+
throw `Failed to get ${tag} version from npm\n${result.stderr}`;
19+
}
20+
return result.stdout.trim();
21+
}
22+
23+
function publishPackage(packagePath, packageOptions, execOptions) {
24+
const {tag, otp} = packageOptions;
25+
const tagFlag = tag ? ` --tag ${tag}` : '';
26+
const otpFlag = otp ? ` --otp ${otp}` : '';
27+
const options = execOptions
28+
? {...execOptions, cwd: packagePath}
29+
: {cwd: packagePath};
30+
31+
return exec(`npm publish${tagFlag}${otpFlag}`, options);
32+
}
33+
34+
module.exports = {
35+
getPackageVersionStrByTag,
36+
publishPackage,
37+
};

scripts/publish-npm.js

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
const {exec, echo, exit} = require('shelljs');
1313
const {parseVersion} = require('./version-utils');
14+
const {getPackageVersionStrByTag, publishPackage} = require('./npm-utils');
1415
const {
1516
exitIfNotOnGit,
1617
getCurrentCommit,
@@ -76,13 +77,8 @@ if (require.main === module) {
7677

7778
// Get `next` version from npm and +1 on the minor for `main` version
7879
function getMainVersion() {
79-
const cmd = 'npm view react-native dist-tags.next';
80-
echo(cmd);
81-
const result = exec(cmd);
82-
if (result.code) {
83-
throw 'Failed to get next version from npm';
84-
}
85-
const {major, minor} = parseVersion(result.stdout.trim(), 'release');
80+
const versionStr = getPackageVersionStrByTag('react-native', 'next');
81+
const {major, minor} = parseVersion(versionStr, 'release');
8682
return `${major}.${parseInt(minor, 10) + 1}.0`;
8783
}
8884

@@ -165,12 +161,12 @@ function publishNpm(buildType) {
165161
// NPM publishing is done just after.
166162
publishAndroidArtifactsToMaven(version, buildType === 'nightly');
167163

168-
const tagFlag = `--tag ${tag}`;
169-
const otp = process.env.NPM_CONFIG_OTP;
170-
const otpFlag = otp ? ` --otp ${otp}` : '';
171-
172-
const packageDirPath = path.join(__dirname, '..', 'packages', 'react-native');
173-
if (exec(`npm publish ${tagFlag}${otpFlag}`, {cwd: packageDirPath}).code) {
164+
const packagePath = path.join(__dirname, '..', 'packages', 'react-native');
165+
const result = publishPackage(packagePath, {
166+
tag,
167+
otp: process.env.NPM_CONFIG_OTP,
168+
});
169+
if (result.code) {
174170
echo('Failed to publish package to npm');
175171
return exit(1);
176172
} else {

0 commit comments

Comments
 (0)