From 1f5ad63486b7b48da63bcdb6a0ad80e16dd330ef Mon Sep 17 00:00:00 2001 From: Sonishi Izuka Date: Fri, 3 Jun 2022 18:49:34 +0900 Subject: [PATCH] test(encrypted-archive): avoid forward compatibility test failures at release time When we try to release a new version, it will generate test data for a version that does not yet exist on npm. Forward compatibility testing is based on new test data and attempts to install a version of `@sounisi5011/encrypted-archive` that does not yet exist on npm. This causes the forward compatibility test to fail only at release time. To work around this, the latest version of `@sounisi5011/encrypted-archive` uses packages on local disk instead if installation from on npm fails. Note: Ideally, we should use the "npm view" command to skip tests for packages that do not exist on npm. However, Jest is not yet capable of skipping tests asynchronously. see https://github.com/facebook/jest/issues/8604 --- .../encrypted-archive/tests/compatibility.ts | 45 +++++++++++++++++-- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/packages/encrypted-archive/tests/compatibility.ts b/packages/encrypted-archive/tests/compatibility.ts index 4dafe1213..7900ee6fa 100644 --- a/packages/encrypted-archive/tests/compatibility.ts +++ b/packages/encrypted-archive/tests/compatibility.ts @@ -6,6 +6,7 @@ import execa from 'execa'; import importFrom from 'import-from'; import semverSatisfies from 'semver/functions/satisfies'; +import { version as latestPackageVersion } from '../package.json'; import { CompressOptions, CryptoAlgorithmName, @@ -90,13 +91,21 @@ describe('forward compatibility (encrypt(latest) -> decrypt(old versions))', () beforeAll(async () => { const packageNameList = packageVersionList .filter(isWorkWithCurrentNode) - .map(packageVersion => - `encrypted-archive-v${packageVersion}@npm:@sounisi5011/encrypted-archive@${packageVersion}` - ); + .map(packageVersion => ({ + packageName: + `encrypted-archive-v${packageVersion}@npm:@sounisi5011/encrypted-archive@${packageVersion}`, + isLatest: packageVersion === latestPackageVersion, + })); /** * If all published `@sounisi5011/encrypted-archive` do not support the current version of Node.js, skips installation. */ if (packageNameList.length < 1) return; + const oldPackageNameList = packageNameList + .filter(({ isLatest }) => !isLatest) + .map(({ packageName }) => packageName); + const latestPackageNameList = packageNameList + .filter(({ isLatest }) => isLatest) + .map(({ packageName }) => packageName); /** * Create a directory @@ -139,9 +148,37 @@ describe('forward compatibility (encrypt(latest) -> decrypt(old versions))', () */ await execa( 'pnpm', - ['add', '--save-exact', ...packageNameList], + ['add', '--save-exact', ...oldPackageNameList], { cwd: oldVersionsStoreDirpath }, ); + /** + * Install the latest package. + * If failed, use latest package from local disk. + * Note: For example, if we try to release a new version, only the latest version will not be able to be installed from npm. + */ + await execa( + 'pnpm', + ['add', '--save-exact', ...latestPackageNameList], + { cwd: oldVersionsStoreDirpath, all: true }, + ).catch(async err => { + if (!/\bERR_PNPM_NO_MATCHING_VERSION\b/.test(err.all ?? '')) throw err; + /** + * Enable `link-workspace-packages` option + */ + await fsAsync.writeFile( + path.resolve(oldVersionsStoreDirpath, '.npmrc'), + '\nlink-workspace-packages=true', + { flag: 'a' }, + ); + /** + * Retry + */ + await execa( + 'pnpm', + ['add', '--save-exact', ...latestPackageNameList], + { cwd: oldVersionsStoreDirpath }, + ); + }); }, 30 * 1000); const testTable = optGen<{