conventional-changelog/conventional-changelog

Add array representation of commit.body to conventional-commits-parser

kleinfreund opened this issue · 4 comments

I'd like to propose adding a new property bodyLines to the commit object created by conventional-commits-parser. It would be a line-by-line representation of commit.body.

I'd be happy to try and contribute this if there is an interest in having it. I created a draft of this feature and it seemed relatively straightforward to implement.

Motivation

I was trying to customize the changelog generated in my project during a semantic-release run. I'm doing so by providing writerOpts.commitPartial for the conventionalcommits preset for @semantic-release/release-notes-generator (uses conventional-commits-parser and conventional-changelog-writer under the hood).

Specifically, I want to add the commit body to the end of the commit.hbs template by appending something like this:

{{#if body}}

  {{body}}
{{/if}}

This works; however, due to the nature of commit.body being a single string, I can't control the indentation if the body consists of multiple lines and so I'm getting a changelog entry like this:

    * feat: support all angle values as input

      Adds support for the angle value units deg, grad, rad, and turn when entering hues (see https://www.w3.org/TR/css-values-4/#angle-value).

Stops normalizing angle values to the range [0, 360) (e.g. a hue value of 450 will no longer be processed, stored, and emitted as 90).

With the addition I'm proposing, I would instead use the following:

{{#each bodyLines}}

  {{this}}
{{/each}}

and get the following entry (note the difference in indentation of the last line):

    * feat: support all angle values as input

      Adds support for the angle value units deg, grad, rad, and turn when entering hues (see https://www.w3.org/TR/css-values-4/#angle-value).

      Stops normalizing angle values to the range [0, 360) (e.g. a hue value of 450 will no longer be processed, stored, and emitted as 90).

Notes

My current semantic-release configuration for reference:

release.config.js
import { readFileSync } from 'node:fs'

const defaultCommitPartial = readFileSync('./node_modules/conventional-changelog-writer/templates/commit.hbs', { encoding: 'utf-8' })
const customCommitPartial = readFileSync('./changelog-template-commit.hbs', { encoding: 'utf-8' })
const commitPartial = defaultCommitPartial + customCommitPartial

export default {
	branches: [
		'main',
	],
	plugins: [
		'@semantic-release/commit-analyzer',
		['@semantic-release/release-notes-generator', {
			preset: 'conventionalcommits',
			writerOpts: {
				commitPartial,
			},
		}],
		'@semantic-release/changelog',
	],
}
changelog-template-commit.hbs
{{#if body}}

  {{body}}

{{/if}}

@kleinfreund Hi. Did you try use finalizeContext option for writer? It can modificate templates context.

Ah, interesting. I wasn't aware of this option. Using it does indeed allow me to add bodyLines more or less exactly as I'm proposing in #1167:

release.config.js
import { readFileSync } from 'node:fs'

const defaultCommitPartial = readFileSync('./node_modules/conventional-changelog-writer/templates/commit.hbs', { encoding: 'utf-8' })
const customCommitPartial = readFileSync('./changelog-template-commit.hbs', { encoding: 'utf-8' })
const commitPartial = defaultCommitPartial + customCommitPartial

/**
 * Adds the commit body line by line so I can add it with the correct indentation in `changelog-template-commit.hbs`.
 */
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 {
	branches: [
		'main',
	],
	plugins: [
		'@semantic-release/commit-analyzer',
		['@semantic-release/release-notes-generator', {
			preset: 'conventionalcommits',
			writerOpts: {
				commitPartial,
				finalizeContext,
			},
		}],
		'@semantic-release/changelog',
	],
}
changelog-template-commit.hbs
{{#each bodyLines}}

  {{this}}
{{/each}}

This would work for me.

I would still like to see this addition be available in parser as it's a little more flexible to work with than commit.body and existing/possible future presets could make use of it. Not configuring all too much is also nice-to-have (but of course nothing more).

(Mostly unrelated to this: I had used packages/conventional-changelog-conventionalcommits/templates/commit.hbs at first as it's from the preset I'm using, but in my local tests, I've seen the commit URL part missing. I'll look at that again to see if there's a bug there as it's working with packages/conventional-changelog-writer/templates/commit.hbs. Could be that the replacement of commitUrlFormat in createWriterOpts is only happening for the default template and not if you override commitPartial.)

Yes, having the same issue as @kleinfreund unfortunately. @kleinfreund did you sort it out???

Yes, having the same issue as @kleinfreund unfortunately. @kleinfreund did you sort it out???

I’m still using the workaround I laid out in #1166 (comment) as my PR adding this was closed.

The actual application of it can be found here: https://github.com/kleinfreund/yet-another-color-picker/blob/77d49f41199eb5e1c8f29bb3e7e37d5d88819233/release.config.js#L5-L16