@@ -56,6 +56,23 @@ on_error() {
56
56
exit " $1 "
57
57
}
58
58
59
+ # Resolves a name and email using .mailmap via git check-mailmap, falling back to the provided values if no match is found.
60
+ #
61
+ # $1 - name
62
+ # $2 - email
63
+ resolve_name_email () {
64
+ local name=" $1 "
65
+ local email=" $2 "
66
+ local resolved
67
+
68
+ resolved=$( git check-mailmap " $name <$email >" 2> /dev/null)
69
+ if [ -n " $resolved " ]; then
70
+ echo " $resolved "
71
+ else
72
+ echo " $name <$email >"
73
+ fi
74
+ }
75
+
59
76
# Resolves GitHub handle to name and email using .mailmap.
60
77
#
61
78
# $1 - GitHub handle
@@ -76,24 +93,47 @@ resolve_user() {
76
93
fi
77
94
}
78
95
79
- # Makes authenticated GitHub API requests.
96
+ # Makes GitHub API requests.
80
97
#
81
98
# $1 - HTTP method (GET or POST)
82
99
# $2 - API endpoint
83
- # $3 - Data for POST requests
100
+ # $3 - data for POST requests
84
101
github_api () {
85
102
local method=" $1 "
86
103
local endpoint=" $2 "
87
104
local data=" $3 "
88
105
89
- if [ " $method " == " GET" ]; then
90
- curl -s -H " Authorization: token $GITHUB_TOKEN " " $GITHUB_API_URL$endpoint "
91
- elif [ " $method " == " POST" ]; then
92
- curl -s -X POST -H " Authorization: token $GITHUB_TOKEN " -H " Content-Type: application/json" -d " $data " " $GITHUB_API_URL$endpoint "
93
- else
94
- echo " Invalid HTTP method: $method "
95
- on_error 1
106
+ # Initialize an array to hold curl headers:
107
+ local headers=()
108
+
109
+ # If GITHUB_TOKEN is set, add the Authorization header:
110
+ if [ -n " $GITHUB_TOKEN " ]; then
111
+ headers+=(" -H" " Authorization: token $GITHUB_TOKEN " )
96
112
fi
113
+
114
+ # Determine the HTTP method and construct the curl command accordingly...
115
+ case " $method " in
116
+ GET)
117
+ curl -s " ${headers[@]} " " $GITHUB_API_URL$endpoint "
118
+ ;;
119
+ POST)
120
+ # For POST requests, always set the Content-Type header>
121
+ headers+=(" -H" " Content-Type: application/json" )
122
+
123
+ # If data is provided, include it in the request:
124
+ if [ -n " $data " ]; then
125
+ curl -s -X POST " ${headers[@]} " -d " $data " " $GITHUB_API_URL$endpoint "
126
+ else
127
+ # Handle cases where POST data is required but not provided:
128
+ echo " POST request requires data."
129
+ on_error 1
130
+ fi
131
+ ;;
132
+ * )
133
+ echo " Invalid HTTP method: $method "
134
+ on_error 1
135
+ ;;
136
+ esac
97
137
}
98
138
99
139
# Main execution sequence.
@@ -103,6 +143,10 @@ main() {
103
143
pr_title=$( echo " $pr_details " | jq -r ' .title' )
104
144
pr_body=$( echo " $pr_details " | jq -r ' .body // ""' )
105
145
pr_url=$( echo " $pr_details " | jq -r ' .html_url' )
146
+ pr_author_login=$( echo " $pr_details " | jq -r ' .user.login' )
147
+
148
+ # Resolve the PR author's name and email using .mailmap:
149
+ pr_author_resolved=$( resolve_user " $pr_author_login " )
106
150
107
151
# Extract reviewers:
108
152
pr_reviews=$( github_api " GET" " /repos/$REPO_OWNER /$REPO_NAME /pulls/$pr_number /reviews" )
@@ -111,8 +155,51 @@ main() {
111
155
# Fetch commits in the PR:
112
156
pr_commits=$( github_api " GET" " /repos/$REPO_OWNER /$REPO_NAME /pulls/$pr_number /commits" )
113
157
114
- # Extract co-authors from commits:
115
- co_authors=$( echo " $pr_commits " | jq -r ' .[].commit.message' | grep -Eio " Co-authored-by:.*" | sort -u)
158
+ # Extract co-authors from commit messages:
159
+ processed_co_authors=" "
160
+ while IFS= read -r co_author_line; do
161
+ name_email=$( echo " $co_author_line " | sed -E ' s/Co-authored-by:[[:space:]]*(.*)/\1/' )
162
+ name=$( echo " $name_email " | sed -E ' s/^(.*)<.*>$/\1/' | xargs)
163
+ email=$( echo " $name_email " | sed -E ' s/^.*<(.*)>$/\1/' | xargs)
164
+ resolved_author=$( resolve_name_email " $name " " $email " )
165
+
166
+ processed_co_authors+=" Co-authored-by: $resolved_author " $' \n '
167
+ done <<< " $co_authors"
168
+
169
+ # Extract commit authors:
170
+ authors_info=$( echo " $pr_commits " | jq -r ' .[] | .commit.author | "\(.name) <\(.email)>"' | sort -u | sed ' /^ *<.*>/d' | sed ' /^$/d' )
171
+
172
+ # Process commit authors:
173
+ commit_authors=" "
174
+ while IFS= read -r author_line; do
175
+ # Skip empty lines:
176
+ if [ -z " $author_line " ]; then
177
+ continue
178
+ fi
179
+
180
+ # Extract name and email:
181
+ name=$( echo " $author_line " | sed -E ' s/^(.*)<.*>$/\1/' | xargs)
182
+ email=$( echo " $author_line " | sed -E ' s/^.*<(.*)>$/\1/' | xargs)
183
+
184
+ # Resolve name and email using .mailmap:
185
+ resolved_author=$( resolve_name_email " $name " " $email " )
186
+
187
+ # Skip if the resolved author matches the resolved PR author:
188
+ if [ " $resolved_author " == " $pr_author_resolved " ]; then
189
+ continue
190
+ fi
191
+
192
+ commit_authors+=" $resolved_author " $' \n '
193
+ done <<< " $authors_info"
194
+
195
+ # Remove any empty lines and duplicates:
196
+ commit_authors=$( echo " $commit_authors " | sort -u | sed ' /^$/d' )
197
+
198
+ # Prefix with 'Co-authored-by: ':
199
+ commit_authors_formatted=$( echo " $commit_authors " | sed ' s/^/Co-authored-by: /' | sort -u)
200
+
201
+ # Combine co-authors and commit authors:
202
+ all_co_authors=$( echo -e " $co_authors \n$commit_authors_formatted " | sort -u | sed ' /^$/d' )
116
203
117
204
# Extract 'Signed-off-by' lines from commits:
118
205
signed_off_bys=$( echo " $pr_commits " | jq -r ' .[].commit.message' | grep -Eio ' Signed-off-by:.*' | sort -u)
@@ -124,6 +211,7 @@ main() {
124
211
125
212
# GitHub-supported closing keywords:
126
213
closing_keywords=(" close" " closes" " closed" " fix" " fixes" " fixed" " resolve" " resolves" " resolved" )
214
+
127
215
# Create a regex pattern from the keywords:
128
216
keywords_pattern=$( IFS=' |' ; echo " ${closing_keywords[*]} " )
129
217
@@ -148,8 +236,8 @@ main() {
148
236
commit_body+=" \n$ref_issues "
149
237
fi
150
238
commit_body+=" \n"
151
- if [ -n " $co_authors " ]; then
152
- commit_body+=" \n$co_authors "
239
+ if [ -n " $all_co_authors " ]; then
240
+ commit_body+=" \n$all_co_authors "
153
241
fi
154
242
for reviewer in $reviewers ; do
155
243
resolved_reviewer=$( resolve_user " $reviewer " )
0 commit comments