Skip to content

Commit cf35bff

Browse files
JamesHenryFrozenPandaz
authored andcommitted
fix(release): ensure changelog renderers are resolvable when processing config (#23214)
(cherry picked from commit 3970a1e)
1 parent fca7694 commit cf35bff

File tree

3 files changed

+87
-28
lines changed

3 files changed

+87
-28
lines changed

packages/nx/src/command-line/release/changelog.ts

+1-27
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { prompt } from 'enquirer';
33
import { readFileSync, writeFileSync } from 'node:fs';
44
import { valid } from 'semver';
55
import { dirSync } from 'tmp';
6-
import type { ChangelogRenderer } from '../../../release/changelog-renderer';
76
import {
87
NxReleaseChangelogConfiguration,
98
readNxJson,
@@ -13,7 +12,6 @@ import {
1312
ProjectGraphProjectNode,
1413
} from '../../config/project-graph';
1514
import { FsTree, Tree } from '../../generators/tree';
16-
import { registerTsProject } from '../../plugins/js/utils/register';
1715
import { createProjectFileMapUsingProjectGraph } from '../../project-graph/file-map-utils';
1816
import { createProjectGraphAsync } from '../../project-graph/project-graph';
1917
import { interpolate } from '../../tasks-runner/utils';
@@ -47,6 +45,7 @@ import { createOrUpdateGithubRelease, getGitHubRepoSlug } from './utils/github';
4745
import { launchEditor } from './utils/launch-editor';
4846
import { parseChangelogMarkdown } from './utils/markdown';
4947
import { printAndFlushChanges } from './utils/print-changes';
48+
import { resolveChangelogRenderer } from './utils/resolve-changelog-renderer';
5049
import { resolveNxJsonConfigErrorMessage } from './utils/resolve-nx-json-error-message';
5150
import {
5251
ReleaseVersion,
@@ -57,7 +56,6 @@ import {
5756
handleDuplicateGitTags,
5857
noDiffInChangelogMessage,
5958
} from './utils/shared';
60-
import { getRootTsConfigPath } from '../../plugins/js/utils/typescript';
6159

6260
export interface NxReleaseChangelogResult {
6361
workspaceChangelog?: {
@@ -641,30 +639,6 @@ async function applyChangesAndExit(
641639
return;
642640
}
643641

644-
function resolveChangelogRenderer(
645-
changelogRendererPath: string
646-
): ChangelogRenderer {
647-
const interpolatedChangelogRendererPath = interpolate(changelogRendererPath, {
648-
workspaceRoot,
649-
});
650-
651-
// Try and load the provided (or default) changelog renderer
652-
let changelogRenderer: ChangelogRenderer;
653-
let cleanupTranspiler = () => {};
654-
try {
655-
const rootTsconfigPath = getRootTsConfigPath();
656-
if (rootTsconfigPath) {
657-
cleanupTranspiler = registerTsProject(rootTsconfigPath);
658-
}
659-
const r = require(interpolatedChangelogRendererPath);
660-
changelogRenderer = r.default || r;
661-
} catch {
662-
} finally {
663-
cleanupTranspiler();
664-
}
665-
return changelogRenderer;
666-
}
667-
668642
async function generateChangelogForWorkspace(
669643
tree: Tree,
670644
args: ChangelogOptions,

packages/nx/src/command-line/release/config/config.ts

+56-1
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@
1111
* defaults and user overrides, as well as handling common errors, up front to produce a single, consistent,
1212
* and easy to consume config object for all the `nx release` command implementations.
1313
*/
14-
import { join } from 'path';
14+
import { join, relative } from 'node:path';
1515
import { NxJsonConfiguration } from '../../../config/nx-json';
1616
import { ProjectFileMap, ProjectGraph } from '../../../config/project-graph';
1717
import { readJsonFile } from '../../../utils/fileutils';
1818
import { findMatchingProjects } from '../../../utils/find-matching-projects';
1919
import { output } from '../../../utils/output';
2020
import { PackageJson } from '../../../utils/package-json';
2121
import { workspaceRoot } from '../../../utils/workspace-root';
22+
import { resolveChangelogRenderer } from '../utils/resolve-changelog-renderer';
2223
import { resolveNxJsonConfigErrorMessage } from '../utils/resolve-nx-json-error-message';
2324
import { DEFAULT_CONVENTIONAL_COMMITS_CONFIG } from './conventional-commits';
2425

@@ -508,6 +509,8 @@ export async function createNxReleaseConfig(
508509
releaseGroups[releaseGroupName] = finalReleaseGroup;
509510
}
510511

512+
ensureChangelogRenderersAreResolvable(releaseGroups, rootChangelogConfig);
513+
511514
return {
512515
error: null,
513516
nxReleaseConfig: {
@@ -884,3 +887,55 @@ function isProjectPublic(
884887
return false;
885888
}
886889
}
890+
891+
function ensureChangelogRenderersAreResolvable(
892+
releaseGroups: NxReleaseConfig['groups'],
893+
rootChangelogConfig: NxReleaseConfig['changelog']
894+
) {
895+
/**
896+
* If any form of changelog config is enabled, ensure that any provided changelog renderers are resolvable
897+
* up front so that we do not end up erroring only after the versioning step has been completed.
898+
*/
899+
const uniqueRendererPaths = new Set<string>();
900+
901+
if (
902+
rootChangelogConfig.workspaceChangelog &&
903+
typeof rootChangelogConfig.workspaceChangelog !== 'boolean' &&
904+
rootChangelogConfig.workspaceChangelog.renderer?.length
905+
) {
906+
uniqueRendererPaths.add(rootChangelogConfig.workspaceChangelog.renderer);
907+
}
908+
if (
909+
rootChangelogConfig.projectChangelogs &&
910+
typeof rootChangelogConfig.projectChangelogs !== 'boolean' &&
911+
rootChangelogConfig.projectChangelogs.renderer?.length
912+
) {
913+
uniqueRendererPaths.add(rootChangelogConfig.projectChangelogs.renderer);
914+
}
915+
916+
for (const group of Object.values(releaseGroups)) {
917+
if (
918+
group.changelog &&
919+
typeof group.changelog !== 'boolean' &&
920+
group.changelog.renderer?.length
921+
) {
922+
uniqueRendererPaths.add(group.changelog.renderer);
923+
}
924+
}
925+
926+
if (!uniqueRendererPaths.size) {
927+
return;
928+
}
929+
930+
for (const rendererPath of uniqueRendererPaths) {
931+
try {
932+
resolveChangelogRenderer(rendererPath);
933+
} catch (e) {
934+
const workspaceRelativePath = relative(workspaceRoot, rendererPath);
935+
output.error({
936+
title: `There was an error when resolving the configured changelog renderer at path: ${workspaceRelativePath}`,
937+
});
938+
throw e;
939+
}
940+
}
941+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import type { ChangelogRenderer } from '../../../../release/changelog-renderer';
2+
import { registerTsProject } from '../../../plugins/js/utils/register';
3+
import { getRootTsConfigPath } from '../../../plugins/js/utils/typescript';
4+
import { interpolate } from '../../../tasks-runner/utils';
5+
import { workspaceRoot } from '../../../utils/workspace-root';
6+
7+
export function resolveChangelogRenderer(
8+
changelogRendererPath: string
9+
): ChangelogRenderer {
10+
const interpolatedChangelogRendererPath = interpolate(changelogRendererPath, {
11+
workspaceRoot,
12+
});
13+
14+
// Try and load the provided (or default) changelog renderer
15+
let changelogRenderer: ChangelogRenderer;
16+
let cleanupTranspiler = () => {};
17+
try {
18+
const rootTsconfigPath = getRootTsConfigPath();
19+
if (rootTsconfigPath) {
20+
cleanupTranspiler = registerTsProject(rootTsconfigPath);
21+
}
22+
const r = require(interpolatedChangelogRendererPath);
23+
changelogRenderer = r.default || r;
24+
} catch (err) {
25+
throw err;
26+
} finally {
27+
cleanupTranspiler();
28+
}
29+
return changelogRenderer;
30+
}

0 commit comments

Comments
 (0)