Skip to content

Commit 34ec109

Browse files
authored
Merge pull request #21803 from crasbe/pr/check_commits
dist/tools: add no-merge and colon check to commit-msg check
2 parents 59af2e4 + bdf88c1 commit 34ec109

File tree

4 files changed

+75
-30
lines changed

4 files changed

+75
-30
lines changed

CONTRIBUTING.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,10 @@ It is possible to check if your code follows these conventions:
149149
simple as it is.
150150
```
151151

152+
* The commit message is automatically checked by the static tests for keywords
153+
that prevent a merge, for example "fixup" or "DONOTMERGE". The full list
154+
of these keywords is stored in `dist/tools/pr_check/no_merge_keywords`.
155+
152156
### Pull Requests
153157
[pull requests]: #pull-requests
154158

@@ -304,6 +308,9 @@ $ git commit --fixup <prefix2 commit hash>
304308

305309
### Squash commits after review
306310

311+
*** Note: If the static tests warn you about a no-merge keyword, please look
312+
at [our commit conventions][commit-conventions].
313+
307314
Squashing a commit is done using the rebase subcommand of git in interactive
308315
mode:
309316

@@ -323,7 +330,7 @@ phase, squashing commits can be performed in a single command:
323330
$ git rebase -i --autosquash
324331
```
325332

326-
**Watch out: Don't squash your commit until a maintainer asks you to do it.**
333+
***Watch out: Don't squash your commit until a maintainer asks you to do it.***
327334

328335
Otherwise the history of review changes is lost and for large PRs, it
329336
makes it difficult for the reviewer to follow them. It might also happen that

dist/tools/commit-msg/check.sh

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@
66
# General Public License v2.1. See the file LICENSE in the top level
77
# directory for more details.
88

9+
# shellcheck source=/dev/null
910
. "$(dirname "$0")/../ci/github_annotate.sh"
1011

1112
github_annotate_setup
1213

1314
MSG_MAX_LENGTH=50
1415
MSG_STRETCH_LENGTH=72
1516

16-
if tput colors 2> /dev/null > /dev/null && [ $(tput colors) -ge 8 ]; then
17+
if tput colors 2> /dev/null > /dev/null && [ "$(tput colors)" -ge 8 ]; then
1718
CERROR1="\033[1;31m"
1819
CWARN1="\033[1;33m"
1920
CERROR2="\033[0;31m"
@@ -31,14 +32,14 @@ if [ -n "${BASH_VERSION}" ]; then
3132
# properly in _escape
3233
ECHO_ESC='echo -e'
3334
else
34-
ECHO='echo'
35+
ECHO_ESC='echo'
3536
fi
3637

3738
# If no branch but an option is given, unset BRANCH.
3839
# Otherwise, consume this parameter.
3940
BRANCH="${1}"
4041
if echo "${BRANCH}" | grep -q '^-'; then
41-
if [ $(git rev-parse --abbrev-ref HEAD) != "master" ]; then
42+
if [ "$(git rev-parse --abbrev-ref HEAD)" != "master" ]; then
4243
BRANCH="master"
4344
else
4445
BRANCH=""
@@ -55,20 +56,39 @@ if [ -z "${BRANCH}" ]; then
5556
fi
5657

5758
ERROR="$(git log \
58-
--no-merges --pretty=format:'%s' $(git merge-base ${BRANCH} HEAD)..HEAD | \
59-
while read msg; do
60-
msg_length=$(echo "${msg}" | awk '{print length($0)}')
59+
--no-merges --pretty=format:'%s' "$(git merge-base "${BRANCH}" HEAD)"..HEAD | \
60+
while read -r msg; do
61+
ERROR=0
62+
MSG=""
6163
62-
if [ ${msg_length} -gt ${MSG_MAX_LENGTH} ]; then
63-
ERROR=0
64-
if [ ${msg_length} -gt ${MSG_STRETCH_LENGTH} ]; then
64+
# Check if the message is too long.
65+
msg_length="$(echo "${msg}" | awk '{print length($0)}')"
66+
if [ "${msg_length}" -gt "${MSG_MAX_LENGTH}" ]; then
67+
if [ "${msg_length}" -gt "${MSG_STRETCH_LENGTH}" ]; then
6568
MSG="Commit message is longer than ${MSG_STRETCH_LENGTH} characters:"
6669
ERROR=1
6770
echo "error"
6871
else
6972
MSG="Commit message is longer than ${MSG_MAX_LENGTH}"
7073
MSG="${MSG} (but < ${MSG_STRETCH_LENGTH}) characters:"
7174
fi
75+
fi
76+
77+
# Check if the message has a colon and if the first colon is followed
78+
# by a space.
79+
if echo "$msg" | grep -q ":"; then
80+
if ! echo "$msg" | grep -Eq '^[^:]*: '; then
81+
MSG="The colon after the area designation is not followed by"
82+
MSG="${MSG} a space."
83+
fi
84+
else
85+
MSG="The commit message is missing a colon after the area"
86+
MSG="${MSG} designation."
87+
ERROR=1
88+
echo "error"
89+
fi
90+
91+
if [ -n "${MSG}" ]; then
7292
if github_annotate_is_on; then
7393
if [ ${ERROR} -eq 1 ]; then
7494
github_annotate_error_no_file "${MSG} \"${msg}\""

