From 7fb447a92be4d67856972785a133d25c7591c0f3 Mon Sep 17 00:00:00 2001
From: Peter Jaszkowiak
Date: Fri, 15 Sep 2023 21:10:39 -0600
Subject: [PATCH 1/6] 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..9856c871 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 still set.
+ // Otherwise, they were probably removed manually.
+ let any_removed = config.labels.iter().any(|label| {
+ // No label on the issue matches.
+ event.issue.labels().iter().all(|l| &l.name != label)
+ });
+
+ if any_removed {
+ // 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
From 559e1d37b23c113d7d5574bf708ca6e4a489a742 Mon Sep 17 00:00:00 2001
From: Maybe Waffle
Date: Sun, 15 Oct 2023 12:48:24 +0200
Subject: [PATCH 2/6] Make `IssuesAction` into a dataful enum, to remove
unwraps
---
src/github.rs | 22 ++++++++++++++++------
src/handlers/autolabel.rs | 4 ++--
src/handlers/major_change.rs | 19 +++----------------
src/handlers/notify_zulip.rs | 18 ++++++++++--------
4 files changed, 31 insertions(+), 32 deletions(-)
diff --git a/src/github.rs b/src/github.rs
index 496a214e..f46b8d55 100644
--- a/src/github.rs
+++ b/src/github.rs
@@ -911,7 +911,7 @@ pub struct IssueCommentEvent {
}
#[derive(PartialEq, Eq, Debug, serde::Deserialize)]
-#[serde(rename_all = "snake_case")]
+#[serde(rename_all = "snake_case", tag = "action")]
pub enum IssuesAction {
Opened,
Edited,
@@ -923,13 +923,22 @@ pub enum IssuesAction {
Reopened,
Assigned,
Unassigned,
- Labeled,
- Unlabeled,
+ Labeled {
+ /// The label added from the issue
+ label: Label,
+ },
+ Unlabeled {
+ /// The label removed from the issue
+ label: Label,
+ },
Locked,
Unlocked,
Milestoned,
Demilestoned,
- ReviewRequested,
+ ReviewRequested {
+ /// The person requested to review the pull request
+ requested_reviewer: User,
+ },
ReviewRequestRemoved,
ReadyForReview,
Synchronize,
@@ -940,13 +949,14 @@ pub enum IssuesAction {
#[derive(Debug, serde::Deserialize)]
pub struct IssuesEvent {
+ #[serde(flatten)]
pub action: IssuesAction,
#[serde(alias = "pull_request")]
pub issue: Issue,
pub changes: Option,
pub repository: Repository,
- /// Some if action is IssuesAction::Labeled, for example
- pub label: Option