Semantic release - include in CHANGELOG the commit subject, body and footer

1.1k Views Asked by At

I am trying to configure semantic release to include the subject, body and footer of the commit messages in CHANGELOG.md file, not just the subject of commit message, but no success. In my changelog I still have only the short subject of commit messages. Is there a way to set the semantic-release at this way?

Any suggestions will be helpful for me.

2

There are 2 best solutions below

0
On

This can be done, but it's not exactly straightforward. The key is to set writerOpts for the @semantic-release/release-notes-generator plugin.

In the following example release.config.js file which is used to configure semantic-release, I'm setting two options: preset (you can use a different preset) and writerOpts (the important parts).

import { readFileSync } from 'node:fs'

const commitPartial = readFileSync('./changelog-template-commit.hbs', { encoding: 'utf-8' })

function finalizeContext (context) {
    for (const commitGroup of context.commitGroups) {
        for (const commit of commitGroup.commits) {
            commit.bodyLines = commit.body?.split('\n').filter((line) => line !== '') ?? []
        }
    }

    return context
}

export default {
    plugins: [
        '@semantic-release/commit-analyzer',
        ['@semantic-release/release-notes-generator', {
            preset: 'conventionalcommits',
            writerOpts: {
                commitPartial,
                finalizeContext,
            },
        }],
        '@semantic-release/changelog',
    ],
}

First, let's look at writerOpts.commitPartial. I'm loading a modified template that I've stored in the changelog-template-commit.hbs file:

{{!--
  Copy of https://github.com/conventional-changelog/conventional-changelog/blob/master/packages/conventional-changelog-conventionalcommits/templates/commit.hbs

  The following have been replaced:

  - `commitUrlFormat` with `{{@root.host}}/{{@root.owner}}/{{@root.repository}}/commit/{{hash}})`
  - `issueUrlFormat` with `{{@root.host}}/{{@root.owner}}/{{@root.repository}}/issues/{{this.id}}`

  As they won't be replaced when overriding the commitPartial
--}}
*{{#if scope}} **{{scope}}:**
{{~/if}} {{#if subject}}
  {{~subject}}
{{~else}}
  {{~header}}
{{~/if}}

{{~!-- commit link --}}{{~#if hash}} {{#if @root.linkReferences~}}
  ([{{shortHash}}]({{@root.host}}/{{@root.owner}}/{{@root.repository}}/commit/{{hash}}))
{{~else}}
  {{~shortHash}}
{{~/if}}{{~/if}}

{{~!-- commit references --}}
{{~#if references~}}
  , closes
  {{~#each references}} {{#if @root.linkReferences~}}
    [
    {{~#if this.owner}}
      {{~this.owner}}/
    {{~/if}}
    {{~this.repository}}{{this.prefix}}{{this.issue}}]({{@root.host}}/{{@root.owner}}/{{@root.repository}}/issues/{{this.id}})
  {{~else}}
    {{~#if this.owner}}
      {{~this.owner}}/
    {{~/if}}
    {{~this.repository}}{{this.prefix}}{{this.issue}}
  {{~/if}}{{/each}}
{{~/if}}
{{!-- End of copy --}}

{{!-- Start of custom additions --}}
{{#each bodyLines}}

  {{this}}
{{/each}}{{#each notes}}
  **BREAKING CHANGE**: {{text}}
{{/each}}

This is a slightly modified version of the original commit template the conventionalcommits preset uses. I've commented the changes I made to it inside the file. At the bottom, you'll find the additions for adding the commit body and breaking changes notes that I made.

For this to work, the writerOpts.finalizeContext option in the config above is needed. It takes each commit's body and turns it into a line by line array. You could technically use the body in the template and not worry about this, but it won't be correctly indented if you have multiple body lines. This is taken care of in my version.


This is probably not perfect and I wish conventional-changelog (which is used by @semantic-release/release-notes-generator) would provide some of this functionality out of the box, but it works for me.

Note that I haven't fully considered all pieces of information that could be in a commit footer like references that might be handled different here by the plugin. You might need to make some more adjustments.

Oh, yes, and I highly recommend trying this locally first using npx semantic-release --dryRun.

1
On

I tried to look up for some issue regarding this ad found out only this https://github.com/conventional-changelog/standard-version/issues/242