@@ -4,6 +4,7 @@ use crate::bors::command::Approver;
4
4
use crate :: bors:: event:: PullRequestEdited ;
5
5
use crate :: bors:: event:: PullRequestPushed ;
6
6
use crate :: bors:: handlers:: labels:: handle_label_trigger;
7
+ use crate :: bors:: CheckSuiteStatus ;
7
8
use crate :: bors:: Comment ;
8
9
use crate :: bors:: RepositoryState ;
9
10
use crate :: github:: CommitSha ;
@@ -24,14 +25,43 @@ pub(super) async fn command_approve(
24
25
approver : & Approver ,
25
26
) -> anyhow:: Result < ( ) > {
26
27
tracing:: info!( "Approving PR {}" , pr. number) ;
28
+
27
29
if !sufficient_approve_permission ( repo_state. clone ( ) , author) {
28
30
deny_approve_request ( & repo_state, pr, author) . await ?;
29
31
return Ok ( ( ) ) ;
30
32
} ;
33
+
31
34
let approver = match approver {
32
35
Approver :: Myself => author. username . clone ( ) ,
33
36
Approver :: Specified ( approver) => approver. clone ( ) ,
34
37
} ;
38
+
39
+ if repo_state. config . load ( ) . wait_on_ci_approval {
40
+ // Get all the check suites for the PR.
41
+ let checks = repo_state
42
+ . client
43
+ . get_check_suites_for_commit ( & pr. head . name , & pr. head . sha )
44
+ . await ?;
45
+
46
+ // Check suite failed, don't approve.
47
+ if checks
48
+ . iter ( )
49
+ . any ( |check| matches ! ( check. status, CheckSuiteStatus :: Failure ) )
50
+ {
51
+ notify_of_rejected_approval ( & repo_state, pr. number ) . await ?;
52
+ return Ok ( ( ) ) ;
53
+ }
54
+
55
+ // Check suite still running, notify user.
56
+ if checks
57
+ . iter ( )
58
+ . any ( |check| matches ! ( check. status, CheckSuiteStatus :: Pending ) )
59
+ {
60
+ notify_of_pending_approval ( & repo_state, pr. number ) . await ?;
61
+ return Ok ( ( ) ) ;
62
+ }
63
+ }
64
+
35
65
db. approve ( repo_state. repository ( ) , pr. number , approver. as_str ( ) )
36
66
. await ?;
37
67
handle_label_trigger ( & repo_state, pr. number , LabelTrigger :: Approved ) . await ?;
@@ -191,7 +221,7 @@ async fn notify_of_edited_pr(
191
221
. post_comment (
192
222
pr_number,
193
223
Comment :: new ( format ! (
194
- r#":warning: The base branch changed to `{base_name}`, and the
224
+ r#":warning: The base branch changed to `{base_name}`, and the
195
225
PR will need to be re-approved."# ,
196
226
) ) ,
197
227
)
@@ -207,14 +237,40 @@ async fn notify_of_pushed_pr(
207
237
. post_comment (
208
238
pr_number,
209
239
Comment :: new ( format ! (
210
- r#":warning: A new commit `{}` was pushed to the branch, the
240
+ r#":warning: A new commit `{}` was pushed to the branch, the
211
241
PR will need to be re-approved."# ,
212
242
head_sha
213
243
) ) ,
214
244
)
215
245
. await
216
246
}
217
247
248
+ async fn notify_of_rejected_approval (
249
+ repo : & RepositoryState ,
250
+ pr_number : PullRequestNumber ,
251
+ ) -> anyhow:: Result < ( ) > {
252
+ repo. client
253
+ . post_comment (
254
+ pr_number,
255
+ Comment :: new ( format ! ( ":x: Approval rejected, CI checks have failed." ) ) ,
256
+ )
257
+ . await
258
+ }
259
+
260
+ async fn notify_of_pending_approval (
261
+ repo : & RepositoryState ,
262
+ pr_number : PullRequestNumber ,
263
+ ) -> anyhow:: Result < ( ) > {
264
+ repo. client
265
+ . post_comment (
266
+ pr_number,
267
+ Comment :: new ( format ! (
268
+ ":hourglass_flowing_sand: Waiting for CI checks to complete before approving..."
269
+ ) ) ,
270
+ )
271
+ . await
272
+ }
273
+
218
274
#[ cfg( test) ]
219
275
mod tests {
220
276
use crate :: {
@@ -348,7 +404,7 @@ mod tests {
348
404
349
405
assert_eq ! (
350
406
tester. get_comment( ) . await ?,
351
- r#":warning: The base branch changed to `main`, and the
407
+ r#":warning: The base branch changed to `main`, and the
352
408
PR will need to be re-approved."# ,
353
409
) ;
354
410
check_pr_unapproved ( & tester, default_pr_number ( ) . into ( ) ) . await ;
@@ -428,7 +484,7 @@ PR will need to be re-approved."#,
428
484
assert_eq ! (
429
485
tester. get_comment( ) . await ?,
430
486
format!(
431
- r#":warning: A new commit `pr-{}-sha` was pushed to the branch, the
487
+ r#":warning: A new commit `pr-{}-sha` was pushed to the branch, the
432
488
PR will need to be re-approved."# ,
433
489
default_pr_number( )
434
490
)
0 commit comments