1+ name : Auto Label Issues
2+
3+ on :
4+ issue_comment :
5+ types : [created]
6+ workflow_dispatch :
7+ inputs :
8+ label-all-issues :
9+ description : ' Add label to all open issues'
10+ type : boolean
11+ default : false
12+ required : false
13+
14+ jobs :
15+ add-label-single :
16+ runs-on : ubuntu-latest
17+ if : |
18+ github.event_name == 'issue_comment' &&
19+ github.event.issue.user.login != github.event.comment.user.login
20+
21+ steps :
22+ - name : Check if commenter is maintainer
23+ id : check-maintainer
24+ uses : actions/github-script@v7
25+ with :
26+ script : |
27+ const response = await github.rest.repos.getCollaboratorPermissionLevel({
28+ owner: context.repo.owner,
29+ repo: context.repo.repo,
30+ username: context.payload.comment.user.login
31+ });
32+
33+ const isMaintianer = ['admin', 'write'].includes(response.data.permission);
34+ return isMaintianer;
35+
36+ - name : Add waiting-for-response label
37+ if : steps.check-maintainer.outputs.result == 'true'
38+ uses : actions/github-script@v7
39+ with :
40+ script : |
41+ await github.rest.issues.addLabels({
42+ owner: context.repo.owner,
43+ repo: context.repo.repo,
44+ issue_number: context.issue.number,
45+ labels: ['waiting-for-response']
46+ });
47+
48+ add-label-all :
49+ runs-on : ubuntu-latest
50+ if : |
51+ github.event_name == 'workflow_dispatch' &&
52+ github.event.inputs.label-all-issues == 'true'
53+
54+ steps :
55+ - name : Process all open issues
56+ uses : actions/github-script@v7
57+ with :
58+ script : |
59+ async function isMaintianer(username) {
60+ try {
61+ const response = await github.rest.repos.getCollaboratorPermissionLevel({
62+ owner: context.repo.owner,
63+ repo: context.repo.repo,
64+ username: username
65+ });
66+ return ['admin', 'write'].includes(response.data.permission);
67+ } catch (error) {
68+ console.error(`Error checking permissions for ${username}:`, error);
69+ return false;
70+ }
71+ }
72+
73+ async function getLastComment(issueNumber) {
74+ try {
75+ const comments = await github.paginate(github.rest.issues.listComments, {
76+ owner: context.repo.owner,
77+ repo: context.repo.repo,
78+ issue_number: issueNumber,
79+ per_page: 100
80+ });
81+
82+ // Return the most recent comment, or null if no comments
83+ return comments.length > 0 ? comments[comments.length - 1] : null;
84+ } catch (error) {
85+ console.error(`Error fetching comments for issue #${issueNumber}:`, error);
86+ return null;
87+ }
88+ }
89+
90+ // Get all open issues
91+ const issues = await github.paginate(github.rest.issues.listForRepo, {
92+ owner: context.repo.owner,
93+ repo: context.repo.repo,
94+ state: 'open',
95+ per_page: 100
96+ });
97+
98+ for (const issue of issues) {
99+ try {
100+ console.log(`Processing issue #${issue.number}...`);
101+
102+ // Get the last comment
103+ const lastComment = await getLastComment(issue.number);
104+
105+ // Skip if no comments
106+ if (!lastComment) {
107+ console.log(`No comments found on issue #${issue.number}, skipping`);
108+ continue;
109+ }
110+
111+ // Check if last commenter is a maintainer
112+ const lastCommenterIsMaintainer = await isMaintianer(lastComment.user.login);
113+
114+ // Skip if last commenter is not a maintainer
115+ if (!lastCommenterIsMaintainer) {
116+ console.log(`Last comment on issue #${issue.number} is not from a maintainer, skipping`);
117+ continue;
118+ }
119+
120+ // Skip if last commenter is the issue author
121+ if (lastComment.user.login === issue.user.login) {
122+ console.log(`Last comment on issue #${issue.number} is from the issue author, skipping`);
123+ continue;
124+ }
125+
126+ // Add the label
127+ await github.rest.issues.addLabels({
128+ owner: context.repo.owner,
129+ repo: context.repo.repo,
130+ issue_number: issue.number,
131+ labels: ['waiting-for-response']
132+ });
133+
134+ console.log(`Added label to issue #${issue.number}`);
135+ } catch (error) {
136+ console.error(`Error processing issue #${issue.number}:`, error);
137+ }
138+ }
0 commit comments