fix(release): ensure changelog renderers are resolvable when processing config (#23214)

This commit is contained in:
James Henry 2024-05-08 19:21:47 +02:00 committed by GitHub
parent 8363ba4a5e
commit 3970a1e288
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 87 additions and 28 deletions

View File

@ -3,7 +3,6 @@ import { prompt } from 'enquirer';
import { readFileSync, writeFileSync } from 'node:fs';
import { valid } from 'semver';
import { dirSync } from 'tmp';
import type { ChangelogRenderer } from '../../../release/changelog-renderer';
import {
NxReleaseChangelogConfiguration,
readNxJson,
@ -13,7 +12,6 @@ import {
ProjectGraphProjectNode,
} from '../../config/project-graph';
import { FsTree, Tree } from '../../generators/tree';
import { registerTsProject } from '../../plugins/js/utils/register';
import { createProjectFileMapUsingProjectGraph } from '../../project-graph/file-map-utils';
import { createProjectGraphAsync } from '../../project-graph/project-graph';
import { interpolate } from '../../tasks-runner/utils';
@ -47,6 +45,7 @@ import { createOrUpdateGithubRelease, getGitHubRepoSlug } from './utils/github';
import { launchEditor } from './utils/launch-editor';
import { parseChangelogMarkdown } from './utils/markdown';
import { printAndFlushChanges } from './utils/print-changes';
import { resolveChangelogRenderer } from './utils/resolve-changelog-renderer';
import { resolveNxJsonConfigErrorMessage } from './utils/resolve-nx-json-error-message';
import {
ReleaseVersion,
@ -57,7 +56,6 @@ import {
handleDuplicateGitTags,
noDiffInChangelogMessage,
} from './utils/shared';
import { getRootTsConfigPath } from '../../plugins/js/utils/typescript';
export interface NxReleaseChangelogResult {
workspaceChangelog?: {
@ -641,30 +639,6 @@ async function applyChangesAndExit(
return;
}
function resolveChangelogRenderer(
changelogRendererPath: string
): ChangelogRenderer {
const interpolatedChangelogRendererPath = interpolate(changelogRendererPath, {
workspaceRoot,
});
// Try and load the provided (or default) changelog renderer
let changelogRenderer: ChangelogRenderer;
let cleanupTranspiler = () => {};
try {
const rootTsconfigPath = getRootTsConfigPath();
if (rootTsconfigPath) {
cleanupTranspiler = registerTsProject(rootTsconfigPath);
}
const r = require(interpolatedChangelogRendererPath);
changelogRenderer = r.default || r;
} catch {
} finally {
cleanupTranspiler();
}
return changelogRenderer;
}
async function generateChangelogForWorkspace(
tree: Tree,
args: ChangelogOptions,

View File

@ -11,7 +11,7 @@
* defaults and user overrides, as well as handling common errors, up front to produce a single, consistent,
* and easy to consume config object for all the `nx release` command implementations.
*/
import { join } from 'path';
import { join, relative } from 'node:path';
import { NxJsonConfiguration } from '../../../config/nx-json';
import { ProjectFileMap, ProjectGraph } from '../../../config/project-graph';
import { readJsonFile } from '../../../utils/fileutils';
@ -19,6 +19,7 @@ import { findMatchingProjects } from '../../../utils/find-matching-projects';
import { output } from '../../../utils/output';
import { PackageJson } from '../../../utils/package-json';
import { workspaceRoot } from '../../../utils/workspace-root';
import { resolveChangelogRenderer } from '../utils/resolve-changelog-renderer';
import { resolveNxJsonConfigErrorMessage } from '../utils/resolve-nx-json-error-message';
import { DEFAULT_CONVENTIONAL_COMMITS_CONFIG } from './conventional-commits';
@ -508,6 +509,8 @@ export async function createNxReleaseConfig(
releaseGroups[releaseGroupName] = finalReleaseGroup;
}
ensureChangelogRenderersAreResolvable(releaseGroups, rootChangelogConfig);
return {
error: null,
nxReleaseConfig: {
@ -884,3 +887,55 @@ function isProjectPublic(
return false;
}
}
function ensureChangelogRenderersAreResolvable(
releaseGroups: NxReleaseConfig['groups'],
rootChangelogConfig: NxReleaseConfig['changelog']
) {
/**
* If any form of changelog config is enabled, ensure that any provided changelog renderers are resolvable
* up front so that we do not end up erroring only after the versioning step has been completed.
*/
const uniqueRendererPaths = new Set<string>();
if (
rootChangelogConfig.workspaceChangelog &&
typeof rootChangelogConfig.workspaceChangelog !== 'boolean' &&
rootChangelogConfig.workspaceChangelog.renderer?.length
) {
uniqueRendererPaths.add(rootChangelogConfig.workspaceChangelog.renderer);
}
if (
rootChangelogConfig.projectChangelogs &&
typeof rootChangelogConfig.projectChangelogs !== 'boolean' &&
rootChangelogConfig.projectChangelogs.renderer?.length
) {
uniqueRendererPaths.add(rootChangelogConfig.projectChangelogs.renderer);
}
for (const group of Object.values(releaseGroups)) {
if (
group.changelog &&
typeof group.changelog !== 'boolean' &&
group.changelog.renderer?.length
) {
uniqueRendererPaths.add(group.changelog.renderer);
}
}
if (!uniqueRendererPaths.size) {
return;
}
for (const rendererPath of uniqueRendererPaths) {
try {
resolveChangelogRenderer(rendererPath);
} catch (e) {
const workspaceRelativePath = relative(workspaceRoot, rendererPath);
output.error({
title: `There was an error when resolving the configured changelog renderer at path: ${workspaceRelativePath}`,
});
throw e;
}
}
}

View File

@ -0,0 +1,30 @@
import type { ChangelogRenderer } from '../../../../release/changelog-renderer';
import { registerTsProject } from '../../../plugins/js/utils/register';
import { getRootTsConfigPath } from '../../../plugins/js/utils/typescript';
import { interpolate } from '../../../tasks-runner/utils';
import { workspaceRoot } from '../../../utils/workspace-root';
export function resolveChangelogRenderer(
changelogRendererPath: string
): ChangelogRenderer {
const interpolatedChangelogRendererPath = interpolate(changelogRendererPath, {
workspaceRoot,
});
// Try and load the provided (or default) changelog renderer
let changelogRenderer: ChangelogRenderer;
let cleanupTranspiler = () => {};
try {
const rootTsconfigPath = getRootTsConfigPath();
if (rootTsconfigPath) {
cleanupTranspiler = registerTsProject(rootTsconfigPath);
}
const r = require(interpolatedChangelogRendererPath);
changelogRenderer = r.default || r;
} catch (err) {
throw err;
} finally {
cleanupTranspiler();
}
return changelogRenderer;
}