1
+ const process = require ( "process" ) ;
2
+ const cp = require ( "child_process" ) ;
3
+
4
+ const Labels = {
5
+ needsAttention : "needs attention" ,
6
+ } ;
7
+
8
+ const workflowMaintainer = process . env . WORKFLOW_MAINTAINER_EMAIL ;
9
+ const repoMaintainers = JSON . parse ( process . env . REPO_MAINTAINERS ) ;
10
+ const repoMaintainersMap = new Map (
11
+ repoMaintainers . maintainers . map ( ( m ) => [ m . github , m . alias ] )
12
+ ) ;
13
+
14
+ async function sendEmail ( to , subject , body ) {
15
+ return cp . execSync ( ".github/scripts/send-email.sh" , {
16
+ env : {
17
+ ...process . env ,
18
+ SUBJECT : subject ,
19
+ TO : to ,
20
+ BODY : JSON . stringify ( body ) ,
21
+ } ,
22
+ } ) ;
23
+ }
24
+
25
+ async function main ( ) {
26
+ const repo = "microsoft/vscode-ai-toolkit" ;
27
+ const output = cp . execSync (
28
+ `gh issue list --repo ${ repo } --state open --json number,title,assignees,labels,url` ,
29
+ { encoding : "utf-8" }
30
+ ) ;
31
+ const issues = JSON . parse ( output ) ;
32
+
33
+ let unknownAssignees = new Set ( ) ;
34
+ // alias => issue[]
35
+ const userMapping = new Map ( ) ;
36
+ for ( const issue of issues ) {
37
+ const needsAttention = ! ! issue ?. labels ?. find ( ( label ) => label ?. name === Labels . needsAttention ) ;
38
+ if ( needsAttention && issue ?. assignees ?. length && issue . assignees . length > 0 ) {
39
+ const emails = issue . assignees . map ( ( assignee ) => {
40
+ const alias = repoMaintainersMap . get ( assignee . login ) ;
41
+ if ( ! alias ) {
42
+ unknownAssignees . add ( assignee . login ) ;
43
+ return undefined ;
44
+ } else {
45
+ return `${ alias } @microsoft.com` ;
46
+ }
47
+ } ) . filter ( ( email ) => ! ! email ) ;
48
+
49
+ for ( const email of emails ) {
50
+ if ( ! userMapping . has ( email ) ) {
51
+ userMapping . set ( email , [ ] ) ;
52
+ }
53
+ userMapping . set ( email , [ ...userMapping . get ( email ) , issue ] ) ;
54
+ }
55
+ }
56
+ }
57
+
58
+ // Send email once for each assigned user
59
+ for ( const [ email , issues ] of userMapping . entries ( ) ) {
60
+ console . log ( `Sending email to ${ email } for issue ${ JSON . stringify ( issues ) } ` ) ;
61
+ const body = `
62
+ <p>Hi, here are GitHub issues that needs your attention:</p>
63
+ ${ issues . map ( ( issue ) => `<p><a href="${ issue . url } ">#${ issue . number } </a>: ${ issue . title } (${ issue . url } )</p>` ) }
64
+ ` ;
65
+ await sendEmail (
66
+ email ,
67
+ `[Needs attention] AI Toolkit GitHub issue report` ,
68
+ body ,
69
+ ) ;
70
+ }
71
+
72
+ if ( unknownAssignees . size > 0 ) {
73
+ await sendEmail (
74
+ workflowMaintainer ,
75
+ `There are unknown assignees in ${ repo } ` ,
76
+ `There are unknown assignees in the issues: ${ Array . from (
77
+ unknownAssignees
78
+ ) . join (
79
+ ", "
80
+ ) } , please update <a href="https://github.com/microsoft/vscode-ai-toolkit/blob/main/.github/data/maintainers.json">maintainers.json</a>. `
81
+ ) ;
82
+ }
83
+ }
84
+
85
+
86
+ main ( )
0 commit comments