くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

commitlintとhuskyでConventional Commitsに従ったコミットログを強制する

いろいろ見ているとコミットメッセージの仕様なんてのがあるらしい。

A specification for adding human and machine readable meaning to commit messages

nuxtvueをみていると、
それに従っているっぽいので、同じような感じでできるように設定してみたときの備忘録(*´ω`*)

使ったのは、この2つ

Conventional Commitsにあわせておくと、Changelogを自動生成できたりするのでより便利に

インストール

$ npm i -D @commitlint/config-conventional @commitlint/cli
$ npm i -D @commitlint/types

設定ファイルの追加

// commitlint.config.ts
import type { UserConfig } from "@commitlint/types";

const config: UserConfig = {
  extends: ["@commitlint/config-conventional"]
};

export default config;

huskyのインストール

# Install & Activate Husky
$ npx husky-init && npm install       # npm
$ pnpm dlx husky-init && pnpm install # pnpm

# create dir by 'husky install'
$ tree .husky/ -a
.husky/
├── _
│   ├── .gitignore
│   └── husky.sh
└── pre-commit

$ git diff HEAD package.json
  "scripts": {
+    "prepare": "husky install"
   },
   "devDependencies": {
     "@commitlint/cli": "^17.2.0",
     "@commitlint/config-conventional": "^17.2.0",
     "@commitlint/types": "^17.0.0",
+    "husky": "^8.0.0",

   }
   
$ cat .husky/pre-commit 
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npm test

hookの追加

$ npx husky add .husky/commit-msg  'npx --no -- commitlint --edit ${1}'

$ cat .husky/commit-msg 
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx --no -- commitlint --edit ${1}

おまけ

pnpmでcommitlintを実行する

$ pnpm husky add .husky/commit-msg  'pnpm commitlint --edit ${1}'

$ cat .husky/commit-msg 
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

pnpm commitlint --edit ${1}

コミットせずに試す

$ echo "aaa" | npx commitlint   # npm
$ echo "aaa" | pnpm commitlint  # pnpm
⧗   input: aaa
✖   subject may not be empty [subject-empty]type may not be empty [type-empty]

✖   found 2 problems, 1 warnings

1行目にissueを含める

import type { UserConfig } from "@commitlint/types";

const config: UserConfig = {
  extends: ["@commitlint/config-conventional"],
  plugins: [{
    rules: {
      "issue-empty": (parsed) => {
        const { header } = parsed;
        const hasIssue = header.match(/(#\d+)/) != null;
        return hasIssue ? [true] : [false, "issue may not to empty"];
      }
    }
  }],
  rules: {
    "issue-empty": [1, "never"],
  }
};

export default config;
$ echo "chore: aaa" | pnpm commitlint
⧗   input: chore: aaa
⚠   issue may not to empty [issue-empty]

参考にしたサイト様