@@ -24,6 +24,8 @@ pub(super) struct NoMergesInput {
24
24
struct NoMergesState {
25
25
/// Hashes of merge commits that have already been mentioned by triagebot in a comment.
26
26
mentioned_merge_commits : HashSet < String > ,
27
+ /// Labels that the bot added as part of the no-merges check.
28
+ added_labels : Vec < String > ,
27
29
}
28
30
29
31
pub ( super ) async fn parse_input (
@@ -72,10 +74,8 @@ pub(super) async fn parse_input(
72
74
}
73
75
}
74
76
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.
79
79
Ok ( Some ( NoMergesInput { merge_commits } ) )
80
80
}
81
81
@@ -103,6 +103,32 @@ pub(super) async fn handle_input(
103
103
let mut client = ctx. db . get ( ) . await ;
104
104
let mut state: IssueData < ' _ , NoMergesState > =
105
105
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
+
106
132
let first_time = state. data . mentioned_merge_commits . is_empty ( ) ;
107
133
108
134
let mut message = config
@@ -137,7 +163,7 @@ pub(super) async fn handle_input(
137
163
if !first_time {
138
164
// Check if the labels are still set.
139
165
// 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| {
141
167
// No label on the issue matches.
142
168
event. issue . labels ( ) . iter ( ) . all ( |l| & l. name != label)
143
169
} ) ;
@@ -150,13 +176,18 @@ pub(super) async fn handle_input(
150
176
}
151
177
}
152
178
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
+
153
190
// Set labels
154
- let labels = config
155
- . labels
156
- . iter ( )
157
- . cloned ( )
158
- . map ( |name| Label { name } )
159
- . collect ( ) ;
160
191
event
161
192
. issue
162
193
. add_labels ( & ctx. github , labels)
0 commit comments