Skip to content

Commit 0fb33ec

Browse files
Copilotswissspidy
andauthored
[WIP] Add auto-labelling for pull requests (#185)
Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Pascal Birchler <pascalb@google.com>
1 parent d2dd348 commit 0fb33ec

File tree

2 files changed

+83
-62
lines changed

2 files changed

+83
-62
lines changed

.github/workflows/issue-triage.yml

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,26 @@
11
---
2-
name: Issue Triage
2+
name: Issue and PR Triage
33

44
'on':
55
issues:
66
types: [opened]
7+
pull_request:
8+
types: [opened]
79
workflow_dispatch:
810
inputs:
911
issue_number:
10-
description: 'Issue number to triage (leave empty to process all)'
12+
description: 'Issue/PR number to triage (leave empty to process all)'
1113
required: false
1214
type: string
1315

1416
jobs:
1517
issue-triage:
1618
uses: wp-cli/.github/.github/workflows/reusable-issue-triage.yml@main
1719
with:
18-
issue_number: ${{ github.event_name == 'workflow_dispatch' && inputs.issue_number || github.event.issue.number }}
20+
issue_number: >-
21+
${{
22+
(github.event_name == 'workflow_dispatch' && inputs.issue_number) ||
23+
(github.event_name == 'pull_request' && github.event.pull_request.number) ||
24+
(github.event_name == 'issues' && github.event.issue.number) ||
25+
''
26+
}}

.github/workflows/reusable-issue-triage.yml

Lines changed: 72 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
11
---
2-
name: Issue Triage
2+
name: Issue and PR Triage
33

44
'on':
55
workflow_call:
66
inputs:
77
issue_number:
8-
description: 'Issue number to triage (leave empty to process all)'
8+
description: 'Issue/PR number to triage (leave empty to process all)'
99
required: false
1010
type: string
1111

1212
permissions:
1313
issues: write
14+
pull-requests: write
1415
contents: read
1516
models: read
1617

1718
jobs:
18-
triage-new-issue:
19-
name: Triage New Issue
20-
if: github.event_name == 'issues'
19+
triage-new-item:
20+
name: Triage New Issue or PR
21+
if: github.event_name == 'issues' || github.event_name == 'pull_request'
2122
runs-on: ubuntu-latest
2223
steps:
2324
- name: Get available labels
@@ -35,27 +36,29 @@ jobs:
3536
3637
- name: Set environment variables
3738
env:
38-
ISSUE_TITLE: ${{ github.event.issue.title }}
39-
ISSUE_BODY: ${{ github.event.issue.body }}
39+
ITEM_TITLE: ${{ github.event_name == 'pull_request' && github.event.pull_request.title || github.event.issue.title }}
40+
ITEM_BODY: ${{ github.event_name == 'pull_request' && github.event.pull_request.body || github.event.issue.body }}
41+
ITEM_TYPE: ${{ github.event_name == 'pull_request' && 'pull request' || 'issue' }}
4042
LABELS_RESULT: ${{ steps.get-labels.outputs.result }}
4143
run: |
4244
{
4345
echo "AVAILABLE_LABELS=${LABELS_RESULT}"
44-
echo "ISSUE_TITLE=${ISSUE_TITLE}"
45-
echo "ISSUE_BODY<<EOF"
46-
echo "${ISSUE_BODY}"
46+
echo "ITEM_TITLE=${ITEM_TITLE}"
47+
echo "ITEM_TYPE=${ITEM_TYPE}"
48+
echo "ITEM_BODY<<EOF"
49+
echo "${ITEM_BODY}"
4750
echo "EOF"
4851
} >> "$GITHUB_ENV"
4952
50-
- name: Analyze issue with AI
53+
- name: Analyze with AI
5154
id: ai-triage
5255
uses: actions/ai-inference@v2
5356
with:
5457
prompt: |
5558
## Role
5659
57-
You are an issue triage assistant. Analyze the current GitHub
58-
issue and identify the most appropriate existing labels. Use the
60+
You are an issue and pull request triage assistant. Analyze the current GitHub
61+
${{ env.ITEM_TYPE }} and identify the most appropriate existing labels. Use the
5962
available tools to gather information; do not ask for information
6063
to be provided.
6164
@@ -74,22 +77,22 @@ jobs:
7477
${{ env.AVAILABLE_LABELS }}
7578
```
7679
77-
**Issue Title**:
80+
**Title**:
7881
```
79-
${{ env.ISSUE_TITLE }}
82+
${{ env.ITEM_TITLE }}
8083
```
8184
82-
**Issue Body**:
85+
**Body**:
8386
```
84-
${{ env.ISSUE_BODY }}
87+
${{ env.ITEM_BODY }}
8588
```
8689
8790
## Steps
8891
89-
1. Review the issue title, issue body, and available labels
92+
1. Review the title, body, and available labels
9093
provided above.
9194
92-
2. Based on the issue title and issue body, classify the issue
95+
2. Based on the title and body, classify the ${{ env.ITEM_TYPE }}
9396
and choose all appropriate labels from the list of available
9497
labels.
9598
@@ -128,18 +131,18 @@ jobs:
128131
console.log('No valid labels to apply');
129132
}
130133
131-
triage-unlabeled-issues:
132-
name: Triage Unlabeled Issues
134+
triage-unlabeled-items:
135+
name: Triage Unlabeled Issues and PRs
133136
if: |
134137
github.event_name == 'workflow_dispatch' &&
135138
inputs.issue_number == ''
136139
runs-on: ubuntu-latest
137140
steps:
138-
- name: Find and dispatch triage for unlabeled issues
141+
- name: Find and dispatch triage for unlabeled items
139142
uses: actions/github-script@v8
140143
with:
141144
script: |
142-
// Get all open issues
145+
// Get all open issues (includes PRs)
143146
const issues = await github.paginate(
144147
github.rest.issues.listForRepo,
145148
{
@@ -150,27 +153,28 @@ jobs:
150153
}
151154
);
152155
153-
console.log(`Found ${issues.length} open issues`);
156+
console.log(`Found ${issues.length} open issues and PRs`);
154157
155-
// Filter issues without labels
156-
const unlabeledIssues = issues.filter(issue =>
157-
!issue.pull_request && issue.labels.length === 0
158+
// Filter items without labels
159+
const unlabeledItems = issues.filter(issue =>
160+
issue.labels.length === 0
158161
);
159162
160163
console.log(
161-
`Found ${unlabeledIssues.length} unlabeled issues`
164+
`Found ${unlabeledItems.length} unlabeled items`
162165
);
163166
164-
if (unlabeledIssues.length === 0) {
165-
console.log('No unlabeled issues to process');
167+
if (unlabeledItems.length === 0) {
168+
console.log('No unlabeled items to process');
166169
return;
167170
}
168171
169-
// Dispatch triage workflow for each unlabeled issue
170-
for (const issue of unlabeledIssues) {
172+
// Dispatch triage workflow for each unlabeled item
173+
for (const item of unlabeledItems) {
174+
const itemType = item.pull_request ? 'PR' : 'issue';
171175
console.log(
172-
`Dispatching triage for issue #${issue.number}: ` +
173-
`"${issue.title}"`
176+
`Dispatching triage for ${itemType} #${item.number}: ` +
177+
`"${item.title}"`
174178
);
175179
176180
try {
@@ -180,12 +184,12 @@ jobs:
180184
workflow_id: 'issue-triage.yml',
181185
ref: context.ref || 'main',
182186
inputs: {
183-
issue_number: issue.number.toString()
187+
issue_number: item.number.toString()
184188
}
185189
});
186190
} catch (error) {
187191
console.error(
188-
`Failed to dispatch triage for issue #${issue.number}: ` +
192+
`Failed to dispatch triage for ${itemType} #${item.number}: ` +
189193
`${error.message}`
190194
);
191195
}
@@ -196,8 +200,8 @@ jobs:
196200
197201
console.log('Finished dispatching triage workflows');
198202
199-
triage-single-issue:
200-
name: Triage Single Issue
203+
triage-single-item:
204+
name: Triage Single Issue or PR
201205
if: |
202206
github.event_name == 'workflow_dispatch' &&
203207
inputs.issue_number != ''
@@ -216,44 +220,53 @@ jobs:
216220
const labelNames = labels.data.map(label => label.name);
217221
return labelNames.join(', ');
218222
219-
- name: Get issue details
220-
id: get-issue
223+
- name: Get item details
224+
id: get-item
221225
uses: actions/github-script@v8
222226
with:
223227
script: |
228+
const itemNumber = parseInt('${{ inputs.issue_number }}');
229+
230+
// Try to get as an issue first (works for both issues and PRs)
224231
const issue = await github.rest.issues.get({
225232
owner: context.repo.owner,
226233
repo: context.repo.repo,
227-
issue_number: parseInt('${{ inputs.issue_number }}')
234+
issue_number: itemNumber
228235
});
236+
237+
const itemType = issue.data.pull_request ? 'pull request' : 'issue';
238+
229239
return {
230240
title: issue.data.title,
231-
body: issue.data.body || ''
241+
body: issue.data.body || '',
242+
type: itemType
232243
};
233244
234245
- name: Set environment variables
235246
env:
236-
ISSUE_TITLE: ${{ fromJSON(steps.get-issue.outputs.result).title }}
237-
ISSUE_BODY: ${{ fromJSON(steps.get-issue.outputs.result).body }}
247+
ITEM_TITLE: ${{ fromJSON(steps.get-item.outputs.result).title }}
248+
ITEM_BODY: ${{ fromJSON(steps.get-item.outputs.result).body }}
249+
ITEM_TYPE: ${{ fromJSON(steps.get-item.outputs.result).type }}
238250
LABELS_RESULT: ${{ steps.get-labels.outputs.result }}
239251
run: |
240252
{
241253
echo "AVAILABLE_LABELS=${LABELS_RESULT}"
242-
echo "ISSUE_TITLE=${ISSUE_TITLE}"
243-
echo "ISSUE_BODY<<EOF"
244-
echo "${ISSUE_BODY}"
254+
echo "ITEM_TITLE=${ITEM_TITLE}"
255+
echo "ITEM_TYPE=${ITEM_TYPE}"
256+
echo "ITEM_BODY<<EOF"
257+
echo "${ITEM_BODY}"
245258
echo "EOF"
246259
} >> "$GITHUB_ENV"
247260
248-
- name: Analyze issue with AI
261+
- name: Analyze with AI
249262
id: ai-triage
250263
uses: actions/ai-inference@v2
251264
with:
252265
prompt: |
253266
## Role
254267
255-
You are an issue triage assistant. Analyze the current GitHub
256-
issue and identify the most appropriate existing labels. Use the
268+
You are an issue and pull request triage assistant. Analyze the current GitHub
269+
${{ env.ITEM_TYPE }} and identify the most appropriate existing labels. Use the
257270
available tools to gather information; do not ask for information
258271
to be provided.
259272
@@ -272,22 +285,22 @@ jobs:
272285
${{ env.AVAILABLE_LABELS }}
273286
```
274287
275-
**Issue Title**:
288+
**Title**:
276289
```
277-
${{ env.ISSUE_TITLE }}
290+
${{ env.ITEM_TITLE }}
278291
```
279292
280-
**Issue Body**:
293+
**Body**:
281294
```
282-
${{ env.ISSUE_BODY }}
295+
${{ env.ITEM_BODY }}
283296
```
284297
285298
## Steps
286299
287-
1. Review the issue title, issue body, and available labels
300+
1. Review the title, body, and available labels
288301
provided above.
289302
290-
2. Based on the issue title and issue body, classify the issue
303+
2. Based on the title and body, classify the ${{ env.ITEM_TYPE }}
291304
and choose all appropriate labels from the list of available
292305
labels.
293306
@@ -302,11 +315,11 @@ jobs:
302315
uses: actions/github-script@v8
303316
env:
304317
AI_RESPONSE: ${{ steps.ai-triage.outputs.response }}
305-
ISSUE_NUMBER: ${{ inputs.issue_number }}
318+
ITEM_NUMBER: ${{ inputs.issue_number }}
306319
with:
307320
script: |
308321
const response = process.env.AI_RESPONSE;
309-
const issueNumber = parseInt(process.env.ISSUE_NUMBER);
322+
const itemNumber = parseInt(process.env.ITEM_NUMBER);
310323
311324
if (!response || response.trim() === '') {
312325
console.log('No labels selected by AI');
@@ -322,7 +335,7 @@ jobs:
322335
await github.rest.issues.addLabels({
323336
owner: context.repo.owner,
324337
repo: context.repo.repo,
325-
issue_number: issueNumber,
338+
issue_number: itemNumber,
326339
labels: labels
327340
});
328341
} else {

0 commit comments

Comments
 (0)