Skip to content

Commit ba78e3d

Browse files
committed
CI+Meta: Synchronize commit linting rules
Our CI commit linter now evaluates commit messages line by line, similar to `Meta/lint-commit.sh`. The URL rule was updated to allow any freestanding URL, optionally prefixed by whitespace.
1 parent e3a56ef commit ba78e3d

File tree

2 files changed

+26
-15
lines changed

2 files changed

+26
-15
lines changed

.github/workflows/lint-commits.yml

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,31 +24,36 @@ jobs:
2424
error: "Commit message contains CRLF line breaks (only unix-style LF linebreaks are allowed)",
2525
},
2626
{
27-
pattern: /^.+(\n(\n.*)*)?$/,
27+
line: 2,
28+
pattern: /^$/,
2829
error: "Empty line between commit title and body is missing",
2930
},
3031
{
31-
pattern: /^((?!^Merge branch )[\s\S])*$/,
32+
line: 1,
33+
pattern: /^(?!Merge branch )/,
3234
error: "Commit is a git merge commit, use the rebase command instead",
3335
},
3436
{
35-
pattern: /^\S.*?\S: .+/,
37+
line: 1,
38+
pattern: /^(Revert "|\S+: )/,
3639
error: "Missing category in commit title (if this is a fix up of a previous commit, it should be squashed)",
3740
},
3841
{
42+
line: 1,
3943
pattern: /^\S.*?: [A-Z0-9]/,
4044
error: "First word of commit after the subsystem is not capitalized",
4145
},
4246
{
43-
pattern: /^.+[^.\n](\n.*)*$/,
47+
line: 1,
48+
pattern: /[^.]$/,
4449
error: "Commit title ends in a period",
4550
},
4651
{
47-
pattern: /^.{0,72}(?:\n(?:(.{0,72})|(.*?([a-z]+:\/\/)?(([a-zA-Z0-9_]|-)+\.)+[a-z]{2,}(:\d+)?([a-zA-Z_0-9@:%\+.~\?&/=]|-)+).*?))*$/,
48-
error: "Commit message lines are too long (maximum allowed is 72 characters, except for URLs)",
52+
pattern: /^(.{0,72}|\s*[a-z]+:\/\/([a-z0-9\-]+\.)+[a-z]{2,}(:\d+)?(\/[a-zA-Z_0-9@:%+.~?&=\-]+)*)$/,
53+
error: "Commit message lines are too long (maximum allowed is 72 characters, except for URLs on their own line)",
4954
},
5055
{
51-
pattern: /^((?!Signed-off-by: )[\s\S])*$/,
56+
pattern: /^(?!Signed-off-by: )/,
5257
error: "Commit body contains a Signed-off-by tag",
5358
},
5459
];
@@ -69,14 +74,20 @@ jobs:
6974
if (author !== null && excludedBotIds.includes(author.id)) {
7075
continue;
7176
}
72-
const commitErrors = [];
73-
for (const { pattern, error } of rules) {
74-
if (!pattern.test(message)) {
75-
commitErrors.push(error);
77+
let commitErrors = [];
78+
message.split("\n").forEach((line, index) => {
79+
for (const { line: ruleLine, pattern, error } of rules) {
80+
if (ruleLine !== undefined && ruleLine !== index + 1) {
81+
continue;
82+
}
83+
if (!pattern.test(line)) {
84+
commitErrors.push(error);
85+
}
7686
}
77-
}
87+
});
7888
if (commitErrors.length > 0) {
7989
const title = message.split("\n")[0];
90+
commitErrors = [...new Set(commitErrors)]; // remove duplicates
8091
errors.push([`${title} (${sha}):`, ...commitErrors].join("\n "));
8192
}
8293
}

Meta/lint-commit.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#!/usr/bin/env bash
2+
set -euo pipefail
23

34
# the file containing the commit message is passed as the first argument
45
commit_file="$1"
@@ -53,14 +54,13 @@ while read -r line; do
5354
error "Commit title ends in a period"
5455
fi
5556

56-
url_pattern="([a-z]+:\/\/)?(([a-zA-Z0-9_]|-)+\.)+[a-z]{2,}(:\d+)?([a-zA-Z_0-9@:%\+.~\?&\/=]|-)+"
57+
url_pattern='^\s*[a-z]+:\/\/([a-z0-9\-]+\.)+[a-z]{2,}(:\d+)?(\/[a-zA-Z_0-9@:%+.~?&=\-]+)*$'
5758
if [[ $line_length -gt 72 ]] && (echo "$line" | grep -E -v -q "$url_pattern"); then
58-
error "Commit message lines are too long (maximum allowed is 72 characters)"
59+
error "Commit message lines are too long (maximum allowed is 72 characters, except for URLs on their own line)"
5960
fi
6061

6162
if [[ "$line" == "Signed-off-by: "* ]]; then
6263
error "Commit body contains a Signed-off-by tag"
6364
fi
64-
6565
done <"$commit_file"
6666
exit 0

0 commit comments

Comments
 (0)