Skip to content
This repository was archived by the owner on Nov 14, 2025. It is now read-only.

Commit 1d4ad3a

Browse files
authored
Update triage to also handle triaging stale issues and letting team members know that they can help with triaging. (#345)
* Refactor triage action inputs to make them optional and implement stale issue triaging logic * Add optional working areas link input and update triage logic for team members * Update comment for stale issue filtering logic to clarify criteria
1 parent 1ad3ee7 commit 1d4ad3a

File tree

3 files changed

+82
-15
lines changed

3 files changed

+82
-15
lines changed

triage/action.yml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,19 @@ inputs:
2020
required: true
2121
issue_number:
2222
description: Issue number
23-
required: true
23+
required: false
2424
event:
2525
description: Event name for a triggered action. Otherwise, this is obtained from the GitHub context.
26-
required: true
26+
required: false
2727
action:
2828
description: Action name for a triggered action. Otherwise, this is obtained from the GitHub context.
29-
required: true
29+
required: false
3030
assignees:
3131
description: Pipe-separated list of assignees to triage new issues to
32-
required: true
32+
required: false
33+
workingAreasLink:
34+
description: Link to the working areas document
35+
required: false
3336
runs:
3437
using: 'node20'
3538
main: 'index.js'

triage/index.js

Lines changed: 34 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

triage/index.ts

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,35 @@
33
* Licensed under the MIT License. See LICENSE in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { OctoKitIssue } from '../api/octokit';
6+
import { getInput } from '@actions/core';
7+
import { OctoKit, OctoKitIssue } from '../api/octokit';
78
import { VSCodeToolsAPIManager } from '../api/vscodeTools';
8-
import { Action } from '../common/Action';
9-
import { getRequiredInput, safeLog } from '../common/utils';
9+
import { Action, getAuthenticationToken } from '../common/Action';
10+
import { daysAgoToHumanReadbleDate, getRequiredInput, safeLog } from '../common/utils';
1011

1112
class IssueTriageAction extends Action {
1213
id = 'IssueTriageAction';
1314

14-
private async triage(issue: OctoKitIssue) {
15+
private async triage(issue: OctoKitIssue, skipTeamCheck = false): Promise<void> {
1516
try {
1617
const githubIssue = await issue.getIssue();
1718
if (!githubIssue) return;
1819

1920
const vscodeToolsAPI = new VSCodeToolsAPIManager();
2021
const teamMembers = new Set((await vscodeToolsAPI.getTeamMembers()).map((t) => t.id));
21-
if (teamMembers.has(githubIssue.author.name)) {
22+
if (!skipTeamCheck && teamMembers.has(githubIssue.author.name)) {
23+
if (githubIssue.assignees.length === 0) {
24+
const link = getInput('workingAreasLink');
25+
if (link) {
26+
await issue.postComment(
27+
`Hi ${githubIssue.author.name}. As a member of the team, you can help us triage this issue by referring to ${link}`,
28+
);
29+
} else {
30+
await issue.postComment(
31+
`Hi ${githubIssue.author.name}. You can help us triage this issue by assigning it to the appropriate person.`,
32+
);
33+
}
34+
}
2235
safeLog('Author is a team member, skipping triaging', githubIssue.author.name);
2336
return;
2437
}
@@ -62,10 +75,31 @@ class IssueTriageAction extends Action {
6275
}
6376

6477
protected override async onOpened(issue: OctoKitIssue): Promise<void> {
65-
// wait 30 seconds before triaging
66-
await new Promise((resolve) => setTimeout(resolve, 30000));
78+
// wait 1 minute before triaging
79+
await new Promise((resolve) => setTimeout(resolve, 60000));
6780
await this.triage(issue);
6881
}
82+
83+
protected override async onTriggered(_octokit: OctoKit): Promise<void> {
84+
const owner = getRequiredInput('owner');
85+
const repo = getRequiredInput('repo');
86+
const token = await getAuthenticationToken();
87+
88+
const staleIssues = _octokit.query({
89+
q: `is:issue is:open no:assignee no:label updated:<${daysAgoToHumanReadbleDate(7)}`,
90+
});
91+
92+
// Loop through issues which are not assigned and no labels and updated more than 7 days ago
93+
for await (const page of staleIssues) {
94+
for (const issueData of page) {
95+
const issue = await issueData.getIssue();
96+
if (!issue) continue;
97+
const octokitIssue = new OctoKitIssue(token, { owner, repo }, { number: issue?.number });
98+
await this.triage(octokitIssue, true);
99+
}
100+
}
101+
safeLog('Completed triaging stale issues.');
102+
}
69103
}
70104

71105
new IssueTriageAction().run(); // eslint-disable-line

0 commit comments

Comments
 (0)