@@ -24,6 +24,8 @@ pub(super) struct NoMergesInput {
2424struct NoMergesState {
2525 /// Hashes of merge commits that have already been mentioned by triagebot in a comment.
2626 mentioned_merge_commits : HashSet < String > ,
27+ /// Labels that the bot added as part of the no-merges check.
28+ added_labels : Vec < String > ,
2729}
2830
2931pub ( super ) async fn parse_input (
@@ -72,10 +74,8 @@ pub(super) async fn parse_input(
7274 }
7375 }
7476
75- if merge_commits. is_empty ( ) {
76- return Ok ( None ) ;
77- }
78-
77+ // Run the handler even if we have no merge commits,
78+ // so we can take an action if some were removed.
7979 Ok ( Some ( NoMergesInput { merge_commits } ) )
8080}
8181
@@ -103,6 +103,32 @@ pub(super) async fn handle_input(
103103 let mut client = ctx. db . get ( ) . await ;
104104 let mut state: IssueData < ' _ , NoMergesState > =
105105 IssueData :: load ( & mut client, & event. issue , NO_MERGES_KEY ) . await ?;
106+
107+ // No merge commits.
108+ if input. merge_commits . is_empty ( ) {
109+ if state. data . mentioned_merge_commits . is_empty ( ) {
110+ // No merge commits from before, so do nothing.
111+ return Ok ( ( ) ) ;
112+ }
113+
114+ // Merge commits were removed, so remove the labels we added.
115+ for name in state. data . added_labels . iter ( ) {
116+ event
117+ . issue
118+ . remove_label ( & ctx. github , name)
119+ . await
120+ . context ( "failed to remove label" ) ?;
121+ }
122+
123+ // FIXME: Minimize prior no_merges comments.
124+
125+ // Clear from state.
126+ state. data . mentioned_merge_commits . clear ( ) ;
127+ state. data . added_labels . clear ( ) ;
128+ state. save ( ) . await ?;
129+ return Ok ( ( ) ) ;
130+ }
131+
106132 let first_time = state. data . mentioned_merge_commits . is_empty ( ) ;
107133
108134 let mut message = config
@@ -137,7 +163,7 @@ pub(super) async fn handle_input(
137163 if !first_time {
138164 // Check if the labels are still set.
139165 // Otherwise, they were probably removed manually.
140- let any_removed = config . labels . iter ( ) . any ( |label| {
166+ let any_removed = state . data . added_labels . iter ( ) . any ( |label| {
141167 // No label on the issue matches.
142168 event. issue . labels ( ) . iter ( ) . all ( |l| & l. name != label)
143169 } ) ;
@@ -150,13 +176,18 @@ pub(super) async fn handle_input(
150176 }
151177 }
152178
179+ let existing_labels = event. issue . labels ( ) ;
180+
181+ let mut labels = Vec :: new ( ) ;
182+ for name in config. labels . iter ( ) {
183+ // Only add labels not already on the issue.
184+ if existing_labels. iter ( ) . all ( |l| & l. name != name) {
185+ state. data . added_labels . push ( name. clone ( ) ) ;
186+ labels. push ( Label { name : name. clone ( ) } ) ;
187+ }
188+ }
189+
153190 // Set labels
154- let labels = config
155- . labels
156- . iter ( )
157- . cloned ( )
158- . map ( |name| Label { name } )
159- . collect ( ) ;
160191 event
161192 . issue
162193 . add_labels ( & ctx. github , labels)
0 commit comments