From dc133359eb7e2584aa64f92e82a2a928e48a35bf Mon Sep 17 00:00:00 2001 From: Urgau Date: Mon, 17 Nov 2025 19:01:46 +0100 Subject: [PATCH] Also add `@bot ready` reminder for review submitted --- src/handlers.rs | 12 ++++++-- src/handlers/review_reminder.rs | 53 ++++++++++++++++++++++++++++++++ src/handlers/review_submitted.rs | 7 +++++ src/handlers/shortcut.rs | 42 ++++--------------------- 4 files changed, 75 insertions(+), 39 deletions(-) create mode 100644 src/handlers/review_reminder.rs diff --git a/src/handlers.rs b/src/handlers.rs index 2f8bcf34..75f27e82 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -37,6 +37,7 @@ mod relabel; mod relnotes; mod rendered_link; mod review_changes_since; +mod review_reminder; mod review_requested; mod review_submitted; pub mod rustc_commits; @@ -144,9 +145,14 @@ pub async fn handle(ctx: &Context, host: &str, event: &Event) -> Vec, +} + +pub(crate) async fn remind_author_of_bot_ready( + ctx: &Context, + issue: &Issue, + config: Option<&ShortcutConfig>, +) -> anyhow::Result<()> { + let Some(_config) = config else { + // Ignore repository that don't have `[shortcut]` enabled + return Ok(()); + }; + + if matches!( + issue.author_association, + AuthorAssociation::Member | AuthorAssociation::Owner + ) { + // Don't post the reminder for org members (public-only unfortunately) and owner of the org. + return Ok(()); + } + + // Get the state of the author reminder for this PR + let mut db = ctx.db.get().await; + let mut state: IssueData<'_, AuthorReminderState> = + IssueData::load(&mut db, issue, AUTHOR_REMINDER_KEY).await?; + + // If no comment already posted, let's post it + if state.data.reminder_comment.is_none() { + let comment_body = format!( + "Reminder, once the PR becomes ready for a review, use `@{bot} ready`.", + bot = &ctx.username, + ); + let comment = issue + .post_comment(&ctx.github, comment_body.as_str()) + .await?; + + state.data.reminder_comment = Some(comment.node_id); + state.save().await?; + } + + Ok(()) +} diff --git a/src/handlers/review_submitted.rs b/src/handlers/review_submitted.rs index c07623b2..2e81d6ad 100644 --- a/src/handlers/review_submitted.rs +++ b/src/handlers/review_submitted.rs @@ -1,5 +1,6 @@ use anyhow::Context as _; +use crate::config::ShortcutConfig; use crate::github::{Issue, IssueCommentAction, IssueCommentEvent, Label, PullRequestReviewState}; use crate::{config::ReviewSubmittedConfig, github::Event, handlers::Context}; @@ -7,6 +8,7 @@ pub(crate) async fn handle( ctx: &Context, event: &Event, config: &ReviewSubmittedConfig, + shortcut_config: Option<&ShortcutConfig>, ) -> anyhow::Result<()> { if let Event::IssueComment( event @ IssueCommentEvent { @@ -61,6 +63,11 @@ pub(crate) async fn handle( }], ) .await?; + + // Add reminder about `@bot review` + super::review_reminder::remind_author_of_bot_ready(ctx, &event.issue, shortcut_config) + .await + .context("failed to remind author of @bot review")?; } } diff --git a/src/handlers/shortcut.rs b/src/handlers/shortcut.rs index 78e9394f..109e3ad6 100644 --- a/src/handlers/shortcut.rs +++ b/src/handlers/shortcut.rs @@ -4,27 +4,16 @@ use crate::{ config::ShortcutConfig, - db::issue_data::IssueData, errors::user_error, github::{Event, Label}, handlers::Context, }; -use octocrab::models::AuthorAssociation; +use anyhow::Context as _; use parser::command::shortcut::ShortcutCommand; -/// Key for the state in the database -const AUTHOR_REMINDER_KEY: &str = "author-reminder"; - -/// State stored in the database for a PR. -#[derive(Debug, Default, serde::Deserialize, serde::Serialize, Clone, PartialEq)] -struct AuthorReminderState { - /// ID of the reminder comment. - reminder_comment: Option, -} - pub(super) async fn handle_command( ctx: &Context, - _config: &ShortcutConfig, + config: &ShortcutConfig, event: &Event, input: ShortcutCommand, ) -> anyhow::Result<()> { @@ -75,29 +64,10 @@ pub(super) async fn handle_command( // Except if the author is a member (or the owner) of the repository, as // the author should already know about the `ready` command and already // have the required permissions to update the labels manually anyway. - if matches!(input, ShortcutCommand::Author) - && !matches!( - issue.author_association, - AuthorAssociation::Member | AuthorAssociation::Owner - ) - { - // Get the state of the author reminder for this PR - let mut db = ctx.db.get().await; - let mut state: IssueData<'_, AuthorReminderState> = - IssueData::load(&mut db, issue, AUTHOR_REMINDER_KEY).await?; - - if state.data.reminder_comment.is_none() { - let comment_body = format!( - "Reminder, once the PR becomes ready for a review, use `@{bot} ready`.", - bot = &ctx.username, - ); - let comment = issue - .post_comment(&ctx.github, comment_body.as_str()) - .await?; - - state.data.reminder_comment = Some(comment.node_id); - state.save().await?; - } + if matches!(input, ShortcutCommand::Author) { + super::review_reminder::remind_author_of_bot_ready(ctx, issue, Some(config)) + .await + .context("failed to send @bot review reminder")?; } Ok(())