Skip to content

Commit 24d215a

Browse files
authored
Merge pull request #2190 from Urgau/remove_labels
Improve removal of multiple GitHub labels at the same time
2 parents a46114b + fe0d953 commit 24d215a

File tree

10 files changed

+124
-73
lines changed

10 files changed

+124
-73
lines changed

src/github.rs

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -785,33 +785,47 @@ impl Issue {
785785
Ok(())
786786
}
787787

788-
pub async fn remove_label(&self, client: &GithubClient, label: &str) -> anyhow::Result<()> {
789-
log::info!("remove_label from {}: {:?}", self.global_id(), label);
790-
// DELETE /repos/:owner/:repo/issues/:number/labels/{name}
791-
let url = format!(
792-
"{repo_url}/issues/{number}/labels/{name}",
793-
repo_url = self.repository().url(client),
794-
number = self.number,
795-
name = label,
788+
pub async fn remove_labels(
789+
&self,
790+
client: &GithubClient,
791+
labels: Vec<Label>,
792+
) -> anyhow::Result<()> {
793+
log::info!("remove_labels from {}: {:?}", self.global_id(), labels);
794+
795+
// Don't try to remove labels not already present on this issue.
796+
let labels = labels
797+
.into_iter()
798+
.filter(|l| self.labels().contains(l))
799+
.collect::<Vec<_>>();
800+
801+
log::info!(
802+
"remove_labels: {} filtered to {:?}",
803+
self.global_id(),
804+
labels
796805
);
797806

798-
if !self
799-
.labels()
800-
.iter()
801-
.any(|l| l.name.to_lowercase() == label.to_lowercase())
802-
{
803-
log::info!(
804-
"remove_label from {}: {:?} already not present, skipping",
805-
self.global_id(),
806-
label
807-
);
807+
if labels.is_empty() {
808808
return Ok(());
809809
}
810810

811-
client
812-
.send_req(client.delete(&url))
813-
.await
814-
.context("failed to delete label")?;
811+
// There is no API to remove all labels at once, so we issue as many
812+
// API requests are required in parallel.
813+
let requests = labels.into_iter().map(|label| async move {
814+
// DELETE /repos/:owner/:repo/issues/:number/labels/{name}
815+
let url = format!(
816+
"{repo_url}/issues/{number}/labels/{name}",
817+
repo_url = self.repository().url(client),
818+
number = self.number,
819+
name = label.name,
820+
);
821+
822+
client
823+
.send_req(client.delete(&url))
824+
.await
825+
.with_context(|| format!("failed to remove {label:?}"))
826+
});
827+
828+
futures::future::try_join_all(requests).await?;
815829

816830
Ok(())
817831
}

src/handlers/autolabel.rs

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -222,18 +222,11 @@ pub(super) async fn handle_input(
222222
}
223223
}
224224

225-
for label in input.remove {
226-
event
227-
.issue
228-
.remove_label(&ctx.github, &label.name)
229-
.await
230-
.with_context(|| {
231-
format!(
232-
"failed to remove {:?} from {:?}",
233-
label,
234-
event.issue.global_id()
235-
)
236-
})?;
237-
}
225+
event
226+
.issue
227+
.remove_labels(&ctx.github, input.remove)
228+
.await
229+
.context("failed to remove labels from the issue")?;
230+
238231
Ok(())
239232
}

src/handlers/check_commits.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -243,13 +243,17 @@ async fn handle_new_state(
243243

244244
// Remove the labels no longer required
245245
if !labels_to_remove.is_empty() {
246-
for label in labels_to_remove {
247-
event
248-
.issue
249-
.remove_label(&ctx.github, &label)
250-
.await
251-
.context("failed to remove a label in check_commits")?;
252-
}
246+
event
247+
.issue
248+
.remove_labels(
249+
&ctx.github,
250+
labels_to_remove
251+
.into_iter()
252+
.map(|name| Label { name })
253+
.collect(),
254+
)
255+
.await
256+
.context("failed to remove a label in check_commits")?;
253257
}
254258

255259
// Add the labels that are now required

src/handlers/concern.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -152,12 +152,19 @@ pub(super) async fn handle_command(
152152
).await.context("unable to post the comment failure it-self")?;
153153
}
154154
} else {
155-
for l in &config.labels {
156-
issue
157-
.remove_label(&ctx.github, &l)
158-
.await
159-
.context("unable to remove the concern labels")?;
160-
}
155+
issue
156+
.remove_labels(
157+
&ctx.github,
158+
config
159+
.labels
160+
.iter()
161+
.map(|l| Label {
162+
name: l.to_string(),
163+
})
164+
.collect(),
165+
)
166+
.await
167+
.context("unable to remove the concern labels")?;
161168
}
162169

