diff --git a/scripts/releases-ci/__tests__/publish-npm-test.js b/scripts/releases-ci/__tests__/publish-npm-test.js index 2fee2e9ab90b..f2568c130793 100644 --- a/scripts/releases-ci/__tests__/publish-npm-test.js +++ b/scripts/releases-ci/__tests__/publish-npm-test.js @@ -80,21 +80,26 @@ describe('publish-npm', () => { jest.resetAllMocks(); }); - describe('publish-npm.js', () => { - it('should fail when invalid build type is passed', async () => { - // Call actual function - // $FlowExpectedError[underconstrained-implicit-instantiation] - const npmUtils = jest.requireActual('../../releases/utils/npm-utils'); - getNpmInfoMock.mockImplementation(npmUtils.getNpmInfo); + it('should fail when invalid build type is passed', async () => { + // Call actual function + // $FlowExpectedError[underconstrained-implicit-instantiation] + const npmUtils = jest.requireActual('../../releases/utils/npm-utils'); + getNpmInfoMock.mockImplementation(npmUtils.getNpmInfo); + + await expect(async () => { + // $FlowExpectedError[incompatible-type] + await publishNpm('invalid'); + }).rejects.toThrow('Unsupported build type: invalid'); + }); - await expect(async () => { - // $FlowExpectedError[incompatible-type] - await publishNpm('invalid'); - }).rejects.toThrow('Unsupported build type: invalid'); + describe('dry-run', () => { + beforeEach(() => { + jest.mock('../../shared/monorepoUtils', () => ({ + ...jest.requireActual('../../shared/monorepoUtils'), + getWorkspaceRoot: jest.fn().mockResolvedValue({version: '1000.0.0'}), + })); }); - }); - describe("publishNpm('dry-run')", () => { it('should set version, hermes version, and not publish', async () => { const version = '1000.0.0-currentco'; getNpmInfoMock.mockReturnValueOnce({ @@ -122,35 +127,73 @@ describe('publish-npm', () => { expect(publishPackageMock).not.toHaveBeenCalled(); }); - it('should set version, not set hermes version, and not publish', async () => { - const version = '1000.0.0-currentco'; - getNpmInfoMock.mockReturnValueOnce({ - version, - tag: null, + describe('when on stable branch', () => { + it('main → RC0: should skip Hermes version', async () => { + const version = '1000.0.0-currentco'; + getNpmInfoMock.mockReturnValueOnce({ + version, + tag: null, + }); + getBranchName.mockReturnValueOnce('0.83-stable'); + + await publishNpm('dry-run'); + + expect(updateHermesVersionsToNightlyMock).not.toHaveBeenCalled(); + expect(setVersionMock).not.toBeCalled(); + expect(updateReactNativeArtifactsMock).toBeCalledWith( + version, + 'dry-run', + ); + + // Generate Android artifacts is now delegate to build_android entirely + expect(generateAndroidArtifactsMock).not.toHaveBeenCalled(); + + expect(consoleLogMock).toHaveBeenCalledWith( + 'Skipping `npm publish` because --dry-run is set.', + ); + + // Expect termination + expect(publishAndroidArtifactsToMavenMock).not.toHaveBeenCalled(); + expect(publishExternalArtifactsToMavenMock).not.toHaveBeenCalled(); + expect(publishPackageMock).not.toHaveBeenCalled(); }); - getBranchName.mockReturnValueOnce('0.83-stable'); - await publishNpm('dry-run'); - - expect(updateHermesVersionsToNightlyMock).not.toHaveBeenCalled(); - expect(setVersionMock).not.toBeCalled(); - expect(updateReactNativeArtifactsMock).toBeCalledWith(version, 'dry-run'); - - // Generate Android artifacts is now delegate to build_android entirely - expect(generateAndroidArtifactsMock).not.toHaveBeenCalled(); - - expect(consoleLogMock).toHaveBeenCalledWith( - 'Skipping `npm publish` because --dry-run is set.', - ); - - // Expect termination - expect(publishAndroidArtifactsToMavenMock).not.toHaveBeenCalled(); - expect(publishExternalArtifactsToMavenMock).not.toHaveBeenCalled(); - expect(publishPackageMock).not.toHaveBeenCalled(); + it('RC0 → RC1: should skip Hermes version and artifacts', async () => { + const version = '0.83.0-rc.0'; + getNpmInfoMock.mockReturnValueOnce({ + version, + tag: null, + }); + getBranchName.mockReturnValueOnce('0.83-stable'); + jest.mock('../../shared/monorepoUtils', () => ({ + ...jest.requireActual('../../shared/monorepoUtils'), + getWorkspaceRoot: jest + .fn() + .mockResolvedValue({version: '0.83.0-rc.0'}), + })); + + await publishNpm('dry-run'); + + expect(updateHermesVersionsToNightlyMock).not.toHaveBeenCalled(); + expect(setVersionMock).not.toBeCalled(); + expect(updateReactNativeArtifactsMock).not.toBeCalled(); + + // Generate Android artifacts is now delegate to build_android entirely + expect(generateAndroidArtifactsMock).not.toHaveBeenCalled(); + + expect(consoleLogMock).toHaveBeenCalledWith( + 'Skipping `npm publish` because --dry-run is set.', + ); + + // Expect termination + expect(publishAndroidArtifactsToMavenMock).not.toHaveBeenCalled(); + expect(publishExternalArtifactsToMavenMock).not.toHaveBeenCalled(); + expect(publishPackageMock).not.toHaveBeenCalled(); + }); }); }); - describe("publishNpm('nightly')", () => { + describe('nightly', () => { beforeAll(() => { jest.mock('../../shared/monorepoUtils', () => ({ ...jest.requireActual('../../shared/monorepoUtils'), @@ -308,7 +351,7 @@ describe('publish-npm', () => { }); }); - describe("publishNpm('release')", () => { + describe('release', () => { it('should publish non-latest', async () => { const expectedVersion = '0.81.1'; getNpmInfoMock.mockImplementation(() => ({ diff --git a/scripts/releases-ci/publish-npm.js b/scripts/releases-ci/publish-npm.js index 985cf4f13872..f1ed1a2ba190 100755 --- a/scripts/releases-ci/publish-npm.js +++ b/scripts/releases-ci/publish-npm.js @@ -28,8 +28,7 @@ const { } = require('../releases/utils/release-utils'); const {getBranchName} = require('../releases/utils/scm-utils'); const {REPO_ROOT} = require('../shared/consts'); -const {getPackages} = require('../shared/monorepoUtils'); -const fs = require('fs'); +const {getPackages, getWorkspaceRoot} = require('../shared/monorepoUtils'); const path = require('path'); const yargs = require('yargs'); @@ -110,16 +109,9 @@ async function publishNpm(buildType /*: BuildType */) /*: Promise */ { // Before updating React Native artifacts versions for dry-run, we check if the version has already been set. // If it has, we don't need to update the artifacts at all (at this will revert them back to 1000.0.0) // If it hasn't, we can update the native artifacts accordingly. - const reactNativePackageJson = path.join( - REPO_ROOT, - 'packages', - 'react-native', - 'package.json', - ); - const packageJsonContent = fs.readFileSync(reactNativePackageJson, 'utf8'); - const packageJson = JSON.parse(packageJsonContent); - - if (packageJson.version === '1000.0.0') { + const projectInfo = await getWorkspaceRoot(); + + if (projectInfo.version === '1000.0.0') { // Set hermes versions to latest available if not on a stable branch if (!/.*-stable/.test(getBranchName())) { await updateHermesVersionsToNightly(); diff --git a/scripts/shared/monorepoUtils.js b/scripts/shared/monorepoUtils.js index 0fa71e6fccb8..549e27df5ab0 100644 --- a/scripts/shared/monorepoUtils.js +++ b/scripts/shared/monorepoUtils.js @@ -45,6 +45,9 @@ export type PackageInfo = { // The absolute path to the package path: string, + // The package version + version: string, + // The parsed package.json contents packageJson: PackageJson, }; @@ -113,6 +116,7 @@ async function parsePackageInfo( { name: packageJson.name, path: packagePath, + version: packageJson.version, packageJson, }, ];