From 1552a778baf308c2b2f2a6675348b3f2d0c041d7 Mon Sep 17 00:00:00 2001 From: Austin Fahsl Date: Sun, 25 Feb 2024 16:25:25 -0700 Subject: [PATCH 01/10] feat(release): add conventional commits props to nxJson config --- .../src/conventional-commits-config.test.ts | 310 ++ .../release-version/release-version.ts | 3 +- .../nx/release/changelog-renderer/index.ts | 24 +- .../nx/src/command-line/release/changelog.ts | 52 +- .../release/config/config.spec.ts | 3706 ++++++++++++++++- .../src/command-line/release/config/config.ts | 98 + .../release/config/conventional-commits.ts | 98 + .../release/utils/resolve-semver-specifier.ts | 21 +- .../src/command-line/release/utils/semver.ts | 15 +- .../nx/src/command-line/release/version.ts | 12 +- packages/nx/src/config/nx-json.ts | 26 + 11 files changed, 4296 insertions(+), 69 deletions(-) create mode 100644 e2e/release/src/conventional-commits-config.test.ts create mode 100644 packages/nx/src/command-line/release/config/conventional-commits.ts diff --git a/e2e/release/src/conventional-commits-config.test.ts b/e2e/release/src/conventional-commits-config.test.ts new file mode 100644 index 0000000000000..6a730dad9f26c --- /dev/null +++ b/e2e/release/src/conventional-commits-config.test.ts @@ -0,0 +1,310 @@ +import { NxJsonConfiguration } from '@nx/devkit'; +import { + cleanupProject, + newProject, + runCLI, + runCommandAsync, + uniq, + updateJson, +} from '@nx/e2e/utils'; + +expect.addSnapshotSerializer({ + serialize(str: string) { + return ( + str + // Remove all output unique to specific projects to ensure deterministic snapshots + .replaceAll(/my-pkg-\d+/g, '{project-name}') + .replaceAll( + /integrity:\s*.*/g, + 'integrity: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' + ) + .replaceAll(/\b[0-9a-f]{40}\b/g, '{SHASUM}') + .replaceAll(/\d*B index\.js/g, 'XXB index.js') + .replaceAll(/\d*B project\.json/g, 'XXB project.json') + .replaceAll(/\d*B package\.json/g, 'XXXB package.json') + .replaceAll(/size:\s*\d*\s?B/g, 'size: XXXB') + .replaceAll(/\d*\.\d*\s?kB/g, 'XXX.XXX kb') + .replaceAll(/[a-fA-F0-9]{7}/g, '{COMMIT_SHA}') + .replaceAll(/Test @[\w\d]+/g, 'Test @{COMMIT_AUTHOR}') + // Normalize the version title date. + .replaceAll(/\(\d{4}-\d{2}-\d{2}\)/g, '(YYYY-MM-DD)') + // We trim each line to reduce the chances of snapshot flakiness + .split('\n') + .map((r) => r.trim()) + .join('\n') + ); + }, + test(val: string) { + return val != null && typeof val === 'string'; + }, +}); + +describe('nx release conventional commits config', () => { + let pkg1: string; + let pkg2: string; + let pkg3: string; + let pkg4: string; + + beforeAll(async () => { + newProject({ + unsetProjectNameAndRootFormat: false, + packages: ['@nx/js'], + }); + + pkg1 = uniq('my-pkg-1'); + runCLI(`generate @nx/workspace:npm-package ${pkg1}`); + + pkg2 = uniq('my-pkg-2'); + runCLI(`generate @nx/workspace:npm-package ${pkg2}`); + + pkg3 = uniq('my-pkg-3'); + runCLI(`generate @nx/workspace:npm-package ${pkg3}`); + + pkg4 = uniq('my-pkg-4'); + runCLI(`generate @nx/workspace:npm-package ${pkg4}`); + + // Update pkg2 to depend on pkg1 + updateJson(`${pkg2}/package.json`, (json) => { + json.dependencies ??= {}; + json.dependencies[`@proj/${pkg1}`] = '0.0.0'; + return json; + }); + + // no git config so that the test ensures git operations happen by default + updateJson('nx.json', (nxJson) => { + nxJson.release = { + projectsRelationship: 'independent', + }; + return nxJson; + }); + + await runCommandAsync(`git add .`); + await runCommandAsync(`git commit -m "chore: initial commit"`); + await runCommandAsync(`git tag -a ${pkg1}@0.0.1 -m "${pkg1}@0.0.1"`); + await runCommandAsync(`git tag -a ${pkg2}@0.0.1 -m "${pkg2}@0.0.1"`); + await runCommandAsync(`git tag -a ${pkg3}@0.0.1 -m "${pkg3}@0.0.1"`); + await runCommandAsync(`git tag -a ${pkg4}@0.0.1 -m "${pkg4}@0.0.1"`); + }, 60000); + afterAll(() => cleanupProject()); + + it('should respect custom conventional commits configuration', async () => { + updateJson('nx.json', (json) => { + json.release = { + ...json.release, + version: { + conventionalCommits: true, + }, + changelog: { + projectChangelogs: { + renderOptions: { + authors: false, // do not show authors in the e2e snapshots + }, + }, + }, + conventionalCommits: { + types: { + fix: false, + docs: { + semverBump: 'patch', + changelog: { + hidden: false, + title: 'Custom Docs Header', + }, + }, + customType: { + semverBump: 'minor', + changelog: { + title: 'Custom Type', + }, + }, + // unspecified semverBump will default to "patch" + chore: { + // "changelog.hidden" defaults to true, but setting changelog: false + // is a shortcut for setting "changelog.hidden" to false. + changelog: false, + }, + }, + }, + }; + return json; + }); + + // update my-pkg-1 with a fix commit + updateJson(`${pkg1}/package.json`, (json) => ({ + ...json, + license: 'MIT', + })); + await runCommandAsync(`git add ${pkg1}/package.json`); + await runCommandAsync(`git commit -m "fix: this is a fix"`); + + const versionResultNoChanges = runCLI(`release version -d`); + + expect(versionResultNoChanges).toContain( + `${pkg1} 🚫 Skipping versioning "@proj/${pkg1}" as no changes were detected.` + ); + expect(versionResultNoChanges).toContain( + `${pkg2} 🚫 Skipping versioning "@proj/${pkg2}" as no changes were detected.` + ); + expect(versionResultNoChanges).toContain( + `${pkg3} 🚫 Skipping versioning "@proj/${pkg3}" as no changes were detected.` + ); + expect(versionResultNoChanges).toContain( + `${pkg4} 🚫 Skipping versioning "@proj/${pkg4}" as no changes were detected.` + ); + + // update my-pkg-3 with a fix commit + updateJson(`${pkg3}/package.json`, (json) => ({ + ...json, + license: 'MIT', + })); + await runCommandAsync(`git add ${pkg3}/package.json`); + await runCommandAsync(`git commit -m "docs: this is a doc"`); + + const versionResultDocsChanges = runCLI(`release version -d`); + + expect(versionResultDocsChanges).toContain( + `${pkg1} 🚫 Skipping versioning "@proj/${pkg1}" as no changes were detected.` + ); + expect(versionResultDocsChanges).toContain( + `${pkg2} 🚫 Skipping versioning "@proj/${pkg2}" as no changes were detected.` + ); + expect(versionResultDocsChanges).toContain( + `${pkg3} ✍️ New version 0.0.2 written to ${pkg3}/package.json` + ); + expect(versionResultNoChanges).toContain( + `${pkg4} 🚫 Skipping versioning "@proj/${pkg4}" as no changes were detected.` + ); + + // update my-pkg-2 with a fix commit + updateJson(`${pkg2}/package.json`, (json) => ({ + ...json, + license: 'MIT', + })); + await runCommandAsync(`git add ${pkg2}/package.json`); + await runCommandAsync( + `git commit -m "customType(${pkg2}): this is a custom type"` + ); + + const versionResultCustomTypeChanges = runCLI(`release version -d`); + expect(versionResultCustomTypeChanges).toContain( + `${pkg1} 🚫 Skipping versioning "@proj/${pkg1}" as no changes were detected.` + ); + expect(versionResultCustomTypeChanges).toContain( + `${pkg2} ✍️ New version 0.1.0 written to ${pkg2}/package.json` + ); + expect(versionResultCustomTypeChanges).toContain( + `${pkg3} ✍️ New version 0.0.2 written to ${pkg3}/package.json` + ); + expect(versionResultNoChanges).toContain( + `${pkg4} 🚫 Skipping versioning "@proj/${pkg4}" as no changes were detected.` + ); + + updateJson(`${pkg1}/package.json`, (json) => ({ + ...json, + license: 'UNLICENSED', + })); + await runCommandAsync(`git add ${pkg1}/package.json`); + await runCommandAsync( + `git commit -m "customType(${pkg1})!: this is a breaking change"` + ); + + const versionResultCustomTypeBreakingChanges = runCLI(`release version -d`); + expect(versionResultCustomTypeBreakingChanges).toContain( + `${pkg1} ✍️ New version 1.0.0 written to ${pkg1}/package.json` + ); + expect(versionResultCustomTypeBreakingChanges).toContain( + `${pkg2} ✍️ New version 0.1.0 written to ${pkg2}/package.json` + ); + expect(versionResultCustomTypeBreakingChanges).toContain( + `${pkg3} ✍️ New version 0.0.2 written to ${pkg3}/package.json` + ); + expect(versionResultNoChanges).toContain( + `${pkg4} 🚫 Skipping versioning "@proj/${pkg4}" as no changes were detected.` + ); + + updateJson(`${pkg4}/package.json`, (json) => ({ + ...json, + license: 'MIT', + })); + await runCommandAsync(`git add ${pkg4}/package.json`); + await runCommandAsync(`git commit -m "chore: this is a chore"`); + + const versionResultChoreChanges = runCLI(`release version -d`); + expect(versionResultChoreChanges).toContain( + `${pkg1} ✍️ New version 1.0.0 written to ${pkg1}/package.json` + ); + expect(versionResultChoreChanges).toContain( + `${pkg2} ✍️ New version 0.1.0 written to ${pkg2}/package.json` + ); + expect(versionResultChoreChanges).toContain( + `${pkg3} ✍️ New version 0.0.2 written to ${pkg3}/package.json` + ); + expect(versionResultCustomTypeBreakingChanges).toContain( + `${pkg3} ✍️ New version 0.0.2 written to ${pkg3}/package.json` + ); + + // Normally, users would use `nx release` or the programmatic api to ensure that + // changelogs are generated for the above version bumps, but for the sake of this + // test, we just want to ensure that each commit is included/excluded as expected. + // Therefore, any version number will work - in this case it's 1.0.0. + const changelogResult = runCLI(`release changelog 1.0.0 -d`); + + // NOTE: pkg4 should not have changes here, since its only commit is a chore. + // Chore commits are hidden from changelogs in the above config via `changelog: false`. + expect(changelogResult).toMatchInlineSnapshot(` + + NX Previewing an entry in {project-name}/CHANGELOG.md for {project-name}@1.0.0 + + + + # 1.0.0 (YYYY-MM-DD) + + + + + + ### Custom Type + + + + - **{project-name}:** this is a custom type + + + NX Previewing an entry in {project-name}/CHANGELOG.md for {project-name}@1.0.0 + + + + # 1.0.0 (YYYY-MM-DD) + + + + + + ### Custom Docs Header + + + + - this is a doc + + + NX Previewing an entry in {project-name}/CHANGELOG.md for {project-name}@1.0.0 + + + + # 1.0.0 (YYYY-MM-DD) + + + + This was a version bump only for {project-name} to align it with other projects, there were no code changes. + + + NX Previewing an entry in {project-name}/CHANGELOG.md for {project-name}@1.0.0 + + + + # 1.0.0 (YYYY-MM-DD) + + + + + + ### Custom Type + + + + - ⚠️ **{project-name}:** this is a breaking change + + + + + + #### ⚠️ Breaking Changes + + + + - ⚠️ **{project-name}:** this is a breaking change + + + NX Committing changes with git + + + NX Tagging commit with git + + + `); + }); +}); diff --git a/packages/js/src/generators/release-version/release-version.ts b/packages/js/src/generators/release-version/release-version.ts index 23a17728cebb6..68c25c7233dbf 100644 --- a/packages/js/src/generators/release-version/release-version.ts +++ b/packages/js/src/generators/release-version/release-version.ts @@ -333,7 +333,8 @@ To fix this you will either need to add a package.json file at that location, or specifier = await resolveSemverSpecifierFromConventionalCommits( previousVersionRef, options.projectGraph, - affectedProjects + affectedProjects, + options.conventionalCommitsConfig ); if (!specifier) { diff --git a/packages/nx/release/changelog-renderer/index.ts b/packages/nx/release/changelog-renderer/index.ts index 9124ad340ddca..00e1723e0d2cd 100644 --- a/packages/nx/release/changelog-renderer/index.ts +++ b/packages/nx/release/changelog-renderer/index.ts @@ -1,4 +1,5 @@ import { major } from 'semver'; +import { NxReleaseConfig } from '../../src/command-line/release/config/config'; import type { GitCommit } from '../../src/command-line/release/utils/git'; import { RepoSlug, @@ -37,6 +38,7 @@ export type ChangelogRenderer = (config: { entryWhenNoChanges: string | false; changelogRenderOptions: DefaultChangelogRenderOptions; repoSlug?: RepoSlug; + conventionalCommitsConfig: NxReleaseConfig['conventionalCommits']; }) => Promise | string; /** @@ -73,26 +75,12 @@ const defaultChangelogRenderer: ChangelogRenderer = async ({ entryWhenNoChanges, changelogRenderOptions, repoSlug, + conventionalCommitsConfig, }): Promise => { + const commitTypes = conventionalCommitsConfig.types; const markdownLines: string[] = []; const breakingChanges = []; - const commitTypes = { - feat: { title: '🚀 Features' }, - perf: { title: '🔥 Performance' }, - fix: { title: '🩹 Fixes' }, - refactor: { title: '💅 Refactors' }, - docs: { title: '📖 Documentation' }, - build: { title: '📦 Build' }, - types: { title: '🌊 Types' }, - chore: { title: '🏡 Chore' }, - examples: { title: '🏀 Examples' }, - test: { title: '✅ Tests' }, - style: { title: '🎨 Styles' }, - ci: { title: '🤖 CI' }, - revert: { title: '⏪ Revert' }, - }; - // If the current range of commits contains both a commit and its revert, we strip them both from the final list for (const commit of commits) { if (commit.type === 'revert') { @@ -139,7 +127,7 @@ const defaultChangelogRenderer: ChangelogRenderer = async ({ continue; } - markdownLines.push('', '### ' + commitTypes[type].title, ''); + markdownLines.push('', '### ' + commitTypes[type].changelog.title, ''); /** * In order to make the final changelog most readable, we organize commits as follows: @@ -215,7 +203,7 @@ const defaultChangelogRenderer: ChangelogRenderer = async ({ continue; } - markdownLines.push('', `### ${commitTypes[type].title}`, ''); + markdownLines.push('', `### ${commitTypes[type].changelog.title}`, ''); const commitsInChronologicalOrder = group.reverse(); for (const commit of commitsInChronologicalOrder) { diff --git a/packages/nx/src/command-line/release/changelog.ts b/packages/nx/src/command-line/release/changelog.ts index ea0939aa9d4ec..c567059e4b34a 100644 --- a/packages/nx/src/command-line/release/changelog.ts +++ b/packages/nx/src/command-line/release/changelog.ts @@ -239,7 +239,8 @@ export async function releaseChangelog( const workspaceChangelogCommits = await getCommits( workspaceChangelogFromSHA, - toSHA + toSHA, + nxReleaseConfig.conventionalCommits ); const workspaceChangelog = await generateChangelogForWorkspace( @@ -315,7 +316,11 @@ export async function releaseChangelog( if (!fromRef && useAutomaticFromRef) { const firstCommit = await getFirstGitCommit(); - const allCommits = await getCommits(firstCommit, toSHA); + const allCommits = await getCommits( + firstCommit, + toSHA, + nxReleaseConfig.conventionalCommits + ); const commitsForProject = allCommits.filter((c) => c.affectedFiles.find((f) => f.startsWith(project.data.root)) ); @@ -336,7 +341,11 @@ export async function releaseChangelog( } if (!commits) { - commits = await getCommits(fromRef, toSHA); + commits = await getCommits( + fromRef, + toSHA, + nxReleaseConfig.conventionalCommits + ); } const projectChangelogs = await generateChangelogForProjects( @@ -345,9 +354,9 @@ export async function releaseChangelog( projectGraph, commits, projectsVersionData, - postGitTasks, releaseGroup, - [project] + [project], + nxReleaseConfig ); let hasPushed = false; @@ -400,7 +409,11 @@ export async function releaseChangelog( // Make sure that the fromRef is actually resolvable const fromSHA = await getCommitHash(fromRef); - const commits = await getCommits(fromSHA, toSHA); + const commits = await getCommits( + fromSHA, + toSHA, + nxReleaseConfig.conventionalCommits + ); const projectChangelogs = await generateChangelogForProjects( tree, @@ -408,9 +421,9 @@ export async function releaseChangelog( projectGraph, commits, projectsVersionData, - postGitTasks, releaseGroup, - projectNodes + projectNodes, + nxReleaseConfig ); let hasPushed = false; @@ -738,6 +751,7 @@ async function generateChangelogForWorkspace( repoSlug: githubRepoSlug, entryWhenNoChanges: config.entryWhenNoChanges, changelogRenderOptions: config.renderOptions, + conventionalCommitsConfig: nxReleaseConfig.conventionalCommits, }); /** @@ -800,9 +814,9 @@ async function generateChangelogForProjects( projectGraph: ProjectGraph, commits: GitCommit[], projectsVersionData: VersionData, - postGitTasks: PostGitTask[], releaseGroup: ReleaseGroupWithName, - projects: ProjectGraphProjectNode[] + projects: ProjectGraphProjectNode[], + nxReleaseConfig: NxReleaseConfig ): Promise { const config = releaseGroup.changelog; // The entire feature is disabled at the release group level, exit early @@ -873,6 +887,7 @@ async function generateChangelogForProjects( }) : false, changelogRenderOptions: config.renderOptions, + conventionalCommitsConfig: nxReleaseConfig.conventionalCommits, }); /** @@ -954,17 +969,22 @@ function checkChangelogFilesEnabled(nxReleaseConfig: NxReleaseConfig): boolean { return false; } -async function getCommits(fromSHA: string, toSHA: string) { +async function getCommits( + fromSHA: string, + toSHA: string, + conventionalCommitsConfig: NxReleaseConfig['conventionalCommits'] +): Promise { const rawCommits = await getGitDiff(fromSHA, toSHA); // Parse as conventional commits return 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; + + const typeConfig = conventionalCommitsConfig.types[type]; + if (!typeConfig) { + // don't include commits with unknown types + return false; } - return false; + return !typeConfig.changelog.hidden; }); } diff --git a/packages/nx/src/command-line/release/config/config.spec.ts b/packages/nx/src/command-line/release/config/config.spec.ts index d2f4504efbda1..d9296caa60bd6 100644 --- a/packages/nx/src/command-line/release/config/config.spec.ts +++ b/packages/nx/src/command-line/release/config/config.spec.ts @@ -74,6 +74,101 @@ describe('createNxReleaseConfig()', () => { "renderer": "nx/release/changelog-renderer", }, }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, "git": { "commit": false, "commitArgs": "", @@ -150,6 +245,101 @@ describe('createNxReleaseConfig()', () => { "renderer": "nx/release/changelog-renderer", }, }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, "git": { "commit": false, "commitArgs": "", @@ -229,6 +419,101 @@ describe('createNxReleaseConfig()', () => { "renderer": "nx/release/changelog-renderer", }, }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, "git": { "commit": false, "commitArgs": "", @@ -324,6 +609,101 @@ describe('createNxReleaseConfig()', () => { "renderer": "nx/release/changelog-renderer", }, }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, "git": { "commit": false, "commitArgs": "", @@ -409,6 +789,101 @@ describe('createNxReleaseConfig()', () => { "renderer": "nx/release/changelog-renderer", }, }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, "git": { "commit": false, "commitArgs": "", @@ -490,6 +965,101 @@ describe('createNxReleaseConfig()', () => { "renderer": "nx/release/changelog-renderer", }, }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, "git": { "commit": false, "commitArgs": "", @@ -574,6 +1144,101 @@ describe('createNxReleaseConfig()', () => { "projectChangelogs": false, "workspaceChangelog": false, }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, "git": { "commit": false, "commitArgs": "", @@ -671,6 +1336,101 @@ describe('createNxReleaseConfig()', () => { "renderer": "nx/release/changelog-renderer", }, }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, "git": { "commit": false, "commitArgs": "", @@ -758,6 +1518,101 @@ describe('createNxReleaseConfig()', () => { "projectChangelogs": false, "workspaceChangelog": false, }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, "git": { "commit": false, "commitArgs": "", @@ -865,10 +1720,105 @@ describe('createNxReleaseConfig()', () => { "projectChangelogs": false, "workspaceChangelog": false, }, - "git": { - "commit": false, - "commitArgs": "", - "commitMessage": "chore(release): publish {version}", + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, + "git": { + "commit": false, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", "stageChanges": false, "tag": false, "tagArgs": "", @@ -960,6 +1910,101 @@ describe('createNxReleaseConfig()', () => { "renderer": "nx/release/changelog-renderer", }, }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, "git": { "commit": false, "commitArgs": "", @@ -1046,6 +2091,101 @@ describe('createNxReleaseConfig()', () => { "renderer": "nx/release/changelog-renderer", }, }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, "git": { "commit": true, "commitArgs": "--no-verify", @@ -1131,6 +2271,101 @@ describe('createNxReleaseConfig()', () => { "renderer": "nx/release/changelog-renderer", }, }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, "git": { "commit": false, "commitArgs": "", @@ -1232,6 +2467,101 @@ describe('createNxReleaseConfig()', () => { "renderer": "nx/release/changelog-renderer", }, }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, "git": { "commit": false, "commitArgs": "", @@ -1311,6 +2641,101 @@ describe('createNxReleaseConfig()', () => { "renderer": "nx/release/changelog-renderer", }, }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, "git": { "commit": false, "commitArgs": "", @@ -1402,6 +2827,101 @@ describe('createNxReleaseConfig()', () => { "renderer": "nx/release/changelog-renderer", }, }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, "git": { "commit": false, "commitArgs": "", @@ -1487,6 +3007,101 @@ describe('createNxReleaseConfig()', () => { "projectChangelogs": false, "workspaceChangelog": false, }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, "git": { "commit": false, "commitArgs": "", @@ -1589,6 +3204,101 @@ describe('createNxReleaseConfig()', () => { "renderer": "nx/release/changelog-renderer", }, }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, "git": { "commit": false, "commitArgs": "", @@ -1691,6 +3401,101 @@ describe('createNxReleaseConfig()', () => { "renderer": "nx/release/changelog-renderer", }, }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, "git": { "commit": false, "commitArgs": "", @@ -1780,7 +3585,1043 @@ describe('createNxReleaseConfig()', () => { "commitReferences": true, "versionTitleDate": true, }, - "renderer": "nx/release/changelog-renderer", + "renderer": "nx/release/changelog-renderer", + }, + }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, + "git": { + "commit": false, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": false, + "tag": false, + "tagArgs": "", + "tagMessage": "", + }, + "groups": { + "__default__": { + "changelog": false, + "projects": [ + "lib-a", + "lib-b", + "nx", + ], + "projectsRelationship": "fixed", + "releaseTagPattern": "v{version}", + "version": { + "conventionalCommits": false, + "generator": "@nx/js:release-version", + "generatorOptions": {}, + }, + }, + }, + "projectsRelationship": "fixed", + "releaseTagPattern": "v{version}", + "version": { + "conventionalCommits": false, + "generator": "@nx/js:release-version", + "generatorOptions": {}, + "git": { + "commit": false, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": true, + "tag": false, + "tagArgs": "", + "tagMessage": "", + }, + }, + }, + } + `); + }); + }); + + describe('user config -> top level conventional commits configuration', () => { + it('should use defaults when config is empty', async () => { + const res1 = await createNxReleaseConfig(projectGraph, { + conventionalCommits: {}, + }); + + expect(res1).toMatchInlineSnapshot(` + { + "error": null, + "nxReleaseConfig": { + "changelog": { + "automaticFromRef": false, + "git": { + "commit": true, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": false, + "tag": true, + "tagArgs": "", + "tagMessage": "", + }, + "projectChangelogs": false, + "workspaceChangelog": { + "createRelease": false, + "entryWhenNoChanges": "This was a version bump only, there were no code changes.", + "file": "{workspaceRoot}/CHANGELOG.md", + "renderOptions": { + "authors": true, + "commitReferences": true, + "versionTitleDate": true, + }, + "renderer": "nx/release/changelog-renderer", + }, + }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, + "git": { + "commit": false, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": false, + "tag": false, + "tagArgs": "", + "tagMessage": "", + }, + "groups": { + "__default__": { + "changelog": false, + "projects": [ + "lib-a", + "lib-b", + "nx", + ], + "projectsRelationship": "fixed", + "releaseTagPattern": "v{version}", + "version": { + "conventionalCommits": false, + "generator": "@nx/js:release-version", + "generatorOptions": {}, + }, + }, + }, + "projectsRelationship": "fixed", + "releaseTagPattern": "v{version}", + "version": { + "conventionalCommits": false, + "generator": "@nx/js:release-version", + "generatorOptions": {}, + "git": { + "commit": false, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": true, + "tag": false, + "tagArgs": "", + "tagMessage": "", + }, + }, + }, + } + `); + + const res2 = await createNxReleaseConfig(projectGraph, { + conventionalCommits: { + types: {}, + }, + }); + + expect(res2).toMatchInlineSnapshot(` + { + "error": null, + "nxReleaseConfig": { + "changelog": { + "automaticFromRef": false, + "git": { + "commit": true, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": false, + "tag": true, + "tagArgs": "", + "tagMessage": "", + }, + "projectChangelogs": false, + "workspaceChangelog": { + "createRelease": false, + "entryWhenNoChanges": "This was a version bump only, there were no code changes.", + "file": "{workspaceRoot}/CHANGELOG.md", + "renderOptions": { + "authors": true, + "commitReferences": true, + "versionTitleDate": true, + }, + "renderer": "nx/release/changelog-renderer", + }, + }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, + "git": { + "commit": false, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": false, + "tag": false, + "tagArgs": "", + "tagMessage": "", + }, + "groups": { + "__default__": { + "changelog": false, + "projects": [ + "lib-a", + "lib-b", + "nx", + ], + "projectsRelationship": "fixed", + "releaseTagPattern": "v{version}", + "version": { + "conventionalCommits": false, + "generator": "@nx/js:release-version", + "generatorOptions": {}, + }, + }, + }, + "projectsRelationship": "fixed", + "releaseTagPattern": "v{version}", + "version": { + "conventionalCommits": false, + "generator": "@nx/js:release-version", + "generatorOptions": {}, + "git": { + "commit": false, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": true, + "tag": false, + "tagArgs": "", + "tagMessage": "", + }, + }, + }, + } + `); + }); + + it('should merge defaults with overrides and new commit types', async () => { + const res = await createNxReleaseConfig(projectGraph, { + conventionalCommits: { + types: { + feat: { + changelog: { + hidden: true, + }, + }, + chore: { + semverBump: 'patch', + changelog: { + title: 'Custom Chore Title', + hidden: false, + }, + }, + customType: { + semverBump: 'major', + changelog: { + title: 'Custom Type Title', + }, + }, + customTypeWithDefaults: {}, + }, + }, + }); + + expect(res).toMatchInlineSnapshot(` + { + "error": null, + "nxReleaseConfig": { + "changelog": { + "automaticFromRef": false, + "git": { + "commit": true, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": false, + "tag": true, + "tagArgs": "", + "tagMessage": "", + }, + "projectChangelogs": false, + "workspaceChangelog": { + "createRelease": false, + "entryWhenNoChanges": "This was a version bump only, there were no code changes.", + "file": "{workspaceRoot}/CHANGELOG.md", + "renderOptions": { + "authors": true, + "commitReferences": true, + "versionTitleDate": true, + }, + "renderer": "nx/release/changelog-renderer", + }, + }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": false, + "title": "Custom Chore Title", + }, + "semverBump": "patch", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "customType": { + "changelog": { + "hidden": false, + "title": "Custom Type Title", + }, + "semverBump": "major", + }, + "customTypeWithDefaults": { + "changelog": { + "hidden": false, + "title": "customTypeWithDefaults", + }, + "semverBump": "patch", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": true, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, + "git": { + "commit": false, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": false, + "tag": false, + "tagArgs": "", + "tagMessage": "", + }, + "groups": { + "__default__": { + "changelog": false, + "projects": [ + "lib-a", + "lib-b", + "nx", + ], + "projectsRelationship": "fixed", + "releaseTagPattern": "v{version}", + "version": { + "conventionalCommits": false, + "generator": "@nx/js:release-version", + "generatorOptions": {}, + }, + }, + }, + "projectsRelationship": "fixed", + "releaseTagPattern": "v{version}", + "version": { + "conventionalCommits": false, + "generator": "@nx/js:release-version", + "generatorOptions": {}, + "git": { + "commit": false, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": true, + "tag": false, + "tagArgs": "", + "tagMessage": "", + }, + }, + }, + } + `); + }); + + it('should parse shorthand for disabling a commit type', async () => { + const res = await createNxReleaseConfig(projectGraph, { + conventionalCommits: { + types: { + feat: false, + customType: false, + }, + }, + }); + + expect(res).toMatchInlineSnapshot(` + { + "error": null, + "nxReleaseConfig": { + "changelog": { + "automaticFromRef": false, + "git": { + "commit": true, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": false, + "tag": true, + "tagArgs": "", + "tagMessage": "", + }, + "projectChangelogs": false, + "workspaceChangelog": { + "createRelease": false, + "entryWhenNoChanges": "This was a version bump only, there were no code changes.", + "file": "{workspaceRoot}/CHANGELOG.md", + "renderOptions": { + "authors": true, + "commitReferences": true, + "versionTitleDate": true, + }, + "renderer": "nx/release/changelog-renderer", + }, + }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "customType": { + "changelog": { + "hidden": true, + "title": "customType", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": true, + "title": "🚀 Features", + }, + "semverBump": "none", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, + "git": { + "commit": false, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": false, + "tag": false, + "tagArgs": "", + "tagMessage": "", + }, + "groups": { + "__default__": { + "changelog": false, + "projects": [ + "lib-a", + "lib-b", + "nx", + ], + "projectsRelationship": "fixed", + "releaseTagPattern": "v{version}", + "version": { + "conventionalCommits": false, + "generator": "@nx/js:release-version", + "generatorOptions": {}, + }, + }, + }, + "projectsRelationship": "fixed", + "releaseTagPattern": "v{version}", + "version": { + "conventionalCommits": false, + "generator": "@nx/js:release-version", + "generatorOptions": {}, + "git": { + "commit": false, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": true, + "tag": false, + "tagArgs": "", + "tagMessage": "", + }, + }, + }, + } + `); + }); + + it('should parse shorthand for disabling changelog appearance for a commit type', async () => { + const res = await createNxReleaseConfig(projectGraph, { + conventionalCommits: { + types: { + fix: { + changelog: false, + }, + customType: { + changelog: false, + }, + }, + }, + }); + + expect(res).toMatchInlineSnapshot(` + { + "error": null, + "nxReleaseConfig": { + "changelog": { + "automaticFromRef": false, + "git": { + "commit": true, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": false, + "tag": true, + "tagArgs": "", + "tagMessage": "", + }, + "projectChangelogs": false, + "workspaceChangelog": { + "createRelease": false, + "entryWhenNoChanges": "This was a version bump only, there were no code changes.", + "file": "{workspaceRoot}/CHANGELOG.md", + "renderOptions": { + "authors": true, + "commitReferences": true, + "versionTitleDate": true, + }, + "renderer": "nx/release/changelog-renderer", + }, + }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "customType": { + "changelog": { + "hidden": true, + "title": "customType", + }, + "semverBump": "patch", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": true, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, }, }, "git": { @@ -1893,6 +4734,101 @@ describe('createNxReleaseConfig()', () => { }, "workspaceChangelog": false, }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, "git": { "commit": false, "commitArgs": "", @@ -2041,6 +4977,101 @@ describe('createNxReleaseConfig()', () => { "renderer": "nx/release/changelog-renderer", }, }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, "git": { "commit": false, "commitArgs": "", @@ -2325,6 +5356,101 @@ describe('createNxReleaseConfig()', () => { "projectChangelogs": false, "workspaceChangelog": false, }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, "git": { "commit": false, "commitArgs": "", @@ -2408,6 +5534,101 @@ describe('createNxReleaseConfig()', () => { "projectChangelogs": false, "workspaceChangelog": false, }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, "git": { "commit": false, "commitArgs": "", @@ -2493,6 +5714,101 @@ describe('createNxReleaseConfig()', () => { "renderer": "nx/release/changelog-renderer", }, }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, "git": { "commit": false, "commitArgs": "", @@ -2581,6 +5897,101 @@ describe('createNxReleaseConfig()', () => { "renderer": "nx/release/changelog-renderer", }, }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, "git": { "commit": false, "commitArgs": "", @@ -2668,6 +6079,101 @@ describe('createNxReleaseConfig()', () => { "renderer": "nx/release/changelog-renderer", }, }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, "git": { "commit": false, "commitArgs": "", @@ -2763,6 +6269,101 @@ describe('createNxReleaseConfig()', () => { "renderer": "nx/release/changelog-renderer", }, }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, "git": { "commit": false, "commitArgs": "", @@ -2848,6 +6449,101 @@ describe('createNxReleaseConfig()', () => { "renderer": "nx/release/changelog-renderer", }, }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, "git": { "commit": false, "commitArgs": "", diff --git a/packages/nx/src/command-line/release/config/config.ts b/packages/nx/src/command-line/release/config/config.ts index 64dd16738e24c..3d23f15768dbd 100644 --- a/packages/nx/src/command-line/release/config/config.ts +++ b/packages/nx/src/command-line/release/config/config.ts @@ -15,6 +15,7 @@ import { NxJsonConfiguration } from '../../../config/nx-json'; import { output, type ProjectGraph } from '../../../devkit-exports'; import { findMatchingProjects } from '../../../utils/find-matching-projects'; import { resolveNxJsonConfigErrorMessage } from '../utils/resolve-nx-json-error-message'; +import { DEFAULT_CONVENTIONAL_COMMITS_CONFIG } from './conventional-commits'; type DeepRequired = Required<{ [K in keyof T]: T[K] extends Required ? T[K] : DeepRequired; @@ -34,6 +35,14 @@ type RemoveTrueFromPropertiesOnEach = { [U in keyof T]: RemoveTrueFromProperties; }; +type RemoveFalseFromType = T extends false ? never : T; +type RemoveFalseFromProperties = { + [P in keyof T]: P extends K ? RemoveFalseFromType : T[P]; +}; +type RemoveFalseFromPropertiesOnEach = { + [U in keyof T]: RemoveFalseFromProperties; +}; + export const IMPLICIT_DEFAULT_RELEASE_GROUP = '__default__'; /** @@ -59,6 +68,20 @@ export type NxReleaseConfig = Omit< DeepRequired, 'workspaceChangelog' | 'projectChangelogs' >; + // Remove the false shorthand from the conventionalCommits config types, it will be normalized to a semver bump of "none" and to be hidden on the changelog + conventionalCommits: { + types: RemoveFalseFromPropertiesOnEach< + DeepRequired< + RemoveFalseFromProperties< + DeepRequired< + NxJsonConfiguration['release']['conventionalCommits']['types'] + >, + string + > + >, + 'changelog' + >; + }; } >, // projects is just a shorthand for the default group's projects configuration, it does not exist in the final config @@ -203,6 +226,7 @@ export async function createNxReleaseConfig( (workspaceProjectsRelationship === 'independent' ? defaultIndependentReleaseTagPattern : defaultFixedReleaseTagPattern), + conventionalCommits: DEFAULT_CONVENTIONAL_COMMITS_CONFIG, }; const groupProjectsRelationship = @@ -279,6 +303,16 @@ export async function createNxReleaseConfig( > ); + const rootConventionalCommitsConfig: NxReleaseConfig['conventionalCommits'] = + fillUnspecifiedConventionalCommitsProperties( + deepMergeDefaults( + [WORKSPACE_DEFAULTS.conventionalCommits], + normalizeConventionalCommitsConfig( + userConfig.conventionalCommits + ) as NxReleaseConfig['conventionalCommits'] + ) + ); + // git configuration is not supported at the group level, only the root/command level const rootVersionWithoutGit = { ...rootVersionConfig }; delete rootVersionWithoutGit.git; @@ -463,6 +497,7 @@ export async function createNxReleaseConfig( version: rootVersionConfig, changelog: rootChangelogConfig, groups: releaseGroups, + conventionalCommits: rootConventionalCommitsConfig, }, }; } @@ -476,6 +511,69 @@ function normalizeTrueToEmptyObject(value: T | boolean): T | {} { return value === true ? {} : value; } +function normalizeConventionalCommitsConfig( + userConventionalCommitsConfig: NxJsonConfiguration['release']['conventionalCommits'] +): NxJsonConfiguration['release']['conventionalCommits'] { + if (!userConventionalCommitsConfig || !userConventionalCommitsConfig.types) { + return userConventionalCommitsConfig; + } + + const types: NxJsonConfiguration['release']['conventionalCommits']['types'] = + {}; + for (const [t, typeConfig] of Object.entries( + userConventionalCommitsConfig.types + )) { + if (typeConfig === false) { + types[t] = { + semverBump: 'none', + changelog: { + hidden: true, + }, + }; + continue; + } + if (typeConfig.changelog === false) { + types[t] = { + ...typeConfig, + changelog: { + hidden: true, + }, + }; + continue; + } + + types[t] = typeConfig; + } + + return { + ...userConventionalCommitsConfig, + types, + }; +} + +/** + * New, custom types specified by users will not be given the appropriate + * defaults with `deepMergeDefaults`, so we need to fill in the gaps here. + */ +function fillUnspecifiedConventionalCommitsProperties( + config: NxReleaseConfig['conventionalCommits'] +) { + const types: NxReleaseConfig['conventionalCommits']['types'] = {}; + for (const [t, typeConfig] of Object.entries(config.types)) { + types[t] = { + semverBump: typeConfig.semverBump || 'patch', + changelog: { + hidden: typeConfig.changelog?.hidden || false, + title: typeConfig.changelog?.title || t, + }, + }; + } + return { + ...config, + types, + }; +} + export async function handleNxReleaseConfigError( error: CreateNxReleaseConfigError ): Promise { diff --git a/packages/nx/src/command-line/release/config/conventional-commits.ts b/packages/nx/src/command-line/release/config/conventional-commits.ts new file mode 100644 index 0000000000000..c3d5941459adf --- /dev/null +++ b/packages/nx/src/command-line/release/config/conventional-commits.ts @@ -0,0 +1,98 @@ +import { NxReleaseConfig } from './config'; + +export const DEFAULT_CONVENTIONAL_COMMITS_CONFIG: NxReleaseConfig['conventionalCommits'] = + { + types: { + feat: { + semverBump: 'minor', + changelog: { + title: '🚀 Features', + hidden: false, + }, + }, + fix: { + semverBump: 'patch', + changelog: { + title: '🩹 Fixes', + hidden: false, + }, + }, + perf: { + semverBump: 'none', + changelog: { + title: '🔥 Performance', + hidden: false, + }, + }, + refactor: { + semverBump: 'none', + changelog: { + title: '💅 Refactors', + hidden: true, + }, + }, + docs: { + semverBump: 'none', + changelog: { + title: '📖 Documentation', + hidden: true, + }, + }, + build: { + semverBump: 'none', + changelog: { + title: '📦 Build', + hidden: true, + }, + }, + types: { + semverBump: 'none', + changelog: { + title: '🌊 Types', + hidden: true, + }, + }, + chore: { + semverBump: 'none', + changelog: { + title: '🏡 Chore', + hidden: true, + }, + }, + examples: { + semverBump: 'none', + changelog: { + title: '🏀 Examples', + hidden: true, + }, + }, + test: { + semverBump: 'none', + changelog: { + title: '✅ Tests', + hidden: true, + }, + }, + style: { + semverBump: 'none', + changelog: { + title: '🎨 Styles', + hidden: true, + }, + }, + ci: { + semverBump: 'none', + changelog: { + title: '🤖 CI', + hidden: true, + }, + }, + revert: { + semverBump: 'none', + changelog: { + title: '⏪ Revert', + hidden: true, + }, + }, + }, + }; diff --git a/packages/nx/src/command-line/release/utils/resolve-semver-specifier.ts b/packages/nx/src/command-line/release/utils/resolve-semver-specifier.ts index 946cca4f45be3..84e8ba28e27ca 100644 --- a/packages/nx/src/command-line/release/utils/resolve-semver-specifier.ts +++ b/packages/nx/src/command-line/release/utils/resolve-semver-specifier.ts @@ -1,27 +1,16 @@ import { prompt } from 'enquirer'; import { RELEASE_TYPES, valid } from 'semver'; import { ProjectGraph } from '../../../config/project-graph'; -import { createFileMapUsingProjectGraph } from '../../../project-graph/file-map-utils'; +import { NxReleaseConfig } from '../config/config'; import { getGitDiff, parseCommits } from './git'; -import { ConventionalCommitsConfig, determineSemverChange } from './semver'; +import { determineSemverChange } from './semver'; import { getCommitsRelevantToProjects } from './shared'; -// TODO: Extract config to nx.json configuration when adding changelog customization -const CONVENTIONAL_COMMITS_CONFIG: ConventionalCommitsConfig = { - types: { - feat: { - semver: 'minor', - }, - fix: { - semver: 'patch', - }, - }, -}; - export async function resolveSemverSpecifierFromConventionalCommits( from: string, projectGraph: ProjectGraph, - projectNames: string[] + projectNames: string[], + conventionalCommitsConfig: NxReleaseConfig['conventionalCommits'] ): Promise { const commits = await getGitDiff(from); const parsedCommits = parseCommits(commits); @@ -30,7 +19,7 @@ export async function resolveSemverSpecifierFromConventionalCommits( parsedCommits, projectNames ); - return determineSemverChange(relevantCommits, CONVENTIONAL_COMMITS_CONFIG); + return determineSemverChange(relevantCommits, conventionalCommitsConfig); } export async function resolveSemverSpecifierFromPrompt( diff --git a/packages/nx/src/command-line/release/utils/semver.ts b/packages/nx/src/command-line/release/utils/semver.ts index ffd86d9ad530c..eab81e82d2f8e 100644 --- a/packages/nx/src/command-line/release/utils/semver.ts +++ b/packages/nx/src/command-line/release/utils/semver.ts @@ -4,6 +4,7 @@ */ import { RELEASE_TYPES, ReleaseType, inc, valid } from 'semver'; +import { NxReleaseConfig } from '../config/config'; import { GitCommit } from './git'; export function isRelativeVersionKeyword(val: string): val is ReleaseType { @@ -16,28 +17,22 @@ export function isValidSemverSpecifier(specifier: string): boolean { ); } -export interface ConventionalCommitsConfig { - types: { - [type: string]: { - semver: 'patch' | 'minor' | 'major'; - }; - }; -} - // https://github.com/unjs/changelogen/blob/main/src/semver.ts export function determineSemverChange( commits: GitCommit[], - config: ConventionalCommitsConfig + config: NxReleaseConfig['conventionalCommits'] ): 'patch' | 'minor' | 'major' | null { let [hasMajor, hasMinor, hasPatch] = [false, false, false]; for (const commit of commits) { - const semverType = config.types[commit.type]?.semver; + const semverType = config.types[commit.type]?.semverBump; if (semverType === 'major' || commit.isBreaking) { hasMajor = true; } else if (semverType === 'minor') { hasMinor = true; } else if (semverType === 'patch') { hasPatch = true; + } else if (semverType === 'none' || !semverType) { + // do not report a change } } diff --git a/packages/nx/src/command-line/release/version.ts b/packages/nx/src/command-line/release/version.ts index d0fcc53ce5a3a..35e98a00b4284 100644 --- a/packages/nx/src/command-line/release/version.ts +++ b/packages/nx/src/command-line/release/version.ts @@ -23,6 +23,7 @@ import { parseGeneratorString } from '../generate/generate'; import { getGeneratorInformation } from '../generate/generator-utils'; import { VersionOptions } from './command-object'; import { + NxReleaseConfig, createNxReleaseConfig, handleNxReleaseConfigError, } from './config/config'; @@ -67,6 +68,7 @@ export interface ReleaseVersionGeneratorSchema { firstRelease?: boolean; // auto means the existing prefix will be preserved, and is the default behavior versionPrefix?: typeof validReleaseVersionPrefixes[number]; + conventionalCommitsConfig?: NxReleaseConfig['conventionalCommits']; } export interface NxReleaseVersionResult { @@ -199,7 +201,8 @@ export async function releaseVersion( generatorData, projectNames, releaseGroup, - versionData + versionData, + nxReleaseConfig.conventionalCommits ); // Capture the callback so that we can run it after flushing the changes to disk generatorCallbacks.push(async () => { @@ -326,7 +329,8 @@ export async function releaseVersion( generatorData, projectNames, releaseGroup, - versionData + versionData, + nxReleaseConfig.conventionalCommits ); // Capture the callback so that we can run it after flushing the changes to disk generatorCallbacks.push(async () => { @@ -447,7 +451,8 @@ async function runVersionOnProjects( generatorData: GeneratorData, projectNames: string[], releaseGroup: ReleaseGroupWithName, - versionData: VersionData + versionData: VersionData, + conventionalCommitsConfig: NxReleaseConfig['conventionalCommits'] ): Promise { const generatorOptions: ReleaseVersionGeneratorSchema = { // Always ensure a string to avoid generator schema validation errors @@ -459,6 +464,7 @@ async function runVersionOnProjects( projectGraph, releaseGroup, firstRelease: args.firstRelease ?? false, + conventionalCommitsConfig, }; // Apply generator defaults from schema.json file etc diff --git a/packages/nx/src/config/nx-json.ts b/packages/nx/src/config/nx-json.ts index cd72363bfea5c..0755430cd005e 100644 --- a/packages/nx/src/config/nx-json.ts +++ b/packages/nx/src/config/nx-json.ts @@ -143,6 +143,31 @@ export interface NxReleaseGitConfiguration { tagArgs?: string; } +export interface NxReleaseConventionalCommitsConfiguration { + types?: Record< + string, + /** + * Optionally override the title and visibility of the changelog section for this type. If set to false, the section will be hidden and the semver bump will be "none". + */ + | { + /** + * The semver bump to apply when a commit of this type is found. If set to "none", the commit will be ignored for versioning purposes. + */ + semverBump?: 'patch' | 'minor' | 'major' | 'none'; + /** + * Optionally override the title and visibility of the changelog section for this type. If set to false, the section will be hidden. + */ + changelog?: + | { + title?: string; + hidden?: boolean; + } + | false; + } + | false + >; +} + interface NxReleaseConfiguration { /** * Shorthand for amending the projects which will be included in the implicit default release group (all projects by default). @@ -248,6 +273,7 @@ interface NxReleaseConfiguration { * Enable and configure automatic git operations as part of the release */ git?: NxReleaseGitConfiguration; + conventionalCommits?: NxReleaseConventionalCommitsConfiguration; } /** From 8eaf11b00438d122df0d717ea4d6326297c42b68 Mon Sep 17 00:00:00 2001 From: Austin Fahsl Date: Mon, 26 Feb 2024 14:58:51 -0700 Subject: [PATCH 02/10] chore(release): update nx-schema --- packages/nx/schemas/nx-schema.json | 52 ++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/packages/nx/schemas/nx-schema.json b/packages/nx/schemas/nx-schema.json index ea32715b88ee1..30805b7f824ed 100644 --- a/packages/nx/schemas/nx-schema.json +++ b/packages/nx/schemas/nx-schema.json @@ -212,6 +212,9 @@ } } }, + "conventionalCommits": { + "$ref": "#/definitions/NxReleaseConventionalCommitsConfiguration" + }, "projectsRelationship": { "type": "string", "enum": ["fixed", "independent"] @@ -623,6 +626,55 @@ "ChangelogRenderOptions": { "type": "object", "additionalProperties": true + }, + "NxReleaseConventionalCommitsConfiguration": { + "type": "object", + "properties": { + "types": { + "type": "object", + "description": "A map of commit types to their configuration. If a type is set to 'false', then it will be hidden from changelogs and will not trigger a version bump.", + "additionalProperties": { + "oneOf": [ + { + "type": "boolean", + "enum": [false] + }, + { + "type": "object", + "properties": { + "semverBump": { + "type": "string", + "enum": ["major", "minor", "patch", "none"], + "description": "The semver bump to apply to the version of the project(s) when a commit of this type is included in the release." + }, + "changelog": { + "description": "Configuration for the changelog section for commits of this type. If set to 'false', then commits of this type will not be included in the changelog.", + "oneOf": [ + { + "type": "boolean", + "enum": [false] + }, + { + "type": "object", + "properties": { + "title": { + "type": "string", + "description": "The title of the section in the changelog for commits of this type" + }, + "hidden": { + "type": "boolean", + "description": "Whether or not to include commits of this type in the changelog" + } + } + } + ] + } + } + } + ] + } + } + } } } } From 1a73168404dfe9bae911bf10794cf9708243a9ef Mon Sep 17 00:00:00 2001 From: Austin Fahsl Date: Mon, 26 Feb 2024 16:11:46 -0700 Subject: [PATCH 03/10] fix(release): reorder filling unspecified props --- .../src/conventional-commits-config.test.ts | 127 ++++++++++++------ .../src/command-line/release/config/config.ts | 12 +- 2 files changed, 94 insertions(+), 45 deletions(-) diff --git a/e2e/release/src/conventional-commits-config.test.ts b/e2e/release/src/conventional-commits-config.test.ts index 6a730dad9f26c..da77461bb2414 100644 --- a/e2e/release/src/conventional-commits-config.test.ts +++ b/e2e/release/src/conventional-commits-config.test.ts @@ -2,6 +2,7 @@ import { NxJsonConfiguration } from '@nx/devkit'; import { cleanupProject, newProject, + readFile, runCLI, runCommandAsync, uniq, @@ -44,6 +45,7 @@ describe('nx release conventional commits config', () => { let pkg2: string; let pkg3: string; let pkg4: string; + let pkg5: string; beforeAll(async () => { newProject({ @@ -63,6 +65,9 @@ describe('nx release conventional commits config', () => { pkg4 = uniq('my-pkg-4'); runCLI(`generate @nx/workspace:npm-package ${pkg4}`); + pkg5 = uniq('my-pkg-5'); + runCLI(`generate @nx/workspace:npm-package ${pkg5}`); + // Update pkg2 to depend on pkg1 updateJson(`${pkg2}/package.json`, (json) => { json.dependencies ??= {}; @@ -84,6 +89,7 @@ describe('nx release conventional commits config', () => { await runCommandAsync(`git tag -a ${pkg2}@0.0.1 -m "${pkg2}@0.0.1"`); await runCommandAsync(`git tag -a ${pkg3}@0.0.1 -m "${pkg3}@0.0.1"`); await runCommandAsync(`git tag -a ${pkg4}@0.0.1 -m "${pkg4}@0.0.1"`); + await runCommandAsync(`git tag -a ${pkg5}@0.0.1 -m "${pkg5}@0.0.1"`); }, 60000); afterAll(() => cleanupProject()); @@ -123,6 +129,8 @@ describe('nx release conventional commits config', () => { // is a shortcut for setting "changelog.hidden" to false. changelog: false, }, + // unspecified semverBump will default to "patch" + perf: {}, }, }, }; @@ -151,6 +159,9 @@ describe('nx release conventional commits config', () => { expect(versionResultNoChanges).toContain( `${pkg4} 🚫 Skipping versioning "@proj/${pkg4}" as no changes were detected.` ); + expect(versionResultNoChanges).toContain( + `${pkg5} 🚫 Skipping versioning "@proj/${pkg5}" as no changes were detected.` + ); // update my-pkg-3 with a fix commit updateJson(`${pkg3}/package.json`, (json) => ({ @@ -171,9 +182,12 @@ describe('nx release conventional commits config', () => { expect(versionResultDocsChanges).toContain( `${pkg3} ✍️ New version 0.0.2 written to ${pkg3}/package.json` ); - expect(versionResultNoChanges).toContain( + expect(versionResultDocsChanges).toContain( `${pkg4} 🚫 Skipping versioning "@proj/${pkg4}" as no changes were detected.` ); + expect(versionResultDocsChanges).toContain( + `${pkg5} 🚫 Skipping versioning "@proj/${pkg5}" as no changes were detected.` + ); // update my-pkg-2 with a fix commit updateJson(`${pkg2}/package.json`, (json) => ({ @@ -195,9 +209,12 @@ describe('nx release conventional commits config', () => { expect(versionResultCustomTypeChanges).toContain( `${pkg3} ✍️ New version 0.0.2 written to ${pkg3}/package.json` ); - expect(versionResultNoChanges).toContain( + expect(versionResultCustomTypeChanges).toContain( `${pkg4} 🚫 Skipping versioning "@proj/${pkg4}" as no changes were detected.` ); + expect(versionResultCustomTypeChanges).toContain( + `${pkg5} 🚫 Skipping versioning "@proj/${pkg5}" as no changes were detected.` + ); updateJson(`${pkg1}/package.json`, (json) => ({ ...json, @@ -218,9 +235,12 @@ describe('nx release conventional commits config', () => { expect(versionResultCustomTypeBreakingChanges).toContain( `${pkg3} ✍️ New version 0.0.2 written to ${pkg3}/package.json` ); - expect(versionResultNoChanges).toContain( + expect(versionResultCustomTypeBreakingChanges).toContain( `${pkg4} 🚫 Skipping versioning "@proj/${pkg4}" as no changes were detected.` ); + expect(versionResultCustomTypeBreakingChanges).toContain( + `${pkg5} 🚫 Skipping versioning "@proj/${pkg5}" as no changes were detected.` + ); updateJson(`${pkg4}/package.json`, (json) => ({ ...json, @@ -239,72 +259,97 @@ describe('nx release conventional commits config', () => { expect(versionResultChoreChanges).toContain( `${pkg3} ✍️ New version 0.0.2 written to ${pkg3}/package.json` ); - expect(versionResultCustomTypeBreakingChanges).toContain( + expect(versionResultChoreChanges).toContain( + `${pkg4} ✍️ New version 0.0.2 written to ${pkg4}/package.json` + ); + expect(versionResultChoreChanges).toContain( + `${pkg5} 🚫 Skipping versioning "@proj/${pkg5}" as no changes were detected.` + ); + + updateJson(`${pkg5}/package.json`, (json) => ({ + ...json, + license: 'MIT', + })); + await runCommandAsync(`git add ${pkg5}/package.json`); + await runCommandAsync( + `git commit -m "perf: this is a performance improvement"` + ); + + const versionResultPerfChanges = runCLI(`release version -d`); + expect(versionResultPerfChanges).toContain( + `${pkg1} ✍️ New version 1.0.0 written to ${pkg1}/package.json` + ); + expect(versionResultPerfChanges).toContain( + `${pkg2} ✍️ New version 0.1.0 written to ${pkg2}/package.json` + ); + expect(versionResultPerfChanges).toContain( `${pkg3} ✍️ New version 0.0.2 written to ${pkg3}/package.json` ); + expect(versionResultPerfChanges).toContain( + `${pkg4} ✍️ New version 0.0.2 written to ${pkg4}/package.json` + ); + expect(versionResultPerfChanges).toContain( + `${pkg5} ✍️ New version 0.0.2 written to ${pkg5}/package.json` + ); // Normally, users would use `nx release` or the programmatic api to ensure that // changelogs are generated for the above version bumps, but for the sake of this // test, we just want to ensure that each commit is included/excluded as expected. // Therefore, any version number will work - in this case it's 1.0.0. - const changelogResult = runCLI(`release changelog 1.0.0 -d`); + runCLI(`release changelog 1.0.0`); - // NOTE: pkg4 should not have changes here, since its only commit is a chore. - // Chore commits are hidden from changelogs in the above config via `changelog: false`. - expect(changelogResult).toMatchInlineSnapshot(` + const pkg1Changelog = readFile(`${pkg1}/CHANGELOG.md`); + expect(pkg1Changelog).toMatchInlineSnapshot(` + # 1.0.0 (YYYY-MM-DD) - NX Previewing an entry in {project-name}/CHANGELOG.md for {project-name}@1.0.0 + ### Custom Type - + # 1.0.0 (YYYY-MM-DD) - + - + - + ### Custom Type - + - + - **{project-name}:** this is a custom type + - ⚠️ **{project-name}:** this is a breaking change - NX Previewing an entry in {project-name}/CHANGELOG.md for {project-name}@1.0.0 + #### ⚠️ Breaking Changes + - ⚠️ **{project-name}:** this is a breaking change + `); - + # 1.0.0 (YYYY-MM-DD) - + - + - + ### Custom Docs Header - + - + - this is a doc - + const pkg2Changelog = readFile(`${pkg2}/CHANGELOG.md`); + expect(pkg2Changelog).toMatchInlineSnapshot(` + # 1.0.0 (YYYY-MM-DD) - NX Previewing an entry in {project-name}/CHANGELOG.md for {project-name}@1.0.0 + ### Custom Type - + # 1.0.0 (YYYY-MM-DD) - + - + This was a version bump only for {project-name} to align it with other projects, there were no code changes. + - **{project-name}:** this is a custom type + `); + const pkg3Changelog = readFile(`${pkg3}/CHANGELOG.md`); + expect(pkg3Changelog).toMatchInlineSnapshot(` + # 1.0.0 (YYYY-MM-DD) - NX Previewing an entry in {project-name}/CHANGELOG.md for {project-name}@1.0.0 + ### Custom Docs Header - + # 1.0.0 (YYYY-MM-DD) - + - + - + ### Custom Type - + - + - ⚠️ **{project-name}:** this is a breaking change - + - + - + #### ⚠️ Breaking Changes - + - + - ⚠️ **{project-name}:** this is a breaking change + - this is a doc + `); + // NOTE: pkg4 should not have changes here, since its only commit is a chore. + // Chore commits are hidden from changelogs in the above config via `changelog: false`. + const pkg4Changelog = readFile(`${pkg4}/CHANGELOG.md`); + expect(pkg4Changelog).toMatchInlineSnapshot(` + # 1.0.0 (YYYY-MM-DD) - NX Committing changes with git + This was a version bump only for {project-name} to align it with other projects, there were no code changes. + `); + const pkg5Changelog = readFile(`${pkg5}/CHANGELOG.md`); + expect(pkg5Changelog).toMatchInlineSnapshot(` + # 1.0.0 (YYYY-MM-DD) - NX Tagging commit with git + ### 🔥 Performance + - this is a performance improvement `); }); }); diff --git a/packages/nx/src/command-line/release/config/config.ts b/packages/nx/src/command-line/release/config/config.ts index 3d23f15768dbd..40067ad3a9aa0 100644 --- a/packages/nx/src/command-line/release/config/config.ts +++ b/packages/nx/src/command-line/release/config/config.ts @@ -304,9 +304,9 @@ export async function createNxReleaseConfig( ); const rootConventionalCommitsConfig: NxReleaseConfig['conventionalCommits'] = - fillUnspecifiedConventionalCommitsProperties( - deepMergeDefaults( - [WORKSPACE_DEFAULTS.conventionalCommits], + deepMergeDefaults( + [WORKSPACE_DEFAULTS.conventionalCommits], + fillUnspecifiedConventionalCommitsProperties( normalizeConventionalCommitsConfig( userConfig.conventionalCommits ) as NxReleaseConfig['conventionalCommits'] @@ -564,7 +564,11 @@ function fillUnspecifiedConventionalCommitsProperties( semverBump: typeConfig.semverBump || 'patch', changelog: { hidden: typeConfig.changelog?.hidden || false, - title: typeConfig.changelog?.title || t, + title: + typeConfig.changelog?.title || + // our default title is better than just the unmodified type name + DEFAULT_CONVENTIONAL_COMMITS_CONFIG.types[t]?.changelog.title || + t, }, }; } From dc51bf2917b1a989360b7a85b722ed6c5182d13e Mon Sep 17 00:00:00 2001 From: Austin Fahsl Date: Mon, 26 Feb 2024 16:30:41 -0700 Subject: [PATCH 04/10] fix(release): preserve defaults if they exist --- .../release/changelog-renderer/index.spec.ts | 10 ++++++ .../src/command-line/release/config/config.ts | 33 +++++++++++++++---- .../config/filter-release-groups.spec.ts | 2 ++ .../command-line/release/utils/semver.spec.ts | 19 ++++++----- 4 files changed, 48 insertions(+), 16 deletions(-) diff --git a/packages/nx/release/changelog-renderer/index.spec.ts b/packages/nx/release/changelog-renderer/index.spec.ts index 224735c303b25..04acbf7350868 100644 --- a/packages/nx/release/changelog-renderer/index.spec.ts +++ b/packages/nx/release/changelog-renderer/index.spec.ts @@ -1,3 +1,4 @@ +import { DEFAULT_CONVENTIONAL_COMMITS_CONFIG } from '../../src/command-line/release/config/conventional-commits'; import type { GitCommit } from '../../src/command-line/release/utils/git'; import defaultChangelogRenderer from './index'; @@ -180,6 +181,7 @@ describe('defaultChangelogRenderer()', () => { changelogRenderOptions: { authors: true, }, + conventionalCommitsConfig: DEFAULT_CONVENTIONAL_COMMITS_CONFIG, }); expect(markdown).toMatchInlineSnapshot(` "## v1.1.0 @@ -213,6 +215,7 @@ describe('defaultChangelogRenderer()', () => { changelogRenderOptions: { authors: false, }, + conventionalCommitsConfig: DEFAULT_CONVENTIONAL_COMMITS_CONFIG, }); expect(markdown).toMatchInlineSnapshot(` "# v1.0.0 @@ -242,6 +245,7 @@ describe('defaultChangelogRenderer()', () => { changelogRenderOptions: { authors: true, }, + conventionalCommitsConfig: DEFAULT_CONVENTIONAL_COMMITS_CONFIG, }; expect( @@ -333,6 +337,7 @@ describe('defaultChangelogRenderer()', () => { changelogRenderOptions: { authors: true, }, + conventionalCommitsConfig: DEFAULT_CONVENTIONAL_COMMITS_CONFIG, }; expect( @@ -363,6 +368,7 @@ describe('defaultChangelogRenderer()', () => { changelogRenderOptions: { authors: true, }, + conventionalCommitsConfig: DEFAULT_CONVENTIONAL_COMMITS_CONFIG, }; expect( @@ -435,6 +441,7 @@ describe('defaultChangelogRenderer()', () => { changelogRenderOptions: { authors: true, }, + conventionalCommitsConfig: DEFAULT_CONVENTIONAL_COMMITS_CONFIG, }); expect(markdown).toMatchInlineSnapshot(` @@ -535,6 +542,7 @@ describe('defaultChangelogRenderer()', () => { changelogRenderOptions: { authors: true, }, + conventionalCommitsConfig: DEFAULT_CONVENTIONAL_COMMITS_CONFIG, }); expect(markdown).toMatchInlineSnapshot(`""`); @@ -580,6 +588,7 @@ describe('defaultChangelogRenderer()', () => { changelogRenderOptions: { authors: true, }, + conventionalCommitsConfig: DEFAULT_CONVENTIONAL_COMMITS_CONFIG, }); expect(markdown).toMatchInlineSnapshot(` @@ -641,6 +650,7 @@ describe('defaultChangelogRenderer()', () => { changelogRenderOptions: { authors: true, }, + conventionalCommitsConfig: DEFAULT_CONVENTIONAL_COMMITS_CONFIG, }); expect(markdown).toMatchInlineSnapshot(` diff --git a/packages/nx/src/command-line/release/config/config.ts b/packages/nx/src/command-line/release/config/config.ts index 40067ad3a9aa0..1676707780552 100644 --- a/packages/nx/src/command-line/release/config/config.ts +++ b/packages/nx/src/command-line/release/config/config.ts @@ -558,17 +558,36 @@ function normalizeConventionalCommitsConfig( function fillUnspecifiedConventionalCommitsProperties( config: NxReleaseConfig['conventionalCommits'] ) { + if (!config || !config.types) { + return config; + } const types: NxReleaseConfig['conventionalCommits']['types'] = {}; for (const [t, typeConfig] of Object.entries(config.types)) { + const defaultTypeConfig = DEFAULT_CONVENTIONAL_COMMITS_CONFIG.types[t]; + + const semverBump = + typeConfig.semverBump || + // preserve our default semver bump if it's not 'none' + // this prevents a 'feat' from becoming a 'patch' just + // because they modified the changelog config for 'feat' + (defaultTypeConfig?.semverBump !== 'none' && + defaultTypeConfig?.semverBump) || + 'patch'; + // don't preserve our default behavior for hidden, ever. + // we should assume that if users are explicitly enabling a + // type, then they intend it to be visible in the changelog + const hidden = typeConfig.changelog?.hidden || false; + const title = + typeConfig.changelog?.title || + // our default title is better than just the unmodified type name + defaultTypeConfig?.changelog.title || + t; + types[t] = { - semverBump: typeConfig.semverBump || 'patch', + semverBump, changelog: { - hidden: typeConfig.changelog?.hidden || false, - title: - typeConfig.changelog?.title || - // our default title is better than just the unmodified type name - DEFAULT_CONVENTIONAL_COMMITS_CONFIG.types[t]?.changelog.title || - t, + hidden, + title, }, }; } diff --git a/packages/nx/src/command-line/release/config/filter-release-groups.spec.ts b/packages/nx/src/command-line/release/config/filter-release-groups.spec.ts index cf6b842a31904..09be1d0c69d29 100644 --- a/packages/nx/src/command-line/release/config/filter-release-groups.spec.ts +++ b/packages/nx/src/command-line/release/config/filter-release-groups.spec.ts @@ -1,5 +1,6 @@ import { type ProjectGraph } from '../../../devkit-exports'; import { IMPLICIT_DEFAULT_RELEASE_GROUP, NxReleaseConfig } from './config'; +import { DEFAULT_CONVENTIONAL_COMMITS_CONFIG } from './conventional-commits'; import { filterReleaseGroups } from './filter-release-groups'; describe('filterReleaseGroups()', () => { @@ -48,6 +49,7 @@ describe('filterReleaseGroups()', () => { tagArgs: '', stageChanges: false, }, + conventionalCommits: DEFAULT_CONVENTIONAL_COMMITS_CONFIG, }; projectGraph = { nodes: { diff --git a/packages/nx/src/command-line/release/utils/semver.spec.ts b/packages/nx/src/command-line/release/utils/semver.spec.ts index a87781bf584c5..263cb1dbf9df6 100644 --- a/packages/nx/src/command-line/release/utils/semver.spec.ts +++ b/packages/nx/src/command-line/release/utils/semver.spec.ts @@ -1,9 +1,7 @@ +import { NxReleaseConfig } from '../config/config'; +import { DEFAULT_CONVENTIONAL_COMMITS_CONFIG } from '../config/conventional-commits'; import { GitCommit } from './git'; -import { - ConventionalCommitsConfig, - deriveNewSemverVersion, - determineSemverChange, -} from './semver'; +import { deriveNewSemverVersion, determineSemverChange } from './semver'; describe('semver', () => { describe('deriveNewSemverVersion()', () => { @@ -76,16 +74,19 @@ describe('semver', () => { }); // tests for determineSemverChange() describe('determineSemverChange()', () => { - const config: ConventionalCommitsConfig = { + const config: NxReleaseConfig['conventionalCommits'] = { types: { feat: { - semver: 'minor', + semverBump: 'minor', + changelog: DEFAULT_CONVENTIONAL_COMMITS_CONFIG.types.feat.changelog, }, fix: { - semver: 'patch', + semverBump: 'patch', + changelog: DEFAULT_CONVENTIONAL_COMMITS_CONFIG.types.fix.changelog, }, chore: { - semver: 'patch', + semverBump: 'patch', + changelog: DEFAULT_CONVENTIONAL_COMMITS_CONFIG.types.chore.changelog, }, }, }; From d5c68913b74d210be3c6b37e45c7c9dd4675b697 Mon Sep 17 00:00:00 2001 From: Austin Fahsl Date: Fri, 1 Mar 2024 10:23:42 -0700 Subject: [PATCH 05/10] chore(release): update code comment --- packages/nx/src/config/nx-json.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nx/src/config/nx-json.ts b/packages/nx/src/config/nx-json.ts index 0755430cd005e..fb36cca5d13be 100644 --- a/packages/nx/src/config/nx-json.ts +++ b/packages/nx/src/config/nx-json.ts @@ -147,7 +147,7 @@ export interface NxReleaseConventionalCommitsConfiguration { types?: Record< string, /** - * Optionally override the title and visibility of the changelog section for this type. If set to false, the section will be hidden and the semver bump will be "none". + * Optionally override the version and changelog for commit types. If set to false, commits of that type will be hidden in the changelog and will not trigger a version bump. */ | { /** From 31cfabf0afc843854c636362853051904c0fa0be Mon Sep 17 00:00:00 2001 From: Austin Fahsl Date: Fri, 1 Mar 2024 13:46:19 -0700 Subject: [PATCH 06/10] docs(release): add recipe for conventional commit type customization --- docs/generated/manifests/menus.json | 24 +++++ docs/generated/manifests/nx.json | 33 +++++++ docs/generated/manifests/tags.json | 7 ++ docs/map.json | 6 ++ ...cally-version-with-conventional-commits.md | 2 +- .../customize-conventional-commit-types.md | 92 +++++++++++++++++++ docs/shared/reference/sitemap.md | 1 + .../src/conventional-commits-config.test.ts | 2 +- 8 files changed, 165 insertions(+), 2 deletions(-) create mode 100644 docs/shared/recipes/nx-release/customize-conventional-commit-types.md diff --git a/docs/generated/manifests/menus.json b/docs/generated/manifests/menus.json index c1e5a6735e4ca..58e978a4f62bf 100644 --- a/docs/generated/manifests/menus.json +++ b/docs/generated/manifests/menus.json @@ -2315,6 +2315,14 @@ "isExternal": false, "children": [], "disableCollapsible": false + }, + { + "name": "Customize Conventional Commit Types", + "path": "/recipes/nx-release/customize-conventional-commit-types", + "id": "customize-conventional-commit-types", + "isExternal": false, + "children": [], + "disableCollapsible": false } ], "disableCollapsible": false @@ -4139,6 +4147,14 @@ "isExternal": false, "children": [], "disableCollapsible": false + }, + { + "name": "Customize Conventional Commit Types", + "path": "/recipes/nx-release/customize-conventional-commit-types", + "id": "customize-conventional-commit-types", + "isExternal": false, + "children": [], + "disableCollapsible": false } ], "disableCollapsible": false @@ -4183,6 +4199,14 @@ "children": [], "disableCollapsible": false }, + { + "name": "Customize Conventional Commit Types", + "path": "/recipes/nx-release/customize-conventional-commit-types", + "id": "customize-conventional-commit-types", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, { "name": "Other", "path": "/recipes/other", diff --git a/docs/generated/manifests/nx.json b/docs/generated/manifests/nx.json index ad6c972c629ba..9f23335f62a3d 100644 --- a/docs/generated/manifests/nx.json +++ b/docs/generated/manifests/nx.json @@ -3166,6 +3166,17 @@ "isExternal": false, "path": "/recipes/nx-release/automate-github-releases", "tags": ["nx-release"] + }, + { + "id": "customize-conventional-commit-types", + "name": "Customize Conventional Commit Types", + "description": "", + "mediaImage": "", + "file": "shared/recipes/nx-release/customize-conventional-commit-types", + "itemList": [], + "isExternal": false, + "path": "/recipes/nx-release/customize-conventional-commit-types", + "tags": ["nx-release"] } ], "isExternal": false, @@ -5667,6 +5678,17 @@ "isExternal": false, "path": "/recipes/nx-release/automate-github-releases", "tags": ["nx-release"] + }, + { + "id": "customize-conventional-commit-types", + "name": "Customize Conventional Commit Types", + "description": "", + "mediaImage": "", + "file": "shared/recipes/nx-release/customize-conventional-commit-types", + "itemList": [], + "isExternal": false, + "path": "/recipes/nx-release/customize-conventional-commit-types", + "tags": ["nx-release"] } ], "isExternal": false, @@ -5728,6 +5750,17 @@ "path": "/recipes/nx-release/automate-github-releases", "tags": ["nx-release"] }, + "/recipes/nx-release/customize-conventional-commit-types": { + "id": "customize-conventional-commit-types", + "name": "Customize Conventional Commit Types", + "description": "", + "mediaImage": "", + "file": "shared/recipes/nx-release/customize-conventional-commit-types", + "itemList": [], + "isExternal": false, + "path": "/recipes/nx-release/customize-conventional-commit-types", + "tags": ["nx-release"] + }, "/recipes/other": { "id": "other", "name": "Other", diff --git a/docs/generated/manifests/tags.json b/docs/generated/manifests/tags.json index 2c415b9d6273d..4e867a1b8c5d1 100644 --- a/docs/generated/manifests/tags.json +++ b/docs/generated/manifests/tags.json @@ -1015,6 +1015,13 @@ "id": "automate-github-releases", "name": "Automate GitHub Releases", "path": "/recipes/nx-release/automate-github-releases" + }, + { + "description": "", + "file": "shared/recipes/nx-release/customize-conventional-commit-types", + "id": "customize-conventional-commit-types", + "name": "Customize Conventional Commit Types", + "path": "/recipes/nx-release/customize-conventional-commit-types" } ], "database": [ diff --git a/docs/map.json b/docs/map.json index 238e1620538ae..fb8964c0b9db1 100644 --- a/docs/map.json +++ b/docs/map.json @@ -1141,6 +1141,12 @@ "id": "automate-github-releases", "tags": ["nx-release"], "file": "shared/recipes/nx-release/automate-github-releases" + }, + { + "name": "Customize Conventional Commit Types", + "id": "customize-conventional-commit-types", + "tags": ["nx-release"], + "file": "shared/recipes/nx-release/customize-conventional-commit-types" } ] }, diff --git a/docs/shared/recipes/nx-release/automatically-version-with-conventional-commits.md b/docs/shared/recipes/nx-release/automatically-version-with-conventional-commits.md index 8c0205343a54d..254836365b03b 100644 --- a/docs/shared/recipes/nx-release/automatically-version-with-conventional-commits.md +++ b/docs/shared/recipes/nx-release/automatically-version-with-conventional-commits.md @@ -32,7 +32,7 @@ For example, if the git history looks like this: - chore(release): 1.0.0 ``` -then Nx Release will select the `minor` version bump and elect to release version 1.1.0. This is because there is a `feat` commit since the last release of 1.0.0. +then Nx Release will select the `minor` version bump and elect to release version 1.1.0. This is because there is a `feat` commit since the last release of 1.0.0. To customize the version bump for different types of commits, or to trigger a version bump with custom commit types, see the [Customize Conventional Commit Types](/recipes/nx-release/customize-conventional-commit-types) recipe. {% callout type="info" title="No changes detected" %} If Nx Release does not find any relevant commits since the last release, it will skip releasing a new version. This works with [independent releases](/recipes/nx-release/release-projects-independently) as well, allowing for only some projects to be released and some to be skipped. diff --git a/docs/shared/recipes/nx-release/customize-conventional-commit-types.md b/docs/shared/recipes/nx-release/customize-conventional-commit-types.md new file mode 100644 index 0000000000000..a2400db31e9e2 --- /dev/null +++ b/docs/shared/recipes/nx-release/customize-conventional-commit-types.md @@ -0,0 +1,92 @@ +# Customize Conventional Commit Types + +Nx Release can defer to the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) standard to automatically determine the next version to release. To enable this behavior for versioning, see [Automatically Version with Conventional Commits](/recipes/nx-release/automatically-version-with-conventional-commits). + +This recipe will cover how to customize the types of commits that trigger version bumps, how to customize the version bump for each type, and how to customize the changelog entry for each commit type. + +## Conventional Commits Usage within Nx Release + +The conventional commits configuration is used in two different places within Nx Release - once in the version step for determining the version bump, and once when generating changelogs. + +### Determine the Version Bump + +When `release.version.conventionalCommits` is `true` in `nx.json`, Nx Release will use the commit messages since the last release to determine the version bump. It will look at the type of each commit and determine the highest version bump from the following list: + +- 'feat' -> minor +- 'fix' -> patch + +For example, if the git history looks like this: + +``` + - fix(pkg-1): fix something + - feat(pkg-2): add a new feature + - chore(pkg-3): update docs + - chore(release): 1.0.0 +``` + +then Nx Release will select the `minor` version bump and elect to release version 1.1.0. This is because there is a `feat` commit since the last release of 1.0.0. To customize the version bump for different types of commits, or to trigger a version bump with custom commit types, see the [Configure Commit Types](#configure-commit-types) section below. + +{% callout type="info" title="No changes detected" %} +If Nx Release does not find any relevant commits since the last release, it will skip releasing a new version. This works with [independent releases](/recipes/nx-release/release-projects-independently) as well, allowing for only some projects to be released and some to be skipped. +{% /callout %} + +### Generate Changelog Sections + +Nx Release sorts changes within changelogs into sections based on the type of commit. By default, `fix`, `feat`, and `perf` commits will be included in the changelog. To customize the headers of changelog sections, include other commit types, or exclude the default commit types, see the [Configure Commit Types](#configure-commit-types) section below. + +See the [Nx repo](https://github.com/nrwl/nx/releases) for examples of a changelogs generated with Nx Release. + +## Configure Commit Types + +Commit types are configured in the `release.conventionalCommits.types` property in `nx.json`: + +```json nx.json +{ + "release": { + "conventionalCommits": { + "types": { + // disable the fix type for versioning and in the changelog + "fix": false, + "docs": { + "semverBump": "patch", + "changelog": { + "hidden": false, + "title": "Documentation Changes" + } + }, + "perf": { + "semverBump": "none", + // omitting "hidden" will default it to false + "changelog": { + "title": "Performance Improvements" + } + }, + "deps": { + "semverBump": "minor", + // omitting "hidden" will default it to false + "changelog": { + "title": "Dependency Updates" + } + }, + // unspecified semverBump will default to "patch" + "chore": { + // "changelog.hidden" defaults to true, but setting changelog: false + // is a shortcut for setting "changelog.hidden" to false. + "changelog": false + }, + // unspecified semverBump will default to "patch" + "styles": {} + } + } + } +} +``` + +In this example, the following types are configured: + +- The `fix` type has been fully disabled, so `fix` commits will not trigger a version bump and will not be included in the changelog. +- The `docs` type will now trigger a `patch` version bump and will have the "Documentation Changes" title in the changelog. +- The `perf` type will NOT trigger a version bump and will have the "Performance Improvements" title in the changelog. +- The `deps` type will trigger a `minor` version bump and will have the "Dependency Updates" title in the changelog. +- The `chore` type will trigger a `patch` version bump, which is the default for if `versionBump` is not specified, and will not be included in the changelog. +- The `styles` type will trigger a `patch` version bump, which is the default for if `versionBump` is not specified, and will be included in the changelog with the corresponding default title. diff --git a/docs/shared/reference/sitemap.md b/docs/shared/reference/sitemap.md index 252ef86386d29..b2735bed0d0e6 100644 --- a/docs/shared/reference/sitemap.md +++ b/docs/shared/reference/sitemap.md @@ -182,6 +182,7 @@ - [Automatically Version with Conventional Commits](/recipes/nx-release/automatically-version-with-conventional-commits) - [Publish in CI/CD](/recipes/nx-release/publish-in-ci-cd) - [Automate GitHub Releases](/recipes/nx-release/automate-github-releases) + - [Customize Conventional Commit Types](/recipes/nx-release/customize-conventional-commit-types) - [Other](/recipes/other) - [Rescope Packages from @nrwl to @nx](/recipes/other/rescope) - [Showcase](/showcase) diff --git a/e2e/release/src/conventional-commits-config.test.ts b/e2e/release/src/conventional-commits-config.test.ts index da77461bb2414..8faafa23918d0 100644 --- a/e2e/release/src/conventional-commits-config.test.ts +++ b/e2e/release/src/conventional-commits-config.test.ts @@ -112,8 +112,8 @@ describe('nx release conventional commits config', () => { fix: false, docs: { semverBump: 'patch', + // no hidden property set, but the user has explicitly overridden the `docs` type, so we assume they want it to appear changelog: { - hidden: false, title: 'Custom Docs Header', }, }, From 4f3b6b3e220ae0f87af895c4b00c2278e60e0c3e Mon Sep 17 00:00:00 2001 From: Austin Fahsl Date: Tue, 5 Mar 2024 20:47:54 -0700 Subject: [PATCH 07/10] chore(release): update registry url in snapshot --- e2e/release/src/private-js-packages.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/e2e/release/src/private-js-packages.test.ts b/e2e/release/src/private-js-packages.test.ts index f11be2e8473b0..d095fd43537b0 100644 --- a/e2e/release/src/private-js-packages.test.ts +++ b/e2e/release/src/private-js-packages.test.ts @@ -271,7 +271,7 @@ describe('nx release - private JS packages', () => { integrity: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX total files: 3 - Published to http://localhost:4873 with tag "latest" + Published to ${e2eRegistryUrl} with tag "latest" > nx run {public-project-name}:nx-release-publish @@ -292,7 +292,7 @@ describe('nx release - private JS packages', () => { integrity: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX total files: 3 - Published to http://localhost:4873 with tag "latest" + Published to ${e2eRegistryUrl} with tag "latest" From 25d49c1d53cdfb759e714a6baa147ee5a7636272 Mon Sep 17 00:00:00 2001 From: Austin Fahsl Date: Tue, 5 Mar 2024 21:22:14 -0700 Subject: [PATCH 08/10] chore(release): update config test snapshots --- .../release/config/config.spec.ts | 395 +++++++++++++++++- 1 file changed, 390 insertions(+), 5 deletions(-) diff --git a/packages/nx/src/command-line/release/config/config.spec.ts b/packages/nx/src/command-line/release/config/config.spec.ts index d174659590ab6..bd31fe9972a7a 100644 --- a/packages/nx/src/command-line/release/config/config.spec.ts +++ b/packages/nx/src/command-line/release/config/config.spec.ts @@ -878,6 +878,101 @@ describe('createNxReleaseConfig()', () => { "renderer": "nx/release/changelog-renderer", }, }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, "git": { "commit": false, "commitArgs": "", @@ -982,6 +1077,101 @@ describe('createNxReleaseConfig()', () => { "renderer": "nx/release/changelog-renderer", }, }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, "git": { "commit": false, "commitArgs": "", @@ -1084,6 +1274,101 @@ describe('createNxReleaseConfig()', () => { "renderer": "nx/release/changelog-renderer", }, }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, "git": { "commit": false, "commitArgs": "", @@ -2838,6 +3123,101 @@ describe('createNxReleaseConfig()', () => { "renderer": "nx/release/changelog-renderer", }, }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "docs": { + "changelog": { + "hidden": true, + "title": "📖 Documentation", + }, + "semverBump": "none", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, "git": { "commit": false, "commitArgs": "", @@ -4203,6 +4583,7 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } @@ -4212,7 +4593,7 @@ describe('createNxReleaseConfig()', () => { describe('user config -> top level conventional commits configuration', () => { it('should use defaults when config is empty', async () => { - const res1 = await createNxReleaseConfig(projectGraph, { + const res1 = await createNxReleaseConfig(projectGraph, projectFileMap, { conventionalCommits: {}, }); @@ -4380,12 +4761,13 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } `); - const res2 = await createNxReleaseConfig(projectGraph, { + const res2 = await createNxReleaseConfig(projectGraph, projectFileMap, { conventionalCommits: { types: {}, }, @@ -4555,6 +4937,7 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } @@ -4562,7 +4945,7 @@ describe('createNxReleaseConfig()', () => { }); it('should merge defaults with overrides and new commit types', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { conventionalCommits: { types: { feat: { @@ -4766,6 +5149,7 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } @@ -4773,7 +5157,7 @@ describe('createNxReleaseConfig()', () => { }); it('should parse shorthand for disabling a commit type', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { conventionalCommits: { types: { feat: false, @@ -4953,6 +5337,7 @@ describe('createNxReleaseConfig()', () => { "tagArgs": "", "tagMessage": "", }, + "preVersionCommand": "", }, }, } @@ -4960,7 +5345,7 @@ describe('createNxReleaseConfig()', () => { }); it('should parse shorthand for disabling changelog appearance for a commit type', async () => { - const res = await createNxReleaseConfig(projectGraph, { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { conventionalCommits: { types: { fix: { From a5d08abaa7141e7f271c7223a65e8117239b5729 Mon Sep 17 00:00:00 2001 From: Austin Fahsl Date: Fri, 8 Mar 2024 16:51:25 -0700 Subject: [PATCH 09/10] feat(release): support true as shorthand for enabling with defaults --- .../customize-conventional-commit-types.md | 22 +- .../src/conventional-commits-config.test.ts | 80 +++- packages/nx/schemas/nx-schema.json | 16 +- .../release/config/config.spec.ts | 386 ++++++++++++++++++ .../src/command-line/release/config/config.ts | 23 +- packages/nx/src/config/nx-json.ts | 15 +- 6 files changed, 525 insertions(+), 17 deletions(-) diff --git a/docs/shared/recipes/nx-release/customize-conventional-commit-types.md b/docs/shared/recipes/nx-release/customize-conventional-commit-types.md index a2400db31e9e2..f90b30267a557 100644 --- a/docs/shared/recipes/nx-release/customize-conventional-commit-types.md +++ b/docs/shared/recipes/nx-release/customize-conventional-commit-types.md @@ -30,9 +30,29 @@ then Nx Release will select the `minor` version bump and elect to release versio If Nx Release does not find any relevant commits since the last release, it will skip releasing a new version. This works with [independent releases](/recipes/nx-release/release-projects-independently) as well, allowing for only some projects to be released and some to be skipped. {% /callout %} +#### Breaking Changes and Major Version Bumps + +Major version bumps are triggered by the presence of a `BREAKING CHANGE` in the footer of the commit message or with '!' after the commit type and scope, as specified by the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) standard. This is regardless of the type or scope of the commit. For example: + +``` +fix: remove deprecated config properties + +BREAKING CHANGE: `settings` and `overrides` keys in config are no longer supported +``` + +``` +fix!: do not trigger a workflow when user submits bad data +``` + +``` +feat(pkg-2)!: redirect users to the new workflow page +``` + +When Nx Release detects a breaking change, it will bump the major version, regardless of the other commits present in the history. Breaking changes will also appear in their own section of the changelog. + ### Generate Changelog Sections -Nx Release sorts changes within changelogs into sections based on the type of commit. By default, `fix`, `feat`, and `perf` commits will be included in the changelog. To customize the headers of changelog sections, include other commit types, or exclude the default commit types, see the [Configure Commit Types](#configure-commit-types) section below. +Nx Release will sort changes within changelogs into sections based on the type of commit. By default, `fix`, `feat`, and `perf` commits will be included in the changelog. To customize the headers of changelog sections, include other commit types, or exclude the default commit types, see the [Configure Commit Types](#configure-commit-types) section below. See the [Nx repo](https://github.com/nrwl/nx/releases) for examples of a changelogs generated with Nx Release. diff --git a/e2e/release/src/conventional-commits-config.test.ts b/e2e/release/src/conventional-commits-config.test.ts index 8faafa23918d0..191edca887961 100644 --- a/e2e/release/src/conventional-commits-config.test.ts +++ b/e2e/release/src/conventional-commits-config.test.ts @@ -46,6 +46,7 @@ describe('nx release conventional commits config', () => { let pkg3: string; let pkg4: string; let pkg5: string; + let pkg6: string; beforeAll(async () => { newProject({ @@ -68,6 +69,9 @@ describe('nx release conventional commits config', () => { pkg5 = uniq('my-pkg-5'); runCLI(`generate @nx/workspace:npm-package ${pkg5}`); + pkg6 = uniq('my-pkg-6'); + runCLI(`generate @nx/workspace:npm-package ${pkg6}`); + // Update pkg2 to depend on pkg1 updateJson(`${pkg2}/package.json`, (json) => { json.dependencies ??= {}; @@ -90,6 +94,7 @@ describe('nx release conventional commits config', () => { await runCommandAsync(`git tag -a ${pkg3}@0.0.1 -m "${pkg3}@0.0.1"`); await runCommandAsync(`git tag -a ${pkg4}@0.0.1 -m "${pkg4}@0.0.1"`); await runCommandAsync(`git tag -a ${pkg5}@0.0.1 -m "${pkg5}@0.0.1"`); + await runCommandAsync(`git tag -a ${pkg6}@0.0.1 -m "${pkg6}@0.0.1"`); }, 60000); afterAll(() => cleanupProject()); @@ -129,8 +134,14 @@ describe('nx release conventional commits config', () => { // is a shortcut for setting "changelog.hidden" to false. changelog: false, }, - // unspecified semverBump will default to "patch" perf: {}, + // true should be the same as specifying {} + refactor: true, + build: { + semverBump: 'none', + // true should be the same as specifying {} + changelog: true, + }, }, }, }; @@ -145,6 +156,13 @@ describe('nx release conventional commits config', () => { await runCommandAsync(`git add ${pkg1}/package.json`); await runCommandAsync(`git commit -m "fix: this is a fix"`); + updateJson(`${pkg6}/package.json`, (json) => ({ + ...json, + license: 'MIT', + })); + await runCommandAsync(`git add ${pkg6}/package.json`); + await runCommandAsync(`git commit -m "build: this is a build"`); + const versionResultNoChanges = runCLI(`release version -d`); expect(versionResultNoChanges).toContain( @@ -162,6 +180,9 @@ describe('nx release conventional commits config', () => { expect(versionResultNoChanges).toContain( `${pkg5} 🚫 Skipping versioning "@proj/${pkg5}" as no changes were detected.` ); + expect(versionResultNoChanges).toContain( + `${pkg6} 🚫 Skipping versioning "@proj/${pkg6}" as no changes were detected.` + ); // update my-pkg-3 with a fix commit updateJson(`${pkg3}/package.json`, (json) => ({ @@ -188,6 +209,9 @@ describe('nx release conventional commits config', () => { expect(versionResultDocsChanges).toContain( `${pkg5} 🚫 Skipping versioning "@proj/${pkg5}" as no changes were detected.` ); + expect(versionResultDocsChanges).toContain( + `${pkg6} 🚫 Skipping versioning "@proj/${pkg6}" as no changes were detected.` + ); // update my-pkg-2 with a fix commit updateJson(`${pkg2}/package.json`, (json) => ({ @@ -215,6 +239,9 @@ describe('nx release conventional commits config', () => { expect(versionResultCustomTypeChanges).toContain( `${pkg5} 🚫 Skipping versioning "@proj/${pkg5}" as no changes were detected.` ); + expect(versionResultCustomTypeChanges).toContain( + `${pkg6} 🚫 Skipping versioning "@proj/${pkg6}" as no changes were detected.` + ); updateJson(`${pkg1}/package.json`, (json) => ({ ...json, @@ -241,6 +268,9 @@ describe('nx release conventional commits config', () => { expect(versionResultCustomTypeBreakingChanges).toContain( `${pkg5} 🚫 Skipping versioning "@proj/${pkg5}" as no changes were detected.` ); + expect(versionResultCustomTypeBreakingChanges).toContain( + `${pkg6} 🚫 Skipping versioning "@proj/${pkg6}" as no changes were detected.` + ); updateJson(`${pkg4}/package.json`, (json) => ({ ...json, @@ -265,6 +295,9 @@ describe('nx release conventional commits config', () => { expect(versionResultChoreChanges).toContain( `${pkg5} 🚫 Skipping versioning "@proj/${pkg5}" as no changes were detected.` ); + expect(versionResultChoreChanges).toContain( + `${pkg6} 🚫 Skipping versioning "@proj/${pkg6}" as no changes were detected.` + ); updateJson(`${pkg5}/package.json`, (json) => ({ ...json, @@ -291,6 +324,36 @@ describe('nx release conventional commits config', () => { expect(versionResultPerfChanges).toContain( `${pkg5} ✍️ New version 0.0.2 written to ${pkg5}/package.json` ); + expect(versionResultPerfChanges).toContain( + `${pkg6} 🚫 Skipping versioning "@proj/${pkg6}" as no changes were detected.` + ); + + updateJson(`${pkg6}/package.json`, (json) => ({ + ...json, + license: 'GNU GPLv3', + })); + await runCommandAsync(`git add ${pkg6}/package.json`); + await runCommandAsync(`git commit -m "refactor: this is refactor"`); + + const versionResultRefactorChanges = runCLI(`release version -d`); + expect(versionResultRefactorChanges).toContain( + `${pkg1} ✍️ New version 1.0.0 written to ${pkg1}/package.json` + ); + expect(versionResultRefactorChanges).toContain( + `${pkg2} ✍️ New version 0.1.0 written to ${pkg2}/package.json` + ); + expect(versionResultRefactorChanges).toContain( + `${pkg3} ✍️ New version 0.0.2 written to ${pkg3}/package.json` + ); + expect(versionResultRefactorChanges).toContain( + `${pkg4} ✍️ New version 0.0.2 written to ${pkg4}/package.json` + ); + expect(versionResultRefactorChanges).toContain( + `${pkg5} ✍️ New version 0.0.2 written to ${pkg5}/package.json` + ); + expect(versionResultRefactorChanges).toContain( + `${pkg6} ✍️ New version 0.0.2 written to ${pkg6}/package.json` + ); // Normally, users would use `nx release` or the programmatic api to ensure that // changelogs are generated for the above version bumps, but for the sake of this @@ -351,5 +414,20 @@ describe('nx release conventional commits config', () => { - this is a performance improvement `); + + const pkg6Changelog = readFile(`${pkg6}/CHANGELOG.md`); + expect(pkg6Changelog).toMatchInlineSnapshot(` + # 1.0.0 (YYYY-MM-DD) + + + ### 💅 Refactors + + - this is refactor + + + ### 📦 Build + + - this is a build + `); }); }); diff --git a/packages/nx/schemas/nx-schema.json b/packages/nx/schemas/nx-schema.json index e2e67c5bb7718..e7242644208e7 100644 --- a/packages/nx/schemas/nx-schema.json +++ b/packages/nx/schemas/nx-schema.json @@ -645,12 +645,11 @@ "properties": { "types": { "type": "object", - "description": "A map of commit types to their configuration. If a type is set to 'false', then it will be hidden from changelogs and will not trigger a version bump.", + "description": "A map of commit types to their configuration. If a type is set to 'true', then it will be enabled with the default 'semverBump' of 'patch' and will appear in the changelog. If a type is set to 'false', then it will not trigger a version bump and will be hidden from the changelog.", "additionalProperties": { "oneOf": [ { - "type": "boolean", - "enum": [false] + "type": "boolean" }, { "type": "object", @@ -658,14 +657,14 @@ "semverBump": { "type": "string", "enum": ["major", "minor", "patch", "none"], - "description": "The semver bump to apply to the version of the project(s) when a commit of this type is included in the release." + "description": "The semver bump to apply to the version of the project(s) when a commit of this type is included in the release.", + "default": "patch" }, "changelog": { - "description": "Configuration for the changelog section for commits of this type. If set to 'false', then commits of this type will not be included in the changelog.", + "description": "Configuration for the changelog section for commits of this type. If set to 'true', then commits of this type will be included in the changelog with their default title for the type. If set to 'false', then commits of this type will not be included in the changelog.", "oneOf": [ { - "type": "boolean", - "enum": [false] + "type": "boolean" }, { "type": "object", @@ -676,7 +675,8 @@ }, "hidden": { "type": "boolean", - "description": "Whether or not to include commits of this type in the changelog" + "description": "Whether or not to include commits of this type in the changelog", + "default": false } } } diff --git a/packages/nx/src/command-line/release/config/config.spec.ts b/packages/nx/src/command-line/release/config/config.spec.ts index bd31fe9972a7a..29321e41d462a 100644 --- a/packages/nx/src/command-line/release/config/config.spec.ts +++ b/packages/nx/src/command-line/release/config/config.spec.ts @@ -5344,6 +5344,197 @@ describe('createNxReleaseConfig()', () => { `); }); + it('should parse shorthand for enabling a commit type', async () => { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { + conventionalCommits: { + types: { + feat: true, + fix: true, + perf: true, + docs: true, + customType: true, + }, + }, + }); + + expect(res).toMatchInlineSnapshot(` + { + "error": null, + "nxReleaseConfig": { + "changelog": { + "automaticFromRef": false, + "git": { + "commit": true, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": false, + "tag": true, + "tagArgs": "", + "tagMessage": "", + }, + "projectChangelogs": false, + "workspaceChangelog": { + "createRelease": false, + "entryWhenNoChanges": "This was a version bump only, there were no code changes.", + "file": "{workspaceRoot}/CHANGELOG.md", + "renderOptions": { + "authors": true, + "commitReferences": true, + "versionTitleDate": true, + }, + "renderer": "nx/release/changelog-renderer", + }, + }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "customType": { + "changelog": { + "hidden": false, + "title": "customType", + }, + "semverBump": "patch", + }, + "docs": { + "changelog": { + "hidden": false, + "title": "📖 Documentation", + }, + "semverBump": "patch", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "patch", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, + "git": { + "commit": false, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": false, + "tag": false, + "tagArgs": "", + "tagMessage": "", + }, + "groups": { + "__default__": { + "changelog": false, + "projects": [ + "lib-a", + "lib-b", + "nx", + ], + "projectsRelationship": "fixed", + "releaseTagPattern": "v{version}", + "version": { + "conventionalCommits": false, + "generator": "@nx/js:release-version", + "generatorOptions": {}, + }, + }, + }, + "projectsRelationship": "fixed", + "releaseTagPattern": "v{version}", + "version": { + "conventionalCommits": false, + "generator": "@nx/js:release-version", + "generatorOptions": {}, + "git": { + "commit": false, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": true, + "tag": false, + "tagArgs": "", + "tagMessage": "", + }, + "preVersionCommand": "", + }, + }, + } + `); + }); + it('should parse shorthand for disabling changelog appearance for a commit type', async () => { const res = await createNxReleaseConfig(projectGraph, projectFileMap, { conventionalCommits: { @@ -5535,6 +5726,201 @@ describe('createNxReleaseConfig()', () => { } `); }); + + it('should parse shorthand for enabling changelog appearance for a commit type', async () => { + const res = await createNxReleaseConfig(projectGraph, projectFileMap, { + conventionalCommits: { + types: { + fix: { + changelog: true, + }, + docs: { + changelog: true, + }, + customType: { + changelog: true, + }, + }, + }, + }); + + expect(res).toMatchInlineSnapshot(` + { + "error": null, + "nxReleaseConfig": { + "changelog": { + "automaticFromRef": false, + "git": { + "commit": true, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": false, + "tag": true, + "tagArgs": "", + "tagMessage": "", + }, + "projectChangelogs": false, + "workspaceChangelog": { + "createRelease": false, + "entryWhenNoChanges": "This was a version bump only, there were no code changes.", + "file": "{workspaceRoot}/CHANGELOG.md", + "renderOptions": { + "authors": true, + "commitReferences": true, + "versionTitleDate": true, + }, + "renderer": "nx/release/changelog-renderer", + }, + }, + "conventionalCommits": { + "types": { + "build": { + "changelog": { + "hidden": true, + "title": "📦 Build", + }, + "semverBump": "none", + }, + "chore": { + "changelog": { + "hidden": true, + "title": "🏡 Chore", + }, + "semverBump": "none", + }, + "ci": { + "changelog": { + "hidden": true, + "title": "🤖 CI", + }, + "semverBump": "none", + }, + "customType": { + "changelog": { + "hidden": false, + "title": "customType", + }, + "semverBump": "patch", + }, + "docs": { + "changelog": { + "hidden": false, + "title": "📖 Documentation", + }, + "semverBump": "patch", + }, + "examples": { + "changelog": { + "hidden": true, + "title": "🏀 Examples", + }, + "semverBump": "none", + }, + "feat": { + "changelog": { + "hidden": false, + "title": "🚀 Features", + }, + "semverBump": "minor", + }, + "fix": { + "changelog": { + "hidden": false, + "title": "🩹 Fixes", + }, + "semverBump": "patch", + }, + "perf": { + "changelog": { + "hidden": false, + "title": "🔥 Performance", + }, + "semverBump": "none", + }, + "refactor": { + "changelog": { + "hidden": true, + "title": "💅 Refactors", + }, + "semverBump": "none", + }, + "revert": { + "changelog": { + "hidden": true, + "title": "⏪ Revert", + }, + "semverBump": "none", + }, + "style": { + "changelog": { + "hidden": true, + "title": "🎨 Styles", + }, + "semverBump": "none", + }, + "test": { + "changelog": { + "hidden": true, + "title": "✅ Tests", + }, + "semverBump": "none", + }, + "types": { + "changelog": { + "hidden": true, + "title": "🌊 Types", + }, + "semverBump": "none", + }, + }, + }, + "git": { + "commit": false, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": false, + "tag": false, + "tagArgs": "", + "tagMessage": "", + }, + "groups": { + "__default__": { + "changelog": false, + "projects": [ + "lib-a", + "lib-b", + "nx", + ], + "projectsRelationship": "fixed", + "releaseTagPattern": "v{version}", + "version": { + "conventionalCommits": false, + "generator": "@nx/js:release-version", + "generatorOptions": {}, + }, + }, + }, + "projectsRelationship": "fixed", + "releaseTagPattern": "v{version}", + "version": { + "conventionalCommits": false, + "generator": "@nx/js:release-version", + "generatorOptions": {}, + "git": { + "commit": false, + "commitArgs": "", + "commitMessage": "chore(release): publish {version}", + "stageChanges": true, + "tag": false, + "tagArgs": "", + "tagMessage": "", + }, + "preVersionCommand": "", + }, + }, + } + `); + }); }); describe('user config -> top level and group level changelog combined', () => { diff --git a/packages/nx/src/command-line/release/config/config.ts b/packages/nx/src/command-line/release/config/config.ts index 4b69e1d64809a..f0b10862019a9 100644 --- a/packages/nx/src/command-line/release/config/config.ts +++ b/packages/nx/src/command-line/release/config/config.ts @@ -48,6 +48,14 @@ type RemoveFalseFromPropertiesOnEach = { [U in keyof T]: RemoveFalseFromProperties; }; +type RemoveBooleanFromType = T extends boolean ? never : T; +type RemoveBooleanFromProperties = { + [P in keyof T]: P extends K ? RemoveBooleanFromType : T[P]; +}; +type RemoveBooleanFromPropertiesOnEach = { + [U in keyof T]: RemoveBooleanFromProperties; +}; + export const IMPLICIT_DEFAULT_RELEASE_GROUP = '__default__'; /** @@ -75,9 +83,9 @@ export type NxReleaseConfig = Omit< >; // Remove the false shorthand from the conventionalCommits config types, it will be normalized to a semver bump of "none" and to be hidden on the changelog conventionalCommits: { - types: RemoveFalseFromPropertiesOnEach< + types: RemoveBooleanFromPropertiesOnEach< DeepRequired< - RemoveFalseFromProperties< + RemoveBooleanFromProperties< DeepRequired< NxJsonConfiguration['release']['conventionalCommits']['types'] >, @@ -539,6 +547,10 @@ function normalizeConventionalCommitsConfig( }; continue; } + if (typeConfig === true) { + types[t] = {}; + continue; + } if (typeConfig.changelog === false) { types[t] = { ...typeConfig, @@ -548,6 +560,13 @@ function normalizeConventionalCommitsConfig( }; continue; } + if (typeConfig.changelog === true) { + types[t] = { + ...typeConfig, + changelog: {}, + }; + continue; + } types[t] = typeConfig; } diff --git a/packages/nx/src/config/nx-json.ts b/packages/nx/src/config/nx-json.ts index dcc215a9975aa..9139c7ba4f927 100644 --- a/packages/nx/src/config/nx-json.ts +++ b/packages/nx/src/config/nx-json.ts @@ -147,24 +147,29 @@ export interface NxReleaseConventionalCommitsConfiguration { types?: Record< string, /** - * Optionally override the version and changelog for commit types. If set to false, commits of that type will be hidden in the changelog and will not trigger a version bump. + * A map of commit types to their configuration. + * If a type is set to 'true', then it will be enabled with the default 'semverBump' of 'patch' and will appear in the changelog. + * If a type is set to 'false', then it will not trigger a version bump and will be hidden from the changelog. */ | { /** - * The semver bump to apply when a commit of this type is found. If set to "none", the commit will be ignored for versioning purposes. + * The semver bump to apply when a commit of this type is found. + * If set to "none", the commit will be ignored for versioning purposes. */ semverBump?: 'patch' | 'minor' | 'major' | 'none'; /** - * Optionally override the title and visibility of the changelog section for this type. If set to false, the section will be hidden. + * Configuration for the changelog section for commits of this type. + * If set to 'true', then commits of this type will be included in the changelog with their default title for the type. + * If set to 'false', then commits of this type will not be included in the changelog. */ changelog?: | { title?: string; hidden?: boolean; } - | false; + | boolean; } - | false + | boolean >; } From 390ef38d0476facddebec61b490f0f5b069ab9ae Mon Sep 17 00:00:00 2001 From: Austin Fahsl Date: Wed, 13 Mar 2024 10:01:27 -0600 Subject: [PATCH 10/10] docs(release): apply suggestions from review Co-authored-by: Isaac Mann --- .../nx-release/customize-conventional-commit-types.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/shared/recipes/nx-release/customize-conventional-commit-types.md b/docs/shared/recipes/nx-release/customize-conventional-commit-types.md index f90b30267a557..dd7e22e97c040 100644 --- a/docs/shared/recipes/nx-release/customize-conventional-commit-types.md +++ b/docs/shared/recipes/nx-release/customize-conventional-commit-types.md @@ -54,13 +54,13 @@ When Nx Release detects a breaking change, it will bump the major version, regar Nx Release will sort changes within changelogs into sections based on the type of commit. By default, `fix`, `feat`, and `perf` commits will be included in the changelog. To customize the headers of changelog sections, include other commit types, or exclude the default commit types, see the [Configure Commit Types](#configure-commit-types) section below. -See the [Nx repo](https://github.com/nrwl/nx/releases) for examples of a changelogs generated with Nx Release. +See the [Nx repo](https://github.com/nrwl/nx/releases) for an example of a changelogs generated with Nx Release. ## Configure Commit Types Commit types are configured in the `release.conventionalCommits.types` property in `nx.json`: -```json nx.json +```json {% fileName="nx.json" %} { "release": { "conventionalCommits": { @@ -105,7 +105,7 @@ Commit types are configured in the `release.conventionalCommits.types` property In this example, the following types are configured: - The `fix` type has been fully disabled, so `fix` commits will not trigger a version bump and will not be included in the changelog. -- The `docs` type will now trigger a `patch` version bump and will have the "Documentation Changes" title in the changelog. +- The `docs` type will trigger a `patch` version bump and will have the "Documentation Changes" title in the changelog. - The `perf` type will NOT trigger a version bump and will have the "Performance Improvements" title in the changelog. - The `deps` type will trigger a `minor` version bump and will have the "Dependency Updates" title in the changelog. - The `chore` type will trigger a `patch` version bump, which is the default for if `versionBump` is not specified, and will not be included in the changelog.