dist/tools/pr_check/check.sh

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,26 @@
77
# directory for more details.
88
#
99

10+
# shellcheck source=/dev/null
1011
. "$(dirname "$0")/../ci/github_annotate.sh"
1112

12-
: "${RIOTBASE:=$(cd $(dirname $0)/../../../; pwd)}"
13-
cd $RIOTBASE
13+
: "${RIOTBASE:="$(cd "$(dirname "$0")"/../../../ || exit; pwd)"}"
14+
cd "$RIOTBASE" || exit
1415

1516
: "${RIOTTOOLS:=${RIOTBASE}/dist/tools}"
1617

1718
EXIT_CODE=0
1819

20+
# Keywords that should trigger the commit message check and prevent an accidental
21+
# merge of something not meant to be merged.
22+
# The pretty-print format of the commit messages is always the following:
23+
# `a5e4f038b8 commit message`
24+
# This has to be reflected in the RegEx matching pattern.
25+
NOMERGE_KEYWORD_FILE="$(dirname "$0")/no_merge_keywords"
26+
1927
github_annotate_setup
2028

21-
if tput colors &> /dev/null && [ $(tput colors) -ge 8 ]; then
29+
if tput colors &> /dev/null && [ "$(tput colors)" -ge 8 ]; then
2230
CERROR="\e[1;31m"
2331
CRESET="\e[0m"
2432
else
@@ -32,30 +40,28 @@ else
3240
RIOT_MASTER="master"
3341
fi
3442

35-
keyword_filter() {
36-
grep -i \
37-
-e "^ [0-9a-f]\+ .\{0,2\}SQUASH" \
38-
-e "^ [0-9a-f]\+ .\{0,2\}FIX" \
39-
-e "^ [0-9a-f]\+ .\{0,2\}REMOVE *ME" \
40-
-e "^ [0-9a-f]\+ .\{0,2\}Update"
41-
}
42-
43-
SQUASH_COMMITS="$(git log $(git merge-base HEAD "${RIOT_MASTER}")...HEAD --pretty=format:" %h %s" | \
44-
keyword_filter)"
43+
SQUASH_COMMITS="$(git log "$(git merge-base HEAD "${RIOT_MASTER}")"...HEAD --pretty=format:"%h %s" | \
44+
grep -i -f "${NOMERGE_KEYWORD_FILE}")"
4545

4646
if [ -n "${SQUASH_COMMITS}" ]; then
4747
if github_annotate_is_on; then
48-
echo "${SQUASH_COMMITS}" | while read commit; do
49-
ANNOTATION="Commit needs to be squashed: \"${commit}\""
50-
ANNOTATION="${ANNOTATION}\n\nPLEASE ONLY SQUASH WHEN ASKED BY A "
48+
ANNOTATION=""
49+
while read -r commit; do
50+
ANNOTATION="${ANNOTATION}Commit needs to be squashed or contains a no-merge keyword: \"${commit}\"\n"
51+
done < <(echo "${SQUASH_COMMITS}")
52+
53+
if [ -n "${ANNOTATION}" ]; then
54+
ANNOTATION="${ANNOTATION}\nPLEASE ONLY SQUASH WHEN ASKED BY A "
5155
ANNOTATION="${ANNOTATION}MAINTAINER!"
5256
ANNOTATION="${ANNOTATION}\nSee: "
53-
ANNOTATION="${ANNOTATION}https://github.com/RIOT-OS/RIOT/blob/master/CONTRIBUTING.md#squash-commits-after-review"
57+
ANNOTATION="${ANNOTATION}https://github.com/RIOT-OS/RIOT/blob/master/CONTRIBUTING.md#squash-commits-after-review\n"
5458
github_annotate_error_no_file "${ANNOTATION}"
55-
done
59+
fi
5660
else
57-
echo -e "${CERROR}Pull request needs squashing:${CRESET}" 1>&2
58-
echo -e "${SQUASH_COMMITS}"
61+
echo -e "${CERROR}Pull request needs squashing or contains no-merge keywords:${CRESET}" 1>&2
62+
while IFS= read -r line; do
63+
echo -e " ${line}"
64+
done <<< "${SQUASH_COMMITS}"
5965
fi
6066
EXIT_CODE=1
6167
fi
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[0-9a-f]\+ SQUASH
2+
[0-9a-f]\+ FIX
3+
[0-9a-f]\+ REMOVE *ME
4+
[0-9a-f]\+ Update
5+
[0-9a-f]\+ \<DONOTMERGE\>
6+
[0-9a-f]\+ \<DO NOT MERGE\>
7+
[0-9a-f]\+ \<DON'T MERGE\>
8+
[0-9a-f]\+ \<NO MERGE\>
9+
[0-9a-f]\+ \<DELETE ME\>
10+
[0-9a-f]\+ \<DELETEME\>
11+
[0-9a-f]\+ \<WIP\>
12+
[0-9a-f]\+ \<TEMP\>

0 commit comments

Comments
 (0)