Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { NxReleaseConfig } from './config';

export const DEFAULT_CONVENTIONAL_COMMITS_CONFIG: NxReleaseConfig['conventionalCommits'] =
{
ignoreProjectScopeForVersionBump: false,
types: {
feat: {
semverBump: 'minor',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ Promise<Map<string, SemverSpecifier | null>> {
);
return determineSemverChange(
relevantCommits,
releaseConfig.conventionalCommits
releaseConfig.conventionalCommits,
releaseConfig.conventionalCommits?.ignoreProjectScopeForVersionBump
);
}

Expand Down
88 changes: 88 additions & 0 deletions packages/nx/src/command-line/release/utils/semver.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,5 +237,93 @@ describe('semver', () => {
).get('default')
).toEqual(null);
});

it('should apply full semver bump to non-scoped commits when ignoreProjectScopeForVersionBump is true', () => {
expect(
determineSemverChange(
new Map([
[
'default',
[
{ commit: fixCommit, isProjectScopedCommit: false },
{
commit: featNonBreakingCommit,
isProjectScopedCommit: false,
},
{ commit: choreCommit, isProjectScopedCommit: false },
],
],
]),
config,
true // ignoreProjectScopeForVersionBump enabled
).get('default')
).toEqual(SemverSpecifier.MINOR);
});

it('should still return major for breaking non-scoped commits when ignoreProjectScopeForVersionBump is true', () => {
expect(
determineSemverChange(
new Map([
[
'default',
[
{ commit: fixCommit, isProjectScopedCommit: false },
{ commit: featBreakingCommit, isProjectScopedCommit: false },
],
],
]),
config,
true // ignoreProjectScopeForVersionBump enabled
).get('default')
).toEqual(SemverSpecifier.MAJOR);
});

it('should return patch for non-scoped patch commits when ignoreProjectScopeForVersionBump is true', () => {
expect(
determineSemverChange(
new Map([
[
'default',
[
{ commit: fixCommit, isProjectScopedCommit: false },
{ commit: choreCommit, isProjectScopedCommit: false },
],
],
]),
config,
true // ignoreProjectScopeForVersionBump enabled
).get('default')
).toEqual(SemverSpecifier.PATCH);
});

it('should respect ignoreProjectScopeForVersionBump for individual projects', () => {
expect(
determineSemverChange(
new Map([
[
'project-a',
[
{ commit: fixCommit, isProjectScopedCommit: false },
{
commit: featNonBreakingCommit,
isProjectScopedCommit: false,
},
],
],
[
'project-b',
[{ commit: fixCommit, isProjectScopedCommit: false }],
],
]),
config,
true // ignoreProjectScopeForVersionBump enabled
)
).toEqual(
new Map([
['project-a', SemverSpecifier.MINOR],
['project-b', SemverSpecifier.PATCH],
])
);
});
});
});
6 changes: 4 additions & 2 deletions packages/nx/src/command-line/release/utils/semver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,17 @@ export function determineSemverChange(
string,
{ commit: GitCommit; isProjectScopedCommit: boolean }[]
>,
config: NxReleaseConfig['conventionalCommits']
config: NxReleaseConfig['conventionalCommits'],
ignoreProjectScopeForVersionBump?: boolean
): Map<string, SemverSpecifier | null> {
const semverChangePerProject: Map<string, SemverSpecifier | null> = new Map();
for (const [projectName, relevantCommit] of relevantCommits) {
let highestChange: SemverSpecifier | null = null;

for (const { commit, isProjectScopedCommit } of relevantCommit) {
if (!isProjectScopedCommit) {
if (!isProjectScopedCommit && !ignoreProjectScopeForVersionBump) {
// commit is relevant to the project, but not directly, report patch change to match side-effectful bump behavior in update dependents in release-group-processor
// unless ignoreProjectScopeForVersionBump is enabled, in which case we use the commit type's configured semver bump
highestChange = Math.max(SemverSpecifier.PATCH, highestChange ?? 0);
continue;
}
Expand Down
12 changes: 12 additions & 0 deletions packages/nx/src/config/nx-json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,18 @@ export interface NxReleaseGitConfiguration {
}

export interface NxReleaseConventionalCommitsConfiguration {
/**
* When enabled, commits affecting a project will use their full semver bump
* even if the commit scope doesn't match the project name.
*
* By default (false), a commit like `feat(other-lib):` affecting a project as a dependency
* will be downgraded to a patch bump. When set to true, the same commit will apply its full
* semver bump (minor for feat, patch for fix, etc.).
*
* This is useful when your commit scopes don't map 1:1 with project names, or when you want
* any commit affecting a project to use its configured semver bump regardless of scope matching.
*/
ignoreProjectScopeForVersionBump?: boolean;
types?: Record<
string,
/**
Expand Down