Skip to content

Commit 7b6dc58

Browse files
Copilotswissspidy
andcommitted
Fix AI inference output handling and implement batch triage via workflow dispatch
Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>
1 parent 64acef4 commit 7b6dc58

1 file changed

Lines changed: 176 additions & 38 deletions

File tree

.github/workflows/issue-triage.yml

Lines changed: 176 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ name: Issue Triage
1111
required: false
1212
default: 'true'
1313
type: boolean
14+
issue_number:
15+
description: 'Issue number to triage (leave empty to process all)'
16+
required: false
17+
type: string
1418

1519
permissions:
1620
issues: write
@@ -86,11 +90,6 @@ jobs:
8690
${{ env.ISSUE_BODY }}
8791
```
8892
89-
**Output File Path**:
90-
```
91-
${{ env.GITHUB_ENV }}
92-
```
93-
9493
## Steps
9594
9695
1. Review the issue title, issue body, and available labels
@@ -100,24 +99,26 @@ jobs:
10099
and choose all appropriate labels from the list of available
101100
labels.
102101
103-
3. Output the selected labels as a comma-separated list to the
104-
file at the path specified in "Output File Path" using the
105-
following format:
102+
3. Return only the selected labels as a comma-separated list,
103+
with no additional text or explanation. For example:
106104
```
107-
SELECTED_LABELS=label1,label2,label3
105+
label1, label2, label3
108106
```
109107
110108
- name: Apply labels
109+
if: steps.ai-triage.outputs.response != ''
111110
uses: actions/github-script@v7
111+
env:
112+
AI_RESPONSE: ${{ steps.ai-triage.outputs.response }}
112113
with:
113114
script: |
114-
const selectedLabels = process.env.SELECTED_LABELS;
115-
if (!selectedLabels || selectedLabels.trim() === '') {
115+
const response = process.env.AI_RESPONSE;
116+
if (!response || response.trim() === '') {
116117
console.log('No labels selected by AI');
117118
return;
118119
}
119120
120-
const labels = selectedLabels.split(',')
121+
const labels = response.split(',')
121122
.map(l => l.trim())
122123
.filter(l => l.length > 0);
123124
@@ -135,28 +136,15 @@ jobs:
135136
136137
triage-unlabeled-issues:
137138
name: Triage Unlabeled Issues
138-
if: github.event_name == 'workflow_dispatch'
139+
if: |
140+
github.event_name == 'workflow_dispatch' &&
141+
github.event.inputs.issue_number == ''
139142
runs-on: ubuntu-latest
140143
steps:
141-
- name: Get available labels
142-
id: get-labels
143-
uses: actions/github-script@v7
144-
with:
145-
script: |
146-
const labels = await github.rest.issues.listLabelsForRepo({
147-
owner: context.repo.owner,
148-
repo: context.repo.repo,
149-
per_page: 100
150-
});
151-
const labelNames = labels.data.map(label => label.name);
152-
return labelNames.join(', ');
153-
154-
- name: Find and triage unlabeled issues
144+
- name: Find and dispatch triage for unlabeled issues
155145
uses: actions/github-script@v7
156146
with:
157147
script: |
158-
const availableLabels = ${{ steps.get-labels.outputs.result }};
159-
160148
// Get all open issues
161149
const issues = await github.paginate(
162150
github.rest.issues.listForRepo,
@@ -184,16 +172,166 @@ jobs:
184172
return;
185173
}
186174
187-
// For manual dispatch, we'll log that AI triage is not yet
188-
// implemented for batch processing
189-
console.log(
190-
'Note: Batch AI triage for unlabeled issues requires ' +
191-
'manual triggering of individual issue workflows or ' +
192-
'implementing batch AI processing in the future.'
193-
);
194-
175+
// Dispatch triage workflow for each unlabeled issue
195176
for (const issue of unlabeledIssues) {
196177
console.log(
197-
`Issue #${issue.number}: "${issue.title}" needs triage`
178+
`Dispatching triage for issue #${issue.number}: ` +
179+
`"${issue.title}"`
198180
);
181+
182+
try {
183+
await github.rest.actions.createWorkflowDispatch({
184+
owner: context.repo.owner,
185+
repo: context.repo.repo,
186+
workflow_id: 'issue-triage.yml',
187+
ref: context.ref || 'main',
188+
inputs: {
189+
process_unlabeled: 'false',
190+
issue_number: issue.number.toString()
191+
}
192+
});
193+
} catch (error) {
194+
console.error(
195+
`Failed to dispatch triage for issue #${issue.number}: ` +
196+
`${error.message}`
197+
);
198+
}
199+
200+
// Add a small delay to avoid rate limiting
201+
await new Promise(resolve => setTimeout(resolve, 100));
202+
}
203+
204+
console.log('Finished dispatching triage workflows');
205+
206+
triage-single-issue:
207+
name: Triage Single Issue
208+
if: |
209+
github.event_name == 'workflow_dispatch' &&
210+
github.event.inputs.issue_number != ''
211+
runs-on: ubuntu-latest
212+
steps:
213+
- name: Get available labels
214+
id: get-labels
215+
uses: actions/github-script@v7
216+
with:
217+
script: |
218+
const labels = await github.rest.issues.listLabelsForRepo({
219+
owner: context.repo.owner,
220+
repo: context.repo.repo,
221+
per_page: 100
222+
});
223+
const labelNames = labels.data.map(label => label.name);
224+
return labelNames.join(', ');
225+
226+
- name: Get issue details
227+
id: get-issue
228+
uses: actions/github-script@v7
229+
with:
230+
script: |
231+
const issue = await github.rest.issues.get({
232+
owner: context.repo.owner,
233+
repo: context.repo.repo,
234+
issue_number: parseInt('${{ github.event.inputs.issue_number }}')
235+
});
236+
return {
237+
title: issue.data.title,
238+
body: issue.data.body || ''
239+
};
240+
241+
- name: Set environment variables
242+
env:
243+
ISSUE_TITLE: ${{ fromJSON(steps.get-issue.outputs.result).title }}
244+
ISSUE_BODY: ${{ fromJSON(steps.get-issue.outputs.result).body }}
245+
LABELS_RESULT: ${{ steps.get-labels.outputs.result }}
246+
run: |
247+
{
248+
echo "AVAILABLE_LABELS=${LABELS_RESULT}"
249+
echo "ISSUE_TITLE=${ISSUE_TITLE}"
250+
echo "ISSUE_BODY<<EOF"
251+
echo "${ISSUE_BODY}"
252+
echo "EOF"
253+
} >> "$GITHUB_ENV"
254+
255+
- name: Analyze issue with AI
256+
id: ai-triage
257+
uses: actions/ai-inference@v1
258+
with:
259+
prompt: |
260+
## Role
261+
262+
You are an issue triage assistant. Analyze the current GitHub
263+
issue and identify the most appropriate existing labels. Use the
264+
available tools to gather information; do not ask for information
265+
to be provided.
266+
267+
## Guidelines
268+
269+
- Only use labels that are from the list of available labels.
270+
- You can choose multiple labels to apply.
271+
- When generating shell commands, you **MUST NOT** use command
272+
substitution with `$(...)`, `<(...)`, or `>(...)`. This is a
273+
security measure to prevent unintended command execution.
274+
275+
## Input Data
276+
277+
**Available Labels** (comma-separated):
278+
```
279+
${{ env.AVAILABLE_LABELS }}
280+
```
281+
282+
**Issue Title**:
283+
```
284+
${{ env.ISSUE_TITLE }}
285+
```
286+
287+
**Issue Body**:
288+
```
289+
${{ env.ISSUE_BODY }}
290+
```
291+
292+
## Steps
293+
294+
1. Review the issue title, issue body, and available labels
295+
provided above.
296+
297+
2. Based on the issue title and issue body, classify the issue
298+
and choose all appropriate labels from the list of available
299+
labels.
300+
301+
3. Return only the selected labels as a comma-separated list,
302+
with no additional text or explanation. For example:
303+
```
304+
label1, label2, label3
305+
```
306+
307+
- name: Apply labels
308+
if: steps.ai-triage.outputs.response != ''
309+
uses: actions/github-script@v7
310+
env:
311+
AI_RESPONSE: ${{ steps.ai-triage.outputs.response }}
312+
ISSUE_NUMBER: ${{ github.event.inputs.issue_number }}
313+
with:
314+
script: |
315+
const response = process.env.AI_RESPONSE;
316+
const issueNumber = parseInt(process.env.ISSUE_NUMBER);
317+
318+
if (!response || response.trim() === '') {
319+
console.log('No labels selected by AI');
320+
return;
321+
}
322+
323+
const labels = response.split(',')
324+
.map(l => l.trim())
325+
.filter(l => l.length > 0);
326+
327+
if (labels.length > 0) {
328+
console.log(`Applying labels: ${labels.join(', ')}`);
329+
await github.rest.issues.addLabels({
330+
owner: context.repo.owner,
331+
repo: context.repo.repo,
332+
issue_number: issueNumber,
333+
labels: labels
334+
});
335+
} else {
336+
console.log('No valid labels to apply');
199337
}

0 commit comments

Comments
 (0)