How (and Why) to enforce conventional commits on your project?
Tags: commitizen, husky, javascript, git
Published: 2023-01-27 18:42:10

After reading a lot of post and checking a few videos I come up with a configuration which will help you to enforce conventional commit messages on your repository.

> But.. Why is it important to use conventional commits?
> - Automatically generating CHANGELOGs.
> - Automatically determining a semantic version bump (based on the types of commits landed).
> - Communicating the nature of changes to teammates, the public, and other stakeholders.
> - Triggering build and publish processes.
> - Making it easier for people to contribute to your projects, by allowing them to explore a more structured commit history.

## Enforcing conventional commits

To accomplish this, we will use:

- husky: for handling the git hooks in a easy (and shareable) way.
- commitizen: for a cli wizard which will help us write conventional commits.
- commitlint: as the name suggests, lint our commit messages.

Ok, hands on. 
```
pre-requisites: 
- project where you have run `npm init` or you already have a package.json.
- project where you have run `git init` or you already have a repository configured.
```

install commitizen as a dev dependency and save the exact version.

```
npx commitizen init cz-conventional-changelog --save-dev --save-exact
```

same for commitlint
```
npm install -D @commitlint/{cli,config-conventional} --save-exact
```

now on a file called .commitlintrc.json  set the extends to the rules from config-conventional
``` 
{  "extends": ["@commitlint/config-conventional"]} 
```

now run husky from npx and run npm install which will trigger the just appended script `prepare` which executes `husky install`:
```
npx husky-init && npm install
```

now you need to add your hooks to prevent a commit message which is not formatted as a conventional commit:

```
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"'
```

NOTE: this hook could be useful as starts up the commitizen wizard every time you type `git commit` on the terminal but it changes the behaviour of the `git commit` command and opens an editor to save the commit message.

```
npx husky add .husky/prepare-commit-msg "exec < /dev/tty && node_modules/.bin/cz --hook || true"
```

Instead, I prefer to add a script on the `package.json` like this:

```
"scripts": {
    ...
    "cz": "cz"
  },
```

so you can run `npm run cz` to start the wizard or even create an alias to shorten this command.

## Releasing

now that you already have a few commits, it's time to create releases and by using semver, you will be able to show those changes on the changelog as patches, minor or major ones.

first install `standard-version` as follows:

```
npm i --save-dev standard-version
```

then place this new scripts on your `package.json`:

```
  "scripts": {
    ...
    "release": "standard-version",
    "release:minor": "standard-version --release-as minor",
    "release:patch": "standard-version --release-as patch",
    "release:major": "standard-version --release-as major"
  },

```

now just for only time do a initial release this way:
```
npm run release -- --first-release
```

CONGRATS! now you have a wonderful auto-generated changelog.md based on your conventional commit messages.

From now on after you commit your changes you will be able to run `npm run release:patch` (minor or major) depending on your changes.

-----

Happy coding!