From a27cc0ff96ea235b052f56183e94980d2e50728b Mon Sep 17 00:00:00 2001
From: Peter Jaszkowiak
Date: Fri, 15 Sep 2023 21:10:39 -0600
Subject: [PATCH] no-merges: match titles instead of labels
also don't re-add labels if they're manually removed
labels are not always set atomically when opening a PR
example: rust-lang/miri#3059
---
src/config.rs | 4 ++--
src/handlers/no_merges.rs | 42 ++++++++++++++++++++++++++++-----------
2 files changed, 32 insertions(+), 14 deletions(-)
diff --git a/src/config.rs b/src/config.rs
index 38e81fce..3386c32a 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -105,9 +105,9 @@ impl AssignConfig {
#[derive(PartialEq, Eq, Debug, serde::Deserialize)]
pub(crate) struct NoMergesConfig {
- /// No action will be taken on PRs with these labels.
+ /// No action will be taken on PRs with these substrings in the title.
#[serde(default)]
- pub(crate) exclude_labels: Vec,
+ pub(crate) exclude_titles: Vec,
/// Set these labels on the PR when merge commits are detected.
#[serde(default)]
pub(crate) labels: Vec,
diff --git a/src/handlers/no_merges.rs b/src/handlers/no_merges.rs
index e90008cd..89d520cb 100644
--- a/src/handlers/no_merges.rs
+++ b/src/handlers/no_merges.rs
@@ -48,11 +48,13 @@ pub(super) async fn parse_input(
return Ok(None);
}
- // Don't trigger if the PR has any of the excluded labels.
- for label in event.issue.labels() {
- if config.exclude_labels.contains(&label.name) {
- return Ok(None);
- }
+ // Don't trigger if the PR has any of the excluded title segments.
+ if config
+ .exclude_titles
+ .iter()
+ .any(|s| event.issue.title.contains(s))
+ {
+ return Ok(None);
}
let mut merge_commits = HashSet::new();
@@ -70,12 +72,11 @@ pub(super) async fn parse_input(
}
}
- let input = NoMergesInput { merge_commits };
- Ok(if input.merge_commits.is_empty() {
- None
- } else {
- Some(input)
- })
+ if merge_commits.is_empty() {
+ return Ok(None);
+ }
+
+ Ok(Some(NoMergesInput { merge_commits }))
}
const DEFAULT_MESSAGE: &str = "
@@ -102,6 +103,7 @@ pub(super) async fn handle_input(
let mut client = ctx.db.get().await;
let mut state: IssueData<'_, NoMergesState> =
IssueData::load(&mut client, &event.issue, NO_MERGES_KEY).await?;
+ let first_time = state.data.mentioned_merge_commits.is_empty();
let mut message = config
.message
@@ -109,7 +111,7 @@ pub(super) async fn handle_input(
.unwrap_or(DEFAULT_MESSAGE)
.to_string();
- let since_last_posted = if state.data.mentioned_merge_commits.is_empty() {
+ let since_last_posted = if first_time {
""
} else {
" (since this message was last posted)"
@@ -132,6 +134,22 @@ pub(super) async fn handle_input(
}
if should_send {
+ if !first_time {
+ // Check if the labels are already set.
+ // Otherwise, they were probably removed manually.
+ if !event
+ .issue
+ .labels()
+ .iter()
+ .all(|label| config.labels.contains(&label.name))
+ {
+ // Assume it was a false positive, so don't
+ // re-add the labels or send a message this time.
+ state.save().await?;
+ return Ok(());
+ }
+ }
+
// Set labels
let labels = config
.labels