Skip to content

Inconsistencies with how commitizen handles footers and the official conventional commits specification. #2111

Open

Description

@michal-gomolinski

Description

Some time ago I found an inconsistency between how commitizen handles the BREAKING CHANGE: footer and how it's described in the conventional commit specification (more on that later) and discovered some more inconsistencies with how commitizen handles footers.

1. Commitizen doesn't require description for the BREAKING CHANGE: footer

The conventional commits specification mentions in https://www.conventionalcommits.org/en/v1.0.0/#specification:

12.If included as a footer, a breaking change MUST consist of the uppercase text BREAKING CHANGE, followed by a colon, space, and description, e.g., BREAKING CHANGE: environment variables now take precedence over config files.

The wording heavily suggests to me that the description is a required part of the BREAKING CHANGE footer.

Interestingly the git trailer feature the footers are based on by default doesn't require the value (description) part: https://git-scm.com/docs/git-interpret-trailers#Documentation/git-interpret-trailers.txt---no-trim-empty. However since the conventional commits specification already goes away from this convention with the BREAKING CHANGE footer allowing the use of white-space in the key this fact could be possibly ignored.

Another piece of evidence that would suggest that the description is required for the BREAKING CHANGE footer is the example parser implementation provided by the conventional
commits team: https://github.com/conventional-commits/parser

There in the grammar described in the README.md we can see:

/* For convenience the <breaking-change>, <separator>, <whitespace>, and
 * <text> tokens of <body-text> should be appended as children to <body> */
<body-text>       ::= [<breaking-change>, ":", <whitespace>*], text

Which again suggests the description should be required.

Why this matters

In projects where commitizen is used with different conventional commit based tooling, e.g.: https://github.com/googleapis/release-please, because some of those tools don't implement features similar to cz commit, cz check, or the commitizen pre-commit hook, can cause commits that were created with cz commit, without the "optional" commits to not be registerd as actual breaking changes by this different tooling, and checking commits with cz check can cause false positives.

2. cz commit doesn't allow adding multiple footers

Self explanatory, conventional commits specification allows multiple footers in the commit:

  1. One or more footers MAY be provided one blank line after the body.

However cz commit only accepts a single footer, and when the commit is a breaking change, the only footer that can be added with cz commit is the BREAKING CHANGE: footer.
This is even more confusing since in the case of the breaking change footer we only expect the user to provide the description for the breaking change, however in the other case we're expecting the user to provide a full <footer-token>: <value>.

3. cz check doesn't check formatting of the footers

Possible Solution

1. Commitizen doesn't require description for the BREAKING CHANGE: footer

If decided that requiring the description now after not requiring it in the past would be a breaking change in itself and this cannot be simply changed now, we could:

  • Add a breaking_change_require_description configuration option that defaults to False, that would check the description only if set to True
  • If decided that this should be the default in the future - throw a deprecation warning if the variable not set and change the default to True somewhere in the future.

Also important to note that if breaking_change_exclamation_in_title is set to True the description shouldn't be required, however if both breaking_change_exclamation_in_title and breaking_change_require_description are set to True the description shouldn't be required, however if not provided the BREAKING CHANGE: footer should be skipped and only the exclamation mark in the title should be added.

2. cz commit doesn't allow adding multiple footers

Another question can be added to the questions dictionary, named breaking_change_description that is only asked when is_breaking_change is True.

The footer question accepts multiple footers by setting the multiline argument of questionary text input question.

3. cz check doesn't check formatting of the footers

Probably the least straight forward part of this since as far as I've checked commitizen doesn't actually parse the commits anywhere, rather does some regex's for the check part.

I've come up with this very ugly regex:

((?:(?:\S+|BREAKING\sCHANGE): )|(?:\S+ #))(.+(?:\n(?!(((\S+|BREAKING\sCHANGE): )|(\S+ #))).+)*)

That get's all of footer like structures into two groups: one for the footer-token and the other for the value. This still however doesn't cover some parts like: how do we actually check those are footers and not somewhere else in the commit body (e.g.: this regex also matches the commit title)

Additional context

Sorry for the long text, however when looking into this all of those issues seem very connected, I'm looking into opening a PR for at least the first two issues, however the third issue may be too complex for addressing it in the same PR.

Related issues

No response

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions