DEV Community

Cover image for Rush and Commitlint
Kinga
Kinga

Posted on • Edited on

Rush and Commitlint

Commitlint ensures that the commit messages adhere to conventional commits convention.

If you don't want to install it globally, there's a Guide: Local setup procedure, which... is not compatible with Rush, because we are not supposed to use package manager commands (e.g. npm install) and Rush will never install dependencies in repo's root.

What now?

Since Rush supports git hooks, and allows us defining custom commands with package dependencies, you can use the steps below to configure rush to commitlint the commit messages.

Commitlint config

First, configure commitlint to use conventional config.
Following the local setup procedure, create a commitlint.config.js in the root of your repo.

If you are using the echo "module.exports = { extends: ['@commitlint/config-conventional'] };" > commitlint.config.js command, make sure the file encoding is UTF-8 and NOT UTF-16 (LE).

You may also define rules that should be enforced. The subject-case in the rule below adds an additional 'sentence-case' value; the 2 parameter ensures that an error will be displayed if the rule checks fail.

commitlint.config.js

module.exports = {
    extends: [
        "@commitlint/config-conventional"
    ],
    rules: {
        "subject-case":[2, 'always', ['lower-case','sentence-case']]
    }
} 
Enter fullscreen mode Exit fullscreen mode

Create autoinstaller

Create rush autoinstaller and add all packages and peer dependencies needed to run commitlint command. This will insure that all required packages are installed before the commitlint command is executed.

rush init-autoinstaller --name rush-commitlint
cd common/autoinstallers/rush-commitlint

pnpm install @commitlint/config-conventional @commitlint/cli @types/node

# When you are finished, run this command to ensure that the
# common/autoinstallers/rush-commitizen/ppnpm-lock.yaml file is up to date
rush update-autoinstaller --name rush-commitlint
Enter fullscreen mode Exit fullscreen mode

Create custom command

commitlint --edit reads the last commit message from the specified file or fallbacks to ./.git/COMMIT_EDITMSG.
Add the below command and parameter to the command-line.json file:

common\config\rush\command-line.json

{
  "$schema": "https://developer.microsoft.com/json-schemas/rush/v5/command-line.schema.json",
  "commands": [
    {
      "name": "commitlint",
      "commandKind": "global",
      "summary": "Used by the pre-commit Git hook. This command invokes commitlint to ensure that the commit messages meet the conventional commit format",
      "safeForSimultaneousRushProcesses": true,
      "autoinstallerName": "rush-commitlint",
      "shellCommand": "commitlint"
    }
  ],
  "parameters": [
    {
      "parameterKind": "string",
      "argumentName": "MESSAGE",
      "longName": "--edit",
      "description": "",
      "associatedCommands": [
        "commitlint"
      ]
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

The command is using rush-commitlint autoinstaller created in the previous step, to ensure the commitlint module and peer dependecies are installed.
When executing rush commitlint --edit $arg rush will invoke the shellCommand with the provided parameters: commitlint --edit $arg.

Add git hook

In order to lint the commit message, use commit-msg hook that calls the rush custom command created above.

The commit-msg hook takes one parameter, which is the path (.git/COMMIT_EDITMSG) to a temporary file that contains the commit message written by the developer. The hook can also be used to refuse the commit after inspecting the message file. If this script exits non-zero, Git aborts the commit process.

Create a commit-msg file:

common\git-hooks\commit-msg

#!/bin/sh
node common/scripts/install-run-rush.js commitlint --edit $1
Enter fullscreen mode Exit fullscreen mode

Rush supports git hooks natively, and will copy the common\git-hooks\commit-msg to .git\hooks\commit-msg during rush install.

rush install
Enter fullscreen mode Exit fullscreen mode

Next time you run git commit, Git will find your script and invoke it.
Remember that the first time the rush commitlint is invoked, rush will execute a number of additional steps to install the dependencies. The next time, however, you will see no delay.

Rush commit messages

Did you define rush commit messages in rush.json? Make sure they conform to the commitlint rules.

rush.json

//...
  "gitPolicy": {
    "versionBumpCommitMessage": "chore: Bump versions [skip ci]",
    "changeLogUpdateCommitMessage": "chore: Update changelogs [skip ci]",
//...
Enter fullscreen mode Exit fullscreen mode

Source Code

You may find the source code on GitHub.

EDIT 2024.07.17: Awesome! It looks like this post inspired this fantastic Rush auto-installer with commit conventions video. 😍

Top comments (6)

Collapse
 
jaasum profile image
Jeremy AAsum

Great guide. Thank you!

For me, in commitlint.config.js however it couldn't find the package, and I had to point to where the package is installed by rush via github.com/conventional-changelog/...

extends: [
    "./common/autoinstallers/rush-commitlint/node_modules/@commitlint/config-conventional/lib/index.js"
  ],
Enter fullscreen mode Exit fullscreen mode
Collapse
 
cubabit profile image
Peter van Holland

Hi @kkazala - can you please fix this page as there is a problem with it .Thanks!

Collapse
 
kkazala profile image
Kinga

thank you @cubabit for letting me know :)
Done

Collapse
 
aaron_conlon profile image
Aaron Conlon

@kkazala Hi,I use node v20.14 to config this feature.But I failed.

Error: Cannot find module "@commitlint/config-conventional" from "/Users/aaron/Desktop/frontend-playground/rush-gitcommit-demo"
Enter fullscreen mode Exit fullscreen mode

By the way, why not install these three commitlint packages as development dependencies?

Collapse
 
kkazala profile image
Kinga

I think @jaasum answered your question above =)
Please note that I wrote this post in 2022. It was few versions of node ago.

I think there's also a rush plugin, inspired by this auto-installer. I wish I saved it when I saw it.
If someone comes across it, could you please post it in the comments?
Thx❣️

Collapse
 
aaron_conlon profile image
Aaron Conlon

thanks