163170
// Apply the new markdown concerns list to the issue

src/handlers/major_change.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -708,7 +708,12 @@ As the automated representative, I would like to thank the author for their work
708708
.await
709709
.context("unable to add the accept label")?;
710710
issue
711-
.remove_label(&ctx.github, &config.second_label)
711+
.remove_labels(
712+
&ctx.github,
713+
vec![Label {
714+
name: config.second_label.clone(),
715+
}],
716+
)
712717
.await
713718
.context("unable to remove the second label")?;
714719
issue

src/handlers/merge_conflicts.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -288,15 +288,19 @@ async fn maybe_add_comment(
288288

289289
let current_labels: HashSet<_> = issue.labels.iter().map(|l| l.name.clone()).collect();
290290
if current_labels.is_disjoint(&config.unless) {
291-
for label in &config.remove {
292-
issue.remove_label(gh, label).await?;
293-
}
294291
let to_add = config
295292
.add
296293
.iter()
297294
.map(|l| Label { name: l.clone() })
298295
.collect();
296+
let to_remove = config
297+
.remove
298+
.iter()
299+
.map(|l| Label { name: l.clone() })
300+
.collect();
301+
299302
issue.add_labels(gh, to_add).await?;
303+
issue.remove_labels(gh, to_remove).await?;
300304
}
301305

302306
Ok(())

src/handlers/relabel.rs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,14 @@ pub(super) async fn handle_command(
7373
}
7474

7575
// Remove labels
76-
for label in to_remove {
77-
if let Err(e) = issue.remove_label(&ctx.github, &label.name).await {
78-
tracing::error!(
79-
"failed to remove {:?} from issue {}: {:?}",
80-
label,
81-
issue.global_id(),
82-
e
83-
);
84-
return Err(e);
85-
}
76+
if let Err(e) = issue.remove_labels(&ctx.github, to_remove.clone()).await {
77+
tracing::error!(
78+
"failed to remove {:?} from issue {}: {:?}",
79+
to_remove,
80+
issue.global_id(),
81+
e
82+
);
83+
return Err(e);
8684
}
8785

8886
Ok(())

src/handlers/review_requested.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,18 @@ pub(crate) async fn handle_input(
5252
)
5353
.await?;
5454

55-
for label in &config.remove_labels {
56-
event.issue.remove_label(&ctx.github, label).await?;
57-
}
55+
event
56+
.issue
57+
.remove_labels(
58+
&ctx.github,
59+
config
60+
.remove_labels
61+
.iter()
62+
.cloned()
63+
.map(|name| Label { name })
64+
.collect(),
65+
)
66+
.await?;
5867

5968
Ok(())
6069
}

src/handlers/review_submitted.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,20 @@ pub(crate) async fn handle(
2323

2424
if event.issue.assignees.contains(&event.comment.user) {
2525
// Remove review labels
26-
for label in &config.review_labels {
27-
event.issue.remove_label(&ctx.github, &label).await?;
28-
}
26+
event
27+
.issue
28+
.remove_labels(
29+
&ctx.github,
30+
config
31+
.review_labels
32+
.iter()
33+
.map(|label| Label {
34+
name: label.clone(),
35+
})
36+
.collect(),
37+
)
38+
.await?;
39+
2940
// Add waiting on author
3041
event
3142
.issue

src/handlers/shortcut.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,17 @@ pub(super) async fn handle_command(
5050
};
5151

5252
if !issue_labels.iter().any(|l| l.name == add) {
53-
for remove in status_labels {
54-
if remove != add {
55-
issue.remove_label(&ctx.github, remove).await?;
56-
}
57-
}
53+
issue
54+
.remove_labels(
55+
&ctx.github,
56+
status_labels
57+
.iter()
58+
.filter(|l| **l != add)
59+
.map(|l| Label { name: (*l).into() })
60+
.collect(),
61+
)
62+
.await?;
63+
5864
issue
5965
.add_labels(
6066
&ctx.github,

0 commit comments

Comments
 (0)