This content was originally published in spanish on my blog
What are Commit Messages?
Commit messages are a way of documenting changes made in a code repository.
These messages are very useful for understanding what changes were made in a project and why they were made.
When working in a development team, it is very important that all team members can understand what changes were made to the code and why they were made.
Conventional Commits
As stated on their official page: It is a specification
for giving meaning to commit messages making them understandable both for machines and for people.
It provides a simple set of rules for creating an explicit commit history; which makes it easier to write automated tools.
This convention fits with SemVer, since we can explain in the commit messages if it's a feature, bugfix, even if there are Breaking Changes.
If you were unfamiliar with the term Semantic Versioning, in this short video I'll explain it to you:
The structure of a commit message following the specification would be as follows:
<type>[optional scope]: <commit description>
[message body, optional]
[footer(s), optional]
Commit Types
The commit types are as follows:
feat: A new feature or functionality. It would have correlation with a MINOR version following SemVer.
fix: A corrected error. It would have correlation with a PATCH version following SemVer.
BREAKING CHANGE: A change that contains this word in the message footer or a ! sign after the type or scope,
breaks compatibility with previous versions. It would have correlation with a MAJOR version following SemVer.
The following types are also allowed:
build: Changes that affect the build system or external dependencies (e.g. changes to the package.json).
ci: Changes to our continuous integration configuration files and scripts.
docs: Changes to documentation.
chore: Other changes that do not affect source code.
perf: A code change that improves performance.
refactor: A code change that does not correct an error or add a feature.
style: Changes that do not affect the meaning of the code (whitespace, format, missing commas, etc).
test: Add missing tests or correct existing tests.
Scope
The scope is optional and serves to specify the scope of the commit. For example, if we are working on a monorepo project, we can specify the package we are modifying.
Examples
Let's see some examples of commit messages following the specification:
Commit that adds a new feature, without a specific scope.
feat: add support for TypeScript
Commit that fixes a bug, within the ui package of our project.
fix(ui): bugfix on Button component
Commit that breaks compatibility with previous versions, although it doesn't add new features or fix bugs.
chore!: drop support for Node 6
BREAKING CHANGE: use JavaScript features not available in Node 6.
Commit that adds missing tests.
test(ui): add missing tests for Button component
Commit that adds a task for the continuous integration/deployment system.
ci: add GitHub Actions workflow
Commit with a long descriptive message and multiple footers.
fix(api): prevent duplicate users from being created
This commit fixes a bug where the API would allow duplicate users to be created with the same email address. This commit also adds a new `unique` constraint to the `users` table to prevent this from happening in the future.
Paired with: X
Fixes #123
Why use Conventional Commits?
It allows for automatic generation of the CHANGELOG file.
Automatically determines version changes following SemVer (based on the types of commits used).
Communicates the nature of changes to other team members or anyone interested.
Activates build and deployment or publishing processes.
Makes it easier for others to contribute to the project by allowing them to explore the commit history in a more structured way.
Tools to use Conventional Commits
VSCode Plugin
The first one I use is the VSCode extension or plugin, Conventional Commit. It helps me choose the type of commit, the scope, write the message,... all based on dialog windows.
Gitemoji
To make our commits more colorful, we can use the Gitemoji convention. It's a convention where
emojis represent the type of commit. For example, the emoji 🐛 represents a bugfix, ✨ a new feature, etc... So with a quick glance you can see what type of change has been made.
Commitlint
Commitlint is a tool that allows us to configure rules to validate commit messages.
Just like we use a linter to check if we follow certain style rules in our code, we can use it for commit messages.
For this, you need to install the @commitlint/cli
and @commitlint/config-conventional
libraries in your project.
npm install --save-dev @commitlint/cli @commitlint/config-conventional
Once installed, you must create a configuration file called commitlint.config.js
in the root of your project with the following content:
module.exports = {
extends: ["@commitlint/config-conventional"],
};
Husky
We already saw what Husky was used for in a previous post. Now we will add a new rule to the pre-commit
hook to verify and validate if the commit message complies with the Conventional Commits rules.
If you already have Husky configured, all you have to do is run the following command in the root of your project to add the command to the commit-msg
hook:
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit ${1}'
And that's it, every time you make a commit, it will verify that it follows the rules.
CHANGELOG
Finally, it is also interesting to be able to automatically generate the CHANGELOG file from the commit messages. There are various tools for this, one of them is Conventional Changelog
Hope this is helpful ✨
Do Like 💛 & Save 🔖
Do Follow me on Twitter and Linkedin for more content related to Web Programming and JavaScript
Top comments (0)