diff --git a/src/config.rs b/src/config.rs index 614776e7..88466fdb 100644 --- a/src/config.rs +++ b/src/config.rs @@ -515,7 +515,12 @@ pub(crate) struct IssueLinksConfig { #[derive(PartialEq, Eq, Debug, serde::Deserialize)] #[serde(rename_all = "kebab-case")] #[serde(deny_unknown_fields)] -pub(crate) struct NoMentionsConfig {} +pub(crate) struct NoMentionsConfig { + /// The check will not be performed on titles that include any of these substrings (case + /// insensitive) + #[serde(default)] + pub(crate) exclude_titles: Vec, +} /// Configuration for PR behind commits checks #[derive(PartialEq, Eq, Debug, serde::Deserialize)] @@ -681,6 +686,7 @@ mod tests { trigger-files = ["posts/"] [no-mentions] + exclude-titles = ["subtree update"] [behind-upstream] days-threshold = 14 @@ -769,7 +775,9 @@ mod tests { issue_links: Some(IssueLinksConfig { check_commits: true, }), - no_mentions: Some(NoMentionsConfig {}), + no_mentions: Some(NoMentionsConfig { + exclude_titles: vec!["subtree update".into()], + }), behind_upstream: Some(BehindUpstreamConfig { days_threshold: Some(14), }), diff --git a/src/handlers/check_commits.rs b/src/handlers/check_commits.rs index 24da8c0a..70473107 100644 --- a/src/handlers/check_commits.rs +++ b/src/handlers/check_commits.rs @@ -106,7 +106,11 @@ pub(super) async fn handle(ctx: &Context, event: &Event, config: &Config) -> any } if let Some(no_mentions) = &config.no_mentions { - warnings.extend(no_mentions::mentions_in_commits(no_mentions, &commits)); + warnings.extend(no_mentions::mentions_in_commits( + &event.issue.title, + no_mentions, + &commits, + )); } if let Some(issue_links) = &config.issue_links { diff --git a/src/handlers/check_commits/no_mentions.rs b/src/handlers/check_commits/no_mentions.rs index 559be45d..4b4cd399 100644 --- a/src/handlers/check_commits/no_mentions.rs +++ b/src/handlers/check_commits/no_mentions.rs @@ -4,12 +4,24 @@ use crate::{config::NoMentionsConfig, github::GithubCommit}; pub(super) fn mentions_in_commits( - _conf: &NoMentionsConfig, + pr_title: &str, + conf: &NoMentionsConfig, commits: &[GithubCommit], ) -> Option { + if conf + .exclude_titles + .iter() + .any(|s| pr_title.to_lowercase().contains(&s.to_lowercase())) + { + return None; + } + let mentions_commits = commits .into_iter() - .filter(|c| !parser::get_mentions(&c.commit.message).is_empty()) + .filter(|c| { + let mentions = parser::get_mentions(&c.commit.message); + !mentions.is_empty() && mentions.iter().any(|m| *m != "rustbot") + }) .map(|c| format!("- {}\n", c.sha)) .collect::(); @@ -33,7 +45,14 @@ fn test_mentions_in_commits() { "This is simple without mentions!", )]; - assert_eq!(mentions_in_commits(&NoMentionsConfig {}, &commits), None); + let default_conf = NoMentionsConfig { + exclude_titles: vec![], + }; + + assert_eq!( + mentions_in_commits("any title", &default_conf, &commits), + None + ); commits.push(dummy_commit_from_body( "10b96a74c484cae79164cbbcdfcd412109e0e4cf", @@ -42,20 +61,51 @@ Signed-off-by: Foo Bar Co-authored-by: Baz Qux ", )); - assert_eq!(mentions_in_commits(&NoMentionsConfig {}, &commits), None); + assert_eq!( + mentions_in_commits("any title", &default_conf, &commits,), + None + ); commits.push(dummy_commit_from_body( - "d7daa17bc97df9377640b0d33cbd0bbeed703c3a", - "This is a body with a @mention!", + "6565ffdd8af4ca0ec7c8faceee59c582edcd83b2", + "This is a body that only mentions @rustbot for a command!", + )); + + assert_eq!( + mentions_in_commits("any title", &default_conf, &commits), + None + ); + + commits.push(dummy_commit_from_body( + "4894129179b361200c9cd733ba0e906bf98747a2", + "This is a body that mentions @rustbot for a command! And then a user @mention", )); assert_eq!( - mentions_in_commits(&NoMentionsConfig {}, &commits), + mentions_in_commits("any title", &default_conf, &commits, ), Some( r"There are username mentions (such as `@user`) in the commit messages of the following commits. *Please remove the mentions to avoid spamming these users.* -- d7daa17bc97df9377640b0d33cbd0bbeed703c3a +- 4894129179b361200c9cd733ba0e906bf98747a2 ".to_string() ) ); + + let _ = commits.pop(); // Remove that @rustbot & @mention case + + commits.push(dummy_commit_from_body( + "d7daa17bc97df9377640b0d33cbd0bbeed703c3a", + "This is a body with a @mention!", + )); + + assert_eq!( + mentions_in_commits( + "exclude this pull from checking ", + &NoMentionsConfig { + exclude_titles: vec![String::from("exclude this")] + }, + &commits + ), + None + ); }