Skip to content

Commit

Permalink
fix(release): ensure non-zero exit code is propagated, change missing…
Browse files Browse the repository at this point in the history
… target handling (#21388)
  • Loading branch information
JamesHenry authored Jan 29, 2024
1 parent 9913148 commit e335b9f
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 27 deletions.
2 changes: 1 addition & 1 deletion e2e/release/src/first-release.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ describe('nx release first run', () => {

await runCommandAsync(`git add .`);
await runCommandAsync(`git commit -m "chore: initial commit"`);
});
}, 60000);
afterAll(() => cleanupProject());

describe('without --first-release', () => {
Expand Down
2 changes: 1 addition & 1 deletion e2e/release/src/private-js-packages.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ describe('nx release - private JS packages', () => {
- {private-project-name}
There are a few possible reasons for this: (1) The projects may be private (2) You may not have an appropriate plugin (such as \`@nx/js\`) installed which adds the target automatically to public projects (3) You intended to configure the target manually, or exclude those projects via config in nx.json
This is usually caused by not having an appropriate plugin, such as "@nx/js" installed, which will add the appropriate "nx-release-publish" target for you automatically.
Pass --verbose to see the stacktrace.
Expand Down
58 changes: 33 additions & 25 deletions packages/nx/src/command-line/release/publish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const releasePublishCLIHandler = (args: PublishOptions) =>
export async function releasePublish(
args: PublishOptions,
isCLI = false
): Promise<void> {
): Promise<number> {
/**
* 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.
Expand Down Expand Up @@ -80,36 +80,44 @@ export async function releasePublish(
const shouldExcludeTaskDependencies =
_args.projects?.length > 0 || _args.groups?.length > 0;

let overallExitStatus = 0;

if (args.projects?.length) {
/**
* Run publishing for all remaining release groups and filtered projects within them
*/
for (const releaseGroup of releaseGroups) {
await runPublishOnProjects(
const status = await runPublishOnProjects(
_args,
projectGraph,
nxJson,
Array.from(releaseGroupToFilteredProjects.get(releaseGroup)),
shouldExcludeTaskDependencies,
isCLI
);
if (status !== 0) {
overallExitStatus = status || 1;
}
}

return process.exit(0);
return overallExitStatus;
}

/**
* Run publishing for all remaining release groups
*/
for (const releaseGroup of releaseGroups) {
await runPublishOnProjects(
const status = await runPublishOnProjects(
_args,
projectGraph,
nxJson,
releaseGroup.projects,
shouldExcludeTaskDependencies,
isCLI
);
if (status !== 0) {
overallExitStatus = status || 1;
}
}

if (_args.dryRun) {
Expand All @@ -118,7 +126,7 @@ export async function releasePublish(
);
}

process.exit(0);
return overallExitStatus;
}

async function runPublishOnProjects(
Expand All @@ -128,7 +136,7 @@ async function runPublishOnProjects(
projectNames: string[],
shouldExcludeTaskDependencies: boolean,
isCLI: boolean
) {
): Promise<number> {
const projectsToRun: ProjectGraphProjectNode[] = projectNames.map(
(projectName) => projectGraph.nodes[projectName]
);
Expand Down Expand Up @@ -166,7 +174,7 @@ async function runPublishOnProjects(
if (args.graph) {
const file = readGraphFileFromGraphArg(args);
const projectNames = projectsToRun.map((t) => t.name);
return await generateGraph(
await generateGraph(
{
watch: false,
all: false,
Expand All @@ -178,14 +186,29 @@ async function runPublishOnProjects(
},
projectNames
);
return 0;
}

const requiredTargetName = 'nx-release-publish';
const projectsWithTarget = projectsToRun.filter((project) =>
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`
);
}

ensureAllProjectsHaveTarget(projectsToRun);
/**
* Run the relevant nx-release-publish executor on each of the selected projects.
*/
const status = await runCommand(
projectsToRun,
projectsWithTarget,
projectGraph,
{ nxJson },
{
Expand All @@ -212,21 +235,6 @@ async function runPublishOnProjects(
'One or more of the selected projects could not be published'
);
}
}

function ensureAllProjectsHaveTarget(projectsToRun: ProjectGraphProjectNode[]) {
const requiredTargetName = 'nx-release-publish';
const projectsMissingTarget = projectsToRun.filter(
(project) => !projectHasTarget(project, requiredTargetName)
);
if (projectsMissingTarget.length === 0) {
return;
}
throw new Error(
`Based on your config, the following projects were matched for publishing but do not have the "${requiredTargetName}" target specified:\n${[
...projectsMissingTarget.map((p) => `- ${p.name}`),
'',
'There are a few possible reasons for this: (1) The projects may be private (2) You may not have an appropriate plugin (such as `@nx/js`) installed which adds the target automatically to public projects (3) You intended to configure the target manually, or exclude those projects via config in nx.json',
].join('\n')}\n`
);
return 0;
}

0 comments on commit e335b9f

Please sign in to comment.