Skip to content

Commit a4d304e

Browse files
committed
Merge branch 'master' of https://github.com/RT-Thread/rt-thread
2 parents f3d2722 + 74245ed commit a4d304e

File tree

2,568 files changed

+28134
-3156386
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

2,568 files changed

+28134
-3156386
lines changed

.github/ALL_BSP_COMPILE.json

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,6 @@
1616
"stm32/stm32f407-rt-spark"
1717
]
1818
},
19-
{
20-
"RTT_BSP": "RTduino_Arduino Libraries (STM32F412 Nucleo)",
21-
"RTT_TOOL_CHAIN": "sourcery-arm",
22-
"SUB_RTT_BSP": [
23-
"stm32/stm32f412-st-nucleo"
24-
]
25-
},
2619
{
2720
"RTT_BSP": "RTduino_Arduino Libraries (Raspberry Pico)",
2821
"RTT_TOOL_CHAIN": "sourcery-arm",
@@ -169,6 +162,7 @@
169162
"stm32/stm32f411-st-nucleo",
170163
"stm32/stm32f411-atk-nano",
171164
"stm32/stm32f411-weact-blackpill",
165+
"stm32/stm32f412-st-nucleo",
172166
"stm32/stm32f413-st-nucleo",
173167
"stm32/stm32f427-robomaster-a",
174168
"stm32/stm32f429-armfly-v6",
@@ -392,8 +386,6 @@
392386
"RTT_TOOL_CHAIN": "sourcery-riscv64-unknown-elf",
393387
"SUB_RTT_BSP": [
394388
"bluetrum/ab32vg1-ab-prougen",
395-
"bouffalo_lab/bl60x",
396-
"bouffalo_lab/bl70x",
397389
"qemu-virt64-riscv"
398390
]
399391
},

.github/workflows/action_runner.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ jobs:
3939
runs-on: [self-hosted, windows, x64]
4040
name: ${{ github.event.inputs.bsp_options }}
4141
steps:
42-
- uses: actions/checkout@v3
42+
- uses: actions/checkout@main
4343
- name: Bsp Scons Compile
4444
if: ${{ success() }}
4545
env:

.github/workflows/action_tools.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ jobs:
4242
env:
4343
TEST_BSP_ROOT: bsp/stm32/stm32f407-atk-explorer
4444
steps:
45-
- uses: actions/checkout@v4
45+
- uses: actions/checkout@main
4646

4747
- name: Install Tools
4848
shell: bash

.github/workflows/action_utest.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ jobs:
5656
TEST_CONFIG_FILE: ${{ matrix.legs.CONFIG_FILE }}
5757
TEST_SD_FILE: ${{ matrix.legs.SD_FILE }}
5858
steps:
59-
- uses: actions/checkout@v4
59+
- uses: actions/checkout@main
6060

