Skip to content

Commit

Permalink
Refactor nightly monorepo publish script (#37707)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #37707

Changelog: [Internal] - Refactor nightly monorepo publish script to also return a map of packages and their current nightly version and rename to reflect. This may refer to a nightly version that was just published (if we detect changes) or the nightly tag on npm if no changes.

In subsequent diffs, will update the react-native nightly script to use this map to set the versions for nightly react-native versions.

Reviewed By: hoxyq

Differential Revision: D46450703

fbshipit-source-id: a061f1c42db1651bf2d1f7763b0f7c1f1f66bd22
  • Loading branch information
lunaleaps authored and facebook-github-bot committed Jun 8, 2023
1 parent 8f7f0bf commit d6fc195
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 18 deletions.
2 changes: 1 addition & 1 deletion scripts/__tests__/publish-npm-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jest
generateAndroidArtifacts: jest.fn(),
publishAndroidArtifactsToMaven: publishAndroidArtifactsToMavenMock,
}))
.mock('../monorepo/publish-nightly-for-each-changed-package');
.mock('../monorepo/get-and-update-nightlies');

const date = new Date('2023-04-20T23:52:39.543Z');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@
* @format
*/

const publishNightlyForEachChangedPackage = require('../publish-nightly-for-each-changed-package');
const getAndUpdateNightlies = require('../get-and-update-nightlies');

const NPM_NIGHTLY_VERSION = 'published-nightly-version';
const mockPackages = [
{
packageManifest: {name: 'packageA', version: 'local-version'},
packageManifest: {name: '@react-native/packageA', version: 'local-version'},
packageAbsolutePath: '/some/place/packageA',
packageRelativePathFromRoot: './place/packageA',
},
Expand Down Expand Up @@ -44,13 +45,13 @@ jest
restore: jest.fn(),
}))
.mock('../../npm-utils', () => ({
getPackageVersionStrByTag: () => 'published-nightly-version',
getPackageVersionStrByTag: () => NPM_NIGHTLY_VERSION,
diffPackages: diffPackagesMock,
publishPackage: publishPackageMock,
pack: jest.fn(),
}));

