1
1
import { Context , Probot } from "probot" ;
2
2
import yaml from "js-yaml" ;
3
3
import * as Task from "./task.js" ;
4
- import { Config } from "./common.js" ;
4
+ import { R2CN , BotComment } from "./common.js" ;
5
5
import * as Student from "./student.js" ;
6
6
import { handle_mentor_cmd } from "./mentor.js" ;
7
7
8
8
9
9
export default ( app : Probot ) => {
10
10
app . log . info ( `api endpoint: ${ process . env . API_ENDPOINT } ` ) ;
11
-
12
- app . on ( [ "issue_comment.created" , "issue_comment.edited" ] , async ( context ) => {
13
- const comment = context . payload . comment ;
14
- const config = await fetchConfig ( context ) ;
15
- if ( comment . user . type === "Bot" ) {
16
- context . log . debug ( "This comment was posted by a bot!" ) ;
17
- return
18
- }
11
+ app . on ( [ "issues.opened" , "issues.labeled" ] , async ( context ) => {
19
12
const labels = context . payload . issue . labels ;
20
- const hasLabel = labels . some ( ( label ) => label . name . startsWith ( "r2cn" ) ) ;
21
- const creator = context . payload . issue . user . login ;
22
- const repo_full_name = context . payload . repository . full_name ;
23
-
24
- if ( hasLabel ) {
25
- context . log . debug ( "R2cn label not found, skipping message" )
13
+ const hasLabel = labels ?. some ( ( label ) => label . name . startsWith ( "r2cn" ) ) ;
14
+ if ( ! hasLabel ) {
15
+ context . log . debug ( "R2cn label not found, skipping message..." )
26
16
return
27
17
}
18
+ const config = await fetchConfig ( context ) ;
28
19
if ( config == null ) {
29
20
context . log . error ( "Config parsing error" ) ;
30
21
return
31
22
}
32
- const repo = config . repos . find ( ( repo ) => repo . name === repo_full_name ) ;
23
+ const repo_full_name = context . payload . repository . full_name ;
24
+ const repo = config . r2cn ?. repos . find ( ( repo ) => repo . name === repo_full_name ) ;
33
25
if ( ! repo ) {
34
26
await context . octokit . issues . createComment ( context . issue ( {
35
- body : config . project . noneProjectComment ,
27
+ body : config . comment . project . noneProjectComment ,
36
28
} ) ) ;
37
29
return
38
30
}
39
-
40
- if ( ! repo . maintainers . includes ( creator ) ) {
31
+ const creator = context . payload . issue . user . login ;
32
+ const maintainer = repo . maintainers . find ( maintainer => maintainer . login === creator ) ;
33
+ if ( ! maintainer ) {
41
34
await context . octokit . issues . createComment ( context . issue ( {
42
- body : config . project . noneMaintainerComment ,
35
+ body : config . comment . project . noneMaintainerComment ,
43
36
} ) ) ;
44
37
return
45
38
}
46
39
const task = await Task . getTask ( context . payload . issue . id ) ;
47
40
if ( task == null ) {
48
- const checkRes : Task . CheckTaskResults = await Task . checkTask ( context . payload . repository , context . payload . issue , config ) ;
41
+ const checkRes : Task . CheckTaskResults = await Task . checkTask ( context . payload . repository , context . payload . issue , config , maintainer ) ;
49
42
if ( checkRes . result ) {
50
43
const newTaskRes = await Task . newTask ( context . payload . repository , context . payload . issue , checkRes . score ) ;
51
44
if ( newTaskRes ) {
52
45
await context . octokit . issues . createComment ( context . issue ( {
53
- body : "Task created successfully."
46
+ body : config . comment . task . success
54
47
} ) ) ;
55
48
}
56
49
} else {
@@ -59,41 +52,79 @@ export default (app: Probot) => {
59
52
} ) ) ;
60
53
}
61
54
} else {
62
- const comment = context . payload . comment . body . trim ( ) ;
55
+ context . log . debug ( "Task Exist, skipping message..." )
56
+ }
57
+ } ) ;
63
58
64
- if ( comment . startsWith ( "/request" ) ) {
65
- let res = await Student . handle_stu_cmd ( context , context . payload . comment . user , comment , config , task ) ;
66
- context . octokit . issues . createComment ( context . issue ( {
67
- body : res . message
68
- } ) ) ;
69
- } else if ( comment . startsWith ( "/intern" ) ) {
70
- let res = await handle_mentor_cmd ( context , context . payload . comment . user , comment , config , task ) ;
71
- context . octokit . issues . createComment ( context . issue ( {
72
- body : res . message
73
- } ) ) ;
74
- } else {
75
- context . log . debug ( "Normal Comment, skipping..." )
76
- }
59
+ app . on ( [ "issue_comment.created" ] , async ( context ) => {
60
+ const config = await fetchConfig ( context ) ;
61
+ if ( context . payload . comment . user . type === "Bot" ) {
62
+ // context.log.debug("This comment was posted by a bot!");
63
+ return
64
+ }
65
+ if ( config == null ) {
66
+ context . log . error ( "Config parsing error" ) ;
67
+ return
68
+ }
69
+ const task = await Task . getTask ( context . payload . issue . id ) ;
70
+ if ( task == null ) {
71
+ await context . octokit . issues . createComment ( context . issue ( {
72
+ body : config . comment . task . taskNotFound
73
+ } ) ) ;
74
+ }
75
+ const command = context . payload . comment . body . trim ( ) ;
76
+ if ( command . startsWith ( "/request" ) ) {
77
+ let res = await Student . handle_stu_cmd ( context , config , { student : context . payload . comment . user , command, task } ) ;
78
+ context . octokit . issues . createComment ( context . issue ( {
79
+ body : res . message
80
+ } ) ) ;
81
+ } else if ( command . startsWith ( "/intern" ) ) {
82
+ let res = await handle_mentor_cmd ( context , config , {
83
+ mentor : context . payload . comment . user , command, issue : context . payload . issue , task
84
+ } ) ;
85
+ context . octokit . issues . createComment ( context . issue ( {
86
+ body : res . message
87
+ } ) ) ;
88
+ } else {
89
+ context . log . debug ( "Normal Comment, skipping..." )
77
90
}
78
91
} ) ;
79
92
} ;
80
93
81
94
82
95
async function fetchConfig ( context : Context ) {
83
- const response = await context . octokit . repos . getContent ( {
96
+ const r2cn_conf = await context . octokit . repos . getContent ( {
97
+ owner : "r2cn-dev" ,
98
+ repo : "r2cn" ,
99
+ path : "r2cn.yaml" ,
100
+ } ) ;
101
+ let r2cn : R2CN | null = null ;
102
+
103
+ if ( "type" in r2cn_conf . data && r2cn_conf . data . type === "file" ) {
104
+ const content = Buffer . from ( r2cn_conf . data . content || "" , "base64" ) . toString ( "utf8" ) ;
105
+ r2cn = yaml . load ( content ) as R2CN ;
106
+ } else {
107
+ context . log . error ( "Parsing r2cn.yaml failed." ) ;
108
+ }
109
+
110
+ const comment_conf = await context . octokit . repos . getContent ( {
84
111
owner : "r2cn-dev" ,
85
- repo : "organization " ,
86
- path : "organization .yaml" ,
112
+ repo : "r2cn-bot " ,
113
+ path : "comment .yaml" ,
87
114
} ) ;
115
+ let comment : BotComment | null = null ;
88
116
89
- if ( "type" in response . data && response . data . type === "file" ) {
90
- // 如果是文件,解码内容
91
- const content = Buffer . from ( response . data . content || "" , "base64" ) . toString ( "utf8" ) ;
92
- context . log . debug ( "Config file content:" , content ) ;
93
- const config : Config = yaml . load ( content ) as Config ;
94
- return config ;
117
+ if ( "type" in comment_conf . data && comment_conf . data . type === "file" ) {
118
+ const content = Buffer . from ( comment_conf . data . content || "" , "base64" ) . toString ( "utf8" ) ;
119
+ comment = yaml . load ( content ) as BotComment ;
120
+ } else {
121
+ context . log . error ( "Parsing comment.yaml failed." ) ;
122
+ }
123
+ // 检查是否成功解析
124
+ if ( r2cn && comment ) {
125
+ return { comment, r2cn } ;
95
126
} else {
96
- context . log . error ( "The path is not a file ." ) ;
127
+ context . log . error ( "Failed to load Config. Either r2cn or comment is null ." ) ;
97
128
return null ;
98
129
}
99
130
}
0 commit comments