-
Notifications
You must be signed in to change notification settings - Fork 16
166 lines (139 loc) · 6.74 KB
/
Copy pathruff-format.yml
File metadata and controls
166 lines (139 loc) · 6.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
name: 🐍 代码格式与质量检查
on:
push:
branches: [ main ]
pull_request:
branches: [ main, master, dev/* ]
jobs:
ruff-check:
name: Ruff 代码检查
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: 检出代码
uses: actions/checkout@v6
- name: 设置 Python 环境
uses: actions/setup-python@v6
with:
python-version: '3.10'
- name: 安装 uv
run: pip install uv
- name: 执行 Ruff 格式化与修复
id: ruff
# 使用 || true 确保即使有错误也不立即中断,以便后续步骤生成报告
run: |
echo "Running ruff format..."
FORMAT_LOG=$(uvx ruff format . 2>&1 || true)
echo "$FORMAT_LOG"
echo "Running ruff check --fix..."
CHECK_LOG=$(uvx ruff check --fix . 2>&1 || true)
echo "$CHECK_LOG"
# 将日志保存到文件供后续脚本读取
echo "$FORMAT_LOG" > format.log
echo "$CHECK_LOG" > check.log
- name: 生成报告与评论
uses: actions/github-script@v8
with:
script: |
const fs = require('fs');
const formatLog = fs.readFileSync('format.log', 'utf8');
const checkLog = fs.readFileSync('check.log', 'utf8');
// --- 解析格式化日志 ---
// 示例: "1 file reformatted, 2 files left unchanged."
const formatMatch = formatLog.match(/(\d+) file(s)? reformatted/);
const reformattedCount = formatMatch ? parseInt(formatMatch[1]) : 0;
const unchangedMatch = formatLog.match(/(\d+) file(s)? left unchanged/);
const unchangedCount = unchangedMatch ? parseInt(unchangedMatch[1]) : 0;
// --- 解析检查日志 ---
// 示例: "Found 2 errors (1 fixed, 1 remaining)."
let fixedCount = 0;
let remainingCount = 0;
let totalErrors = 0;
const errorMatch = checkLog.match(/Found (\d+) error/);
if (errorMatch) {
totalErrors = parseInt(errorMatch[1]);
const fixedMatch = checkLog.match(/\((\d+) fixed/);
if (fixedMatch) fixedCount = parseInt(fixedMatch[1]);
const remainingMatch = checkLog.match(/, (\d+) remaining\)/);
if (remainingMatch) {
remainingCount = parseInt(remainingMatch[1]);
} else {
// 如果没有详细的 fixed/remaining 信息,通常意味着没有修复或全部剩余
if (fixedCount === 0) remainingCount = totalErrors;
}
}
// --- 构建报告内容 ---
let summary = '';
let isSuccess = (reformattedCount === 0 && remainingCount === 0);
if (isSuccess) {
summary = '### ✅ All checked pass!';
} else {
summary = '### ⚠️ 代码质量检查报告\n\n';
summary += '> 发现部分文件需要格式化或存在代码问题,建议在本地运行 `ruff format .` 和 `ruff check --fix .`。\n\n';
// 格式化部分
if (reformattedCount > 0) {
summary += `**🖌️ 格式化**: \`${reformattedCount}\` 个文件被重新格式化 (未变更: ${unchangedCount})\n`;
} else {
summary += `**🖌️ 格式化**: ✅ 无需变更\n`;
}
// 代码检查部分
if (totalErrors > 0) {
summary += `**🛡️ 代码检查**: 发现 \`${totalErrors}\` 个问题\n`;
summary += `- 🛠️ 已自动修复: \`${fixedCount}\`\n`;
summary += `- ❌ 剩余未修复: \`${remainingCount}\`\n`;
} else {
summary += `**🛡️ 代码检查**: ✅ 通过\n`;
}
// 错误详情 (如果有剩余错误)
if (remainingCount > 0) {
// 截取部分日志以防过长
const logPreview = checkLog.length > 2000 ? checkLog.substring(0, 2000) + '\n... (日志过长已截断)' : checkLog;
summary += `\n<details><summary>🔍 错误详情</summary>\n\n\`\`\`text${logPreview}\n\n\`\`\`\n</details>`;
}
}
// --- 输出到 Job Summary ---
await core.summary.addRaw(summary).write();
// --- PR 评论 (仅在 PR 事件触发时) ---
if (context.eventName === 'pull_request') {
const issue_number = context.issue.number;
const owner = context.repo.owner;
const repo = context.repo.repo;
// 获取现有评论
const comments = await github.rest.issues.listComments({
owner,
repo,
issue_number,
});
// 查找机器人之前发的 Ruff 报告评论
const botComment = comments.data.find(comment =>
comment.user.type === 'Bot' &&
(comment.body.includes('代码质量检查报告') || comment.body.includes('All checked pass'))
);
if (botComment) {
// 如果已有评论,更新它
await github.rest.issues.updateComment({
owner,
repo,
comment_id: botComment.id,
body: summary
});
} else {
// 如果没有,且检查未通过,则创建新评论
// (如果通过了且之前没评论,就不发了,保持清爽;除非你想让用户知道通过了)
// 这里逻辑:如果有问题 -> 发/更;如果没问题 -> 只有在之前有过报错评论时才更新为通过,否则不打扰。
if (!isSuccess) {
await github.rest.issues.createComment({
owner,
repo,
issue_number,
body: summary
});
}
}
}
// --- 设置 Job 状态 ---
if (!isSuccess) {
core.setFailed('代码格式或质量检测未通过,请检查报告。');
}