Skip to content

Commit 6906bd4

Browse files
Create label-all-issues.yml
1 parent be4d91a commit 6906bd4

File tree

1 file changed

+107
-0
lines changed

1 file changed

+107
-0
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
name: Label All Issues
2+
3+
on:
4+
schedule:
5+
- cron: '0 0 * * 0' # Run at midnight every Sunday
6+
workflow_dispatch:
7+
8+
jobs:
9+
label-issues:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v2
13+
14+
- name: Label All Issues
15+
uses: actions/github-script@v6
16+
with:
17+
github-token: ${{secrets.GITHUB_TOKEN}}
18+
script: |
19+
const fs = require('fs').promises;
20+
21+
async function parseYaml(filePath) {
22+
const content = await fs.readFile(filePath, 'utf8');
23+
const lines = content.split('\n');
24+
const result = {};
25+
let currentKey = null;
26+
27+
for (const line of lines) {
28+
const trimmedLine = line.trim();
29+
if (trimmedLine === '' || trimmedLine.startsWith('#')) continue;
30+
31+
if (trimmedLine.includes(':')) {
32+
[currentKey, value] = trimmedLine.split(':').map(s => s.trim());
33+
result[currentKey] = [];
34+
if (value) {
35+
result[currentKey].push(value.replace(/^['"]|['"]$/g, ''));
36+
}
37+
} else if (trimmedLine.startsWith('-') && currentKey) {
38+
let value = trimmedLine.slice(1).trim();
39+
value = value.replace(/^['"]|['"]$/g, '');
40+
result[currentKey].push(value);
41+
}
42+
}
43+
44+
return result;
45+
}
46+
47+
async function getIssues(octokit, owner, repo, page = 1) {
48+
const response = await octokit.rest.issues.listForRepo({
49+
owner: owner,
50+
repo: repo,
51+
state: 'all',
52+
per_page: 100,
53+
page: page
54+
});
55+
return response.data;
56+
}
57+
58+
async function addLabelsToIssue(octokit, owner, repo, issueNumber, labels) {
59+
await octokit.rest.issues.addLabels({
60+
owner: owner,
61+
repo: repo,
62+
issue_number: issueNumber,
63+
labels: labels
64+
});
65+
}
66+
67+
async function labelAllIssues() {
68+
try {
69+
console.log('Reading label rules file...');
70+
const labelRules = await parseYaml('.github/label-rules.yml');
71+
console.log('Parsed label rules:', JSON.stringify(labelRules, null, 2));
72+
73+
let page = 1;
74+
let issues;
75+
do {
76+
issues = await getIssues(github, context.repo.owner, context.repo.repo, page);
77+
for (const issue of issues) {
78+
const title = issue.title.toLowerCase();
79+
const labelsToAdd = [];
80+
for (const [label, keywords] of Object.entries(labelRules)) {
81+
if (keywords.some(keyword => {
82+
if (keyword.startsWith('/') && keyword.endsWith('/')) {
83+
const regex = new RegExp(keyword.slice(1, -1), 'i');
84+
return regex.test(title);
85+
}
86+
return title.includes(keyword.toLowerCase());
87+
})) {
88+
labelsToAdd.push(label);
89+
}
90+
}
91+
if (labelsToAdd.length > 0) {
92+
await addLabelsToIssue(github, context.repo.owner, context.repo.repo, issue.number, labelsToAdd);
93+
console.log(`Added labels to issue #${issue.number}: ${labelsToAdd.join(', ')}`);
94+
} else {
95+
console.log(`No matching labels found for issue #${issue.number}`);
96+
}
97+
}
98+
page++;
99+
} while (issues.length > 0);
100+
} catch (error) {
101+
console.error('Error in workflow:', error.message);
102+
console.error('Error stack:', error.stack);
103+
core.setFailed(error.message);
104+
}
105+
}
106+
107+
labelAllIssues();

0 commit comments

Comments
 (0)