fix(release): allow dynamically continuing when current version is unresolvable (#28034)
This commit is contained in:
parent
b717aaf67e
commit
5216f7aac4
@ -47,6 +47,7 @@
|
|||||||
"chalk": "^4.1.0",
|
"chalk": "^4.1.0",
|
||||||
"columnify": "^1.6.0",
|
"columnify": "^1.6.0",
|
||||||
"detect-port": "^1.5.1",
|
"detect-port": "^1.5.1",
|
||||||
|
"enquirer": "~2.3.6",
|
||||||
"fast-glob": "3.2.7",
|
"fast-glob": "3.2.7",
|
||||||
"ignore": "^5.0.4",
|
"ignore": "^5.0.4",
|
||||||
"js-tokens": "^4.0.0",
|
"js-tokens": "^4.0.0",
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import {
|
|||||||
writeJson,
|
writeJson,
|
||||||
} from '@nx/devkit';
|
} from '@nx/devkit';
|
||||||
import * as chalk from 'chalk';
|
import * as chalk from 'chalk';
|
||||||
|
import { prompt } from 'enquirer';
|
||||||
import { exec } from 'node:child_process';
|
import { exec } from 'node:child_process';
|
||||||
import { rm } from 'node:fs/promises';
|
import { rm } from 'node:fs/promises';
|
||||||
import { join } from 'node:path';
|
import { join } from 'node:path';
|
||||||
@ -231,11 +232,26 @@ To fix this you will either need to add a package.json file at that location, or
|
|||||||
spinner.stop();
|
spinner.stop();
|
||||||
|
|
||||||
if (options.fallbackCurrentVersionResolver === 'disk') {
|
if (options.fallbackCurrentVersionResolver === 'disk') {
|
||||||
logger.buffer(
|
if (
|
||||||
`📄 Unable to resolve the current version from the registry ${registry}. Falling back to the version on disk of ${currentVersionFromDisk}`
|
!currentVersionFromDisk &&
|
||||||
);
|
(options.specifierSource === 'conventional-commits' ||
|
||||||
currentVersion = currentVersionFromDisk;
|
options.specifierSource === 'version-plans')
|
||||||
currentVersionResolvedFromFallback = true;
|
) {
|
||||||
|
currentVersion = await handleNoAvailableDiskFallback({
|
||||||
|
logger,
|
||||||
|
projectName,
|
||||||
|
packageJsonPath,
|
||||||
|
specifierSource: options.specifierSource,
|
||||||
|
currentVersionSourceMessage: `from the registry ${registry}`,
|
||||||
|
resolutionSuggestion: `you should publish an initial version to the registry`,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
logger.buffer(
|
||||||
|
`📄 Unable to resolve the current version from the registry ${registry}. Falling back to the version on disk of ${currentVersionFromDisk}`
|
||||||
|
);
|
||||||
|
currentVersion = currentVersionFromDisk;
|
||||||
|
currentVersionResolvedFromFallback = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Error(
|
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 use the --first-release option or set "release.version.generatorOptions.fallbackCurrentVersionResolver" to "disk" in order to fallback to the version on disk when the registry lookup fails.`
|
`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 use the --first-release option or set "release.version.generatorOptions.fallbackCurrentVersionResolver" to "disk" in order to fallback to the version on disk when the registry lookup fails.`
|
||||||
@ -259,7 +275,7 @@ To fix this you will either need to add a package.json file at that location, or
|
|||||||
currentVersion = currentVersionFromDisk;
|
currentVersion = currentVersionFromDisk;
|
||||||
if (!currentVersion) {
|
if (!currentVersion) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Unable to determine the current version for project "${project.name}" from ${packageJsonPath}`
|
`Unable to determine the current version for project "${project.name}" from ${packageJsonPath}, please ensure that the "version" field is set within the file`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
logger.buffer(
|
logger.buffer(
|
||||||
@ -281,11 +297,26 @@ To fix this you will either need to add a package.json file at that location, or
|
|||||||
);
|
);
|
||||||
if (!latestMatchingGitTag) {
|
if (!latestMatchingGitTag) {
|
||||||
if (options.fallbackCurrentVersionResolver === 'disk') {
|
if (options.fallbackCurrentVersionResolver === 'disk') {
|
||||||
logger.buffer(
|
if (
|
||||||
`📄 Unable to resolve the current version from git tag using pattern "${releaseTagPattern}". Falling back to the version on disk of ${currentVersionFromDisk}`
|
!currentVersionFromDisk &&
|
||||||
);
|
(options.specifierSource === 'conventional-commits' ||
|
||||||
currentVersion = currentVersionFromDisk;
|
options.specifierSource === 'version-plans')
|
||||||
currentVersionResolvedFromFallback = true;
|
) {
|
||||||
|
currentVersion = await handleNoAvailableDiskFallback({
|
||||||
|
logger,
|
||||||
|
projectName,
|
||||||
|
packageJsonPath,
|
||||||
|
specifierSource: options.specifierSource,
|
||||||
|
currentVersionSourceMessage: `from git tag using pattern "${releaseTagPattern}"`,
|
||||||
|
resolutionSuggestion: `you should set an initial git tag on a relevant commit`,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
logger.buffer(
|
||||||
|
`📄 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 {
|
} else {
|
||||||
throw new Error(
|
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 use the --first-release option or set "release.version.generatorOptions.fallbackCurrentVersionResolver" to "disk" in order to fallback to the version on disk when no matching git tags are found.`
|
`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 use the --first-release option or set "release.version.generatorOptions.fallbackCurrentVersionResolver" to "disk" in order to fallback to the version on disk when no matching git tags are found.`
|
||||||
@ -993,3 +1024,58 @@ class ProjectLogger {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow users to be unblocked when locally running releases for the very first time with certain combinations that require an initial
|
||||||
|
* version in order to function (e.g. a relative semver bump derived via conventional commits or version plans) by providing an interactive
|
||||||
|
* prompt to let them opt into using 0.0.0 as the implied current version.
|
||||||
|
*/
|
||||||
|
async function handleNoAvailableDiskFallback({
|
||||||
|
logger,
|
||||||
|
projectName,
|
||||||
|
packageJsonPath,
|
||||||
|
specifierSource,
|
||||||
|
currentVersionSourceMessage,
|
||||||
|
resolutionSuggestion,
|
||||||
|
}: {
|
||||||
|
logger: ProjectLogger;
|
||||||
|
projectName: string;
|
||||||
|
packageJsonPath: string;
|
||||||
|
specifierSource: Exclude<
|
||||||
|
ReleaseVersionGeneratorSchema['specifierSource'],
|
||||||
|
'prompt'
|
||||||
|
>;
|
||||||
|
currentVersionSourceMessage: string;
|
||||||
|
resolutionSuggestion: string;
|
||||||
|
}): Promise<string> {
|
||||||
|
const unresolvableCurrentVersionError = new Error(
|
||||||
|
`Unable to resolve the current version ${currentVersionSourceMessage} and there is no version on disk to fall back to. This is invalid with ${specifierSource} because the new version is determined by relatively bumping the current version. To resolve this, ${resolutionSuggestion}, or set an appropriate value for "version" in ${packageJsonPath}`
|
||||||
|
);
|
||||||
|
if (process.env.CI === 'true') {
|
||||||
|
// We can't prompt in CI, so error immediately
|
||||||
|
throw unresolvableCurrentVersionError;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const reply = await prompt<{ useZero: boolean }>([
|
||||||
|
{
|
||||||
|
name: 'useZero',
|
||||||
|
message: `\n${chalk.yellow(
|
||||||
|
`Warning: Unable to resolve the current version for "${projectName}" ${currentVersionSourceMessage} and there is no version on disk to fall back to. This is invalid with ${specifierSource} because the new version is determined by relatively bumping the current version.\n\nTo resolve this, ${resolutionSuggestion}, or set an appropriate value for "version" in ${packageJsonPath}`
|
||||||
|
)}. \n\nAlternatively, would you like to continue now by using 0.0.0 as the current version?`,
|
||||||
|
type: 'confirm',
|
||||||
|
initial: false,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
if (!reply.useZero) {
|
||||||
|
// Throw any error to skip the fallback to 0.0.0, may as well use the one we already have
|
||||||
|
throw unresolvableCurrentVersionError;
|
||||||
|
}
|
||||||
|
const currentVersion = '0.0.0';
|
||||||
|
logger.buffer(
|
||||||
|
`📄 Forcibly resolved the current version as "${currentVersion}" based on your response to the prompt above.`
|
||||||
|
);
|
||||||
|
return currentVersion;
|
||||||
|
} catch {
|
||||||
|
throw unresolvableCurrentVersionError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user