@@ -24,6 +24,9 @@ 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
+ #[ serde( default ) ]
29
+ added_labels : Vec < String > ,
27
30
}
28
31
29
32
pub ( super ) async fn parse_input (
@@ -72,10 +75,8 @@ pub(super) async fn parse_input(
72
75
}
73
76
}
74
77
75
- if merge_commits. is_empty ( ) {
76
- return Ok ( None ) ;
77
- }
78
-
78
+ // Run the handler even if we have no merge commits,
79
+ // so we can take an action if some were removed.
79
80
Ok ( Some ( NoMergesInput { merge_commits } ) )
80
81
}
81
82
@@ -103,6 +104,32 @@ pub(super) async fn handle_input(
103
104
let mut client = ctx. db . get ( ) . await ;
104
105
let mut state: IssueData < ' _ , NoMergesState > =
105
106
IssueData :: load ( & mut client, & event. issue , NO_MERGES_KEY ) . await ?;
107
+
108
+ // No merge commits.
109
+ if input. merge_commits . is_empty ( ) {
110
+ if state. data . mentioned_merge_commits . is_empty ( ) {
111
+ // No merge commits from before, so do nothing.
112
+ return Ok ( ( ) ) ;
113
+ }
114
+
115
+ // Merge commits were removed, so remove the labels we added.
116
+ for name in state. data . added_labels . iter ( ) {
117
+ event
118
+ . issue
119
+ . remove_label ( & ctx. github , name)
120
+ . await
121
+ . context ( "failed to remove label" ) ?;
122
+ }
123
+
124
+ // FIXME: Minimize prior no_merges comments.
125
+
126
+ // Clear from state.
127
+ state. data . mentioned_merge_commits . clear ( ) ;
128
+ state. data . added_labels . clear ( ) ;
129
+ state. save ( ) . await ?;
130
+ return Ok ( ( ) ) ;
131
+ }
132
+
106
133
let first_time = state. data . mentioned_merge_commits . is_empty ( ) ;
107
134
108
135
let mut message = config
@@ -137,7 +164,7 @@ pub(super) async fn handle_input(
137
164
if !first_time {
138
165
// Check if the labels are still set.
139
166
// Otherwise, they were probably removed manually.
140
- let any_removed = config . labels . iter ( ) . any ( |label| {
167
+ let any_removed = state . data . added_labels . iter ( ) . any ( |label| {
141
168
// No label on the issue matches.
142
169
event. issue . labels ( ) . iter ( ) . all ( |l| & l. name != label)
143
170
} ) ;
@@ -150,13 +177,18 @@ pub(super) async fn handle_input(
150
177
}
151
178
}
152
179
180
+ let existing_labels = event. issue . labels ( ) ;
181
+
182
+ let mut labels = Vec :: new ( ) ;
183
+ for name in config. labels . iter ( ) {
184
+ // Only add labels not already on the issue.
185
+ if existing_labels. iter ( ) . all ( |l| & l. name != name) {
186
+ state. data . added_labels . push ( name. clone ( ) ) ;
187
+ labels. push ( Label { name : name. clone ( ) } ) ;
188
+ }
189
+ }
190
+
153
191
// Set labels
154
- let labels = config
155
- . labels
156
- . iter ( )
157
- . cloned ( )
158
- . map ( |name| Label { name } )
159
- . collect ( ) ;
160
192
event
161
193
. issue
162
194
. add_labels ( & ctx. github , labels)
0 commit comments