@@ -14,6 +14,8 @@ pub(super) enum Invocation {
14
14
NewProposal ,
15
15
AcceptedProposal ,
16
16
Rename { prev_issue : ZulipGitHubReference } ,
17
+ ConcernsAdded ,
18
+ ConcernsResolved ,
17
19
}
18
20
19
21
pub ( super ) async fn parse_input (
@@ -61,6 +63,21 @@ pub(super) async fn parse_input(
61
63
return Ok ( Some ( Invocation :: AcceptedProposal ) ) ;
62
64
}
63
65
66
+ // If the concerns label was added, then considered that the
67
+ // major change is blocked
68
+ if matches ! ( & event. action, IssuesAction :: Labeled { label } if Some ( & label. name) == config. concerns_label. as_ref( ) )
69
+ {
70
+ return Ok ( Some ( Invocation :: ConcernsAdded ) ) ;
71
+ }
72
+
73
+ // If the concerns label was removed, then considered that
74
+ // all concerns have been resolved; the major change is no
75
+ // longer blocked.
76
+ if matches ! ( & event. action, IssuesAction :: Unlabeled { label: Some ( label) } if Some ( & label. name) == config. concerns_label. as_ref( ) )
77
+ {
78
+ return Ok ( Some ( Invocation :: ConcernsResolved ) ) ;
79
+ }
80
+
64
81
// Opening an issue with a label assigned triggers both
65
82
// "Opened" and "Labeled" events.
66
83
//
@@ -99,18 +116,24 @@ pub(super) async fn handle_input(
99
116
cmnt. post ( & ctx. github ) . await ?;
100
117
return Ok ( ( ) ) ;
101
118
}
102
- let zulip_msg = match cmd {
103
- Invocation :: NewProposal => format ! (
104
- "A new proposal has been announced: [{} #{}]({}). It will be \
105
- announced at the next meeting to try and draw attention to it, \
106
- but usually MCPs are not discussed during triage meetings. If \
107
- you think this would benefit from discussion amongst the \
108
- team, consider proposing a design meeting.",
109
- event. issue. title, event. issue. number, event. issue. html_url,
119
+ let ( zulip_msg, label_to_add) = match cmd {
120
+ Invocation :: NewProposal => (
121
+ format ! (
122
+ "A new proposal has been announced: [{} #{}]({}). It will be \
123
+ announced at the next meeting to try and draw attention to it, \
124
+ but usually MCPs are not discussed during triage meetings. If \
125
+ you think this would benefit from discussion amongst the \
126
+ team, consider proposing a design meeting.",
127
+ event. issue. title, event. issue. number, event. issue. html_url,
128
+ ) ,
129
+ Some ( & config. meeting_label ) ,
110
130
) ,
111
- Invocation :: AcceptedProposal => format ! (
112
- "This proposal has been accepted: [#{}]({})." ,
113
- event. issue. number, event. issue. html_url,
131
+ Invocation :: AcceptedProposal => (
132
+ format ! (
133
+ "This proposal has been accepted: [#{}]({})." ,
134
+ event. issue. number, event. issue. html_url,
135
+ ) ,
136
+ Some ( & config. meeting_label ) ,
114
137
) ,
115
138
Invocation :: Rename { prev_issue } => {
116
139
let issue = & event. issue ;
@@ -167,13 +190,32 @@ pub(super) async fn handle_input(
167
190
168
191
return Ok ( ( ) ) ;
169
192
}
193
+ Invocation :: ConcernsAdded => (
194
+ // Ideally, we would remove the `enabled_label` (if present) and add it back once all concerns are resolved.
195
+ //
196
+ // However, since this handler is stateless, we can't track when to re-add it, it's also a bit unclear if it
197
+ // should be re-added at all. Also historically the `enable_label` wasn't removed either, so we don't touch it.
198
+ format ! ( "Concern(s) have been raised on the [associated GitHub issue]({}). This proposal is now blocked until those concerns are fully resolved." , event. issue. html_url) ,
199
+ None
200
+ ) ,
201
+ Invocation :: ConcernsResolved => (
202
+ if event. issue . labels ( ) . contains ( & Label {
203
+ name : config. enabling_label . to_string ( ) ,
204
+ } ) {
205
+ format ! ( "All concerns on the [associated GitHub issue]({}) have been resolved, this proposal is no longer blocked, and will be approved in 10 days if no (new) objections are raised." , event. issue. html_url)
206
+ } else {
207
+ format ! ( "All concerns on the [associated GitHub issue]({}) have been resolved, this proposal is no longer blocked." , event. issue. html_url)
208
+ } ,
209
+ None
210
+ )
170
211
} ;
212
+
171
213
handle (
172
214
ctx,
173
215
config,
174
216
& event. issue ,
175
217
zulip_msg,
176
- config . meeting_label . clone ( ) ,
218
+ label_to_add . cloned ( ) ,
177
219
cmd == Invocation :: NewProposal ,
178
220
)
179
221
. await
@@ -228,7 +270,7 @@ pub(super) async fn handle_command(
228
270
config,
229
271
issue,
230
272
zulip_msg,
231
- config. second_label . clone ( ) ,
273
+ Some ( config. second_label . clone ( ) ) ,
232
274
false ,
233
275
)
234
276
. await
@@ -239,10 +281,11 @@ async fn handle(
239
281
config : & MajorChangeConfig ,
240
282
issue : & Issue ,
241
283
zulip_msg : String ,
242
- label_to_add : String ,
284
+ label_to_add : Option < String > ,
243
285
new_proposal : bool ,
244
286
) -> anyhow:: Result < ( ) > {
245
- let github_req = issue. add_labels ( & ctx. github , vec ! [ Label { name: label_to_add } ] ) ;
287
+ let github_req = label_to_add
288
+ . map ( |label_to_add| issue. add_labels ( & ctx. github , vec ! [ Label { name: label_to_add } ] ) ) ;
246
289
247
290
let partial_issue = issue. to_zulip_github_reference ( ) ;
248
291
let zulip_topic = zulip_topic_from_issue ( & partial_issue) ;
@@ -292,9 +335,13 @@ See documentation at [https://forge.rust-lang.org](https://forge.rust-lang.org/c
292
335
293
336
let zulip_req = zulip_req. send ( & ctx. zulip ) ;
294
337
295
- let ( gh_res, zulip_res) = futures:: join!( github_req, zulip_req) ;
296
- zulip_res. context ( "zulip post failed" ) ?;
297
- gh_res. context ( "label setting failed" ) ?;
338
+ if let Some ( github_req) = github_req {
339
+ let ( gh_res, zulip_res) = futures:: join!( github_req, zulip_req) ;
340
+ zulip_res. context ( "zulip post failed" ) ?;
341
+ gh_res. context ( "label setting failed" ) ?;
342
+ } else {
343
+ zulip_req. await . context ( "zulip post failed" ) ?;
344
+ }
298
345
Ok ( ( ) )
299
346
}
300
347
0 commit comments