Skip to content

Commit Templates ​

Customize the release commit title and body with placeholders, and take advantage of smart defaults in independent monorepo mode.

When Relizy bumps versions, it creates a single release commit containing the version changes and the updated changelogs. The title of that commit is controlled by templates.commitMessage, and you can optionally populate the body with templates.commitBody.

Why a separate body? ​

In independent monorepos, the legacy single-line title (chore(release): bump version to {{newVersion}} where {{newVersion}} expands to the full list of name@version pairs) can quickly exceed commitlint header-max-length limits once a release touches many packages:

text
chore(release): bump version to @scope/[email protected], @scope/[email protected], @scope/[email protected], …

Relizy now keeps titles short by default in independent mode and pushes the full list into the commit body.

Smart defaults ​

Defaults are resolved based on monorepo.versionMode:

Version modeDefault commitMessageDefault commitBody
unified / selectivechore(release): bump version to {{newVersion}}(none)
independentchore(release): bump {{packageCount}} packages{{packageList}}

If you set either commitMessage or commitBody yourself, your value is preserved — Relizy only fills in undefined fields.

templates.commitMessage ​

  • Config key: templates.commitMessage
  • Type: string

The commit title. Must stay within your commitlint header-max-length when using linting (typically 72 or 100 characters).

templates.commitBody ​

  • Config key: templates.commitBody
  • Type: string | undefined

Optional commit body. When defined, it is passed to git commit as a second -m argument, producing a proper commit body (blank line separator handled by git).

Available placeholders ​

Both commitMessage and commitBody support the same placeholders:

PlaceholderDescriptionExample
{{newVersion}}In independent mode, comma-separated name@version list. In other modes, the new root version.1.2.0 or @scope/[email protected], @scope/[email protected]
{{rootVersion}}Version from the root package.json. Useful in independent mode where {{newVersion}} is a list.1.2.0
{{packageCount}}Number of packages bumped in this release.7
{{packageNames}}Comma-separated list of bumped package names.@scope/a, @scope/b
{{packageList}}Comma-separated list of bumped name@version.@scope/[email protected], @scope/[email protected]

In non-monorepo and unified/selective setups, {{packageCount}}, {{packageNames}}, and {{packageList}} still work and reflect the bumped packages resolved for that release.

Examples ​

Short title with a detailed body (independent mode default) ​

ts
import { defineConfig } from 'relizy'

export default defineConfig({
  monorepo: { versionMode: 'independent', packages: ['packages/*'] },
  // Equivalent to the built-in default for independent mode:
  templates: {
    commitMessage: 'chore(release): bump {{packageCount}} packages',
    commitBody: '{{packageList}}',
  },
})

Produces:

text
chore(release): bump 3 packages

@scope/[email protected], @scope/[email protected], @scope/[email protected]

Include the root version in the title ​

ts
import { defineConfig } from 'relizy'

export default defineConfig({
  monorepo: { versionMode: 'independent', packages: ['packages/*'] },
  templates: {
    commitMessage: 'chore(release): release {{rootVersion}} ({{packageCount}} packages)',
    commitBody: '{{packageList}}',
  },
})

Opt out of the body ​

Set commitBody to an empty string to force an empty body, or simply override commitMessage and leave commitBody unset if you want to rely entirely on the title.

ts
import { defineConfig } from 'relizy'

export default defineConfig({
  monorepo: { versionMode: 'independent', packages: ['packages/*'] },
  templates: {
    commitMessage: 'release: {{packageCount}} packages',
    // commitBody stays undefined → no body
  },
})

WARNING

If you customize commitMessage but leave commitBody undefined, Relizy will not auto-apply the independent-mode body default. Smart defaults only trigger when both fields are unset.

Unified / selective mode ​

Defaults are unchanged — no body, single-line title:

text
chore(release): bump version to 1.2.0

You can still opt into the placeholders if you want a richer message:

ts
export default defineConfig({
  monorepo: { versionMode: 'selective', packages: ['packages/*'] },
  templates: {
    commitMessage: 'chore(release): v{{newVersion}} ({{packageCount}} packages)',
    commitBody: '{{packageList}}',
  },
})

Tips for commitlint users ​

If your project uses commitlint with header-max-length, the independent-mode default is designed to stay well under 72 characters. If you customize commitMessage, double-check with:

bash
echo "chore(release): bump 12 packages" | wc -c

And push long listings to commitBody where length is unrestricted.

Released under the MIT License.