describe('publishNightlyForEachChangedPackage', () => {
describe('getAndUpdateNightlies', () => {
beforeEach(() => {
jest.clearAllMocks();
});
Expand All @@ -60,42 +61,77 @@ describe('publishNightlyForEachChangedPackage', () => {
publishPackageMock.mockImplementationOnce(() => ({code: 0}));
diffPackagesMock.mockImplementationOnce(() => 'some-file-name.js\n');

publishNightlyForEachChangedPackage(nightlyVersion);
const latestNightlies = getAndUpdateNightlies(nightlyVersion);

// ensure we set the version of the last published nightly (for diffing)
expect(writeFileSyncMock.mock.calls[0][1]).toBe(
'{\n "name": "packageA",\n "version": "published-nightly-version"\n}\n',
'{\n "name": "@react-native/packageA",\n "version": "published-nightly-version"\n}\n',
);

expect(diffPackagesMock).toBeCalledWith(
'packageA@nightly',
'packageA-published-nightly-version.tgz',
'@react-native/packageA@nightly',
'react-native-packageA-published-nightly-version.tgz',
{
cwd: '/some/place/packageA',
},
);

// when determining that we DO want to publish, ensure we update the version to the provded nightly version we want to use
expect(writeFileSyncMock.mock.calls[1][1]).toBe(
`{\n "name": "packageA",\n "version": "${nightlyVersion}"\n}\n`,
`{\n "name": "@react-native/packageA",\n "version": "${nightlyVersion}"\n}\n`,
);

expect(publishPackageMock).toBeCalled();

// Expect the map returned to accurately list the latest nightly version
expect(latestNightlies).toEqual({
'@react-native/packageA': '0.73.0-nightly-202108-shortcommit',
});
});
describe('fails to publish', () => {
let consoleError;
beforeEach(() => {
consoleError = console.error;
console.error = jest.fn();
});

afterEach(() => {
console.error = consoleError;
});

it('doesnt update nightly version when fails to publish', () => {
const nightlyVersion = '0.73.0-nightly-202108-shortcommit';
publishPackageMock.mockImplementationOnce(() => ({
code: 1,
stderr: 'Some error about it failing to publish',
}));
diffPackagesMock.mockImplementationOnce(() => 'some-file-name.js\n');

const latestNightlies = getAndUpdateNightlies(nightlyVersion);

// Expect the map returned to accurately list the latest nightly version
expect(latestNightlies).toEqual({});
});
});

it('doesnt publish because no changes', () => {
const nightlyVersion = '0.73.0-nightly-202108-shortcommit';
diffPackagesMock.mockImplementationOnce(() => '\n');

publishNightlyForEachChangedPackage(nightlyVersion);
const latestNightlies = getAndUpdateNightlies(nightlyVersion);

expect(writeFileSyncMock.mock.calls[0][1]).toBe(
'{\n "name": "packageA",\n "version": "published-nightly-version"\n}\n',
'{\n "name": "@react-native/packageA",\n "version": "published-nightly-version"\n}\n',
);

// in this test, we expect there to be no differences between last published nightly and local
// so we never update the version and we don't publish
expect(writeFileSyncMock.mock.calls.length).toBe(1);
expect(publishPackageMock).not.toBeCalled();

// Since we don't update, we expect the map to list the latest nightly on npm
expect(latestNightlies).toEqual({
'@react-native/packageA': 'published-nightly-version',
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,15 @@ function hasChanges(
}

/**
* Publish nightlies for monorepo packages that changed since last publish.
* This is called by `react-native`'s nightly job.
* Get the latest nightly version of each monorepo package and publishes a new nightly if there have been updates.
* Returns a map of monorepo packages and its latest nightly version.
*
* This is called by `react-native`'s nightly job.
* Note: This does not publish `package/react-native`'s nightly. That is handled in `publish-npm`.
*/
function publishNightlyForEachChangedPackage(nightlyVersion) {
function getAndUpdateNightlies(nightlyVersion) {
const nightlyVersions = {};

forEachPackage(
(packageAbsolutePath, packageRelativePathFromRoot, packageManifest) => {
if (packageManifest.private) {
Expand Down Expand Up @@ -103,6 +106,7 @@ function publishNightlyForEachChangedPackage(nightlyVersion) {
console.log(
`Detected no changes in ${packageManifest.name}@nightly since last publish. Skipping.`,
);
nightlyVersions[packageManifest.name] = lastPublishedNightlyVersion;
return;
}

Expand All @@ -127,9 +131,11 @@ function publishNightlyForEachChangedPackage(nightlyVersion) {
console.log(
`\u2705 Successfully published new version of ${packageManifest.name}`,
);
nightlyVersions[packageManifest.name] = nightlyVersion;
}
},
);
return nightlyVersions;
}

module.exports = publishNightlyForEachChangedPackage;
module.exports = getAndUpdateNightlies;
4 changes: 2 additions & 2 deletions scripts/publish-npm.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const {
getCurrentCommit,
isTaggedLatest,
} = require('./scm-utils');
const publishNightlyForEachChangedPackage = require('./monorepo/publish-nightly-for-each-changed-package');
const getAndUpdateNightlies = require('./monorepo/get-and-update-nightlies');
const {
generateAndroidArtifacts,
publishAndroidArtifactsToMaven,
Expand Down Expand Up @@ -150,7 +150,7 @@ function publishNpm(buildType) {

// set and publish the relevant monorepo packages
if (buildType === 'nightly') {
publishNightlyForEachChangedPackage(version);
getAndUpdateNightlies(version);
}

generateAndroidArtifacts(version);
Expand Down

0 comments on commit d6fc195

Please sign in to comment.