📓 Lint commit messages
# Rules
## body-case
- **condition**: `body` is in case `value`
- **rule**: `always`
- **value**
```text
'lower-case'
```
- **possible values**
```js
[
"lower-case", // default
"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
];
```
## body-empty
- **condition**: `body` is empty
- **rule**: `never`
## body-full-stop
- **condition**: `body` ends with `value`
- **rule**: `never`
- **value**
```text
'.'
```
## body-leading-blank
- **condition**: `body` begins with blank line
- **rule**: `always`
## body-max-length
- **condition**: `body` has `value` or less characters
- **rule**: `always`
- **value**
```text
Infinity
```
## body-max-line-length
- **condition**: `body` lines have `value` or less characters, or contain a URL
- **rule**: `always`
- **value**
```text
Infinity
```
## body-min-length
- **condition**: `body` has `value` or more characters
- **rule**: `always`
- **value**
```text
0
```
## breaking-change-exclamation-mark
- **condition**: Either both or neither `header` has an exclamation mark before the `:` marker
and a line in `footer` matches the regular expression `^BREAKING[ -]CHANGE:`
- **rule**: `always`
> [!NOTE]
>
> This rule enforces that breaking changes are marked by both a `!` in the header
> and `BREAKING CHANGE` in the footer. The behavior is that of an XNOR operation:
>
> - It passes when either both are present or both are not.
> - It fails when one is present and the other is not.
## footer-empty
- **condition**: `footer` is empty
- **rule**: `never`
## footer-leading-blank
- **condition**: `footer` begins with blank line
- **rule**: `always`
## footer-max-length
- **condition**: `footer` has `value` or less characters
- **rule**: `always`
- **value**
```text
Infinity
```
## footer-max-line-length
- **condition**: `footer` lines have `value` or less characters
- **rule**: `always`
- **value**
```text
Infinity
```
## footer-min-length
- **condition**: `footer` has `value` or more characters
- **rule**: `always`
- **value**
```text
0
```
## header-case
- **condition**: `header` is in case `value`
- **rule**: `always`
- **value**
```text
'lower-case'
```
- **possible values**
```js
[
"lower-case", // default
"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
];
```
## header-full-stop
- **condition**: `header` ends with `value`
- **rule**: `never`
- **value**
```text
'.'
```
## header-max-length
- **condition**: `header` has `value` or less characters
- **rule**: `always`
- **value**
```text
72
```
## header-min-length
- **condition**: `header` has `value` or more characters
- **rule**: `always`
- **value**
```text
0
```
## header-trim
- **condition**: `header` must not have initial or trailing whitespaces
- **rule**: `always`
## references-empty
- **condition**: `references` has at least one entry
- **rule**: `never`
## scope-case
- **condition**: `scope` is in case `value`
- **rule**: `always`
- **value**
```text
'lower-case'
```
- **possible values**
```js
[
"lower-case", // default
"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
];
```
- extended value (object based)
```js
{
cases: ["kebab-case"],
delimiters: ["/"]
}
```
- `cases` — list of allowed case formats
- `delimiters` — optional list of delimiter strings used to split multi-segment scopes (default: `["/", "\", ","]`)
## scope-delimiter-style
- **condition**: all delimiters found in `scope` must match `value`
- **rule**: `always`
- **value**
```text
["/", "\", ","]
```
> [!NOTE]
>
> - When using this rule together with [scope-enum](#scope-enum) or [scope-case](#scope-case), make sure to provide the same `delimiters` configuration in those rules as well. Otherwise scope parsing may become inconsistent.
## scope-empty
- **condition**: `scope` is empty
- **rule**: `never`
## scope-enum
- **condition**: `scope` is found in value
- **rule**: `always`
- **value**
```text
[]
```
- extended value (object based)
```js
{
scopes: ["foo", "bar"],
delimiters: ["/"]
}
```
- `scopes` — list of allowed scope values
- `delimiters` — optional list of delimiter strings used to split multi-segment scopes (default: `["/", "\", ","]`)
> [!NOTE]
>
> - This rule always passes if no scopes are provided in the message or the value > is an empty array.
> - When set to `always`, all message scopes must be found in the value.
> - When set to `never`, none of the message scopes can be found in the value.
## scope-max-length
- **condition**: `scope` has `value` or less characters
- **rule**: `always`
- **value**
```text
Infinity
```
## scope-min-length
- **condition**: `scope` has `value` or more characters
- **rule**: `always`
- **value**
```text
0
```
## signed-off-by
- **condition**: `message` has `value`
- **rule**: `always`
- **value**
```text
'Signed-off-by:'
```
## subject-case
- **condition**: `subject` is in case `value`
- **rule**: `never`
- **value**
```js
["sentence-case", "start-case", "pascal-case", "upper-case"];
```
- **possible values**
```js
[
"lower-case", // lower case
"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
];
```
## subject-empty
- **condition**: `subject` is empty
- **rule**: `never`
## subject-exclamation-mark
- **condition**: `subject` has exclamation before the `:` marker
- **rule**: `never`
## subject-full-stop
- **condition**: `subject` ends with `value`
- **rule**: `never`
- **value**
```text
'.'
```
## subject-max-length
- **condition**: `subject` has `value` or less characters
- **rule**: `always`
- **value**
```text
Infinity
```
## subject-min-length
- **condition**: `subject` has `value` or more characters
- **rule**: `always`
- **value**
```text
0
```
## trailer-exists
- **condition**: `message` has trailer `value`
- **rule**: `always`
- **value**
```text
'Signed-off-by:'
```
## type-case
- **description**: `type` is in case `value`
- **rule**: `always`
- **value**
```text
'lower-case'
```
- **possible values**
```js
[
"lower-case", // default
"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
];
```
## type-empty
- **condition**: `type` is empty
- **rule**: `never`
## type-enum
- **condition**: `type` is found in value
- **rule**: `always`
- **value**
```js
["build", "chore", "ci", "docs", "feat", "fix", "perf", "refactor", "revert", "style", "test"];
```
## type-max-length
- **condition**: `type` has `value` or less characters
- **rule**: `always`
- **value**
```text
Infinity
```
## type-min-length
- **condition**: `type` has `value` or more characters
- **rule**: `always`
- **value**
```text
0
```