Husky add rules for your commits

Husky add rules for your commits

Husky is a tool that lets you add Git hooks to run scripts for commit checks before certain Git actions (commit, push, merge, etc.).

11 November 20244 min read

Installing and configuring Husky in your project

1️⃣ Install Husky

In your project, run :

1pnpm install husky --save-dev

2️⃣ Activate Husky in the project

Execute this command to initialise Husky :

1npx husky init

This will create a .husky/ folder and configure Husky in your project.

👉 Create a .husky/commit-msg file:

1# Ignorer les commits de fusion
2if grep -q "^Merge branch" "$1"; then
3  exit 0
4fi
5
6pnpm commitlint --edit $1

👉 Creates a .husky/pre-commit file:

This file must be empty

👉 Creates a .husky/prepare-commit-msg file:

1# Function to validate commit message format
2validate_commit_msg() {
3    commit_msg="$1"
4
5    # Check if the message starts with a valid type
6    if ! echo "$commit_msg" | grep -qE "^(feat|fix|refactor|style|docs|test|chore):.+"; then
7        echo "Error: Commit message must start with one of: feat:, fix:, refactor:, style:, docs:, test:, chore:"
8        return 1
9    fi
10
11    # # Check if the subject line is capitalized
12    # if ! echo "$commit_msg" | head -n1 | grep -q "^[A-Z]"; then
13    #     echo "Error: Subject line must be capitalized"
14    #     return 1
15    # fi
16
17    # Check if the subject line ends with a period
18    if echo "$commit_msg" | head -n1 | grep -q "\.$"; then
19        echo "Error: Subject line must not end with a period"
20        return 1
21    fi
22
23    # Check subject line length
24    # if [ $(echo "$commit_msg" | head -n1 | wc -c) -gt 51 ]; then
25    #     echo "Error: Subject line must be 50 characters or less"
26    #     return 1
27    # fi
28
29    # Check if there's a blank line between subject and body (if body exists)
30    if [ $(echo "$commit_msg" | wc -l) -gt 1 ] && [ -n "$(echo "$commit_msg" | sed -n '2p')" ]; then
31        echo "Error: There must be a blank line between the subject and body"
32        return 1
33    fi
34
35    # Check body line length
36    if echo "$commit_msg" | tail -n +3 | grep -q ".\{73\}"; then
37        echo "Error: Body lines must be 72 characters or less"
38        return 1
39    fi
40
41    return 0
42}
43
44# Function to display .gitmessage content
45display_gitmessage() {
46    echo "\nCommit message guidelines:"
47    echo "------------------------"
48    cat .gitmessage
49    echo "------------------------"
50}
51
52# Read the commit message
53commit_msg=$(cat "$1")
54
55# Validate the commit message
56if ! validate_commit_msg "$commit_msg"; then
57    echo "Commit message does not meet the required format. Please see the guidelines below:"
58    display_gitmessage
59    exit 1
60fi
61
62# If we've made it here, the commit message is valid
63exit 0

Then make the files executable:

1chmod +x .husky/commit-msg
2chmod +x .husky/pre-commit
3chmod +x .husky/prepare-commit-msg
4

3️⃣ Add commitlint

1pnpm install @commitlint/{config-conventional,cli} --save-dev

👉 At the root of the project, create a commitlint.config.js file:

1module.exports = {
2  extends: ['@commitlint/config-conventional'],
3  ignores: [(message) => message.startsWith('#')],
4  rules: {
5    'type-enum': [
6      2,
7      'always',
8      ['feat', 'fix', 'docs', 'style', 'refactor', 'test', 'chore'],
9    ],
10    'subject-empty': [2, 'never'],
11    'type-empty': [2, 'never'],
12    'subject-case': [0],
13    'header-max-length': [2, 'always', 100],
14  },
15  parserPreset: {
16    parserOpts: {
17      headerPattern: /^(\w+)(?:\((.*)\))?:(.*)$/,
18      headerCorrespondence: ['type', 'scope', 'subject'],
19    },
20  },
21}

👉 At the root of the project create a .gitmessage file :

1# <type>: <subject>
2# |<----  Using a Maximum Of 50 Characters  ---->|
3
4# Explain why this change is being made
5# |<----   Try To Limit Each Line to a Maximum Of 72 Characters   ---->|
6
7# --- COMMIT END ---
8# Type can be
9#    feat     (new feature)
10#    fix      (bug fix)
11#    refactor (refactoring production code)
12#    style    (formatting, missing semi colons, etc; no code change)
13#    docs     (changes to documentation)
14#    test     (adding or refactoring tests; no production code change)
15#    chore    (updating grunt tasks etc; no production code change)
16# --------------------
17# Remember to
18#   - Capitalize the subject line
19#   - Use the imperative mood in the subject line
20#   - Do not end the subject line with a period
21#   - Separate subject from body with a blank line
22#   - Use the body to explain what and why vs. how
23#   - Can use multiple lines with "-" for bullet points in body
24# --------------------
25# For major changes, start the first line of the commit message with "BREAKING CHANGE:"

Check

  • Try committing a file to see if the hooks work :
1git commit -m "test commit"

If Husky is configured correctly, it will block the commit if the checks fail.