@@ -32,59 +32,64 @@ jobs:
3232 run : |
3333 PR_NUMBER=${{ github.event.pull_request.number }}
3434 echo "PR_NUMBER=${PR_NUMBER}" >> $GITHUB_OUTPUT
35-
3635 - name : Checkout code
3736 uses : actions/checkout@v4
3837 with :
3938 ref : master
4039 sparse-checkout : MAINTAINERS
4140 persist-credentials : false
42-
4341 - name : Get changed files
4442 id : changed_files
4543 run : |
46- # 获取 PR 的变更文件列表
44+ # 通过 GitHub API 获取 PR 的变更文件列表
4745 changed_files=$(curl -s \
4846 "https://api.github.com/repos/${{ github.repository }}/pulls/${{ steps.extract-pr.outputs.PR_NUMBER }}/files" | \
49- jq -r '.[].filename')
47+ jq -r '.[].filename') # 使用 jq 提取文件名
5048 echo "$changed_files" | grep -v '^MAINTAINERS$' > changed_files.txt
51-
52- # 检查现有 bot 评论
49+
5350 existing_comment=$(curl -s \
54- "https://api.github.com/repos/${{ github.repository }}/issues/${{ steps.extract-pr.outputs.PR_NUMBER }}/comments" | \
55- jq -r '.[] | select(.user.login == "github-actions[bot]") | {body: .body} | @base64')
51+ "https://api.github.com/repos/${{ github.repository }}/issues/${{ steps.extract-pr.outputs.PR_NUMBER }}/comments" | \
52+ jq -r '.[] | select(.user.login == "github-actions[bot]") | {body: .body} | @base64')
5653
5754 echo "=== Changed Files ==="
5855 cat changed_files.txt
5956 echo "====================="
6057
61- comment_time=""
62- if [[ -n "$existing_comment" ]]; then
63- comment_body=$(echo "$existing_comment" | head -1 | base64 -d | jq -r .body | sed -nE 's/.*Last Updated: ([0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2} UTC).*/\1/p')
64- if [[ -n "$comment_body" ]]; then
65- comment_time=$(date -d "$comment_body" +%s)
66- fi
58+ comment_body=""
59+ if [[ ! -z "$existing_comment" ]]; then
60+ comment_body=$(echo "$existing_comment" | head -1 | base64 -d | jq -r .body|sed -nE 's/.*Last Updated: ([0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2} UTC).*/\1/p')
61+
62+ comment_time=$(date -d "$comment_body" +%s)
63+
64+ echo "${comment_body}"
65+ echo "COMMENT_TIME=${comment_time}" >> $GITHUB_OUTPUT
66+ else
67+ comment_time=""
68+ echo "COMMENT_TIME=${comment_time}" >> $GITHUB_OUTPUT
6769 fi
68- echo "COMMENT_TIME=${comment_time}" >> $GITHUB_OUTPUT
70+ echo "COMMENT_TIME=${comment_time}"
71+
6972
7073 - name : Parse MAINTAINERS file
7174 id : parse_maintainer
7275 run : |
73- # 解析 MAINTAINERS 文件,提取 tag、path 和 owners
76+ # 使用 AWK 解析 MAINTAINERS 文件格式:
77+ # 提取 tag(标签)、path(路径)和 owners(维护者 GitHub ID)
7478 awk '
7579 /^tag:/ {
76- tag = substr($0, index($0, $2))
80+ tag = substr($0, index($0, $2)) # 提取标签内容
7781 }
7882 /^path:/ {
83+ # 提取 path 字段并去除前后空格
7984 path = substr($0, index($0, $2))
80- gsub(/^[ \t]+|[ \t]+$/, "", path)
85+ gsub(/^[ \t]+|[ \t]+$/, "", path) # 清理前后空格和制表符
8186 }
8287 /^owners:/ {
83- owners = substr($0, index($0, $2))
84- split(owners, parts, /[()]/)
88+ owners = substr($0, index($0, $2)) # 提取维护者信息
89+ split(owners, parts, /[()]/) # 拆分出 GitHub ID(括号内内容)
8590 github_ids = ""
8691 for (i=2; i<=length(parts); i+=2) {
87- github_ids = github_ids "@" parts[i] " "
92+ github_ids = github_ids "@" parts[i] " " # 拼接为 @user 格式
8893 }
8994 print tag "|" path "|" github_ids
9095 }
@@ -93,148 +98,154 @@ jobs:
9398 - name : Generate reviewers list
9499 id : generate_reviewers
95100 run : |
96- rm -f triggered_reviewers.txt triggered_tags.txt unique_reviewers.txt unique_tags.txt
97- touch triggered_reviewers.txt triggered_tags.txt unique_reviewers.txt unique_tags.txt
101+ rm -f triggered_reviewers.txt triggered_tags.txt
102+ touch triggered_reviewers.txt triggered_tags.txt
98103
99104 while IFS='|' read -r tag path reviewers; do
100105 # 转义路径中的正则特殊字符
101106 escaped_path=$(sed 's/[.[\*^$]/\\&/g' <<< "$path")
102- # 匹配路径及其子目录
107+
108+ # 使用增强型正则匹配路径及其所有子目录
103109 if grep -qE "^$escaped_path(/.*)*" changed_files.txt; then
104110 echo "$reviewers" | tr -s ' ' '\n' | sed '/^$/d' >> triggered_reviewers.txt
105111 echo "$tag" >> triggered_tags.txt
106112 echo "Matched: $path → $tag"
107113 fi
108114 done < tag_data.csv
109115
110- # 生成去重后的审阅者和标签列表
111- sort triggered_reviewers.txt | uniq > unique_reviewers.txt
112- sort triggered_tags.txt | uniq > unique_tags.txt
113-
114116 echo "=== Matched Paths ==="
115- cat unique_tags .txt
117+ cat triggered_tags .txt
116118 echo "=== Matched Reviewers ==="
117- cat unique_reviewers .txt
119+ cat triggered_reviewers .txt
118120
119121 - name : Restore Reviewers Cache
120- id : reviewers-cache-restore
122+ id : reviewers-cache-restore
121123 if : ${{ steps.changed_files.outputs.COMMENT_TIME != '' }}
122124 uses : actions/cache/restore@v4
123- with :
125+ with :
124126 path : |
125127 unique_tags_bak.txt
126128 unique_reviewers_bak.txt
127129 key : ${{ runner.os }}-auto-assign-reviewers-${{ steps.extract-pr.outputs.PR_NUMBER }}-${{ steps.changed_files.outputs.COMMENT_TIME }}
128-
129130 - name : Get approval status
130131 id : get_approval
131132 run : |
132133 current_time=$(date -u +"%Y-%m-%d %H:%M UTC")
133-
134- # 检查 unique_reviewers.txt 是否存在
135- if [[ ! -f unique_reviewers.txt ]]; then
136- echo "Error: unique_reviewers.txt not found. Skipping approval status generation."
137- echo "CURRENT_TIME=${current_time}" >> $GITHUB_OUTPUT
138- exit 0
139- fi
140-
141134 reviewers=$(cat unique_reviewers.txt | tr '\n' '|')
142-
135+
143136 # 获取 PR 的所有评论
144137 comments=$(curl -s \
145138 "https://api.github.com/repos/${{ github.repository }}/issues/${{ steps.extract-pr.outputs.PR_NUMBER }}/comments")
146139
147140 echo '#!/bin/bash' > approval_data.sh
148141 echo 'declare -A approvals=()' >> approval_data.sh
149-
150- # 解析 LGTM 评论
142+
143+ # 使用 jq 解析包含 LGTM 的有效评论
151144 jq -r --arg reviewers "$reviewers" '
152- .[] |
153- select(.user.login != "github-actions[bot]") |
154- select(.body | test("^\\s*LGTM\\s*$"; "i")) |
145+ .[] |
146+ select(.user.login != "github-actions[bot]") | # 排除 bot 的评论
147+ select(.body | test("^\\s*LGTM\\s*$"; "i")) | # 匹配 LGTM 评论(不区分大小写)
155148 .user.login as $user |
156149 "@\($user)" as $mention |
157- ($reviewers | split("\\|") | index($mention)) as $is_reviewer |
158- if $is_reviewer != null then
159- "approvals[\"\($mention)\"]=\"\(.created_at)\""
160- else
161- empty
162- end
150+ select($mention | inside($reviewers)) | # 过滤有效审查者
151+ "approvals[\"\($mention)\"]=\"\(.created_at)\"" # 记录审批时间
163152 ' <<< "$comments" >> approval_data.sh
164-
165- # 加载审批数据
153+
154+ # 加载审查数据并生成状态报告
166155 chmod +x approval_data.sh
167156 source ./approval_data.sh
168157
169- # 生成审批状态报告
158+ jq -r --arg reviewers "$reviewers" '
159+ .[] |
160+ select(.user.login != "github-actions[bot]") | # 排除 bot 的评论
161+ select(.body | test("^\\s*LGTM\\s*$"; "i")) | # 匹配 LGTM 评论(不区分大小写)
162+ .user.login as $user |
163+ "@\($user)" as $mention |
164+ select($mention | inside($reviewers)) | # 过滤有效审查者
165+ "\($mention) \(.created_at)" # 输出审查者和时间
166+ ' <<< "$comments" >> approval_data.txt
167+
170168 notified_users=""
171169 if [[ -f unique_reviewers_bak.txt ]]; then
172170 notified_users=$(cat unique_reviewers_bak.txt | xargs)
171+ else
172+ notified_users=""
173173 fi
174174
175175 {
176176 echo "---"
177177 echo "### 📊 Current Review Status (Last Updated: $current_time)"
178178 while read -r reviewer; do
179- display_name="${reviewer#@}"
179+ formatted_reviewers=""
180+ for r in $reviewers; do
181+ if [[ " ${notified_users[@]} " =~ " $reviewer " ]]; then
182+ formatted_reviewers+="${reviewer#@}"
183+ else
184+ formatted_reviewers+="$reviewer"
185+ fi
186+ done
187+
180188 if [[ -n "${approvals[$reviewer]}" ]]; then
181189 timestamp=$(date -d "${approvals[$reviewer]}" -u +"%Y-%m-%d %H:%M UTC")
182- echo "- ✅ **$display_name** Reviewed On $timestamp"
190+
191+ echo "- ✅ **$formatted_reviewers** Reviewed On $timestamp"
183192 else
184- echo "- ⌛ **$display_name ** Pending Review"
193+ echo "- ⌛ **$formatted_reviewers ** Pending Review"
185194 fi
186195 done < unique_reviewers.txt
187196 } > review_status.md
188-
197+
189198 echo "CURRENT_TIME=${current_time}" >> $GITHUB_OUTPUT
190-
191199 - name : Generate review data
192200 id : generate_review
193201 run : |
202+ unique_tags=""
194203 unique_tags=$(cat unique_tags.txt | xargs)
195204 unique_tags_bak=""
196205 if [[ -f unique_tags_bak.txt ]]; then
197206 unique_tags_bak=$(cat unique_tags_bak.txt | xargs)
198207 fi
199208
200- # 确定新标签
201209 existing_tags=""
202210 for r in $unique_tags; do
203- if [[ ! " $unique_tags_bak " =~ " $r " ]]; then
211+ if [[ " ${unique_tags_bak[@]} " =~ " $r " ]]; then
212+ echo "$r 不存在于数组中"
213+ else
204214 existing_tags+="$r "
205215 fi
206216 done
207217
218+ current_time=$(date -u +"%Y-%m-%d %H:%M UTC")
208219 {
220+
221+ # 生成审查分配信息
209222 echo "## 📌 Code Review Assignment"
210223 echo ""
211224
212225 while IFS='|' read -r tag path reviewers; do
213226 if grep -qE "^$path(/|$)" changed_files.txt; then
214227 echo "### 🏷️ Tag: $tag"
215- echo "**Path:** \`$path\`"
228+ echo "**Path:** \`$path\` "
216229
217- # 根据标签是否为新标签决定是否移除 @
218- if [[ " $existing_tags " =~ " $tag " ]]; then
219- echo "**Reviewers:** $reviewers"
230+ if [[ " ${existing_tags[@]} " =~ " $tag " ]]; then
231+ echo "**Reviewers:** $reviewers "
220232 else
221233 formatted_reviewers=""
222234 for r in $reviewers; do
223235 formatted_reviewers+="${r#@} "
224236 done
225- echo "**Reviewers:** $formatted_reviewers"
237+ echo "**Reviewers:** $formatted_reviewers "
226238 fi
227239
228240 echo "<details>"
229241 echo "<summary><b>Changed Files</b> (Click to expand)</summary>"
230242 echo ""
231- grep -E "^$path(/|$)" changed_files.txt | sed 's/^/- /'
243+ grep -E "^$path(/|$)" changed_files.txt | sed 's/^/- /' # 列出匹配的变更文件
232244 echo ""
233245 echo "</details>"
234246 echo ""
235247 fi
236248 done < tag_data.csv
237-
238249 # 插入审查状态
239250 cat review_status.md
240251
@@ -253,43 +264,43 @@ jobs:
253264 echo "> ℹ️ **刷新CI状态操作需要具备仓库写入权限。**"
254265 echo "> ℹ️ **Refresh CI status operation requires repository Write permission.**"
255266 } > review_data.md
256-
257267 - name : Post/Update comment
258268 id : post_comment
259269 run : |
260- # 查找现有 bot 评论
270+ # 查找现有的 bot 评论
261271 existing_comment=$(curl -s \
262272 -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
263273 "https://api.github.com/repos/${{ github.repository }}/issues/${{ steps.extract-pr.outputs.PR_NUMBER }}/comments" | \
264274 jq -r '.[] | select(.user.login == "github-actions[bot]") | {id: .id, body: .body} | @base64')
265-
275+
266276 if [[ -n "$existing_comment" ]]; then
267277 # 更新现有评论
268278 comment_id=$(echo "$existing_comment" | head -1 | base64 -d | jq -r .id)
269279 echo "Updating existing comment $comment_id"
270- curl -s -X PATCH \
280+ response=$( curl -s -X PATCH \
271281 -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
272282 -d "$(jq -n --arg body "$(cat review_data.md)" '{body: $body}')" \
273- "https://api.github.com/repos/${{ github.repository }}/issues/comments/$comment_id"
283+ "https://api.github.com/repos/${{ github.repository }}/issues/comments/$comment_id")
274284 else
275285 # 创建新评论
276286 echo "Creating new comment"
277- curl -s -X POST \
287+ response=$( curl -s -X POST \
278288 -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
279289 -d "$(jq -n --arg body "$(cat review_data.md)" '{body: $body}')" \
280- "https://api.github.com/repos/${{ github.repository }}/issues/${{ steps.extract-pr.outputs.PR_NUMBER }}/comments"
290+ "https://api.github.com/repos/${{ github.repository }}/issues/${{ steps.extract-pr.outputs.PR_NUMBER }}/comments")
281291 fi
282-
283292 - name : Get Comment Time
284293 id : get_comment_time
285294 run : |
286- current_time="${{ steps.get_approval.outputs.CURRENT_TIME }}"
287- comment_time=$(date -d "$current_time" +%s)
295+ existing_comment=$(curl -s \
296+ "https://api.github.com/repos/${{ github.repository }}/issues/${{ steps.extract-pr.outputs.PR_NUMBER }}/comments" | \
297+ jq -r '.[] | select(.user.login == "github-actions[bot]") | {body: .body} | @base64')
298+ comment_body="${{ steps.get_approval.outputs.CURRENT_TIME }}"
299+ comment_time=$(date -d "$comment_body" +%s)
288300 echo "CURRENT_TIME=${comment_time}" >> $GITHUB_OUTPUT
289301 cp unique_reviewers.txt unique_reviewers_bak.txt
290302 cp unique_tags.txt unique_tags_bak.txt
291-
292- - name : Save Reviewers Cache
303+ - name : Restore Reviewers Save
293304 id : reviewers-cache-save
294305 uses : actions/cache/save@v4
295306 with :
0 commit comments