diff --git a/src/functional.test.ts b/src/functional.test.ts index 45a35b75..ceb6aafb 100644 --- a/src/functional.test.ts +++ b/src/functional.test.ts @@ -606,116 +606,6 @@ describe('create-release-branch (functional)', () => { ); }); - it('errors before making any changes if the edited release spec omits changed packages', async () => { - await withMonorepoProjectEnvironment( - { - packages: { - $root$: { - name: '@scope/monorepo', - version: '1.0.0', - directoryPath: '.', - }, - a: { - name: '@scope/a', - version: '0.1.2', - directoryPath: 'packages/a', - }, - b: { - name: '@scope/b', - version: '1.1.4', - directoryPath: 'packages/b', - }, - c: { - name: '@scope/c', - version: '2.0.13', - directoryPath: 'packages/c', - }, - d: { - name: '@scope/d', - version: '1.2.3', - directoryPath: 'packages/d', - }, - }, - workspaces: { - '.': ['packages/*'], - }, - }, - async (environment) => { - await expect( - environment.runTool({ - releaseSpecification: { - packages: { - a: 'major', - c: 'patch', - }, - }, - }), - ).toThrowExecaError( - ` -Error: Your release spec could not be processed due to the following issues: - -* The following packages, which have changed since their latest release, are missing. - - - @scope/b - - @scope/d - - Consider including them in the release spec so that any packages that rely on them won't break in production. - - If you are ABSOLUTELY SURE that this won't occur, however, and want to postpone the release of a package, then list it with a directive of "intentionally-skip". For example: - - packages: - "@scope/b": intentionally-skip - "@scope/d": intentionally-skip - -The release spec file has been retained for you to edit again and make the necessary fixes. Once you've done this, re-run this tool. - -<> -<> -`.trim(), - { - replacements: [ - { - from: `${environment.tempDirectoryPath}/RELEASE_SPEC.yml`, - to: '<>', - }, - ], - }, - ); - - expect(await environment.readJsonFile('package.json')).toStrictEqual({ - name: '@scope/monorepo', - version: '1.0.0', - private: true, - workspaces: ['packages/*'], - }); - expect( - await environment.readJsonFileWithinPackage('a', 'package.json'), - ).toStrictEqual({ - name: '@scope/a', - version: '0.1.2', - }); - expect( - await environment.readJsonFileWithinPackage('b', 'package.json'), - ).toStrictEqual({ - name: '@scope/b', - version: '1.1.4', - }); - expect( - await environment.readJsonFileWithinPackage('c', 'package.json'), - ).toStrictEqual({ - name: '@scope/c', - version: '2.0.13', - }); - expect( - await environment.readJsonFileWithinPackage('d', 'package.json'), - ).toStrictEqual({ - name: '@scope/d', - version: '1.2.3', - }); - }, - ); - }); - it('does not update the versions of any packages that have been tagged with intentionally-skip', async () => { await withMonorepoProjectEnvironment( { diff --git a/src/release-specification.test.ts b/src/release-specification.test.ts index c665acb9..3932e3c6 100644 --- a/src/release-specification.test.ts +++ b/src/release-specification.test.ts @@ -572,118 +572,6 @@ Your release spec could not be processed due to the following issues: }); }); - it('throws if there are any packages not listed in the release spec which have changed', async () => { - await withSandbox(async (sandbox) => { - const project = buildMockProject({ - workspacePackages: { - a: buildMockPackage('a', { - hasChangesSinceLatestRelease: true, - }), - b: buildMockPackage('b', { - hasChangesSinceLatestRelease: true, - }), - c: buildMockPackage('c', { - hasChangesSinceLatestRelease: true, - }), - }, - }); - const releaseSpecificationPath = path.join( - sandbox.directoryPath, - 'release-spec', - ); - await fs.promises.writeFile( - releaseSpecificationPath, - YAML.stringify({ - packages: { - a: 'major', - }, - }), - ); - - await expect( - validateReleaseSpecification(project, releaseSpecificationPath), - ).rejects.toThrow( - ` -Your release spec could not be processed due to the following issues: - -* The following packages, which have changed since their latest release, are missing. - - - b - - c - - Consider including them in the release spec so that any packages that rely on them won't break in production. - - If you are ABSOLUTELY SURE that this won't occur, however, and want to postpone the release of a package, then list it with a directive of "intentionally-skip". For example: - - packages: - b: intentionally-skip - c: intentionally-skip - -The release spec file has been retained for you to edit again and make the necessary fixes. Once you've done this, re-run this tool. - -${releaseSpecificationPath} -`.trim(), - ); - }); - }); - - it('throws if there are any packages listed in the release spec which have changed but their version specifiers are null', async () => { - await withSandbox(async (sandbox) => { - const project = buildMockProject({ - workspacePackages: { - a: buildMockPackage('a', { - hasChangesSinceLatestRelease: true, - }), - b: buildMockPackage('b', { - hasChangesSinceLatestRelease: true, - }), - c: buildMockPackage('c', { - hasChangesSinceLatestRelease: true, - }), - }, - }); - const releaseSpecificationPath = path.join( - sandbox.directoryPath, - 'release-spec', - ); - await fs.promises.writeFile( - releaseSpecificationPath, - YAML.stringify({ - packages: { - a: 'major', - b: null, - c: null, - }, - }), - ); - - await expect( - validateReleaseSpecification(project, releaseSpecificationPath), - ).rejects.toThrow( - ` -Your release spec could not be processed due to the following issues: - -* The following packages, which have changed since their latest release, are missing. - - - b - - c - - Consider including them in the release spec so that any packages that rely on them won't break in production. - - If you are ABSOLUTELY SURE that this won't occur, however, and want to postpone the release of a package, then list it with a directive of "intentionally-skip". For example: - - packages: - b: intentionally-skip - c: intentionally-skip - -The release spec file has been retained for you to edit again and make the necessary fixes. Once you've done this, re-run this tool. - -${releaseSpecificationPath} -`.trim(), - ); - }); - }); - it('throws if there are any packages in the release with a major version bump using the word "major", but any of their dependents defined as "dependencies" are not listed in the release', async () => { await withSandbox(async (sandbox) => { const project = buildMockProject({ diff --git a/src/release-specification.ts b/src/release-specification.ts index 9ab314e4..a81c4ea7 100644 --- a/src/release-specification.ts +++ b/src/release-specification.ts @@ -207,84 +207,6 @@ export async function validateReleaseSpecification( const errors: { message: string | string[]; lineNumber?: number }[] = []; - const changedPackageNames = Object.keys(project.workspacePackages).filter( - (packageName) => - project.workspacePackages[packageName].hasChangesSinceLatestRelease, - ); - - const missingChangedPackageNames = changedPackageNames.filter( - (packageName) => - !hasProperty(unvalidatedReleaseSpecification.packages, packageName) || - unvalidatedReleaseSpecification.packages[packageName] === null, - ); - - const packageNamesToReportMissing = missingChangedPackageNames.filter( - (missingChangedPackageName) => { - const missingChangedPackage = - project.workspacePackages[missingChangedPackageName]; - - const isInternalDependency = Object.values( - project.workspacePackages, - ).some((workspacePackage) => { - const { dependencies, peerDependencies } = - workspacePackage.validatedManifest; - return ( - hasProperty(dependencies, missingChangedPackageName) || - hasProperty(peerDependencies, missingChangedPackageName) - ); - }); - - const hasInternalDependencyWithBreakingChanges = Object.keys({ - ...missingChangedPackage.validatedManifest.dependencies, - ...missingChangedPackage.validatedManifest.peerDependencies, - }) - .filter((dependency) => project.workspacePackages[dependency]) - .some((dependency) => { - const internalDependencyVersionSpecifierOrDirective = - unvalidatedReleaseSpecification.packages[dependency]; - return ( - internalDependencyVersionSpecifierOrDirective && - (internalDependencyVersionSpecifierOrDirective === 'major' || - (isValidSemver(internalDependencyVersionSpecifierOrDirective) && - diff( - missingChangedPackage.validatedManifest.version, - internalDependencyVersionSpecifierOrDirective, - ) === 'major')) - ); - }); - - return !isInternalDependency && !hasInternalDependencyWithBreakingChanges; - }, - ); - - if (packageNamesToReportMissing.length > 0) { - errors.push({ - message: [ - 'The following packages, which have changed since their latest release, are missing.', - packageNamesToReportMissing - .map((packageName) => ` - ${packageName}`) - .join('\n'), - " Consider including them in the release spec so that any packages that rely on them won't break in production.", - ` If you are ABSOLUTELY SURE that this won't occur, however, and want to postpone the release of a package, then list it with a directive of "intentionally-skip". For example:`, - YAML.stringify({ - packages: packageNamesToReportMissing.reduce( - (object, packageName) => { - return { - ...object, - [packageName]: INTENTIONALLY_SKIP_PACKAGE_DIRECTIVE, - }; - }, - {}, - ), - }) - .trim() - .split('\n') - .map((line) => ` ${line}`) - .join('\n'), - ].join('\n\n'), - }); - } - Object.entries(unvalidatedReleaseSpecification.packages).forEach( ([changedPackageName, versionSpecifierOrDirective], index) => { const lineNumber = indexOfFirstUsableLine + index + 2;