Skip to content

Commit 70252d0

Browse files
committed
feat: assign PR reviews based on the MAINTAINERS list
1 parent 3436aa6 commit 70252d0

File tree

2 files changed

+185
-0
lines changed

2 files changed

+185
-0
lines changed
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
#
2+
# Copyright (c) 2006-2025, RT-Thread Development Team
3+
#
4+
# SPDX-License-Identifier: Apache-2.0
5+
#
6+
# Change Logs:
7+
# Date Author Notes
8+
# 2025-01-21 kurisaW Initial version
9+
#
10+
11+
# Script Function Description: Assign PR reviews based on the MAINTAINERS list.
12+
13+
name: Auto Review Assistant
14+
15+
on:
16+
pull_request:
17+
types: [opened, synchronize, reopened]
18+
workflow_dispatch:
19+
issue_comment:
20+
types: [created]
21+
22+
jobs:
23+
assign-reviewers:
24+
runs-on: ubuntu-22.04
25+
if: github.repository_owner == 'RT-Thread'
26+
permissions:
27+
issues: write
28+
pull-requests: write
29+
contents: read
30+
steps:
31+
- name: Checkout code
32+
uses: actions/checkout@v3
33+
34+
- name: Get changed files
35+
id: changed_files
36+
run: |
37+
changed_files=$(curl -s \
38+
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN_AUTO_REVIEW }}" \
39+
"https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files" | \
40+
jq -r '.[].filename')
41+
42+
echo "$changed_files" | grep -v '^MAINTAINERS$' > changed_files.txt
43+
44+
- name: Parse MAINTAINERS file
45+
id: parse_maintainer
46+
run: |
47+
awk '
48+
/^tag:/ { tag=$2 }
49+
/^path:/ { path=$2 }
50+
/^owners:/ {
51+
split($0, parts, /[()]/)
52+
github_ids = ""
53+
for (i=2; i<=length(parts); i+=2) {
54+
github_ids = github_ids "@" parts[i] " "
55+
}
56+
print tag "|" path "|" github_ids
57+
}
58+
' MAINTAINERS > tag_data.csv
59+
60+
- name: Generate reviewers list
61+
id: generate_reviewers
62+
run: |
63+
rm -f triggered_reviewers.txt
64+
while IFS='|' read -r tag path reviewers; do
65+
if grep -qE "^$path(/|$)" changed_files.txt; then
66+
echo "$reviewers" | tr ' ' '\n' >> triggered_reviewers.txt
67+
fi
68+
done < tag_data.csv
69+
awk 'NF && !seen[$0]++' triggered_reviewers.txt > unique_reviewers.txt
70+
71+
- name: Get approval status
72+
id: get_approval
73+
run: |
74+
current_time=$(date -u +"%Y-%m-%d %H:%M UTC")
75+
reviewers=$(cat unique_reviewers.txt | tr '\n' '|')
76+
77+
comments=$(curl -s \
78+
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN_AUTO_REVIEW }}" \
79+
"https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments")
80+
81+
echo '#!/bin/bash' > approval_data.sh
82+
echo 'declare -A approvals=()' >> approval_data.sh
83+
84+
jq -r --arg reviewers "$reviewers" '
85+
.[] |
86+
select(.user.login != "github-actions[bot]") |
87+
select(.body | test("^\\s*LGTM\\s*$"; "i")) |
88+
.user.login as $user |
89+
"@\($user)" as $mention |
90+
select($mention | inside($reviewers)) |
91+
"approvals[\"\($mention)\"]=\"\(.created_at)\""
92+
' <<< "$comments" >> approval_data.sh
93+
94+
chmod +x approval_data.sh
95+
source ./approval_data.sh
96+
97+
{
98+
echo "---"
99+
echo "### 📊 Current Review Status (Last Updated: $current_time)"
100+
while read -r reviewer; do
101+
if [[ -n "${approvals[$reviewer]}" ]]; then
102+
timestamp=$(date -d "${approvals[$reviewer]}" -u +"%Y-%m-%d %H:%M UTC")
103+
echo "- ✅ **$reviewer** Reviewed On $timestamp"
104+
else
105+
echo "- ⌛ **$reviewer** Pending Review"
106+
fi
107+
done < unique_reviewers.txt
108+
} > review_status.md
109+
110+
- name: Generate review data
111+
id: generate_review
112+
run: |
113+
current_time=$(date -u +"%Y-%m-%d %H:%M UTC")
114+
{
115+
echo "## 📌 Code Review Assignment"
116+
echo ""
117+
118+
while IFS='|' read -r tag path reviewers; do
119+
if grep -qE "^$path(/|$)" changed_files.txt; then
120+
echo "### 🏷️ Tag: $tag"
121+
echo "**Path:** \`$path\` "
122+
echo "**Reviewers:** $reviewers "
123+
echo "<details>"
124+
echo "<summary><b>Changed Files</b> (Click to expand)</summary>"
125+
echo ""
126+
grep -E "^$path(/|$)" changed_files.txt | sed 's/^/- /'
127+
echo ""
128+
echo "</details>"
129+
echo ""
130+
fi
131+
done < tag_data.csv
132+
133+
cat review_status.md
134+
135+
echo "---"
136+
echo "### 📝 Review Instructions"
137+
echo ""
138+
echo "1. **维护者可以通过单击此处来刷新审查状态:** [🔄 刷新状态](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/rerun"
139+
echo " **Maintainers can refresh the review status by clicking here:** [🔄 Refresh Status](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/rerun"
140+
echo ""
141+
echo "2. **确认审核通过后评论 \`LGTM/lgtm\`**"
142+
echo " **Comment \`LGTM/lgtm\` after confirming approval**"
143+
echo ""
144+
echo "3. **PR合并前需至少一位维护者确认**"
145+
echo " **PR must be confirmed by at least one maintainer before merging**"
146+
echo ""
147+
echo "> ℹ️ **刷新CI状态操作需要具备仓库写入权限。**"
148+
echo "> ℹ️ **Refresh CI status operation requires repository Write permission.**"
149+
} > review_data.md
150+
151+
- name: Post/Update comment
152+
id: post_comment
153+
run: |
154+
existing_comment=$(curl -s \
155+
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN_AUTO_REVIEW }}" \
156+
"https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments" | \
157+
jq -r '.[] | select(.user.login == "github-actions[bot]") | {id: .id, body: .body} | @base64')
158+
159+
if [[ -n "$existing_comment" ]]; then
160+
comment_id=$(echo "$existing_comment" | head -1 | base64 -d | jq -r .id)
161+
echo "Updating existing comment $comment_id"
162+
response=$(curl -s -X PATCH \
163+
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN_AUTO_REVIEW }}" \
164+
-d "$(jq -n --arg body "$(cat review_data.md)" '{body: $body}')" \
165+
"https://api.github.com/repos/${{ github.repository }}/issues/comments/$comment_id")
166+
else
167+
echo "Creating new comment"
168+
response=$(curl -s -X POST \
169+
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN_AUTO_REVIEW }}" \
170+
-d "$(jq -n --arg body "$(cat review_data.md)" '{body: $body}')" \
171+
"https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments")
172+
fi

MAINTAINERS

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# MAINTAINERS for autoreview assigning in github comment
2+
3+
tag: workflow
4+
path: .github
5+
owners: Li Tao(supperthomas)<[email protected]>
6+
7+
tag: stm32f407-rt-spark
8+
path: bsp/stm32/stm32f407-rt-spark
9+
owners: Zhang Bingru(Rbb666)<[email protected]>
10+
11+
tag: libc
12+
path: components/libc
13+
owners: Man Jiantin(mysterywolf)<[email protected]>

0 commit comments

Comments
 (0)