-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprepare-commit-msg
executable file
·194 lines (157 loc) · 5.42 KB
/
prepare-commit-msg
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#!/bin/bash
# This script is used by the prepare-commit-msg hook to check the commit itself
# and prevent some mistakes. To commit message formater, check commit-msg hook.
if [[ ${BASH_SOURCE[0]} -ef "$0" ]]; then
# source config and common file
source "${0%/*}/components/config"
source "${0%/*}/components/common"
else
# source from unit test
source "./components/config"
source "./components/common"
fi
# is_new is a function to check if the current commit is an amend
is_new() {
# check if the argument is provided
if [[ $# -ne 1 ]]; then
error "is_new function require sha1 argument"
return $FAILURE
fi
local _sha1="$1"
# check if the commit is a new commit
if [[ -z "$_sha1" ]]; then
return $SUCCESS
fi
return $FAILURE
}
# secure_wip is a function to check if the previous commit is a WIP
secure_wip() {
# check if this flag is disabled
if [[ $WIP_SECURE_COMMIT -eq $FALSE ]]; then
warning "Conniting after a WIP commit are allowed 😱"
return $SUCCESS
fi
# check if two arg are provided
if [[ $# -ne 2 ]]; then
error "secure_wip function require two arguments"
return $FAILURE
fi
local _sha1="$1"
local _message="$2" # previous commit message if it is a new commit
# check if it is not a new commit
if ! is_new "$_sha1"; then
return $SUCCESS
fi
# check if the previous commit is a WIP
if grep -q -Ei 'WIP ?(\([^)]\) ?)?:' <<<"$_message"; then
error "Previous commit is a WIP, please fix it before new commit"
error "$_message"
return $FAILURE
fi
return $SUCCESS
}
# secure_branch is a function to check if the branch is protected
secure_branch() {
# check if this flag is disabled
if [[ $BRANCH_PROTECTED -eq $FALSE ]]; then
warning "Protecting branch are not enabled to prevent commit mistake 😱"
return $SUCCESS
fi
# check argument
if [[ $# -ne 1 ]]; then
error "secure_branch function require one argument"
return $FAILURE
fi
local _branch="$1"
# check if the branch name is empty
if [[ -z "$_branch" ]]; then
warning "Branch name is empty, that's strange 🤔"
return $SUCCESS
fi
# check if there is a regex to match the branch name
if [[ -z "$BRANCH_PROTECTED_NAME" ]]; then
info "No regex to match a protected branch name"
return $SUCCESS
fi
# check if the branch regex match the branch name
if grep -q -E "$BRANCH_PROTECTED_NAME" <<<"$_branch"; then
error "Pushing on protected branch '$_branch' is not allowed"
return $FAILURE
fi
return $SUCCESS
}
# secure_gpg is a function to check if the commit needs GPG signing
secure_gpg() {
# check if this flag is disabled
if [[ $GPG_REQUIRED -eq $FALSE ]]; then
warning "GPG signing is not required 🔓"
return $SUCCESS
fi
# check argument
if [[ $# -ne 2 ]]; then
error "secure_branch_push function require one argument"
return $FAILURE
fi
local _gpgsign="$1"
local _signing_key="$2"
# Check if any GPG keys are available
if ! gpg --list-secret-keys --keyid-format LONG | grep -q "sec " >/dev/null; then
error "No GPG keys found. To create one:"
error "1. gpg --full-generate-key"
error "2. Choose RSA and RSA (default)"
error "3. Keysize 4096 or bigger"
error "4. Set expiry (0 = no expiry)"
error "5. Fill in your user information"
return $FAILURE
fi
# Check if user.signingkey is configured
if [[ -z $_signing_key ]]; then
error "GPG signing key not configured. To set it:"
error "1. List your keys: gpg --list-secret-keys --keyid-format LONG"
error "2. Copy your key ID (after sec rsa4096/ for example)"
error "3. Run: git config --global user.signingkey YOUR_KEY_ID"
# Show available keys to help user
info "Available GPG keys:"
gpg --list-secret-keys --keyid-format LONG
return $FAILURE
fi
# check if commit signing is enabled
if [[ -z $_gpgsign ]]; then
if [[ $GPG_AUTOFIX -eq $TRUE ]]; then
info "Auto enabling GPG signing for this repository 🔐"
git config commit.gpgsign true
return $SUCCESS
fi
error "GPG signing is required but not enabled"
error "Run: 'git config commit.gpgsign true' to enable it"
return $FAILURE
fi
return $SUCCESS
}
## MAIN
# do not execute if this script is sourced required for unit testing
if [[ ${BASH_SOURCE[0]} -ef "$0" ]]; then
# Fille where the commit message is stored
COMMIT_MSG_FILE="$1"
# Source of the commit message (message, template, merge, squash or commit)
COMMIT_SOURCE="$2"
# SHA1 of the commit (empty if it is a new commit)
SHA1="$3"
# get the gpgsign flag
_gpgsign=$(git config --get user.signingkey 2>/dev/null)
# get the user signing key
_signing_key=$(git config --get user.signingkey 2>/dev/null)
# check the PGP signature
if ! secure_gpg "$_gpgsign" "$_signing_key"; then
exit $FAILURE
fi
# check if the previous commit is a WIP
if ! secure_wip "$SHA1" "$(git log -1 --pretty=%s)"; then
exit $FAILURE
fi
# check if the branch is protected
if ! secure_branch "$(git branch --show-current)"; then
exit $FAILURE
fi
exit $SUCCESS
fi