UNPKG

nx

Version:

The core Nx plugin contains the core functionality of Nx like the project graph, nx commands and task orchestration.

165 lines (164 loc) • 8.17 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.releasePublishCLIHandler = void 0; exports.createAPI = createAPI; const nx_json_1 = require("../../config/nx-json"); const file_map_utils_1 = require("../../project-graph/file-map-utils"); const project_graph_1 = require("../../project-graph/project-graph"); const run_command_1 = require("../../tasks-runner/run-command"); const command_line_utils_1 = require("../../utils/command-line-utils"); const output_1 = require("../../utils/output"); const handle_errors_1 = require("../../utils/handle-errors"); const project_graph_utils_1 = require("../../utils/project-graph-utils"); const graph_1 = require("../graph/graph"); const config_1 = require("./config/config"); const deep_merge_json_1 = require("./config/deep-merge-json"); const filter_release_groups_1 = require("./config/filter-release-groups"); const print_config_1 = require("./utils/print-config"); const releasePublishCLIHandler = (args) => (0, handle_errors_1.handleErrors)(args.verbose, () => createAPI({})(args, true)); exports.releasePublishCLIHandler = releasePublishCLIHandler; function createAPI(overrideReleaseConfig) { /** * 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. */ return async function releasePublish(args, isCLI = false) { /** * When used via the CLI, the args object will contain a __overrides_unparsed__ property that is * important for invoking the relevant executor behind the scenes. * * We intentionally do not include that in the function signature, however, so as not to cause * confusing errors for programmatic consumers of this function. */ const _args = args; const projectGraph = await (0, project_graph_1.createProjectGraphAsync)({ exitOnError: true }); const nxJson = (0, nx_json_1.readNxJson)(); const userProvidedReleaseConfig = (0, deep_merge_json_1.deepMergeJson)(nxJson.release ?? {}, overrideReleaseConfig ?? {}); // Apply default configuration to any optional user configuration const { error: configError, nxReleaseConfig } = await (0, config_1.createNxReleaseConfig)(projectGraph, await (0, file_map_utils_1.createProjectFileMapUsingProjectGraph)(projectGraph), userProvidedReleaseConfig); if (configError) { return await (0, config_1.handleNxReleaseConfigError)(configError); } // --print-config exits directly as it is not designed to be combined with any other programmatic operations if (args.printConfig) { return (0, print_config_1.printConfigAndExit)({ userProvidedReleaseConfig, nxReleaseConfig, isDebug: args.printConfig === 'debug', }); } 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); } /** * If the user is filtering to a subset of projects or groups, we should not run the publish task * for dependencies, because that could cause projects outset of the filtered set to be published. */ const shouldExcludeTaskDependencies = _args.projects?.length > 0 || _args.groups?.length > 0 || args.excludeTaskDependencies; let overallExitStatus = 0; if (args.projects?.length) { /** * Run publishing for all remaining release groups and filtered projects within them */ for (const releaseGroup of releaseGroups) { const status = await runPublishOnProjects(_args, projectGraph, nxJson, Array.from(releaseGroupToFilteredProjects.get(releaseGroup)), isCLI, { excludeTaskDependencies: shouldExcludeTaskDependencies, loadDotEnvFiles: process.env.NX_LOAD_DOT_ENV_FILES !== 'false', }); if (status !== 0) { overallExitStatus = status || 1; } } return overallExitStatus; } /** * Run publishing for all remaining release groups */ for (const releaseGroup of releaseGroups) { const status = await runPublishOnProjects(_args, projectGraph, nxJson, releaseGroup.projects, isCLI, { excludeTaskDependencies: shouldExcludeTaskDependencies, loadDotEnvFiles: process.env.NX_LOAD_DOT_ENV_FILES !== 'false', }); if (status !== 0) { overallExitStatus = status || 1; } } return overallExitStatus; }; } async function runPublishOnProjects(args, projectGraph, nxJson, projectNames, isCLI, extraOptions) { const projectsToRun = projectNames.map((projectName) => projectGraph.nodes[projectName]); const overrides = (0, command_line_utils_1.createOverrides)(args.__overrides_unparsed__); if (args.registry) { overrides.registry = args.registry; } if (args.tag) { overrides.tag = args.tag; } if (args.otp) { overrides.otp = args.otp; } if (args.access) { overrides.access = args.access; } if (args.dryRun) { overrides.dryRun = args.dryRun; /** * Ensure the env var is set too, so that any and all publish executors triggered * indirectly via dependsOn can also pick up on the fact that this is a dry run. */ process.env.NX_DRY_RUN = 'true'; } if (args.firstRelease) { overrides.firstRelease = args.firstRelease; } const requiredTargetName = 'nx-release-publish'; if (args.graph) { const file = (0, command_line_utils_1.readGraphFileFromGraphArg)(args); const projectNamesWithTarget = projectsToRun .map((t) => t.name) .filter((projectName) => (0, project_graph_utils_1.projectHasTarget)(projectGraph.nodes[projectName], requiredTargetName)); await (0, graph_1.generateGraph)({ watch: true, all: false, open: true, view: 'tasks', targets: [requiredTargetName], projects: projectNamesWithTarget, file, }, projectNamesWithTarget); return 0; } const projectsWithTarget = projectsToRun.filter((project) => (0, project_graph_utils_1.projectHasTarget)(project, requiredTargetName)); if (projectsWithTarget.length === 0) { throw new Error(`Based on your config, the following projects were matched for publishing but do not have the "${requiredTargetName}" target specified:\n${[ ...projectsToRun.map((p) => `- ${p.name}`), '', `This is usually caused by not having an appropriate plugin, such as "@nx/js" installed, which will add the appropriate "${requiredTargetName}" target for you automatically.`, ].join('\n')}\n`); } /** * Run the relevant nx-release-publish executor on each of the selected projects. */ const status = await (0, run_command_1.runCommand)(projectsWithTarget, projectGraph, { nxJson }, { targets: [requiredTargetName], outputStyle: 'static', ...args, // It is possible for workspaces to have circular dependencies between packages and still release them to a registry nxIgnoreCycles: true, }, overrides, null, {}, extraOptions); if (status !== 0) { // In order to not add noise to the overall CLI output, do not throw an additional error if (isCLI) { return status; } // Throw an additional error for programmatic API usage throw new Error('One or more of the selected projects could not be published'); } return 0; }