-
Notifications
You must be signed in to change notification settings - Fork 5.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: assign PR reviews based on the MAINTAINERS list
- Loading branch information
Showing
2 changed files
with
185 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
# | ||
# Copyright (c) 2006-2025, RT-Thread Development Team | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
# | ||
# Change Logs: | ||
# Date Author Notes | ||
# 2025-01-21 kurisaW Initial version | ||
# | ||
|
||
# Script Function Description: Assign PR reviews based on the MAINTAINERS list. | ||
|
||
name: Auto Review Assistant | ||
|
||
on: | ||
pull_request: | ||
types: [opened, synchronize, reopened] | ||
workflow_dispatch: | ||
issue_comment: | ||
types: [created] | ||
|
||
jobs: | ||
assign-reviewers: | ||
runs-on: ubuntu-22.04 | ||
if: github.repository_owner == 'RT-Thread' | ||
permissions: | ||
issues: write | ||
pull-requests: write | ||
contents: read | ||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v3 | ||
|
||
- name: Get changed files | ||
id: changed_files | ||
run: | | ||
changed_files=$(curl -s \ | ||
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN_AUTO_REVIEW }}" \ | ||
"https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files" | \ | ||
jq -r '.[].filename') | ||
echo "$changed_files" | grep -v '^MAINTAINERS$' > changed_files.txt | ||
- name: Parse MAINTAINERS file | ||
id: parse_maintainer | ||
run: | | ||
awk ' | ||
/^tag:/ { tag=$2 } | ||
/^path:/ { path=$2 } | ||
/^owners:/ { | ||
split($0, parts, /[()]/) | ||
github_ids = "" | ||
for (i=2; i<=length(parts); i+=2) { | ||
github_ids = github_ids "@" parts[i] " " | ||
} | ||
print tag "|" path "|" github_ids | ||
} | ||
' MAINTAINERS > tag_data.csv | ||
- name: Generate reviewers list | ||
id: generate_reviewers | ||
run: | | ||
rm -f triggered_reviewers.txt | ||
while IFS='|' read -r tag path reviewers; do | ||
if grep -qE "^$path(/|$)" changed_files.txt; then | ||
echo "$reviewers" | tr ' ' '\n' >> triggered_reviewers.txt | ||
fi | ||
done < tag_data.csv | ||
awk 'NF && !seen[$0]++' triggered_reviewers.txt > unique_reviewers.txt | ||
- name: Get approval status | ||
id: get_approval | ||
run: | | ||
current_time=$(date -u +"%Y-%m-%d %H:%M UTC") | ||
reviewers=$(cat unique_reviewers.txt | tr '\n' '|') | ||
comments=$(curl -s \ | ||
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN_AUTO_REVIEW }}" \ | ||
"https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments") | ||
echo '#!/bin/bash' > approval_data.sh | ||
echo 'declare -A approvals=()' >> approval_data.sh | ||
jq -r --arg reviewers "$reviewers" ' | ||
.[] | | ||
select(.user.login != "github-actions[bot]") | | ||
select(.body | test("^\\s*LGTM\\s*$"; "i")) | | ||
.user.login as $user | | ||
"@\($user)" as $mention | | ||
select($mention | inside($reviewers)) | | ||
"approvals[\"\($mention)\"]=\"\(.created_at)\"" | ||
' <<< "$comments" >> approval_data.sh | ||
chmod +x approval_data.sh | ||
source ./approval_data.sh | ||
{ | ||
echo "---" | ||
echo "### 📊 Current Review Status (Last Updated: $current_time)" | ||
while read -r reviewer; do | ||
if [[ -n "${approvals[$reviewer]}" ]]; then | ||
timestamp=$(date -d "${approvals[$reviewer]}" -u +"%Y-%m-%d %H:%M UTC") | ||
echo "- ✅ **$reviewer** Reviewed On $timestamp" | ||
else | ||
echo "- ⌛ **$reviewer** Pending Review" | ||
fi | ||
done < unique_reviewers.txt | ||
} > review_status.md | ||
- name: Generate review data | ||
id: generate_review | ||
run: | | ||
current_time=$(date -u +"%Y-%m-%d %H:%M UTC") | ||
{ | ||
echo "## 📌 Code Review Assignment" | ||
echo "" | ||
while IFS='|' read -r tag path reviewers; do | ||
if grep -qE "^$path(/|$)" changed_files.txt; then | ||
echo "### 🏷️ Tag: $tag" | ||
echo "**Path:** \`$path\` " | ||
echo "**Reviewers:** $reviewers " | ||
echo "<details>" | ||
echo "<summary><b>Changed Files</b> (Click to expand)</summary>" | ||
echo "" | ||
grep -E "^$path(/|$)" changed_files.txt | sed 's/^/- /' | ||
echo "" | ||
echo "</details>" | ||
echo "" | ||
fi | ||
done < tag_data.csv | ||
cat review_status.md | ||
echo "---" | ||
echo "### 📝 Review Instructions" | ||
echo "" | ||
echo "1. **维护者可以通过单击此处来刷新审查状态:** [🔄 刷新状态](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/rerun)" | ||
echo " **Maintainers can refresh the review status by clicking here:** [🔄 Refresh Status](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/rerun)" | ||
echo "" | ||
echo "2. **确认审核通过后评论 \`LGTM/lgtm\`**" | ||
echo " **Comment \`LGTM/lgtm\` after confirming approval**" | ||
echo "" | ||
echo "3. **PR合并前需至少一位维护者确认**" | ||
echo " **PR must be confirmed by at least one maintainer before merging**" | ||
echo "" | ||
echo "> ℹ️ **刷新CI状态操作需要具备仓库写入权限。**" | ||
echo "> ℹ️ **Refresh CI status operation requires repository Write permission.**" | ||
} > review_data.md | ||
- name: Post/Update comment | ||
id: post_comment | ||
run: | | ||
existing_comment=$(curl -s \ | ||
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN_AUTO_REVIEW }}" \ | ||
"https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments" | \ | ||
jq -r '.[] | select(.user.login == "github-actions[bot]") | {id: .id, body: .body} | @base64') | ||
if [[ -n "$existing_comment" ]]; then | ||
comment_id=$(echo "$existing_comment" | head -1 | base64 -d | jq -r .id) | ||
echo "Updating existing comment $comment_id" | ||
response=$(curl -s -X PATCH \ | ||
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN_AUTO_REVIEW }}" \ | ||
-d "$(jq -n --arg body "$(cat review_data.md)" '{body: $body}')" \ | ||
"https://api.github.com/repos/${{ github.repository }}/issues/comments/$comment_id") | ||
else | ||
echo "Creating new comment" | ||
response=$(curl -s -X POST \ | ||
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN_AUTO_REVIEW }}" \ | ||
-d "$(jq -n --arg body "$(cat review_data.md)" '{body: $body}')" \ | ||
"https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments") | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# MAINTAINERS for autoreview assigning in github comment | ||
|
||
tag: workflow | ||
path: .github | ||
owners: Li Tao(supperthomas)<[email protected]> | ||
|
||
tag: stm32f407-rt-spark | ||
path: bsp/stm32/stm32f407-rt-spark | ||
owners: Zhang Bingru(Rbb666)<[email protected]> | ||
|
||
tag: libc | ||
path: components/libc | ||
owners: Man Jiantin(mysterywolf)<[email protected]> |