From 7bcff07f139a4529c4d4193f4ea7c31ac01f6775 Mon Sep 17 00:00:00 2001 From: Luna Wei Date: Fri, 9 Jun 2023 09:20:08 -0700 Subject: [PATCH] Refactor nightly monorepo publish script (#37707) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/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: c4e425924aa6cfdcf10e932e1b151ba05d9b7237 --- scripts/__tests__/publish-npm-test.js | 2 +- ...st.js => get-and-update-nightlies-test.js} | 58 +++++++++++++++---- ...package.js => get-and-update-nightlies.js} | 14 +++-- scripts/publish-npm.js | 4 +- 4 files changed, 60 insertions(+), 18 deletions(-) rename scripts/monorepo/__tests__/{publish-nightly-for-each-changed-package-test.js => get-and-update-nightlies-test.js} (54%) rename scripts/monorepo/{publish-nightly-for-each-changed-package.js => get-and-update-nightlies.js} (88%) diff --git a/scripts/__tests__/publish-npm-test.js b/scripts/__tests__/publish-npm-test.js index 32bc613ff98628..3f2b88626a8728 100644 --- a/scripts/__tests__/publish-npm-test.js +++ b/scripts/__tests__/publish-npm-test.js @@ -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'); diff --git a/scripts/monorepo/__tests__/publish-nightly-for-each-changed-package-test.js b/scripts/monorepo/__tests__/get-and-update-nightlies-test.js similarity index 54% rename from scripts/monorepo/__tests__/publish-nightly-for-each-changed-package-test.js rename to scripts/monorepo/__tests__/get-and-update-nightlies-test.js index b7d420809bfec6..5453b0c7344997 100644 --- a/scripts/monorepo/__tests__/publish-nightly-for-each-changed-package-test.js +++ b/scripts/monorepo/__tests__/get-and-update-nightlies-test.js @@ -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', }, @@ -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(); }); @@ -60,16 +61,16 @@ 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', }, @@ -77,25 +78,60 @@ describe('publishNightlyForEachChangedPackage', () => { // 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', + }); }); }); diff --git a/scripts/monorepo/publish-nightly-for-each-changed-package.js b/scripts/monorepo/get-and-update-nightlies.js similarity index 88% rename from scripts/monorepo/publish-nightly-for-each-changed-package.js rename to scripts/monorepo/get-and-update-nightlies.js index 38ee594e7e4075..c38c79a705351d 100644 --- a/scripts/monorepo/publish-nightly-for-each-changed-package.js +++ b/scripts/monorepo/get-and-update-nightlies.js @@ -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) { @@ -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; } @@ -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; diff --git a/scripts/publish-npm.js b/scripts/publish-npm.js index 653a3782c56925..e0223288059e34 100755 --- a/scripts/publish-npm.js +++ b/scripts/publish-npm.js @@ -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, @@ -150,7 +150,7 @@ function publishNpm(buildType) { // set and publish the relevant monorepo packages if (buildType === 'nightly') { - publishNightlyForEachChangedPackage(version); + getAndUpdateNightlies(version); } generateAndroidArtifacts(version);