File: /var/www/web.enelar.com.co/node_modules/nx/src/command-line/release/changelog.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.releaseChangelog = exports.releaseChangelogCLIHandler = void 0;
const chalk = require("chalk");
const node_fs_1 = require("node:fs");
const semver_1 = require("semver");
const tmp_1 = require("tmp");
const nx_json_1 = require("../../config/nx-json");
const tree_1 = require("../../generators/tree");
const register_1 = require("../../plugins/js/utils/register");
const project_graph_1 = require("../../project-graph/project-graph");
const utils_1 = require("../../tasks-runner/utils");
const logger_1 = require("../../utils/logger");
const output_1 = require("../../utils/output");
const params_1 = require("../../utils/params");
const path_1 = require("../../utils/path");
const typescript_1 = require("../../utils/typescript");
const workspace_root_1 = require("../../utils/workspace-root");
const config_1 = require("./config/config");
const filter_release_groups_1 = require("./config/filter-release-groups");
const git_1 = require("./utils/git");
const github_1 = require("./utils/github");
const launch_editor_1 = require("./utils/launch-editor");
const markdown_1 = require("./utils/markdown");
const print_changes_1 = require("./utils/print-changes");
const shared_1 = require("./utils/shared");
const releaseChangelogCLIHandler = (args) => (0, params_1.handleErrors)(args.verbose, () => releaseChangelog(args));
exports.releaseChangelogCLIHandler = releaseChangelogCLIHandler;
/**
* NOTE: This function is also exported for programmatic usage and forms part of the public API
* of Nx. We intentionally do not wrap the implementation with handleErrors because users need
* to have control over their own error handling when using the API.
*/
async function releaseChangelog(args) {
const projectGraph = await (0, project_graph_1.createProjectGraphAsync)({ exitOnError: true });
const nxJson = (0, nx_json_1.readNxJson)();
if (args.verbose) {
process.env.NX_VERBOSE_LOGGING = 'true';
}
// Apply default configuration to any optional user configuration
const { error: configError, nxReleaseConfig } = await (0, config_1.createNxReleaseConfig)(projectGraph, nxJson.release);
if (configError) {
return await (0, config_1.handleNxReleaseConfigError)(configError);
}
const { error: filterError, releaseGroups, releaseGroupToFilteredProjects, } = (0, filter_release_groups_1.filterReleaseGroups)(projectGraph, nxReleaseConfig, args.projects, args.groups);
if (filterError) {
output_1.output.error(filterError);
process.exit(1);
}
/**
* For determining the versions to use within changelog files, there are a few different possibilities:
* - the user is using the nx CLI, and therefore passes a single --version argument which represents the version for any and all changelog
* files which will be generated (i.e. both the workspace changelog, and all project changelogs, depending on which of those has been enabled)
* - the user is using the nxReleaseChangelog API programmatically, and:
* - passes only a version property
* - this works in the same way as described above for the CLI
* - passes only a versionData object
* - this is a special case where the user is providing a version for each project, and therefore the version argument is not needed
* - NOTE: it is not possible to generate a workspace level changelog with only a versionData object, and this will produce an error
* - passes both a version and a versionData object
* - in this case, the version property will be used as the reference for the workspace changelog, and the versionData object will be used
* to generate project changelogs
*/
const { workspaceChangelogVersion, projectsVersionData } = resolveChangelogVersions(args, releaseGroups, releaseGroupToFilteredProjects);
const to = args.to || 'HEAD';
const toSHA = await (0, git_1.getCommitHash)(to);
const headSHA = to === 'HEAD' ? toSHA : await (0, git_1.getCommitHash)('HEAD');
/**
* Protect the user against attempting to create a new commit when recreating an old release changelog,
* this seems like it would always be unintentional.
*/
const autoCommitEnabled = args.gitCommit ?? nxReleaseConfig.changelog.git.commit;
if (autoCommitEnabled && headSHA !== toSHA) {
throw new Error(`You are attempting to recreate the changelog for an old release, but you have enabled auto-commit mode. Please disable auto-commit mode by updating your nx.json, or passing --git-commit=false`);
}
const fromRef = args.from ||
(await (0, git_1.getLatestGitTagForPattern)(nxReleaseConfig.releaseTagPattern))?.tag;
if (!fromRef) {
throw new Error(`Unable to determine the previous git tag, please provide an explicit git reference using --from`);
}
// Make sure that the fromRef is actually resolvable
const fromSHA = await (0, git_1.getCommitHash)(fromRef);
const rawCommits = await (0, git_1.getGitDiff)(fromSHA, toSHA);
// Parse as conventional commits
const commits = (0, git_1.parseCommits)(rawCommits).filter((c) => {
const type = c.type;
// Always ignore non user-facing commits for now
// TODO: allow this filter to be configurable via config in a future release
if (type === 'feat' || type === 'fix' || type === 'perf') {
return true;
}
return false;
});
const tree = new tree_1.FsTree(workspace_root_1.workspaceRoot, args.verbose);
const userCommitMessage = args.gitCommitMessage || nxReleaseConfig.changelog.git.commitMessage;
const commitMessageValues = (0, shared_1.createCommitMessageValues)(releaseGroups, releaseGroupToFilteredProjects, projectsVersionData, userCommitMessage);
// Resolve any git tags as early as possible so that we can hard error in case of any duplicates before reaching the actual git command
const gitTagValues = args.gitTag ?? nxReleaseConfig.changelog.git.tag
? (0, shared_1.createGitTagValues)(releaseGroups, releaseGroupToFilteredProjects, projectsVersionData)
: [];
(0, shared_1.handleDuplicateGitTags)(gitTagValues);
const postGitTasks = [];
await generateChangelogForWorkspace(tree, args, projectGraph, nxReleaseConfig, workspaceChangelogVersion, commits, postGitTasks);
if (args.projects?.length) {
/**
* Run changelog generation for all remaining release groups and filtered projects within them
*/
for (const releaseGroup of releaseGroups) {
const projectNodes = Array.from(releaseGroupToFilteredProjects.get(releaseGroup)).map((name) => projectGraph.nodes[name]);
await generateChangelogForProjects(tree, args, projectGraph, commits, projectsVersionData, postGitTasks, releaseGroup, projectNodes);
}
return await applyChangesAndExit(args, nxReleaseConfig, tree, toSHA, postGitTasks, commitMessageValues, gitTagValues);
}
/**
* Run changelog generation for all remaining release groups
*/
for (const releaseGroup of releaseGroups) {
const projectNodes = releaseGroup.projects.map((name) => projectGraph.nodes[name]);
await generateChangelogForProjects(tree, args, projectGraph, commits, projectsVersionData, postGitTasks, releaseGroup, projectNodes);
}
return await applyChangesAndExit(args, nxReleaseConfig, tree, toSHA, postGitTasks, commitMessageValues, gitTagValues);
}
exports.releaseChangelog = releaseChangelog;
function resolveChangelogVersions(args, releaseGroups, releaseGroupToFilteredProjects) {
if (!args.version && !args.versionData) {
throw new Error(`You must provide a version string and/or a versionData object.`);
}
/**
* TODO: revaluate this assumption holistically in a dedicated PR when we add support for calver
* (e.g. the Release class also uses semver utils to check if prerelease).
*
* Right now, the given version must be valid semver in order to proceed
*/
if (args.version && !(0, semver_1.valid)(args.version)) {
throw new Error(`The given version "${args.version}" is not a valid semver version. Please provide your version in the format "1.0.0", "1.0.0-beta.1" etc`);
}
const versionData = releaseGroups.reduce((versionData, releaseGroup) => {
const releaseGroupProjectNames = Array.from(releaseGroupToFilteredProjects.get(releaseGroup));
for (const projectName of releaseGroupProjectNames) {
if (!args.versionData) {
versionData[projectName] = {
newVersion: args.version,
currentVersion: '',
dependentProjects: [], // not relevant within changelog/commit generation
};
continue;
}
/**
* In the case where a versionData object was provided, we need to make sure all projects are present,
* otherwise it suggests a filtering mismatch between the version and changelog command invocations.
*/
if (!args.versionData[projectName]) {
throw new Error(`The provided versionData object does not contain a version for project "${projectName}". This suggests a filtering mismatch between the version and changelog command invocations.`);
}
}
return versionData;
}, args.versionData || {});
return {
workspaceChangelogVersion: args.version,
projectsVersionData: versionData,
};
}
async function applyChangesAndExit(args, nxReleaseConfig, tree, toSHA, postGitTasks, commitMessageValues, gitTagValues) {
let latestCommit = toSHA;
const changes = tree.listChanges();
/**
* In the case where we are expecting changelog file updates, but there is nothing
* to flush from the tree, we exit early. This could happen we using conventional
* commits, for example.
*/
const changelogFilesEnabled = checkChangelogFilesEnabled(nxReleaseConfig);
if (changelogFilesEnabled && !changes.length) {
output_1.output.warn({
title: `No changes detected for changelogs`,
bodyLines: [
`No changes were detected for any changelog files, so no changelog entries will be generated.`,
],
});
return 0;
}
// Generate a new commit for the changes, if configured to do so
if (args.gitCommit ?? nxReleaseConfig.changelog.git.commit) {
await (0, shared_1.commitChanges)(changes.map((f) => f.path), !!args.dryRun, !!args.verbose, commitMessageValues, args.gitCommitArgs || nxReleaseConfig.changelog.git.commitArgs);
// Resolve the commit we just made
latestCommit = await (0, git_1.getCommitHash)('HEAD');
}
// Generate a one or more git tags for the changes, if configured to do so
if (args.gitTag ?? nxReleaseConfig.changelog.git.tag) {
output_1.output.logSingleLine(`Tagging commit with git`);
for (const tag of gitTagValues) {
await (0, git_1.gitTag)({
tag,
message: args.gitTagMessage || nxReleaseConfig.changelog.git.tagMessage,
additionalArgs: args.gitTagArgs || nxReleaseConfig.changelog.git.tagArgs,
dryRun: args.dryRun,
verbose: args.verbose,
});
}
}
// Run any post-git tasks in series
for (const postGitTask of postGitTasks) {
await postGitTask(latestCommit);
}
if (args.dryRun) {
logger_1.logger.warn(`\nNOTE: The "dryRun" flag means no changelogs were actually created.`);
}
return 0;
}
function resolveChangelogRenderer(changelogRendererPath) {
// Try and load the provided (or default) changelog renderer
let changelogRenderer;
let cleanupTranspiler = () => { };
try {
const rootTsconfigPath = (0, typescript_1.getRootTsConfigPath)();
if (rootTsconfigPath) {
cleanupTranspiler = (0, register_1.registerTsProject)(rootTsconfigPath);
}
const r = require(changelogRendererPath);
changelogRenderer = r.default || r;
}
catch {
}
finally {
cleanupTranspiler();
}
return changelogRenderer;
}
async function generateChangelogForWorkspace(tree, args, projectGraph, nxReleaseConfig, workspaceChangelogVersion, commits, postGitTasks) {
const config = nxReleaseConfig.changelog.workspaceChangelog;
const isEnabled = args.workspaceChangelog ?? config;
// The entire feature is disabled at the workspace level, exit early
if (isEnabled === false) {
return;
}
// If explicitly null it must mean that no changes were detected (e.g. when using conventional commits), so do nothing
if (workspaceChangelogVersion === null) {
return;
}
// The user explicitly passed workspaceChangelog=true but does not have a workspace changelog config in nx.json
if (!config) {
throw new Error(`Workspace changelog is enabled but no configuration was provided. Please provide a workspaceChangelog object in your nx.json`);
}
if (!workspaceChangelogVersion && args.workspaceChangelog) {
throw new Error(`Workspace changelog is enabled but no overall version was provided. Please provide an explicit version using --version`);
}
// Only trigger interactive mode for the workspace changelog if the user explicitly requested it via "all" or "workspace"
const interactive = args.interactive === 'all' || args.interactive === 'workspace';
const dryRun = !!args.dryRun;
const gitRemote = args.gitRemote;
const changelogRenderer = resolveChangelogRenderer(config.renderer);
let interpolatedTreePath = config.file || '';
if (interpolatedTreePath) {
interpolatedTreePath = (0, utils_1.interpolate)(interpolatedTreePath, {
projectName: '',
projectRoot: '',
workspaceRoot: '', // within the tree, workspaceRoot is the root
});
}
const releaseVersion = new shared_1.ReleaseVersion({
version: workspaceChangelogVersion,
releaseTagPattern: nxReleaseConfig.releaseTagPattern,
});
// We are either creating/previewing a changelog file, a GitHub release, or both
let logTitle = dryRun ? 'Previewing a' : 'Generating a';
switch (true) {
case interpolatedTreePath && config.createRelease === 'github':
logTitle += ` GitHub release and an entry in ${interpolatedTreePath} for ${chalk.white(releaseVersion.gitTag)}`;
break;
case !!interpolatedTreePath:
logTitle += `n entry in ${interpolatedTreePath} for ${chalk.white(releaseVersion.gitTag)}`;
break;
case config.createRelease === 'github':
logTitle += ` GitHub release for ${chalk.white(releaseVersion.gitTag)}`;
}
output_1.output.log({
title: logTitle,
});
const githubRepoSlug = (0, github_1.getGitHubRepoSlug)(gitRemote);
let contents = await changelogRenderer({
projectGraph,
commits,
releaseVersion: releaseVersion.rawVersion,
project: null,
repoSlug: githubRepoSlug,
entryWhenNoChanges: config.entryWhenNoChanges,
changelogRenderOptions: config.renderOptions,
});
/**
* If interactive mode, make the changelog contents available for the user to modify in their editor of choice,
* in a similar style to git interactive rebases/merges.
*/
if (interactive) {
const tmpDir = (0, tmp_1.dirSync)().name;
const changelogPath = (0, path_1.joinPathFragments)(tmpDir,
// Include the tree path in the name so that it is easier to identify which changelog file is being edited
`PREVIEW__${interpolatedTreePath.replace(/\//g, '_')}`);
(0, node_fs_1.writeFileSync)(changelogPath, contents);
await (0, launch_editor_1.launchEditor)(changelogPath);
contents = (0, node_fs_1.readFileSync)(changelogPath, 'utf-8');
}
/**
* The exact logic we use for printing the summary/diff to the user is dependent upon whether they are creating
* a changelog file, a GitHub release, or both.
*/
let printSummary = () => { };
const noDiffInChangelogMessage = chalk.yellow(`NOTE: There was no diff detected for the changelog entry. Maybe you intended to pass alternative git references via --from and --to?`);
if (interpolatedTreePath) {
let rootChangelogContents = tree.exists(interpolatedTreePath)
? tree.read(interpolatedTreePath).toString()
: '';
if (rootChangelogContents) {
// NOTE: right now existing releases are always expected to be in markdown format, but in the future we could potentially support others via a custom parser option
const changelogReleases = (0, markdown_1.parseChangelogMarkdown)(rootChangelogContents).releases;
const existingVersionToUpdate = changelogReleases.find((r) => r.version === releaseVersion.rawVersion);
if (existingVersionToUpdate) {
rootChangelogContents = rootChangelogContents.replace(`## ${releaseVersion.rawVersion}\n\n\n${existingVersionToUpdate.body}`, contents);
}
else {
// No existing version, simply prepend the new release to the top of the file
rootChangelogContents = `${contents}\n\n${rootChangelogContents}`;
}
}
else {
// No existing changelog contents, simply create a new one using the generated contents
rootChangelogContents = contents;
}
tree.write(interpolatedTreePath, rootChangelogContents);
printSummary = () => (0, print_changes_1.printAndFlushChanges)(tree, !!dryRun, 3, false, noDiffInChangelogMessage);
}
if (config.createRelease === 'github') {
if (!githubRepoSlug) {
output_1.output.error({
title: `Unable to create a GitHub release because the GitHub repo slug could not be determined.`,
bodyLines: [
`Please ensure you have a valid GitHub remote configured. You can run \`git remote -v\` to list your current remotes.`,
],
});
process.exit(1);
}
const token = await (0, github_1.resolveGithubToken)();
const githubRequestConfig = {
repo: githubRepoSlug,
token,
};
let existingGithubReleaseForVersion;
try {
existingGithubReleaseForVersion = await (0, github_1.getGithubReleaseByTag)(githubRequestConfig, releaseVersion.gitTag);
}
catch (err) {
if (err.response?.status === 401) {
output_1.output.error({
title: `Unable to resolve data via the GitHub API. You can use any of the following options to resolve this:`,
bodyLines: [
'- Set the `GITHUB_TOKEN` or `GH_TOKEN` environment variable to a valid GitHub token with `repo` scope',
'- Have an active session via the official gh CLI tool (https://cli.github.com) in your current terminal',
],
});
process.exit(1);
}
if (err.response?.status === 404) {
// No existing release found, this is fine
}
else {
// Rethrow unknown errors for now
throw err;
}
}
let existingPrintSummaryFn = printSummary;
printSummary = () => {
const logTitle = `https://github.com/${githubRepoSlug}/releases/tag/${releaseVersion.gitTag}`;
if (existingGithubReleaseForVersion) {
console.error(`${chalk.white('UPDATE')} ${logTitle}${dryRun ? chalk.keyword('orange')(' [dry-run]') : ''}`);
}
else {
console.error(`${chalk.green('CREATE')} ${logTitle}${dryRun ? chalk.keyword('orange')(' [dry-run]') : ''}`);
}
// Only print the diff here if we are not already going to be printing changes from the Tree
if (!interpolatedTreePath) {
console.log('');
(0, print_changes_1.printDiff)(existingGithubReleaseForVersion
? existingGithubReleaseForVersion.body
: '', contents, 3, noDiffInChangelogMessage);
}
existingPrintSummaryFn();
};
// Only schedule the actual GitHub update when not in dry-run mode
if (!dryRun) {
postGitTasks.push(async (latestCommit) => {
// Before we can create/update the release we need to ensure the commit exists on the remote
await (0, git_1.gitPush)();
await (0, github_1.createOrUpdateGithubRelease)(githubRequestConfig, {
version: releaseVersion.gitTag,
prerelease: releaseVersion.isPrerelease,
body: contents,
commit: latestCommit,
}, existingGithubReleaseForVersion);
});
}
}
printSummary();
}
async function generateChangelogForProjects(tree, args, projectGraph, commits, projectsVersionData, postGitTasks, releaseGroup, projects) {
const config = releaseGroup.changelog;
// The entire feature is disabled at the release group level, exit early
if (config === false) {
return;
}
// Only trigger interactive mode for the project changelog if the user explicitly requested it via "all" or "projects"
const interactive = args.interactive === 'all' || args.interactive === 'projects';
const dryRun = !!args.dryRun;
const gitRemote = args.gitRemote;
const changelogRenderer = resolveChangelogRenderer(config.renderer);
for (const project of projects) {
let interpolatedTreePath = config.file || '';
if (interpolatedTreePath) {
interpolatedTreePath = (0, utils_1.interpolate)(interpolatedTreePath, {
projectName: project.name,
projectRoot: project.data.root,
workspaceRoot: '', // within the tree, workspaceRoot is the root
});
}
/**
* newVersion will be null in the case that no changes were detected (e.g. in conventional commits mode),
* no changelog entry is relevant in that case.
*/
if (projectsVersionData[project.name].newVersion === null) {
continue;
}
const releaseVersion = new shared_1.ReleaseVersion({
version: projectsVersionData[project.name].newVersion,
releaseTagPattern: releaseGroup.releaseTagPattern,
projectName: project.name,
});
// We are either creating/previewing a changelog file, a GitHub release, or both
let logTitle = dryRun ? 'Previewing a' : 'Generating a';
switch (true) {
case interpolatedTreePath && config.createRelease === 'github':
logTitle += ` GitHub release and an entry in ${interpolatedTreePath} for ${chalk.white(releaseVersion.gitTag)}`;
break;
case !!interpolatedTreePath:
logTitle += `n entry in ${interpolatedTreePath} for ${chalk.white(releaseVersion.gitTag)}`;
break;
case config.createRelease === 'github':
logTitle += ` GitHub release for ${chalk.white(releaseVersion.gitTag)}`;
}
output_1.output.log({
title: logTitle,
});
const githubRepoSlug = config.createRelease === 'github'
? (0, github_1.getGitHubRepoSlug)(gitRemote)
: undefined;
let contents = await changelogRenderer({
projectGraph,
commits,
releaseVersion: releaseVersion.rawVersion,
project: project.name,
repoSlug: githubRepoSlug,
entryWhenNoChanges: typeof config.entryWhenNoChanges === 'string'
? (0, utils_1.interpolate)(config.entryWhenNoChanges, {
projectName: project.name,
projectRoot: project.data.root,
workspaceRoot: '', // within the tree, workspaceRoot is the root
})
: false,
changelogRenderOptions: config.renderOptions,
});
/**
* If interactive mode, make the changelog contents available for the user to modify in their editor of choice,
* in a similar style to git interactive rebases/merges.
*/
if (interactive) {
const tmpDir = (0, tmp_1.dirSync)().name;
const changelogPath = (0, path_1.joinPathFragments)(tmpDir,
// Include the tree path in the name so that it is easier to identify which changelog file is being edited
`PREVIEW__${interpolatedTreePath.replace(/\//g, '_')}`);
(0, node_fs_1.writeFileSync)(changelogPath, contents);
await (0, launch_editor_1.launchEditor)(changelogPath);
contents = (0, node_fs_1.readFileSync)(changelogPath, 'utf-8');
}
/**
* The exact logic we use for printing the summary/diff to the user is dependent upon whether they are creating
* a changelog file, a GitHub release, or both.
*/
let printSummary = () => { };
const noDiffInChangelogMessage = chalk.yellow(`NOTE: There was no diff detected for the changelog entry. Maybe you intended to pass alternative git references via --from and --to?`);
if (interpolatedTreePath) {
let changelogContents = tree.exists(interpolatedTreePath)
? tree.read(interpolatedTreePath).toString()
: '';
if (changelogContents) {
// NOTE: right now existing releases are always expected to be in markdown format, but in the future we could potentially support others via a custom parser option
const changelogReleases = (0, markdown_1.parseChangelogMarkdown)(changelogContents).releases;
const existingVersionToUpdate = changelogReleases.find((r) => r.version === releaseVersion.rawVersion);
if (existingVersionToUpdate) {
changelogContents = changelogContents.replace(`## ${releaseVersion.rawVersion}\n\n\n${existingVersionToUpdate.body}`, contents);
}
else {
// No existing version, simply prepend the new release to the top of the file
changelogContents = `${contents}\n\n${changelogContents}`;
}
}
else {
// No existing changelog contents, simply create a new one using the generated contents
changelogContents = contents;
}
tree.write(interpolatedTreePath, changelogContents);
printSummary = () => (0, print_changes_1.printAndFlushChanges)(tree, !!dryRun, 3, false, noDiffInChangelogMessage,
// Only print the change for the current changelog file at this point
(f) => f.path === interpolatedTreePath);
}
if (config.createRelease === 'github') {
if (!githubRepoSlug) {
output_1.output.error({
title: `Unable to create a GitHub release because the GitHub repo slug could not be determined.`,
bodyLines: [
`Please ensure you have a valid GitHub remote configured. You can run \`git remote -v\` to list your current remotes.`,
],
});
process.exit(1);
}
const token = await (0, github_1.resolveGithubToken)();
const githubRequestConfig = {
repo: githubRepoSlug,
token,
};
let existingGithubReleaseForVersion;
try {
existingGithubReleaseForVersion = await (0, github_1.getGithubReleaseByTag)(githubRequestConfig, releaseVersion.gitTag);
}
catch (err) {
if (err.response?.status === 401) {
output_1.output.error({
title: `Unable to resolve data via the GitHub API. You can use any of the following options to resolve this:`,
bodyLines: [
'- Set the `GITHUB_TOKEN` or `GH_TOKEN` environment variable to a valid GitHub token with `repo` scope',
'- Have an active session via the official gh CLI tool (https://cli.github.com) in your current terminal',
],
});
process.exit(1);
}
if (err.response?.status === 404) {
// No existing release found, this is fine
}
else {
// Rethrow unknown errors for now
throw err;
}
}
let existingPrintSummaryFn = printSummary;
printSummary = () => {
const logTitle = `https://github.com/${githubRepoSlug}/releases/tag/${releaseVersion.gitTag}`;
if (existingGithubReleaseForVersion) {
console.error(`${chalk.white('UPDATE')} ${logTitle}${dryRun ? chalk.keyword('orange')(' [dry-run]') : ''}`);
}
else {
console.error(`${chalk.green('CREATE')} ${logTitle}${dryRun ? chalk.keyword('orange')(' [dry-run]') : ''}`);
}
// Only print the diff here if we are not already going to be printing changes from the Tree
if (!interpolatedTreePath) {
console.log('');
(0, print_changes_1.printDiff)(existingGithubReleaseForVersion
? existingGithubReleaseForVersion.body
: '', contents, 3, noDiffInChangelogMessage);
}
existingPrintSummaryFn();
};
// Only schedule the actual GitHub update when not in dry-run mode
if (!dryRun) {
postGitTasks.push(async (latestCommit) => {
// Before we can create/update the release we need to ensure the commit exists on the remote
await (0, git_1.gitPush)(gitRemote);
await (0, github_1.createOrUpdateGithubRelease)(githubRequestConfig, {
version: releaseVersion.gitTag,
prerelease: releaseVersion.isPrerelease,
body: contents,
commit: latestCommit,
}, existingGithubReleaseForVersion);
});
}
}
printSummary();
}
}
function checkChangelogFilesEnabled(nxReleaseConfig) {
if (nxReleaseConfig.changelog.workspaceChangelog &&
nxReleaseConfig.changelog.workspaceChangelog.file) {
return true;
}
for (const releaseGroup of Object.values(nxReleaseConfig.groups)) {
if (releaseGroup.changelog && releaseGroup.changelog.file) {
return true;
}
}
return false;
}