-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcommitlint.config.ts
143 lines (126 loc) · 4.76 KB
/
commitlint.config.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import type { UserConfig } from "@commitlint/types";
import { RuleConfigSeverity } from "@commitlint/types";
const types = [
"feat", // new user-facing feature (must have (or may introduce a new) scope)
"enha", // enhancement of any kind (must have a scope)
"fix", // bug fix (must have a scope)
"docs", // documentation enhancement (same as 'enha(docs)')
"style", // code style enhancement (same as 'enha(style)')
"refactor", // refactoring code enhancement (must have a scope)
"perf", // performance improvement enhancement (must have a scope)
"test", // testing enhancement (must have a scope)
"build", // build enhancement
"ci", // ci enhancement
"chore", // Relating to repository maintenance
"revert", // reverting a previous commit
"merge", // merging branches
];
const typesRequiringScope = ["feat", "enha", "fix", "refactor", "perf", "test"];
/**
* Scopes are used to describe the area of the project that the commit affects.
* They are used to group commits together and to provide context to the commit
* message.
*
* The scopes are divided into two categories: areas and topics. Areas are
* broader categories that describe the area of the project that the commit
* affects, while topics are more specific categories that describe the
* functionality or purpose of the commit.
*
* For example, commits that add a new feature to the frontend user interface
* might look like this:
*
* - `feat(ui,auth): add forgot password functionality ...`
* - `feat(ui,projects): Implement project url sharing ...`
*
* Another example might be a commit that adds a new feature to the backend API related to
* user authentication:
*
* `feat(api,auth): use new endpoint for user authentication ...`
*
*/
const scopes = {
areas: [
/* Frontend */
"ui", // UI related changes
"api", // REST API related changes
"supabase", // Supabase related changes
/* Others */
"core", // core changes neither specific to frontend nor backend
"docs", // documentation changes
"style", // code style changes
"webserver", // webserver and proxying changes
"version", // version bumping
],
topics: [
"auth",
"blog",
"analytics",
"automation",
"faq",
"projects",
"roles",
"settings",
"inbox",
],
};
const Configuration: UserConfig = {
extends: ["@commitlint/config-conventional"],
rules: {
"type-case": [RuleConfigSeverity.Error, "always", "lower-case"],
"type-empty": [RuleConfigSeverity.Error, "never"],
"type-enum": [RuleConfigSeverity.Error, "always", types],
"subject-case": [RuleConfigSeverity.Disabled, "always", "lower-case"],
"subject-empty": [RuleConfigSeverity.Error, "never"],
"subject-outer-whitespace": [RuleConfigSeverity.Error, "always"],
"scope-rich": [RuleConfigSeverity.Error, "always"],
"body-max-line-length": [RuleConfigSeverity.Warning, "always", 150],
"header-max-length": [RuleConfigSeverity.Warning, "always", 100],
},
plugins: [
{
rules: {
"scope-rich": (commit, when) => {
const errorMessages: string[] = [
"scope is required for commit of type" +
`[${typesRequiringScope.join(", ")}]`,
`scope must be one of the areas [${scopes.areas.join(", ")}], ` +
"optionally paired with one of the topics " +
`[${scopes.topics.join(", ")}], ` +
"all separated by a comma (no spaces)",
];
const scope = commit.scope ?? "";
const scopeRequired = typesRequiringScope.includes(commit.type!);
if (when !== "always" || !scopeRequired) return [true, undefined];
if (scopeRequired && !scope.length) {
return [false, errorMessages[0]];
}
if (scope.includes(",")) {
// area must be provided and valid, and if topics are provided,
// they must be valid
const [area, ...topics] = scope.split(",");
if (
!scopes.areas.includes(area) ||
topics.some((topic) => !scopes.topics.includes(topic))
) {
return [false, errorMessages[1]];
}
} else if (!scopes.areas.includes(scope)) {
return [false, errorMessages[1]];
}
return [true, undefined];
},
"subject-outer-whitespace": (commit, when) => {
const errorMessages: string[] = [
"subject must not have more than one preceding whitespace character",
];
if (when !== "always" || !commit.subject) return [true, undefined];
if ([" ", "\t", "\n", "\r"].includes(commit.subject[0])) {
return [false, errorMessages[0]];
}
return [true, undefined];
},
},
},
],
};
export default Configuration;