HEX
Server: Apache/2.4.52 (Ubuntu)
System: Linux ip-172-31-4-197 6.8.0-1036-aws #38~22.04.1-Ubuntu SMP Fri Aug 22 15:44:33 UTC 2025 x86_64
User: ubuntu (1000)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
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;
}