From 8a6d967f071e3c06296a01bc291a63ca9870b9ea Mon Sep 17 00:00:00 2001 From: Urgau Date: Wed, 12 Nov 2025 19:04:57 +0100 Subject: [PATCH 1/2] Move rfcbot FCP check to utils and error on `concern` command --- src/handlers/concern.rs | 24 ++++++------------------ src/utils.rs | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/handlers/concern.rs b/src/handlers/concern.rs index a6b509ea..9a589e12 100644 --- a/src/handlers/concern.rs +++ b/src/handlers/concern.rs @@ -8,6 +8,7 @@ use crate::{ github::{Event, Label}, handlers::Context, interactions::EditIssueBody, + utils::is_issue_under_rfcbot_fcp, }; use parser::command::concern::ConcernCommand; @@ -45,24 +46,11 @@ pub(super) async fn handle_command( }; let issue = &issue_comment.issue; - // Verify that this issue isn't a rfcbot FCP, skip if it is - match crate::rfcbot::get_all_fcps().await { - Ok(fcps) => { - if fcps.iter().any(|(_, fcp)| { - u64::from(fcp.issue.number) == issue.number - && fcp.issue.repository == issue_comment.repository.full_name - }) { - tracing::info!( - "{}#{} tried to register a concern, blocked by our rfcbot FCP check", - issue_comment.repository.full_name, - issue.number, - ); - return Ok(()); - } - } - Err(err) => { - tracing::warn!("unable to fetch rfcbot active FCPs: {err:?}, skipping check"); - } + // Verify that this issue isn't a rfcbot FCP + if is_issue_under_rfcbot_fcp(&issue_comment.repository.full_name, issue.number).await { + return user_error!( + "Cannot set `@rustbot concern` on an active [rfcbot](https://rfcbot.rs/) FCP, use `@rfcbot concern` instead." + ); } // Verify that the comment author is a team member in our team repo diff --git a/src/utils.rs b/src/utils.rs index ab65d2ea..cd78c854 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -35,3 +35,24 @@ pub(crate) async fn is_repo_autorized( Ok(true) } + +pub(crate) async fn is_issue_under_rfcbot_fcp( + issue_full_repo_name: &str, + issue_number: u64, +) -> bool { + match crate::rfcbot::get_all_fcps().await { + Ok(fcps) => { + if fcps.iter().any(|(_, fcp)| { + u64::from(fcp.issue.number) == issue_number + && fcp.issue.repository == issue_full_repo_name + }) { + return true; + } + } + Err(err) => { + tracing::warn!("unable to fetch rfcbot active FCPs: {err:?}, skipping check"); + } + } + + false +} From c24d8630a2cfbe9fc19cb0d749479cff81b6b83c Mon Sep 17 00:00:00 2001 From: Urgau Date: Wed, 12 Nov 2025 19:05:48 +0100 Subject: [PATCH 2/2] Block acceptance and second of major change under active rfcbot FCP --- src/handlers/major_change.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/handlers/major_change.rs b/src/handlers/major_change.rs index 661dde46..fdf51bed 100644 --- a/src/handlers/major_change.rs +++ b/src/handlers/major_change.rs @@ -2,6 +2,7 @@ use std::fmt::Display; use crate::errors::user_error; use crate::jobs::Job; +use crate::utils::is_issue_under_rfcbot_fcp; use crate::zulip::api::Recipient; use crate::{ config::MajorChangeConfig, @@ -262,6 +263,13 @@ pub(super) async fn handle_command( return user_error!("Only team members can second issues."); } + // Verify that this issue isn't a rfcbot FCP + if is_issue_under_rfcbot_fcp(&issue.repository().full_repo_name(), issue.number).await { + return user_error!( + "Cannot second a major change on an active [rfcbot](https://rfcbot.rs/) FCP." + ); + } + let has_concerns = if let Some(concerns_label) = &config.concerns_label { issue.labels().iter().any(|l| &l.name == concerns_label) } else { @@ -474,6 +482,7 @@ enum SecondedLogicError { at: DateTime, }, NoMajorChangeConfig, + UnderRfcBotFcp, } impl std::error::Error for SecondedLogicError {} @@ -506,6 +515,7 @@ impl Display for SecondedLogicError { write!(f, "concerns label added at {at}") } SecondedLogicError::NoMajorChangeConfig => write!(f, "no `[major_change]` config"), + SecondedLogicError::UnderRfcBotFcp => write!(f, "under rfcbot fcp"), } } } @@ -679,6 +689,10 @@ async fn try_accept_mcp( open: issue.is_open() }); } + + if is_issue_under_rfcbot_fcp(&major_change.repo, major_change.issue).await { + anyhow::bail!(SecondedLogicError::UnderRfcBotFcp); + } } if !issue.labels.iter().any(|l| l.name == config.accept_label) {