From bd32d5a9997b4bfc33efa8279ee04a865a3a2cb0 Mon Sep 17 00:00:00 2001 From: MT Lewis Date: Mon, 16 Sep 2024 11:40:27 +0100 Subject: [PATCH] yarn-plugin: add additional check during pack to confirm that all backstage versions have been replaced Adds an additional check during pack which walks all the dependencies in the manifest, and verifies that there are no remaining `backstage:` versions. I'm not aware of any realistic cases where the code that does the replacement would be expected to fail, but since a backstage:^ package in the manifest will break the release, it seems prudent to double check and fail fast to allow us to catch unexpected results. Signed-off-by: MT Lewis --- .changeset/seven-ladybugs-fetch.md | 5 +++ .../handlers/beforeWorkspacePacking.test.ts | 32 ++++++++++++++++++- .../src/handlers/beforeWorkspacePacking.ts | 15 +++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 .changeset/seven-ladybugs-fetch.md diff --git a/.changeset/seven-ladybugs-fetch.md b/.changeset/seven-ladybugs-fetch.md new file mode 100644 index 0000000000..31c670f181 --- /dev/null +++ b/.changeset/seven-ladybugs-fetch.md @@ -0,0 +1,5 @@ +--- +'yarn-plugin-backstage': patch +--- + +Add additional check before packing workspace to verify that all backstage:^ versions have been removed. diff --git a/packages/yarn-plugin/src/handlers/beforeWorkspacePacking.test.ts b/packages/yarn-plugin/src/handlers/beforeWorkspacePacking.test.ts index ca99b88437..d156182923 100644 --- a/packages/yarn-plugin/src/handlers/beforeWorkspacePacking.test.ts +++ b/packages/yarn-plugin/src/handlers/beforeWorkspacePacking.test.ts @@ -28,6 +28,14 @@ jest.mock('@backstage/release-manifests', () => ({ name: '@backstage/core', version: '3.2.1', }, + { + name: '@backstage/plugin-1', + version: '6.5.4', + }, + { + name: '@backstage/plugin-2', + version: '9.8.7', + }, ], }), })); @@ -100,7 +108,29 @@ describe('beforeWorkspacePacking', () => { await expect(() => beforeWorkspacePacking(makeWorkspace(result), result), - ).rejects.toThrow(); + ).rejects.toThrow(/unexpected version range/i); + }); + + it(`throws an error if the final manifest unexpectedly contains backstage: versions`, async () => { + const result = { + name: 'test-package', + [dependencyType]: { + get ['@backstage/core']() { + return 'backstage:^'; + }, + set ['@backstage/core'](_value: unknown) { + // ignore the attempt to set the value to + // allow testing the validation logic at + // the end of the hook. + }, + '@backstage/plugin-1': 'backstage:^', + '@backstage/plugin-2': 'backstage:^', + }, + }; + + await expect(() => + beforeWorkspacePacking(makeWorkspace(result), result), + ).rejects.toThrow(/failed to replace all "backstage:" ranges/i); }); it('converts backstage:^ versions to the corresponding package version prefixed by ^', async () => { diff --git a/packages/yarn-plugin/src/handlers/beforeWorkspacePacking.ts b/packages/yarn-plugin/src/handlers/beforeWorkspacePacking.ts index b804f64226..41014a55a6 100644 --- a/packages/yarn-plugin/src/handlers/beforeWorkspacePacking.ts +++ b/packages/yarn-plugin/src/handlers/beforeWorkspacePacking.ts @@ -15,9 +15,13 @@ */ import { Descriptor, Workspace, structUtils } from '@yarnpkg/core'; +import { some } from 'lodash'; import { getCurrentBackstageVersion, getPackageVersion } from '../util'; import { PROTOCOL } from '../constants'; +const hasBackstageVersion = (range: string) => + structUtils.parseRange(range).protocol === PROTOCOL; + const getFinalDependencyType = ( dependencyType: string, descriptor: Descriptor, @@ -69,4 +73,15 @@ export const beforeWorkspacePacking = async ( )}`; } } + + if ( + some( + ['dependencies', 'devDependencies', 'optionalDependencies'], + dependencyType => some(rawManifest[dependencyType], hasBackstageVersion), + ) + ) { + throw new Error( + `Failed to replace all "backstage:" ranges in manifest for ${rawManifest.name}`, + ); + } };