6161
- name: Install Tools
6262
shell: bash
Lines changed: 337 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,337 @@
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+
# 2025-03-14 hydevcode
10+
# 2025-05-10 kurisaW Fixed file existence, cache, and comment time issues
11+
# 2025-05-11 kurisaW Fixed missing unique files creation and cache logic
12+
13+
# Script Function Description: Assign PR reviews based on the MAINTAINERS list.
14+
15+
name: Auto Review Assistant
16+
17+
on:
18+
pull_request_target:
19+
branches: [ master ]
20+
types: [opened, synchronize, reopened]
21+
22+
jobs:
23+
assign-reviewers:
24+
runs-on: ubuntu-22.04
25+
if: github.repository_owner == 'RT-Thread'
26+
permissions:
27+
issues: read
28+
pull-requests: write
29+
contents: read
30+
steps:
31+
- name: Extract PR number
32+
id: extract-pr
33+
run: |
34+
PR_NUMBER=${{ github.event.pull_request.number }}
35+
echo "PR_NUMBER=${PR_NUMBER}" >> $GITHUB_OUTPUT
36+
37+
- name: Checkout code
38+
uses: actions/checkout@v4
39+
with:
40+
ref: master
41+
sparse-checkout: MAINTAINERS
42+
persist-credentials: false
43+
44+
- name: Get changed files
45+
id: changed_files
46+
run: |
47+
# 通过 GitHub API 获取 PR 的变更文件列表
48+
changed_files=$(curl -s \
49+
"https://api.github.com/repos/${{ github.repository }}/pulls/${{ steps.extract-pr.outputs.PR_NUMBER }}/files" | \
50+
jq -r '.[].filename') # 使用 jq 提取文件名
51+
echo "$changed_files" | grep -v '^MAINTAINERS$' > changed_files.txt
52+
53+
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')
56+
57+
echo "=== Changed Files ==="
58+
cat changed_files.txt
59+
echo "====================="
60+
61+
comment_body=""
62+
if [[ ! -z "$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+
comment_time=$(date -d "$comment_body" +%s)
65+
echo "${comment_body}"
66+
echo "COMMENT_TIME=${comment_time}" >> $GITHUB_OUTPUT
67+
else
68+
comment_time=""
69+
echo "COMMENT_TIME=${comment_time}" >> $GITHUB_OUTPUT
70+
fi
71+
echo "COMMENT_TIME=${comment_time}"
72+
73+
- name: Parse MAINTAINERS file
74+
id: parse_maintainer
75+
run: |
76+
# 使用 AWK 解析 MAINTAINERS 文件格式:
77+
# 提取 tag(标签)、path(路径)和 owners(维护者 GitHub ID)
78+
awk '
79+
/^tag:/ {
80+
tag = substr($0, index($0, $2)) # 提取标签内容
81+
}
82+
/^path:/ {
83+
# 提取 path 字段并去除前后空格
84+
path = substr($0, index($0, $2))
85+
gsub(/^[ \t]+|[ \t]+$/, "", path) # 清理前后空格和制表符
86+
}
87+
/^owners:/ {
88+
owners = substr($0, index($0, $2)) # 提取维护者信息
89+
split(owners, parts, /[()]/) # 拆分出 GitHub ID(括号内内容)
90+
github_ids = ""
91+
for (i=2; i<=length(parts); i+=2) {
92+
github_ids = github_ids "@" parts[i] " " # 拼接为 @user 格式
93+
}
94+
print tag "|" path "|" github_ids
95+
}
96+
' MAINTAINERS > tag_data.csv
97+
98+
- name: Generate reviewers list
99+
id: generate_reviewers
100+
run: |
101+
rm -f triggered_reviewers.txt triggered_tags.txt unique_reviewers.txt unique_tags.txt
102+
touch triggered_reviewers.txt triggered_tags.txt unique_reviewers.txt unique_tags.txt
103+
104+
while IFS='|' read -r tag path reviewers; do
105+
# 转义路径中的正则特殊字符
106+
escaped_path=$(sed 's/[.[\*^$]/\\&/g' <<< "$path")
107+
108+
# 使用增强型正则匹配路径及其所有子目录
109+
if grep -qE "^$escaped_path(/.*)*" changed_files.txt; then
110+
echo "$reviewers" | tr -s ' ' '\n' | sed '/^$/d' >> triggered_reviewers.txt
111+
echo "$tag" >> triggered_tags.txt
112+
echo "Matched: $path → $tag"
113+
fi
114+
done < tag_data.csv
115+
116+
# 生成去重的 unique_reviewers.txt 和 unique_tags.txt
117+
sort -u triggered_reviewers.txt > unique_reviewers.txt
118+
sort -u triggered_tags.txt > unique_tags.txt
119+
120+
# 检查是否有匹配的 reviewers
121+
if [[ -s unique_reviewers.txt ]]; then
122+
echo "HAS_REVIEWERS=true" >> $GITHUB_OUTPUT
123+
else
124+
echo "HAS_REVIEWERS=false" >> $GITHUB_OUTPUT
125+
fi
126+
127+
echo "=== Matched Paths ==="
128+
cat unique_tags.txt
129+
echo "=== Matched Reviewers ==="
130+
cat unique_reviewers.txt
131+
132+
- name: Restore Reviewers Cache
133+
id: reviewers-cache-restore
134+
if: ${{ steps.changed_files.outputs.COMMENT_TIME != '' }}
135+
uses: actions/cache/restore@v4
136+
with:
137+
path: |
138+
unique_tags_bak.txt
139+
unique_reviewers_bak.txt
140+
key: ${{ runner.os }}-auto-assign-reviewers-${{ steps.extract-pr.outputs.PR_NUMBER }}-${{ steps.changed_files.outputs.COMMENT_TIME }}
141+
142+
- name: Get approval status
143+
id: get_approval
144+
run: |
145+
current_time=$(date -u +"%Y-%m-%d %H:%M UTC")
146+
147+
# 检查 unique_reviewers.txt 是否存在且非空
148+
if [[ ! -s unique_reviewers.txt ]]; then
149+
echo "No reviewers found, creating empty unique_reviewers.txt"
150+
touch unique_reviewers.txt
151+
fi
152+
153+
reviewers=$(cat unique_reviewers.txt | tr '\n' '|' | sed 's/|$//')
154+
155+
# 获取 PR 的所有评论
156+
comments=$(curl -s \
157+
"https://api.github.com/repos/${{ github.repository }}/issues/${{ steps.extract-pr.outputs.PR_NUMBER }}/comments")
158+
159+
echo '#!/bin/bash' > approval_data.sh
160+
echo 'declare -A approvals=()' >> approval_data.sh
161+
162+
# 使用 jq 解析包含 LGTM 的有效评论
163+
jq -r --arg reviewers "$reviewers" '
164+
.[] |
165+
select(.user.login != "github-actions[bot]") | # 排除 bot 的评论
166+
select(.body | test("^\\s*LGTM\\s*$"; "i")) | # 匹配 LGTM 评论(不区分大小写)
167+
.user.login as $user |
168+
"@\($user)" as $mention |
169+
select($mention | inside($reviewers)) | # 过滤有效审查者
170+
"approvals[\"\($mention)\"]=\"\(.created_at)\"" # 记录审批时间
171+
' <<< "$comments" >> approval_data.sh
172+
173+
# 加载审查数据并生成状态报告
174+
chmod +x approval_data.sh
175+
source ./approval_data.sh
176+
177+
jq -r --arg reviewers "$reviewers" '
178+
.[] |
179+
select(.user.login != "github-actions[bot]") | # 排除 bot 的评论
180+
select(.body | test("^\\s*LGTM\\s*$"; "i")) | # 匹配 LGTM 评论(不区分大小写)
181+
.user.login as $user |
182+
"@\($user)" as $mention |
183+
select($mention | inside($reviewers)) | # 过滤有效审查者
184+
"\($mention) \(.created_at)" # 输出审查者和时间
185+
' <<< "$comments" >> approval_data.txt
186+
187+
notified_users=""
188+
if [[ -f unique_reviewers_bak.txt ]]; then
189+
notified_users=$(cat unique_reviewers_bak.txt | xargs)
190+
else
191+
notified_users=""
192+
fi
193+
194+
{
195+
echo "---"
196+
echo "### 📊 Current Review Status (Last Updated: $current_time)"
197+
while read -r reviewer; do
198+
formatted_reviewers=""
199+
for r in $reviewers; do
200+
if [[ " ${notified_users[@]} " =~ " $reviewer " ]]; then
201+
formatted_reviewers+="${reviewer#@}"
202+
else
203+
formatted_reviewers+="$reviewer"
204+
fi
205+
done
206+
207+
if [[ -n "${approvals[$reviewer]}" ]]; then
208+
timestamp=$(date -d "${approvals[$reviewer]}" -u +"%Y-%m-%d %H:%M UTC")
209+
echo "- ✅ **$formatted_reviewers** Reviewed On $timestamp"
210+
else
211+
echo "- ⌛ **$formatted_reviewers** Pending Review"
212+
fi
213+
done < unique_reviewers.txt
214+
} > review_status.md
215+
216+
echo "CURRENT_TIME=${current_time}" >> $GITHUB_OUTPUT
217+
218+
- name: Generate review data
219+
id: generate_review
220+
if: steps.generate_reviewers.outputs.HAS_REVIEWERS == 'true'
221+
run: |
222+
unique_tags=""
223+
if [[ -s unique_tags.txt ]]; then
224+
unique_tags=$(cat unique_tags.txt | xargs)
225+
fi
226+
unique_tags_bak=""
227+
if [[ -f unique_tags_bak.txt ]]; then
228+
unique_tags_bak=$(cat unique_tags_bak.txt | xargs)
229+
fi
230+
231+
existing_tags=""
232+
for r in $unique_tags; do
233+
if [[ " ${unique_tags_bak[@]} " =~ " $r " ]]; then
234+
echo "$r 不存在于数组中"
235+
else
236+
existing_tags+="$r "
237+
fi
238+
done
239+
240+
current_time=$(date -u +"%Y-%m-%d %H:%M UTC")
241+
{
242+
# 生成审查分配信息
243+
echo "## 📌 Code Review Assignment"
244+
echo ""
245+
246+
while IFS='|' read -r tag path reviewers; do
247+
if grep -qE "^$path(/|$)" changed_files.txt; then
248+
echo "### 🏷️ Tag: $tag"
249+
echo "**Path:** \`$path\` "
250+
251+
if [[ " ${existing_tags[@]} " =~ " $tag " ]]; then
252+
echo "**Reviewers:** $reviewers "
253+
else
254+
formatted_reviewers=""
255+
for r in $reviewers; do
256+
formatted_reviewers+="${r#@} "
257+
done
258+
echo "**Reviewers:** $formatted_reviewers "
259+
fi
260+
261+
echo "<details>"
262+
echo "<summary><b>Changed Files</b> (Click to expand)</summary>"
263+
echo ""
264+
grep -E "^$path(/|$)" changed_files.txt | sed 's/^/- /' # 列出匹配的变更文件
265+
echo ""
266+
echo "</details>"
267+
echo ""
268+
fi
269+
done < tag_data.csv
270+
# 插入审查状态
271+
cat review_status.md
272+
273+
echo "---"
274+
echo "### 📝 Review Instructions"
275+
echo ""
276+
echo "1. **维护者可以通过单击此处来刷新审查状态:** [🔄 刷新状态](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})"
277+
echo " **Maintainers can refresh the review status by clicking here:** [🔄 Refresh Status](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})"
278+
echo ""
279+
echo "2. **确认审核通过后评论 \`LGTM/lgtm\`**"
280+
echo " **Comment \`LGTM/lgtm\` after confirming approval**"
281+
echo ""
282+
echo "3. **PR合并前需至少一位维护者确认**"
283+
echo " **PR must be confirmed by at least one maintainer before merging**"
284+
echo ""
285+
echo "> ℹ️ **刷新CI状态操作需要具备仓库写入权限。**"
286+
echo "> ℹ️ **Refresh CI status operation requires repository Write permission.**"
287+
} > review_data.md
288+
289+
- name: Post/Update comment
290+
id: post_comment
291+
if: steps.generate_reviewers.outputs.HAS_REVIEWERS == 'true'
292+
run: |
293+
# 查找现有的 bot 评论
294+
existing_comment=$(curl -s \
295+
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
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]") | {id: .id, body: .body} | @base64')
298+
299+
if [[ -n "$existing_comment" ]]; then
300+
# 更新现有评论
301+
comment_id=$(echo "$existing_comment" | head -1 | base64 -d | jq -r .id)
302+
echo "Updating existing comment $comment_id"
303+
response=$(curl -s -X PATCH \
304+
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
305+
-d "$(jq -n --arg body "$(cat review_data.md)" '{body: $body}')" \
306+
"https://api.github.com/repos/${{ github.repository }}/issues/comments/$comment_id")
307+
else
308+
# 创建新评论
309+
echo "Creating new comment"
310+
response=$(curl -s -X POST \
311+
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
312+
-d "$(jq -n --arg body "$(cat review_data.md)" '{body: $body}')" \
313+
"https://api.github.com/repos/${{ github.repository }}/issues/${{ steps.extract-pr.outputs.PR_NUMBER }}/comments")
314+
fi
315+
316+
- name: Get Comment Time
317+
id: get_comment_time
318+
if: steps.generate_reviewers.outputs.HAS_REVIEWERS == 'true'
319+
run: |
320+
existing_comment=$(curl -s \
321+
"https://api.github.com/repos/${{ github.repository }}/issues/${{ steps.extract-pr.outputs.PR_NUMBER }}/comments" | \
322+
jq -r '.[] | select(.user.login == "github-actions[bot]") | {body: .body} | @base64')
323+
comment_body="${{ steps.get_approval.outputs.CURRENT_TIME }}"
324+
comment_time=$(date -d "$comment_body" +%s)
325+
echo "CURRENT_TIME=${comment_time}" >> $GITHUB_OUTPUT
326+
cp unique_reviewers.txt unique_reviewers_bak.txt
327+
cp unique_tags.txt unique_tags_bak.txt
328+
329+
- name: Save Reviewers Cache
330+
id: reviewers-cache-save
331+
if: steps.generate_reviewers.outputs.HAS_REVIEWERS == 'true'
332+
uses: actions/cache/save@v4
333+
with:
334+
path: |
335+
unique_tags_bak.txt
336+
unique_reviewers_bak.txt
337+
key: ${{ runner.os }}-auto-assign-reviewers-${{ steps.extract-pr.outputs.PR_NUMBER }}-${{ steps.get_comment_time.outputs.CURRENT_TIME }}

0 commit comments

Comments
 (0)