From 8a66733ffe3b38e22f57ac2b9130a45973d15504 Mon Sep 17 00:00:00 2001 From: Austin Fahsl Date: Mon, 15 Jan 2024 22:20:24 -0700 Subject: [PATCH] feat(release): add fallbackCurrentVersionResolver option --- e2e/release/src/release.test.ts | 104 ++++++++++++++++++ .../release-version/release-version.ts | 99 +++++++++++------ .../nx/src/command-line/release/version.ts | 1 + 3 files changed, 173 insertions(+), 31 deletions(-) diff --git a/e2e/release/src/release.test.ts b/e2e/release/src/release.test.ts index ce976e4ed7069..02a0a5a21dd7a 100644 --- a/e2e/release/src/release.test.ts +++ b/e2e/release/src/release.test.ts @@ -1058,5 +1058,109 @@ ${JSON.stringify( new RegExp(`Successfully ran target nx-release-publish for`, 'g') ).length ).toEqual(2); + + // change the releaseTagPattern to something that doesn't exist in order to test fallbackCurrentVersionResolver + updateJson('nx.json', (nxJson) => { + nxJson.release = { + groups: { + group1: { + projects: [pkg1, pkg2, pkg3], + releaseTagPattern: '>{version}', + }, + }, + git: { + commit: true, + tag: true, + }, + version: { + generatorOptions: { + currentVersionResolver: 'git-tag', + }, + }, + }; + return nxJson; + }); + + const releaseOutput4 = runCLI(`release patch --skip-publish`, { + silenceError: true, + }); + + expect(releaseOutput4).toMatchInlineSnapshot(` + + > NX Running release version for project: {project-name} + + {project-name} 🔍 Reading data for package "@proj/{project-name}" from {project-name}/package.json + + > NX No git tags matching pattern ">{version}" for project "{project-name}" were found. You will need to create an initial matching tag to use as a base for determining the next version. Alternatively, you can set the "version.generatorOptions.fallbackCurrentVersionResolver" to "disk" in order to fallback to the version on disk when no matching git tags are found. + + + `); + + updateJson('nx.json', (nxJson) => { + nxJson.release.version.generatorOptions.fallbackCurrentVersionResolver = + 'disk'; + return nxJson; + }); + + const releaseOutput5 = runCLI(`release patch --skip-publish --verbose`); + + expect(releaseOutput5).toMatch( + `📄 Unable to resolve the current version from git tag using pattern ">{version}". Falling back to the version on disk of 1400.1.0` + ); + expect( + releaseOutput5.match( + new RegExp( + `📄 Using the current version 1400\\.1\\.0 already resolved from disk fallback\\.`, + 'g' + ) + ).length + ).toEqual(2); + + updateJson('nx.json', (nxJson) => { + nxJson.release.version.generatorOptions.currentVersionResolver = + 'registry'; + nxJson.release.version.generatorOptions.currentVersionResolverMetadata = { + tag: 'other', + }; + delete nxJson.release.version.generatorOptions + .fallbackCurrentVersionResolver; + return nxJson; + }); + + const releaseOutput6 = runCLI(`release patch --skip-publish`, { + silenceError: true, + }); + + expect(releaseOutput6).toMatchInlineSnapshot(` + + > NX Running release version for project: {project-name} + + {project-name} 🔍 Reading data for package "@proj/{project-name}" from {project-name}/package.json + + > NX Unable to resolve the current version from the registry ${e2eRegistryUrl}. Please ensure that the package exists in the registry in order to use the "registry" currentVersionResolver. Alternatively, you can set the "version.generatorOptions.fallbackCurrentVersionResolver" to "disk" in order to fallback to the version on disk when the registry lookup fails. + + - Resolving the current version for tag "other" on ${e2eRegistryUrl} + + `); + + updateJson('nx.json', (nxJson) => { + nxJson.release.version.generatorOptions.fallbackCurrentVersionResolver = + 'disk'; + return nxJson; + }); + + const releaseOutput7 = runCLI(`release patch --skip-publish --verbose`); + + expect(releaseOutput7).toMatch( + `📄 Unable to resolve the current version from the registry ${e2eRegistryUrl}. Falling back to the version on disk of 1400.1.1` + ); + expect( + releaseOutput7.match( + new RegExp( + `📄 Using the current version 1400\\.1\\.1 already resolved from disk fallback\\.`, + 'g' + ) + ).length + ).toEqual(2); }, 500000); }); diff --git a/packages/js/src/generators/release-version/release-version.ts b/packages/js/src/generators/release-version/release-version.ts index 5c3042b03109a..3b34a71f8286e 100644 --- a/packages/js/src/generators/release-version/release-version.ts +++ b/packages/js/src/generators/release-version/release-version.ts @@ -75,6 +75,7 @@ export async function releaseVersionGenerator( } let currentVersion: string; + let currentVersionResolvedFromFallback: boolean = false; // only used for options.currentVersionResolver === 'git-tag', but // must be declared here in order to reuse it for additional projects @@ -146,31 +147,53 @@ To fix this you will either need to add a package.json file at that location, or color.spinnerColor as typeof colors[number]['spinnerColor']; spinner.start(); - // Must be non-blocking async to allow spinner to render - currentVersion = await new Promise((resolve, reject) => { - exec( - `npm view ${packageName} version --registry=${registry} --tag=${tag}`, - (error, stdout, stderr) => { - if (error) { - return reject(error); + try { + // Must be non-blocking async to allow spinner to render + currentVersion = await new Promise((resolve, reject) => { + exec( + `npm view ${packageName} version --registry=${registry} --tag=${tag}`, + (error, stdout, stderr) => { + if (error) { + return reject(error); + } + if (stderr) { + return reject(stderr); + } + return resolve(stdout.trim()); } - if (stderr) { - return reject(stderr); - } - return resolve(stdout.trim()); - } - ); - }); + ); + }); - spinner.stop(); + spinner.stop(); - log( - `📄 Resolved the current version as ${currentVersion} for tag "${tag}" from registry ${registry}` - ); + log( + `📄 Resolved the current version as ${currentVersion} for tag "${tag}" from registry ${registry}` + ); + } catch (e) { + spinner.stop(); + + if (options.fallbackCurrentVersionResolver === 'disk') { + log( + `📄 Unable to resolve the current version from the registry ${registry}. Falling back to the version on disk of ${currentVersionFromDisk}` + ); + currentVersion = currentVersionFromDisk; + currentVersionResolvedFromFallback = true; + } else { + throw new Error( + `Unable to resolve the current version from the registry ${registry}. Please ensure that the package exists in the registry in order to use the "registry" currentVersionResolver. Alternatively, you can set the "version.generatorOptions.fallbackCurrentVersionResolver" to "disk" in order to fallback to the version on disk when the registry lookup fails.` + ); + } + } } else { - log( - `📄 Using the current version ${currentVersion} already resolved from the registry ${registry}` - ); + if (currentVersionResolvedFromFallback) { + log( + `📄 Using the current version ${currentVersion} already resolved from disk fallback.` + ); + } else { + log( + `📄 Using the current version ${currentVersion} already resolved from the registry ${registry}` + ); + } } break; } @@ -194,19 +217,33 @@ To fix this you will either need to add a package.json file at that location, or } ); if (!latestMatchingGitTag) { - throw new Error( - `No git tags matching pattern "${releaseTagPattern}" for project "${project.name}" were found. You will need to create an initial matching tag to use as a base for determining the next version.` + if (options.fallbackCurrentVersionResolver === 'disk') { + log( + `📄 Unable to resolve the current version from git tag using pattern "${releaseTagPattern}". Falling back to the version on disk of ${currentVersionFromDisk}` + ); + currentVersion = currentVersionFromDisk; + currentVersionResolvedFromFallback = true; + } else { + throw new Error( + `No git tags matching pattern "${releaseTagPattern}" for project "${project.name}" were found. You will need to create an initial matching tag to use as a base for determining the next version. Alternatively, you can set the "version.generatorOptions.fallbackCurrentVersionResolver" to "disk" in order to fallback to the version on disk when no matching git tags are found.` + ); + } + } else { + currentVersion = latestMatchingGitTag.extractedVersion; + log( + `📄 Resolved the current version as ${currentVersion} from git tag "${latestMatchingGitTag.tag}".` ); } - - currentVersion = latestMatchingGitTag.extractedVersion; - log( - `📄 Resolved the current version as ${currentVersion} from git tag "${latestMatchingGitTag.tag}".` - ); } else { - log( - `📄 Using the current version ${currentVersion} already resolved from git tag "${latestMatchingGitTag.tag}".` - ); + if (currentVersionResolvedFromFallback) { + log( + `📄 Using the current version ${currentVersion} already resolved from disk fallback.` + ); + } else { + log( + `📄 Using the current version ${currentVersion} already resolved from git tag "${latestMatchingGitTag.tag}".` + ); + } } break; } diff --git a/packages/nx/src/command-line/release/version.ts b/packages/nx/src/command-line/release/version.ts index b5797e3c3b075..709626455a67e 100644 --- a/packages/nx/src/command-line/release/version.ts +++ b/packages/nx/src/command-line/release/version.ts @@ -56,6 +56,7 @@ export interface ReleaseVersionGeneratorSchema { packageRoot?: string; currentVersionResolver?: 'registry' | 'disk' | 'git-tag'; currentVersionResolverMetadata?: Record; + fallbackCurrentVersionResolver?: 'disk'; } export interface NxReleaseVersionResult {