commitlint について
commitlint の設定と利用方法を扱い、Conventional Commits のルールに沿ってコミットメッセージを検証するスキルです。ルール設定、設定ファイルの検出、CLI・コードからの検証に加え、フックや CI/CD、LLM による文面生成との連携も説明します。
主な機能
- 01commitlint 設定ファイルの検出
- 02Conventional Commits ルールの設定
- 03CLI・コードからのメッセージ検証
- 04フック・CI/CD とのチェック連携
- 05LLM プロンプト用ルールの抽出
活用シーン
- 01リポジトリでコミットメッセージ検査を設定
- 02CI/CD パイプラインでコミットを検証
- 03差分とルールに基づくメッセージ生成
- 04commitlint 設定エラーの調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ jamie-bitflight/ claude_skills --skill commitlintインストール後、Claude Code で/commitlintを入力して読み込まれたか確認します。
詳細
Commitlint
commitlint の設定とルールを使用して、コミットメッセージが Conventional Commits 形式に準拠しているか検証します。
このスキルを使用する場面
次の場合にこのスキルを使用します。
- リポジトリに commitlint をセットアップする
- commitlint のルールと共有可能な設定を構成する
- commitlint をコミット前フックや CI/CD パイプラインと統合する
- commitlint の設定からルールを抽出し、コミットメッセージ生成用の LLM プロンプトを作成する
- コミットメッセージをプログラムで検証する
- commitlint の設定や検証エラーをトラブルシューティングする
- commitlint のルール構文と重要度レベルを理解する
- リポジトリ内の commitlint 設定ファイルを検出する
主な機能
設定の検出
commitlint は cosmiconfig を使用して、次の優先順位で設定ファイルを検索します。
専用の設定ファイル:
.commitlintrc
.commitlintrc.json
.commitlintrc.yaml
.commitlintrc.yml
.commitlintrc.js
.commitlintrc.cjs
.commitlintrc.mjs
.commitlintrc.ts
.commitlintrc.cts
commitlint.config.js
commitlint.config.cjs
commitlint.config.mjs
commitlint.config.ts
commitlint.config.cts
パッケージファイル:
package.jsonのcommitlintフィールドpackage.yaml(PNPM)のcommitlintフィールド
設定形式
JavaScript ES Modules(推奨):
// commitlint.config.js or commitlint.config.mjs
export default {
extends: ['@commitlint/config-conventional'],
};
TypeScript:
// commitlint.config.ts
import type { UserConfig } from '@commitlint/types';
import { RuleConfigSeverity } from '@commitlint/types';
const config: UserConfig = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [RuleConfigSeverity.Error, 'always', ['feat', 'fix', 'docs']],
},
};
export default config;
JSON:
{
"extends": ["@commitlint/config-conventional"]
}
YAML:
extends:
- "@commitlint/config-conventional"
ルールの設定
ルールは配列 [level, applicability, value] で設定します。
重要度レベル:
| レベル | 意味 | TypeScript Enum |
|---|---|---|
| 0 | 無効 | RuleConfigSeverity.Disabled |
| 1 | 警告 | RuleConfigSeverity.Warning |
| 2 | エラー | RuleConfigSeverity.Error |
適用条件:
'always'- ルールに一致する必要があります'never'- ルールに一致してはいけません
ルールの例:
rules: {
// Error if type is not in enum
'type-enum': [2, 'always', ['feat', 'fix', 'docs', 'style', 'refactor', 'perf', 'test', 'build', 'ci', 'chore', 'revert']],
// Error if type is empty
'type-empty': [2, 'never'],
// Error if subject is empty
'subject-empty': [2, 'never'],
// Error if header exceeds 100 chars
'header-max-length': [2, 'always', 100],
// Error if subject ends with period
'subject-full-stop': [2, 'never', '.'],
// Warning if body doesn't have leading blank line
'body-leading-blank': [1, 'always'],
}
一般的な設定
@commitlint/config-conventional
最も広く使用されている共有可能な設定です。デフォルトのエラーレベルのルール:
| Rule | Configuration | Pass Example | Fail Example |
|---|---|---|---|
type-enum | ['build', 'chore', 'ci', 'docs', 'feat', 'fix', 'perf', 'refactor', 'revert', 'style', 'test'] | fix: message | foo: message |
type-case | 'lowerCase' | fix: message | FIX: message |
type-empty | never | fix: message | : message |
subject-case | never + ['sentence-case', 'start-case', 'pascal-case', 'upper-case'] | fix: some message | fix: Some Message |
subject-empty | never | fix: message | fix: |
subject-full-stop | never, '.' | fix: message | fix: message. |
header-max-length | 100 | 短いヘッダー | ヘッダーが100文字超 |
body-leading-blank | always(警告) | 本文の前に空行 | 空行なし |
body-max-line-length | 100 | 100文字以下の行 | 100文字超の行 |
footer-leading-blank | always(警告) | フッターの前に空行 | 空行なし |
footer-max-line-length | 100 | 100文字以下の行 | 100文字超の行 |
設定スキーマの全体
// commitlint.config.js
export default {
// Extend shareable configs (resolved via node resolution)
extends: ['@commitlint/config-conventional'],
// Parser preset for parsing commit messages
parserPreset: 'conventional-changelog-atom',
// Output formatter
formatter: '@commitlint/format',
// Custom rules (override inherited rules)
rules: {
'type-enum': [2, 'always', ['feat', 'fix', 'docs', 'style', 'refactor', 'test', 'chore']],
},
// Functions that return true to ignore specific commits
// Merged with default ignores (merge commits, reverts, semver tags)
ignores: [(commit) => commit.includes('WIP')],
// Whether to use default ignore patterns
// Default patterns: 'Merge pull request', 'Revert X', 'v1.2.3', etc.
defaultIgnores: true,
// Custom help URL shown on failure
helpUrl: 'https://example.com/commit-guidelines',
// Prompt configuration (for @commitlint/cz-commitlint)
prompt: {
messages: {},
questions: {
type: {
description: 'Select the type of change:',
},
},
},
};
CLI の使用方法
インストール
# npm
npm install -D @commitlint/cli @commitlint/config-conventional
# yarn
yarn add -D @commitlint/cli @commitlint/config-conventional
# pnpm
pnpm add -D @commitlint/cli @commitlint/config-conventional
よく使うコマンド
# Lint the last commit
npx commitlint --last
# Lint a range of commits
npx commitlint --from HEAD~5
# Lint from a specific commit
npx commitlint --from abc1234
# Lint message from stdin
echo "feat: add feature" | npx commitlint
# Lint message from file
npx commitlint < .git/COMMIT_EDITMSG
# Lint with edit flag (reads .git/COMMIT_EDITMSG)
npx commitlint --edit
# Lint with custom config path
npx commitlint --config ./custom-commitlint.config.js
# Print resolved config
npx commitlint --print-config
# Strict mode (warnings become exit code 2)
npx commitlint --last --strict
終了コード
| Code | Meaning |
|---|---|
| 0 | 成功(エラーなし) |
| 1 | リントエラーが見つかりました |
| 2 | 警告が見つかりました(厳格モードのみ) |
| 3 | エラーが見つかりました(厳格モード) |
| 9 | 設定ファイルが見つかりません(-g フラグ指定時) |
ルールリファレンス
Type ルール
| Rule | Condition | Default Applicability |
|---|---|---|
type-enum | type が value に含まれている | always |
type-case | type が value のケースである | always, 'lower-case' |
type-empty | type が空である | never |
type-max-length | type の文字数が value 以下である | always, Infinity |
type-min-length | type の文字数が value 以上である | always, 0 |
件名のルール
| ルール | 条件 | デフォルトの適用方法 |
|---|---|---|
subject-case | subject が value のケースである | always |
subject-empty | subject が空である | never |
subject-full-stop | subject が value で終わる | never, '.' |
subject-max-length | subject が value 文字以下である | always, Infinity |
subject-min-length | subject が value 文字以上である | always, 0 |
subject-exclamation-mark | subject の : の前に感嘆符がある | never |
スコープのルール
| ルール | 条件 | デフォルトの適用方法 |
|---|---|---|
scope-enum | scope が value に含まれている | always, [] |
scope-case | scope が value のケースである | always, 'lower-case' |
scope-empty | scope が空である | never |
scope-max-length | scope が value 文字以下である | always, Infinity |
scope-min-length | scope が value 文字以上である | always, 0 |
ヘッダーのルール
| ルール | 条件 | デフォルトの適用方法 |
|---|---|---|
header-case | header が value のケースである | always, 'lower-case' |
header-full-stop | header が value で終わる | never, '.' |
header-max-length | header が value 文字以下である | always, 72 |
header-min-length | header が value 文字以上である | always, 0 |
header-trim | header の先頭と末尾に空白がない | always |
本文のルール
| ルール | 条件 | デフォルトの適用方法 |
|---|---|---|
body-leading-blank | body が空行で始まる | always |
body-empty | body が空である | never |
body-max-length | body が value 文字以下である | always, Infinity |
body-max-line-length | body の各行が value 文字以下である(URLを除く) | always, Infinity |
body-min-length | body が value 文字以上である | always, 0 |
body-case | body が value のケースである | always, 'lower-case' |
body-full-stop | body が value で終わる | never, '.' |
フッターのルール
| ルール | 条件 | デフォルトの適用方法 |
|---|---|---|
footer-leading-blank | footer が空行で始まる | always |
footer-empty | footer が空である | never |
footer-max-length | footer が value 文字以下である | always, Infinity |
footer-max-line-length | footer の各行が value 文字以下である | always, Infinity |
footer-min-length | footer が value 文字以上である | always, 0 |
ケース値
ケース(*-case)をチェックするルールの場合:
[
'lower-case', // lowercase
'upper-case', // UPPERCASE
'camel-case', // camelCase
'kebab-case', // kebab-case
'pascal-case', // PascalCase
'sentence-case', // Sentence case
'snake-case', // snake_case
'start-case', // Start Case
]
プログラムからの使用
設定の読み込み
import load from '@commitlint/load';
async function getCommitlintConfig() {
const config = await load();
console.log(config.rules);
return config;
}
メッセージの検証
import load from '@commitlint/load';
import lint from '@commitlint/lint';
async function validateMessage(message) {
const config = await load();
const result = await lint(message, config.rules);
return {
valid: result.valid,
errors: result.errors,
warnings: result.warnings,
};
}
LLM 統合パターン
プロンプト生成用のルール抽出
commitlint の設定から、LLM に適した制約を生成します。
def extract_rules_for_prompt(config: dict) -> str:
"""Extract commitlint rules into LLM-friendly format."""
rules = config.get("rules", {})
prompt_parts = []
# Extract type-enum if present
if "type-enum" in rules:
level, applicability, types = rules["type-enum"]
if level > 0 and applicability == "always":
prompt_parts.append(f"Allowed commit types: {', '.join(types)}")
# Extract scope-enum if present
if "scope-enum" in rules:
level, applicability, scopes = rules["scope-enum"]
if level > 0 and applicability == "always" and scopes:
prompt_parts.append(f"Allowed scopes: {', '.join(scopes)}")
# Extract header-max-length
if "header-max-length" in rules:
level, applicability, length = rules["header-max-length"]
if level > 0:
prompt_parts.append(f"Header must be {length} characters or less")
# Extract subject-case
if "subject-case" in rules:
level, applicability, cases = rules["subject-case"]
if level > 0 and applicability == "never":
prompt_parts.append(f"Subject must NOT use: {', '.join(cases)}")
return "\n".join(prompt_parts)
検証ループ
import subprocess
async def validate_with_commitlint(message: str, cwd: Path | None = None) -> tuple[bool, list[str]]:
"""
Validate commit message with commitlint.
Args:
message: The commit message to validate
cwd: Working directory (defaults to current directory)
Returns:
Tuple of (is_valid, error_messages)
"""
result = subprocess.run(["npx", "commitlint"], input=message, capture_output=True, text=True, cwd=cwd)
if result.returncode == 0:
return True, []
# Parse errors from stderr
errors = [line.strip() for line in result.stderr.split("\n") if line.strip()]
return False, errors
検証ループのパターン:
- LLM が差分とルールに基づいてコミットメッセージを生成します
- 生成されたメッセージに対して commitlint を実行します
- 検証に失敗した場合、コンテキストとともにエラーを LLM に返します
- 再試行します(デフォルトでは最大 3 回)
- 最終メッセージを返します(有効なメッセージ、または再試行後のベストエフォート)
よくある問題
Node v24 の ESM の問題:
ES モジュールの設定には .mjs 拡張子を使用するか、package.json に "type": "module" を追加してください
extends の不足:
extends または rules がない設定では、「Please add rules」エラーが発生します。少なくとも次のいずれかを含めてください。
export default {
extends: ['@commitlint/config-conventional'],
};
空の設定エラー:
設定ファイルには、少なくとも extends または rules を定義する必要があります。
scope enum の空の配列:
scope-enum に [] を指定すると、すべてのスコープが許可されます。制限するには、具体的な配列を使用してください。
rules: {
'scope-enum': [2, 'always', ['api', 'ui', 'docs']],
}
subject のケースに関する注意点:
@commitlint/config-conventional は特定のケースに対して never を使用します。つまり、そのケースは禁止されており、必須ではありません。
// This forbids sentence-case, start-case, pascal-case, upper-case
'subject-case': [2, 'never', ['sentence-case', 'start-case', 'pascal-case', 'upper-case']]
プリコミット統合
commitlint をプリコミットフックと統合するには、フックマネージャーを直接設定してください。ワークスペースにインストール済みのプリコミットプラグインが含まれている場合は、フックの設定方法を確認するために利用できます。
Conventional Commits のリファレンス
Conventional Commits のフォーマット仕様と例については、このドキュメント内のリファレンスを使用してください。ワークスペースにインストール済みの Conventional Commits プラグインが含まれている場合は、追加の例やメッセージのパターンを確認するために利用できます。
リファレンス
公式ドキュメント
- Commitlint 公式サイト(2025-01-15 閲覧)
- 設定リファレンス(2025-01-15 閲覧)
- ルールリファレンス(2025-01-15 閲覧)
- CLI リファレンス(2025-01-15 閲覧)
- スタートガイド(2025-01-15 閲覧)
- GitHub リポジトリ(2025-01-15 閲覧)
関連仕様
- Conventional Commits - コミットメッセージのフォーマット仕様
- Cosmiconfig - 設定ファイルの検出メカニズム