Skip to content

Commit

Permalink
feat: assign PR reviews based on the MAINTAINERS list
Browse files Browse the repository at this point in the history
  • Loading branch information
kurisaW committed Jan 23, 2025
1 parent 3436aa6 commit 369074a
Show file tree
Hide file tree
Showing 2 changed files with 185 additions and 0 deletions.
172 changes: 172 additions & 0 deletions .github/workflows/auto-assign-reviewers.yml
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
13 changes: 13 additions & 0 deletions MAINTAINERS
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]>

0 comments on commit 369074a

Please sign in to comment.