LinkORB Engineering

Conventional commit standards in [#git]

Conventional commits is a set of rules for writing clear and concise commit messages in a human and machine readable format. On the human side, this convention ensures collaborators understand changes and the motivation for such changes at a glance. On the machine side of things, conventional commits allow the easy creation of a standard commit history that automation tools can operate on.

Writing a conventional commit message

All LinkORB teams collaborating on a Git repository use conventional commit messages of the following format:

<type>[(<scope>)]: <subject> #<cardNumber>
<EMPTY LINE>
[body]
<EMPTY LINE>
[footer]

The commit message must have a header, an optional body, and an optional footer.

Write a short commit message header

The commit message’s header is a short (50 character or less) sentence. It must start with a conventional commit type and preferably terminate with the related Team HQ card number prefixed by # as shown in the following synopsis.

<type>[(optional scope)]: <subject> #<cardNumber>

While terminating a commit message header with a Team HQ card number is the preferred approach, you may omit the card number from the header and move it to the commit message’s body. This can be useful if including the card number would otherwise prevent you from including important information in the 50-character header.

The following describe elements of a conventional commit header:

  • type: The type of change introduced in by a commit. It’s usually feat, fix, docs, chore, test, or docs. See commit types for more information.
  • scope: An optional one-word category that provides additional context on the part(s) of the codebase impacted.
  • subject: A one-sentence, imperative mood, present tense description of the change(s).
  • cardNumber: The card number of the associated Team HQ work item. E.g. #4096.

Examples:

docs: add auto email to sys architecture #4096
feat(api): email customer when product ships #3072

Please keep the commit message’s header short (50 characters or less). See configure commit message rulers in VSCode, nano, and vim for more information.

An imperative mood present tense sentence demands an action. For example, implement one-click copy button for code blocks instead of implemented one-click copy button for code blocks

Commit types

TypeDescriptionExample
featNon-breaking change which adds new functionalityfeat: auto refresh messages #1024
fixNon-breaking change which fixes a bug or an issuefix: expired token loop #2048
choreGeneral tasks or anything that doesn’t fit the other commit typeschore: replace outdated links #3072
chore(deps)Changes to dependencieschore(deps): replace Markdown framework #4096
testAdds or modifies a testtest: add login e2e tests #2048
docsCreates or updates documentationdocs: update commit conventions #1024
styleChanges that do not affect the meaning and function of codedocs: update installation & usage guide #1024
perfCode change that improves performanceperf: reduce load time by 50% #4096
revertReverts a commitrevert: remove leaked secret #2048
refactorCode change that neither fixes a bug nor adds a new featurechore: move controller to separate module #3072
ciChanges to continuous integration or delivery scripts/filesci: update commit msg validation #4096

Commit messages for merge operations are auto-generated. They do not require a commit type nor a card number.

A note on breaking changes

A breaking change is a modification that requires dependent actors to also make a corresponding change; such as additional required parameters to an existing function. Add an exclamation mark (!) to the end of the <type> field (i.e. <type>![optional scope]: subject) to indicate a breaking change. See Write an optional commit message footer for more information on breaking changes.

Semantic versioning with conventional commits

A GitHub Action workflow validates each commit and PR against the standards in this document, and triggers workflows if the commit message is compliant. For example, fix, style, test, refactor, and perf commit types will trigger a patch release (e.g. from v1.1.1 to v1.1.2). feat, will trigger a minor release (e.g. from v1.1.1 to v1.2.0), and a breaking change (<type>!) will trigger a major release (e.g. v1.1.1 to v2.0.0).

Write an optional commit message body

A commit message’s body is optional. If you decide a commit message needs a body, do the following:

  • Leave a blank line between the header (subject line above) and the body
  • Write the Team HQ card number of the related task only if you have omitted the card number from the commit message header. This should be prefixed by #. E.g. #4096
  • Summarize changes and the motivation for such changes
  • Contrast previous and current behaviour
  • Keep lines short (72 characters or less)
  • Group related subjects into paragraphs
  • Leave an empty line between the header (subject line above) and the body

Like a commit message’s body, the footer is also optional. Use the footer to summarize supplemental information such as:

  • A description of breaking changes
  • Issues the commit closes
  • Dependent work item identifiers (Team HQ cards)
  • Links to related Cyans topic(s)
  • Co-authors

A breaking change is a modification that will require dependent actors to also make a corresponding change; such as additional required parameters to an existing function.

If the commit introduces a breaking change:

  • Leave a blank line between other sections of the footer and the BREAKING CHANGE section.
  • Begin messages about breaking changes with the words BREAKING CHANGE:.

Please note that all the guidelines in this document also apply to changes committed to a repository through GitHub’s UI.

Modify your last commit

git commit --amend can be used to update the content of your last commit. If you notice a mistake in your last commit message, simply run the following command to reopen the commit message in a text editor.

git commit --amend

Please note that the commit template is not available in the commit message editor when amending your last commit. You may have to rely on the editor’s own rulers to stay within the header and body line length limits.

Further reading

About Git