Skip to content

Issue Triage

Issue Triage #1059

Workflow file for this run

name: Issue Triage
on:
schedule:
- cron: '0 * * * *'
issues:
types: [opened]
workflow_dispatch:
permissions:
issues: write
contents: read
jobs:
triage:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Add needs-triage label to new issues
if: github.event_name == 'issues'
uses: actions/github-script@v7
with:
script: |
const issueNumber = context.issue.number;
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
labels: ['status:needs-triage']
});
console.log(`Added needs-triage label to issue #${issueNumber}`);
- name: Analyze and label issues
uses: actions/github-script@v7
with:
script: |
const { data: issues } = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
labels: 'status:needs-triage',
per_page: 10
});
for (const issue of issues) {
const title = issue.title.toLowerCase();
const body = (issue.body || '').toLowerCase();
const content = title + ' ' + body;
const labelsToAdd = [];
if (content.includes('bug') || content.includes('error')) {
labelsToAdd.push('type:bug');
} else if (content.includes('feature')) {
labelsToAdd.push('type:feature');
} else if (content.includes('improve') || content.includes('refactor')) {
labelsToAdd.push('type:enhancement');
} else if (content.includes('docs') || content.includes('readme')) {
labelsToAdd.push('type:docs');
}
if (content.includes('critical') || content.includes('urgent')) {
labelsToAdd.push('priority:critical');
} else if (content.includes('important') || content.includes('security')) {
labelsToAdd.push('priority:high');
} else {
labelsToAdd.push('priority:medium');
}
if (content.includes('backend') || content.includes('rust') || content.includes('api')) {
labelsToAdd.push('area:backend');
} else if (content.includes('frontend') || content.includes('react') || content.includes('ui')) {
labelsToAdd.push('area:frontend');
}
if (labelsToAdd.length > 0) {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
labels: labelsToAdd
});
}
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
name: 'status:needs-triage'
}).catch(() => {});
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
labels: ['status:pm-reviewed']
});
const labelList = labelsToAdd.join(', ') || 'None detected';
const analysisComment = [
'## PM Issue Analysis',
'',
'### Summary',
'This issue has been automatically analyzed.',
'',
'### Classification',
`- **Labels**: ${labelList}`,
'- **Status**: PM Reviewed',
'',
'### Next Steps',
'1. Assignee needed',
'2. Detailed task breakdown may be required',
'',
'---',
'*Auto-generated by GitHub Actions*'
].join('\n');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
body: analysisComment
});
console.log(`Processed issue #${issue.number}: ${issue.title}`);
}