Skip to content

Commit

Permalink
feat(release): add fallbackCurrentVersionResolver option
Browse files Browse the repository at this point in the history
  • Loading branch information
fahslaj committed Jan 16, 2024
1 parent 42aefd8 commit a23c665
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 32 deletions.
106 changes: 105 additions & 1 deletion e2e/release/src/release.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ expect.addSnapshotSerializer({
},
});

describe('nx release', () => {
describe('nx release basic', () => {
let pkg1: string;
let pkg2: string;
let pkg3: string;
Expand Down Expand Up @@ -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<NxJsonConfiguration>('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<NxJsonConfiguration>('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<NxJsonConfiguration>('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<NxJsonConfiguration>('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);
});
99 changes: 68 additions & 31 deletions packages/js/src/generators/release-version/release-version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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<string>((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<string>((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;
}
Expand All @@ -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;
}
Expand Down
1 change: 1 addition & 0 deletions packages/nx/src/command-line/release/version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export interface ReleaseVersionGeneratorSchema {
packageRoot?: string;
currentVersionResolver?: 'registry' | 'disk' | 'git-tag';
currentVersionResolverMetadata?: Record<string, unknown>;
fallbackCurrentVersionResolver?: 'disk';
}

export interface NxReleaseVersionResult {
Expand Down

0 comments on commit a23c665

Please sign in to comment.