forked from opensandbox-group/OpenSandbox
-
Notifications
You must be signed in to change notification settings - Fork 1
125 lines (110 loc) · 4.77 KB
/
pr-label-check.yml
File metadata and controls
125 lines (110 loc) · 4.77 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
name: PR Label Check
on:
pull_request_target:
types: [opened, reopened, labeled, unlabeled, synchronize]
branches: [main]
permissions:
pull-requests: write
jobs:
check-labels:
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v7
with:
script: |
const pr = context.payload.pull_request;
const labels = pr.labels;
const prNumber = pr.number;
const owner = context.repo.owner;
const repo = context.repo.repo;
const marker = "<!-- LABEL_CHECK_BOT -->";
function suggestLabels(files) {
const dirs = new Set();
for (const f of files) {
const p = f.filename.split("/");
dirs.add(p[0]);
if (p.length >= 2) dirs.add(p[0] + "/" + p[1]);
}
const s = [];
if (dirs.has("docs") || dirs.has("oseps") || dirs.has("specs") ||
dirs.has("examples")) {
s.push("documentation");
}
if (dirs.has("components/egress")) s.push("component/egress");
if (dirs.has("components/ingress")) s.push("component/ingress");
if (dirs.has("components/execd")) s.push("component/execd");
if (dirs.has("components/code-interpreter")) s.push("component/code-interpreter");
if (dirs.has("components/internal")) {
s.push("component/egress", "component/ingress");
}
// k8s / server
if (dirs.has("kubernetes")) s.push("component/k8s");
if (dirs.has("server")) s.push("component/server");
// SDK
if (dirs.has("sdks")) {
s.push("sdks");
if (dirs.has("sdks/go")) s.push("sdk/go");
if (dirs.has("sdks/java")) s.push("sdk/java");
if (dirs.has("sdks/python")) s.push("sdk/python");
if (dirs.has("sdks/js")) s.push("sdk/js");
if (dirs.has("sdks/csharp")) s.push("sdk/c#");
}
return [...new Set(s)].sort();
}
if (labels.length === 0) {
const { data: files } = await github.rest.pulls.listFiles({
owner, repo, pull_number: prNumber,
});
const suggested = suggestLabels(files);
const { data: allLabels } = await github.rest.issues.listLabelsForRepo({
owner, repo,
});
let tip = "";
const suggestedSet = new Set(suggested);
const allow = ["bug", "documentation", "feature", "dependencies", "packages"];
const otherLabels = allLabels.filter(l =>
!suggestedSet.has(l.name) && allow.includes(l.name)
);
if (suggested.length > 0) {
tip = `\n\n📋 **Recommended labels** (based on changed files):\n`;
for (const name of suggested) {
tip += `- \`${name}\` ⬅️\n`;
}
if (otherLabels.length > 0) {
tip += `\nOther available labels:\n`;
for (const lab of otherLabels) {
const desc = lab.description ? ` - ${lab.description}` : "";
tip += `- \`${lab.name}\`${desc}\n`;
}
}
}
const touchedDirs = [...new Set(files.map(f => f.filename.split("/")[0]))].join("、");
const hint = `\n\n💡 Tip: Use \`feature\` for new functionality or improvements, \`bug\` for fixes.`;
const { data: comments } = await github.rest.issues.listComments({
owner, repo, issue_number: prNumber,
});
const existing = comments.filter(
c => c.user?.type === "Bot" && c.body?.includes(marker)
);
if (existing.length === 0) {
await github.rest.issues.createComment({
owner, repo, issue_number: prNumber,
body: `${marker}
⚠️ This PR has no labels. Please add one based on the changes.
Changed directories: ${touchedDirs}.${tip}${hint}
cc @${pr.user.login}`,
});
}
} else {
const { data: comments } = await github.rest.issues.listComments({
owner, repo, issue_number: prNumber,
});
const botComments = comments.filter(
c => c.user?.type === "Bot" && c.body?.includes(marker)
);
for (const c of botComments) {
await github.rest.issues.deleteComment({
owner, repo, comment_id: c.id,
});
}
}