1
- use crate :: api:: { github, ServerResult } ;
1
+ use crate :: api:: github:: Issue ;
2
2
use crate :: comparison:: { ComparisonSummary , Direction } ;
3
3
use crate :: load:: { Config , SiteCtxt , TryCommit } ;
4
4
5
5
use anyhow:: Context as _;
6
6
use database:: ArtifactId ;
7
7
use hashbrown:: HashSet ;
8
- use regex:: Regex ;
9
8
use reqwest:: header:: USER_AGENT ;
10
- use serde:: Deserialize ;
9
+ use serde:: { Deserialize , Serialize } ;
11
10
12
11
use std:: { fmt:: Write , sync:: Arc , time:: Duration } ;
13
12
14
13
type BoxedError = Box < dyn std:: error:: Error + Send + Sync > ;
15
14
16
- lazy_static:: lazy_static! {
17
- static ref BODY_TRY_COMMIT : Regex =
18
- Regex :: new( r#"(?:\W|^)@rust-timer\s+build\s+(\w+)(?:\W|$)(?:include=(\S+))?\s*(?:exclude=(\S+))?\s*(?:runs=(\d+))?"# ) . unwrap( ) ;
19
- static ref BODY_QUEUE : Regex =
20
- Regex :: new( r#"(?:\W|^)@rust-timer\s+queue(?:\W|$)(?:include=(\S+))?\s*(?:exclude=(\S+))?\s*(?:runs=(\d+))?"# ) . unwrap( ) ;
21
- static ref BODY_MAKE_PR_FOR : Regex =
22
- Regex :: new( r#"(?:\W|^)@rust-timer\s+make-pr-for\s+(\w+)(?:\W|$)"# ) . unwrap( ) ;
23
- static ref BODY_UDPATE_PR_FOR : Regex =
24
- Regex :: new( r#"(?:\W|^)@rust-timer\s+update-branch-for\s+(\w+)(?:\W|$)"# ) . unwrap( ) ;
25
- }
26
-
27
- async fn get_authorized_users ( ) -> ServerResult < Vec < usize > > {
15
+ pub async fn get_authorized_users ( ) -> Result < Vec < usize > , String > {
28
16
let url = format ! ( "{}/permissions/perf.json" , :: rust_team_data:: v1:: BASE_URL ) ;
29
17
let client = reqwest:: Client :: new ( ) ;
30
18
client
@@ -40,120 +28,8 @@ async fn get_authorized_users() -> ServerResult<Vec<usize>> {
40
28
. map ( |perms| perms. github_ids )
41
29
}
42
30
43
- pub async fn handle_github (
44
- request : github:: Request ,
45
- ctxt : Arc < SiteCtxt > ,
46
- ) -> ServerResult < github:: Response > {
47
- if request. comment . body . contains ( " homu: " ) {
48
- if let Some ( sha) = handle_homu_res ( & request) . await {
49
- return enqueue_sha ( request, & ctxt, sha) . await ;
50
- }
51
- }
52
-
53
- if !request. comment . body . contains ( "@rust-timer " ) {
54
- return Ok ( github:: Response ) ;
55
- }
56
-
57
- if request. comment . author_association != github:: Association :: Owner
58
- && !get_authorized_users ( )
59
- . await ?
60
- . contains ( & request. comment . user . id )
61
- {
62
- post_comment (
63
- & ctxt. config ,
64
- request. issue . number ,
65
- "Insufficient permissions to issue commands to rust-timer." ,
66
- )
67
- . await ;
68
- return Ok ( github:: Response ) ;
69
- }
70
-
71
- if let Some ( captures) = BODY_QUEUE . captures ( & request. comment . body ) {
72
- let include = captures. get ( 1 ) . map ( |v| v. as_str ( ) ) ;
73
- let exclude = captures. get ( 2 ) . map ( |v| v. as_str ( ) ) ;
74
- let runs = captures. get ( 3 ) . and_then ( |v| v. as_str ( ) . parse :: < i32 > ( ) . ok ( ) ) ;
75
- {
76
- let conn = ctxt. conn ( ) . await ;
77
- conn. queue_pr ( request. issue . number , include, exclude, runs)
78
- . await ;
79
- }
80
- post_comment (
81
- & ctxt. config ,
82
- request. issue . number ,
83
- "Awaiting bors try build completion.
84
-
85
- @rustbot label: +S-waiting-on-perf" ,
86
- )
87
- . await ;
88
- return Ok ( github:: Response ) ;
89
- }
90
-
91
- if let Some ( captures) = BODY_TRY_COMMIT . captures ( & request. comment . body ) {
92
- if let Some ( commit) = captures. get ( 1 ) . map ( |c| c. as_str ( ) . to_owned ( ) ) {
93
- let include = captures. get ( 2 ) . map ( |v| v. as_str ( ) ) ;
94
- let exclude = captures. get ( 3 ) . map ( |v| v. as_str ( ) ) ;
95
- let runs = captures. get ( 4 ) . and_then ( |v| v. as_str ( ) . parse :: < i32 > ( ) . ok ( ) ) ;
96
- let commit = commit. trim_start_matches ( "https://github.com/rust-lang/rust/commit/" ) ;
97
- {
98
- let conn = ctxt. conn ( ) . await ;
99
- conn. queue_pr ( request. issue . number , include, exclude, runs)
100
- . await ;
101
- }
102
- let f = enqueue_sha ( request, & ctxt, commit. to_owned ( ) ) ;
103
- return f. await ;
104
- }
105
- }
106
-
107
- let captures = BODY_MAKE_PR_FOR
108
- . captures_iter ( & request. comment . body )
109
- . collect :: < Vec < _ > > ( ) ;
110
- for capture in captures {
111
- if let Some ( rollup_merge) = capture. get ( 1 ) . map ( |c| c. as_str ( ) . to_owned ( ) ) {
112
- let rollup_merge =
113
- rollup_merge. trim_start_matches ( "https://github.com/rust-lang/rust/commit/" ) ;
114
- let client = reqwest:: Client :: new ( ) ;
115
- pr_and_try_for_rollup (
116
- & client,
117
- ctxt. clone ( ) ,
118
- & request. issue . repository_url ,
119
- & rollup_merge,
120
- & request. comment . html_url ,
121
- )
122
- . await
123
- . map_err ( |e| format ! ( "{:?}" , e) ) ?;
124
- }
125
- }
126
-
127
- let captures = BODY_UDPATE_PR_FOR
128
- . captures_iter ( & request. comment . body )
129
- . collect :: < Vec < _ > > ( ) ;
130
- for capture in captures {
131
- if let Some ( rollup_merge) = capture. get ( 1 ) . map ( |c| c. as_str ( ) . to_owned ( ) ) {
132
- let rollup_merge =
133
- rollup_merge. trim_start_matches ( "https://github.com/rust-lang/rust/commit/" ) ;
134
-
135
- // This just creates or updates the branch for this merge commit.
136
- // Intended for resolving the race condition of master merging in
137
- // between us updating the commit and merging things.
138
- let client = reqwest:: Client :: new ( ) ;
139
- let branch =
140
- branch_for_rollup ( & client, & ctxt, & request. issue . repository_url , rollup_merge)
141
- . await
142
- . map_err ( |e| e. to_string ( ) ) ?;
143
- post_comment (
144
- & ctxt. config ,
145
- request. issue . number ,
146
- & format ! ( "Master base SHA: {}" , branch. master_base_sha) ,
147
- )
148
- . await ;
149
- }
150
- }
151
-
152
- Ok ( github:: Response )
153
- }
154
-
155
31
// Returns the PR number
156
- async fn pr_and_try_for_rollup (
32
+ pub async fn pr_and_try_for_rollup (
157
33
client : & reqwest:: Client ,
158
34
ctxt : Arc < SiteCtxt > ,
159
35
repository_url : & str ,
@@ -226,13 +102,13 @@ build hasn't yet started.",
226
102
Ok ( pr_number)
227
103
}
228
104
229
- struct RollupBranch {
230
- master_base_sha : String ,
231
- rolled_up_pr_number : u32 ,
232
- name : String ,
105
+ pub struct RollupBranch {
106
+ pub master_base_sha : String ,
107
+ pub rolled_up_pr_number : u32 ,
108
+ pub name : String ,
233
109
}
234
110
235
- async fn branch_for_rollup (
111
+ pub async fn branch_for_rollup (
236
112
client : & reqwest:: Client ,
237
113
ctxt : & SiteCtxt ,
238
114
repository_url : & str ,
@@ -467,7 +343,7 @@ pub async fn get_commit(
467
343
ctxt : & SiteCtxt ,
468
344
repository_url : & str ,
469
345
sha : & str ,
470
- ) -> anyhow:: Result < github :: Commit > {
346
+ ) -> anyhow:: Result < Commit > {
471
347
let timer_token = ctxt
472
348
. config
473
349
. keys
@@ -498,13 +374,33 @@ pub async fn get_commit(
498
374
}
499
375
}
500
376
501
- async fn enqueue_sha (
502
- request : github:: Request ,
503
- ctxt : & SiteCtxt ,
504
- commit : String ,
505
- ) -> ServerResult < github:: Response > {
377
+ #[ derive( Debug , Clone , Deserialize ) ]
378
+ pub struct Commit {
379
+ pub sha : String ,
380
+ pub commit : InnerCommit ,
381
+ pub parents : Vec < CommitParent > ,
382
+ }
383
+
384
+ #[ derive( Debug , Clone , Deserialize ) ]
385
+ pub struct InnerCommit {
386
+ #[ serde( default ) ]
387
+ pub message : String ,
388
+ pub tree : CommitTree ,
389
+ }
390
+
391
+ #[ derive( Debug , Clone , Deserialize ) ]
392
+ pub struct CommitTree {
393
+ pub sha : String ,
394
+ }
395
+
396
+ #[ derive( Debug , Clone , Deserialize ) ]
397
+ pub struct CommitParent {
398
+ pub sha : String ,
399
+ }
400
+
401
+ pub async fn enqueue_sha ( issue : Issue , ctxt : & SiteCtxt , commit : String ) -> Result < ( ) , String > {
506
402
let client = reqwest:: Client :: new ( ) ;
507
- let commit_response = get_commit ( & client, ctxt, & request . issue . repository_url , & commit)
403
+ let commit_response = get_commit ( & client, ctxt, & issue. repository_url , & commit)
508
404
. await
509
405
. map_err ( |e| e. to_string ( ) ) ?;
510
406
if commit_response. parents . len ( ) != 2 {
@@ -513,17 +409,17 @@ async fn enqueue_sha(
513
409
commit_response. sha,
514
410
commit_response. parents. len( )
515
411
) ;
516
- return Ok ( github :: Response ) ;
412
+ return Ok ( ( ) ) ;
517
413
}
518
414
let try_commit = TryCommit {
519
415
sha : commit_response. sha . clone ( ) ,
520
416
parent_sha : commit_response. parents [ 0 ] . sha . clone ( ) ,
521
- issue : request . issue . clone ( ) ,
417
+ issue : issue. clone ( ) ,
522
418
} ;
523
419
let queued = {
524
420
let conn = ctxt. conn ( ) . await ;
525
421
conn. pr_attach_commit (
526
- request . issue . number ,
422
+ issue. number ,
527
423
& commit_response. sha ,
528
424
& commit_response. parents [ 0 ] . sha ,
529
425
)
@@ -536,9 +432,9 @@ async fn enqueue_sha(
536
432
commit_response. parents[ 0 ] . sha,
537
433
try_commit. comparison_url( ) ,
538
434
) ;
539
- post_comment ( & ctxt. config , request . issue . number , msg) . await ;
435
+ post_comment ( & ctxt. config , issue. number , msg) . await ;
540
436
}
541
- Ok ( github :: Response )
437
+ Ok ( ( ) )
542
438
}
543
439
544
440
#[ derive( Debug , Deserialize ) ]
@@ -547,22 +443,23 @@ enum HomuComment {
547
443
TryBuildCompleted { merge_sha : String } ,
548
444
}
549
445
550
- async fn handle_homu_res ( request : & github:: Request ) -> Option < String > {
551
- if !request. comment . body . contains ( "Try build successful" ) {
446
+ /// Parse comment from homu containing try build sha
447
+ pub async fn parse_homu_comment ( comment_body : & str ) -> Option < String > {
448
+ if !comment_body. contains ( "Try build successful" ) {
552
449
return None ;
553
450
}
554
451
555
452
let start = "<!-- homu: " ;
556
- let start_idx = request . comment . body . find ( start) . expect ( "found homu" ) + start. len ( ) ;
557
- let end_idx = start_idx + request . comment . body [ start_idx..] . find ( " -->" ) . unwrap ( ) ;
453
+ let start_idx = comment_body . find ( start) . expect ( "found homu" ) + start. len ( ) ;
454
+ let end_idx = start_idx + comment_body [ start_idx..] . find ( " -->" ) . unwrap ( ) ;
558
455
559
- let sha = match serde_json:: from_str ( & request . comment . body [ start_idx..end_idx] ) {
456
+ let sha = match serde_json:: from_str ( & comment_body [ start_idx..end_idx] ) {
560
457
Ok ( HomuComment :: TryBuildCompleted { merge_sha } ) => merge_sha,
561
458
Err ( err) => {
562
459
log:: warn!(
563
460
"failed to parse try build result; comment: {:?}, part: {:?}, err: {:?}" ,
564
- request . comment . body ,
565
- & request . comment . body [ start_idx..end_idx] ,
461
+ comment_body ,
462
+ & comment_body [ start_idx..end_idx] ,
566
463
err
567
464
) ;
568
465
return None ;
@@ -588,7 +485,7 @@ where
588
485
"https://api.github.com/repos/rust-lang/rust/issues/{}/comments" ,
589
486
pr
590
487
) )
591
- . json ( & github :: PostComment {
488
+ . json ( & PostComment {
592
489
body : body. to_owned ( ) ,
593
490
} )
594
491
. header ( USER_AGENT , "perf-rust-lang-org-server" )
@@ -599,6 +496,11 @@ where
599
496
}
600
497
}
601
498
499
+ #[ derive( Debug , Clone , Serialize ) ]
500
+ pub struct PostComment {
501
+ pub body : String ,
502
+ }
503
+
602
504
pub async fn post_finished ( ctxt : & SiteCtxt ) {
603
505
// If the github token is not configured, do not run this -- we don't want
604
506
// to mark things as complete without posting the comment.
0 commit comments