@@ -5,7 +5,8 @@ use crate::bors::RepositoryState;
5
5
use crate :: bors:: command:: RollupMode ;
6
6
use crate :: bors:: command:: { Approver , CommandPrefix } ;
7
7
use crate :: bors:: comment:: {
8
- approve_non_open_pr_comment, approve_wip_title, delegate_comment, delegate_try_builds_comment,
8
+ approve_blocking_labels_present, approve_non_open_pr_comment, approve_wip_title,
9
+ delegate_comment, delegate_try_builds_comment,
9
10
} ;
10
11
use crate :: bors:: handlers:: has_permission;
11
12
use crate :: bors:: handlers:: labels:: handle_label_trigger;
@@ -38,7 +39,7 @@ pub(super) async fn command_approve(
38
39
return Ok ( ( ) ) ;
39
40
} ;
40
41
41
- if let Some ( error_comment) = check_pr_approval_validity ( pr) . await ? {
42
+ if let Some ( error_comment) = check_pr_approval_validity ( pr, & repo_state ) . await ? {
42
43
repo_state
43
44
. client
44
45
. post_comment ( pr. number ( ) , error_comment)
@@ -69,7 +70,10 @@ const WIP_KEYWORDS: &[&str] = &["wip", "[do not merge]"];
69
70
/// Check that the given PR can be approved in its current state.
70
71
/// Returns `Ok(Some(comment))` if it **cannot** be approved; the comment should be sent to the
71
72
/// pull request.
72
- async fn check_pr_approval_validity ( pr : & PullRequestData ) -> anyhow:: Result < Option < Comment > > {
73
+ async fn check_pr_approval_validity (
74
+ pr : & PullRequestData ,
75
+ repo : & RepositoryState ,
76
+ ) -> anyhow:: Result < Option < Comment > > {
73
77
// Check PR status
74
78
if !matches ! ( pr. github. status, PullRequestStatus :: Open ) {
75
79
return Ok ( Some ( approve_non_open_pr_comment ( ) ) ) ;
@@ -81,6 +85,24 @@ async fn check_pr_approval_validity(pr: &PullRequestData) -> anyhow::Result<Opti
81
85
return Ok ( Some ( approve_wip_title ( wip_kw) ) ) ;
82
86
}
83
87
88
+ // Check blocking labels
89
+ let config = repo. config . load ( ) ;
90
+ let blocking_labels: Vec < & str > = pr
91
+ . github
92
+ . labels
93
+ . iter ( )
94
+ . map ( |label| label. as_str ( ) )
95
+ . filter ( |label| {
96
+ config
97
+ . labels_blocking_approval
98
+ . iter ( )
99
+ . any ( |blocking_label| blocking_label == label)
100
+ } )
101
+ . collect ( ) ;
102
+ if !blocking_labels. is_empty ( ) {
103
+ return Ok ( Some ( approve_blocking_labels_present ( & blocking_labels) ) ) ;
104
+ }
105
+
84
106
Ok ( None )
85
107
}
86
108
@@ -1102,7 +1124,7 @@ mod tests {
1102
1124
. set_pr_status_draft ( default_repo_name ( ) , default_pr_number ( ) )
1103
1125
. await ?;
1104
1126
tester. post_comment ( "@bors r+" ) . await ?;
1105
- insta:: assert_snapshot!( tester. get_comment( ) . await ?, @"Only open, non-draft PRs can be approved" ) ;
1127
+ insta:: assert_snapshot!( tester. get_comment( ) . await ?, @":clipboard: Only open, non-draft PRs can be approved. " ) ;
1106
1128
tester. default_pr ( ) . await . expect_unapproved ( ) ;
1107
1129
Ok ( ( ) )
1108
1130
} )
@@ -1116,7 +1138,7 @@ mod tests {
1116
1138
. set_pr_status_closed ( default_repo_name ( ) , default_pr_number ( ) )
1117
1139
. await ?;
1118
1140
tester. post_comment ( "@bors r+" ) . await ?;
1119
- insta:: assert_snapshot!( tester. get_comment( ) . await ?, @"Only open, non-draft PRs can be approved" ) ;
1141
+ insta:: assert_snapshot!( tester. get_comment( ) . await ?, @":clipboard: Only open, non-draft PRs can be approved. " ) ;
1120
1142
tester. default_pr ( ) . await . expect_unapproved ( ) ;
1121
1143
Ok ( ( ) )
1122
1144
} )
@@ -1130,7 +1152,7 @@ mod tests {
1130
1152
. set_pr_status_merged ( default_repo_name ( ) , default_pr_number ( ) )
1131
1153
. await ?;
1132
1154
tester. post_comment ( "@bors r+" ) . await ?;
1133
- insta:: assert_snapshot!( tester. get_comment( ) . await ?, @"Only open, non-draft PRs can be approved" ) ;
1155
+ insta:: assert_snapshot!( tester. get_comment( ) . await ?, @":clipboard: Only open, non-draft PRs can be approved. " ) ;
1134
1156
tester. default_pr ( ) . await . expect_unapproved ( ) ;
1135
1157
Ok ( ( ) )
1136
1158
} )
@@ -1156,4 +1178,56 @@ mod tests {
1156
1178
} )
1157
1179
. await ;
1158
1180
}
1181
+
1182
+ #[ sqlx:: test]
1183
+ async fn approve_pr_with_blocked_label ( pool : sqlx:: PgPool ) {
1184
+ BorsBuilder :: new ( pool)
1185
+ . github ( GitHubState :: default ( ) . with_default_config (
1186
+ r#"
1187
+ labels_blocking_approval = ["proposed-final-comment-period"]
1188
+ "# ,
1189
+ ) )
1190
+ . run_test ( async |tester : & mut BorsTester | {
1191
+ tester
1192
+ . edit_pr ( default_repo_name ( ) , default_pr_number ( ) , |pr| {
1193
+ pr. labels = vec ! [
1194
+ "S-waiting-on-review" . to_string( ) ,
1195
+ "proposed-final-comment-period" . to_string( ) ,
1196
+ ] ;
1197
+ } )
1198
+ . await ?;
1199
+ tester. post_comment ( "@bors r+" ) . await ?;
1200
+ insta:: assert_snapshot!( tester. get_comment( ) . await ?, @":clipboard: This PR cannot be approved because it currently has the following label: `proposed-final-comment-period`." ) ;
1201
+ tester. default_pr ( ) . await . expect_unapproved ( ) ;
1202
+ Ok ( ( ) )
1203
+ } )
1204
+ . await ;
1205
+ }
1206
+
1207
+ #[ sqlx:: test]
1208
+ async fn approve_pr_with_blocked_labels ( pool : sqlx:: PgPool ) {
1209
+ BorsBuilder :: new ( pool)
1210
+ . github ( GitHubState :: default ( ) . with_default_config (
1211
+ r#"
1212
+ labels_blocking_approval = ["proposed-final-comment-period", "final-comment-period"]
1213
+ "# ,
1214
+ ) )
1215
+ . run_test ( async |tester : & mut BorsTester | {
1216
+ tester
1217
+ . edit_pr ( default_repo_name ( ) , default_pr_number ( ) , |pr| {
1218
+ pr. labels = vec ! [
1219
+ "S-waiting-on-review" . to_string( ) ,
1220
+ "proposed-final-comment-period" . to_string( ) ,
1221
+ "final-comment-period" . to_string( ) ,
1222
+ "S-blocked" . to_string( ) ,
1223
+ ] ;
1224
+ } )
1225
+ . await ?;
1226
+ tester. post_comment ( "@bors r+" ) . await ?;
1227
+ insta:: assert_snapshot!( tester. get_comment( ) . await ?, @":clipboard: This PR cannot be approved because it currently has the following labels: `proposed-final-comment-period`, `final-comment-period`." ) ;
1228
+ tester. default_pr ( ) . await . expect_unapproved ( ) ;
1229
+ Ok ( ( ) )
1230
+ } )
1231
+ . await ;
1232
+ }
1159
1233
}
0 commit comments