Introducing Commitiquette
Tags: git, node, commit
Published: 2020-02-22 08:32:03

Commitiquette is a Commitizen plugin that uses your CommitLint configuration, allowing you to maintain a single set of rules for commit messages.

Consistent commit messages that follow a convention are useful for automating generation of changelogs, automating versioning based on **fix** (patch), **feature** (minor) and **breaking change** (major) of the commit. 

Conventional commits have the beneficial side-effect of causing developers to make more small commits, rather than fewer large commits, limited to the type and scope of the change. This may actually be the most important feature of conventional commit messages. 

Commiting code should be like voting in Chicago. Commit early and commit often. 

If you are already familiar with CommitLint and Commitizen, you can skip the next two sections and just configure Commitiquette. 

## Commitizen 

There are more options for installing and configuring Commitizen than we will go into here. See the [official documentation](http://commitizen.github.io/cz-cli/) to learn more. 

To add Commitizen to your project, paste the following command in the project's root directory. 

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

Next add Husky to manage git hooks 

```
npm install husky --save-dev
```

Finally we will add the following snippet to our `packages.json`

```
"husky": {
  "hooks": {
    "prepare-commit-msg": "exec < /dev/tty && git cz --hook || true",
  }
}
```

At this point Commitizen should be configured in your repository. When you commit changes with `git commit`you will be prompted by Commitizen. 

## CommitLint

While Commitizen is helpful in guiding contributers in creating commit messages, developers using a GUI to commit won't be prompted by can easily unwittingly bypass it. This is why it is important to lint the commit messages.

CommitLint had lots of options for installation and configuration, including setup for CI. See the official [documentaion](https://commitlint.js.org/) for more options. 

Install and configure CommitLint in your project 

```
npm install --save-dev @commitlint/{cli,config-conventional}
echo "module.exports = {extends: ['@commitlint/config-conventional']};" > commitlint.config.js
```

Next we will need to add another like to the husky configuration within `package.json`

```
"husky": {
  "hooks": {
    "prepare-commit-msg": "exec < /dev/tty && git cz --hook || true",
    "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
  }
}
```

At this point, Commitlint should stop commits where the message fails the lint. Again, this is not bulletproof. If you require gated commits CommitLint should be configured in CI.

## Commitiquette 

CommitLint and Commitizen should be somewhat in sync applying similar rules. Though as soon as you apply project or workspace specific rules, you will find you will need to maintain these rules twice.

This is where Commitiquette comes in by using the CommitLint config for Commitizen. 

We will install Commitiquette
```
npm install commitiquette --save-dev
```

Next we update Commitizens's config to use Commitiquette. In `package.json` find the Commitizen config added previously by `npx commitizen init...` and update is so

```
  "config": {
    "commitizen": {
      "path": "commitiquette"
    }
  },
```

Now we can change our `commitlint.config.js` and Commitizen will pick these changes up automatically! 

See the CommitLint documentation for a complete list of [rules](https://commitlint.js.org/#/reference-rule) that may be applied to both CommitLint and Commitiquette. 


So now let's configure CommitLint to validate our scope is an item in an array. 
```
module.exports = {
  extends: ['@commitlint/config-conventional'],
  rules: {
    'scope-enum': [2, 'always', ['docs', 'core', 'lib', 'misc', 'etc']]
  }
};
```

CommitLint will now validate that the scope is one of the elements defined in the above rule. Commitizen, through the Commitiquette plugin, will prompt the contributor to select from this list for the scope of the commit.

Commitiquette can help guide contributors to make smaller, focused commits that follow a shared set of rule based conventions.