Skip to content

GLM 5

GLM 5 #36

name: Auto-label issues with AI
on:
issues:
types: [opened]
permissions:
issues: write
models: read
jobs:
label-issue:
runs-on: ubuntu-latest
steps:
- name: Get AI label suggestions
id: ai
uses: actions/github-script@v7
with:
script: |
const issue = context.payload.issue;
const title = issue.title;
const body = issue.body || '(no description)';
const prompt = `Analyze this GitHub issue and return ONLY comma-separated numbers for applicable labels.
Available labels:
1. Documentation - Issues or improvements related to documentation
2. Duplicate - This issue already exists
3. Enhancement - Improvement to existing functionality
4. good first issue - Good for newcomers
5. help wanted - Extra attention is needed
6. invalid - This doesn't seem right
7. question - Further information is requested
8. wontfix - This will not be worked on
9. ⊘ CRITICAL - Critical priority issue
13. ➥ Feature Request - Request for new functionality
16. 𓆣 Bug - Something isn't working
18. ꕤ DEV - Developer-created notes/issues for tracking progress, project planning, and development state
Issue Title: ${title}
Issue Body: ${body}
Return ONLY the numbers, comma-separated. Examples:
- For a bug report: 16
- For a feature request: 13
- For a critical bug: 16,9
- For a docs improvement: 1,3
- For a simple bug good for beginners: 16,4,5
- For a developer note / project tracking issue: 18
- If unclear/invalid: 6 or 7
NOTE: You can combine and mix various labels, but do not add any labels that are not listed above.
Your response (numbers only):`;
// Call GitHub Models API
const response = await fetch('https://models.inference.ai.azure.com/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.GITHUB_TOKEN}`
},
body: JSON.stringify({
model: 'DeepSeek-V3-0324',
messages: [
{ role: 'system', content: 'You are a GitHub issue classifier. Return ONLY comma-separated numbers, nothing else.' },
{ role: 'user', content: prompt }
],
max_tokens: 50,
temperature: 0.1
})
});
if (!response.ok) {
const error = await response.text();
core.setFailed(`API request failed: ${response.status} - ${error}`);
return;
}
const data = await response.json();
const aiResponse = data.choices[0].message.content.trim();
core.info(`AI response: ${aiResponse}`);
core.setOutput('labels', aiResponse);
env:
GITHUB_TOKEN: ${{ github.token }}
- name: Apply labels
uses: actions/github-script@v7
with:
script: |
const labelMap = {
'1': 'Documentation',
'2': 'Duplicate',
'3': 'Enhancement',
'4': 'good first issue',
'5': 'help wanted',
'6': 'invalid',
'7': 'question',
'8': 'wontfix',
'9': '⊘ CRITICAL',
'10': '⚲ Planned',
'11': '✓ Resolved',
'12': '✗ Cancelled',
'13': '➥ Feature Request',
'14': '⦻ Confirmed',
'15': '⧖ In Progress',
'16': '𓆣 Bug',
'17': '𖦏 Investigating',
'18': 'ꕤ DEV'
};
const aiLabels = '${{ steps.ai.outputs.labels }}';
const numbers = aiLabels.match(/\d+/g) || [];
// Always add Needs Triage, plus any AI-suggested labels
const labelsToAdd = ['➤ Needs Triage'];
for (const num of numbers) {
if (labelMap[num]) {
labelsToAdd.push(labelMap[num]);
}
}
// Remove duplicates
const uniqueLabels = [...new Set(labelsToAdd)];
core.info(`Applying labels: ${uniqueLabels.join(', ')}`);
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.issue.number,
labels: uniqueLabels
});