diff --git a/src/github.rs b/src/github.rs index 6be878aa..d6a92688 100644 --- a/src/github.rs +++ b/src/github.rs @@ -391,6 +391,8 @@ impl ZulipGitHubReference { #[derive(Debug, serde::Deserialize)] pub struct Comment { + pub id: u64, + pub node_id: String, #[serde(deserialize_with = "opt_string")] pub body: String, pub html_url: String, @@ -403,6 +405,17 @@ pub struct Comment { pub pr_review_state: Option, } +#[derive(Debug, serde::Deserialize, serde::Serialize, Eq, PartialEq)] +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] +pub enum ReportedContentClassifiers { + Abuse, + Duplicate, + OffTopic, + Outdated, + Resolved, + Spam, +} + #[derive(Debug, serde::Deserialize, Eq, PartialEq)] #[serde(rename_all = "snake_case")] pub enum PullRequestReviewState { @@ -581,24 +594,24 @@ impl Issue { client: &GithubClient, id: u64, new_body: &str, - ) -> anyhow::Result<()> { + ) -> anyhow::Result { let comment_url = format!("{}/issues/comments/{}", self.repository().url(client), id); #[derive(serde::Serialize)] struct NewComment<'a> { body: &'a str, } - client - .send_req( + let comment = client + .json( client .patch(&comment_url) .json(&NewComment { body: new_body }), ) .await .context("failed to edit comment")?; - Ok(()) + Ok(comment) } - pub async fn post_comment(&self, client: &GithubClient, body: &str) -> anyhow::Result<()> { + pub async fn post_comment(&self, client: &GithubClient, body: &str) -> anyhow::Result { #[derive(serde::Serialize)] struct PostComment<'a> { body: &'a str, @@ -608,10 +621,32 @@ impl Issue { .strip_prefix("https://api.github.com") .expect("expected api host"); let comments_url = format!("{}{comments_path}", client.api_url); - client - .send_req(client.post(&comments_url).json(&PostComment { body })) + let comment = client + .json(client.post(&comments_url).json(&PostComment { body })) .await .context("failed to post comment")?; + Ok(comment) + } + + pub async fn hide_comment( + &self, + client: &GithubClient, + node_id: &str, + reason: ReportedContentClassifiers, + ) -> anyhow::Result<()> { + client + .graphql_query( + "mutation($node_id: ID!, $reason: ReportedContentClassifiers!) { + minimizeComment(input: {subjectId: $node_id, classifier: $reason}) { + __typename + } + }", + serde_json::json!({ + "node_id": node_id, + "reason": reason, + }), + ) + .await?; Ok(()) } diff --git a/src/handlers/no_merges.rs b/src/handlers/no_merges.rs index c1d87271..e94b26f0 100644 --- a/src/handlers/no_merges.rs +++ b/src/handlers/no_merges.rs @@ -4,7 +4,7 @@ use crate::{ config::NoMergesConfig, db::issue_data::IssueData, - github::{IssuesAction, IssuesEvent, Label}, + github::{IssuesAction, IssuesEvent, Label, ReportedContentClassifiers}, handlers::Context, }; use anyhow::Context as _; @@ -24,6 +24,9 @@ pub(super) struct NoMergesInput { struct NoMergesState { /// Hashes of merge commits that have already been mentioned by triagebot in a comment. mentioned_merge_commits: HashSet, + /// List of all the no_merge comments as GitHub GraphQL NodeId. + #[serde(default)] + no_merge_comments: Vec, /// Labels that the bot added as part of the no-merges check. #[serde(default)] added_labels: Vec, @@ -124,10 +127,22 @@ pub(super) async fn handle_input( .context("failed to remove label")?; } - // FIXME: Minimize prior no_merges comments. + // Minimize prior no_merges comments. + for node_id in state.data.no_merge_comments.iter() { + event + .issue + .hide_comment( + &ctx.github, + node_id.as_str(), + ReportedContentClassifiers::Resolved, + ) + .await + .context("failed to hide previous merge commit comment")?; + } // Clear from state. state.data.mentioned_merge_commits.clear(); + state.data.no_merge_comments.clear(); state.data.added_labels.clear(); state.save().await?; return Ok(()); @@ -202,11 +217,13 @@ pub(super) async fn handle_input( .context("failed to set no_merges labels")?; // Post comment - event + let comment = event .issue .post_comment(&ctx.github, &message) .await .context("failed to post no_merges comment")?; + + state.data.no_merge_comments.push(comment.node_id); state.save().await?; } Ok(()) diff --git a/src/interactions.rs b/src/interactions.rs index f3d6a115..0abce1d9 100644 --- a/src/interactions.rs +++ b/src/interactions.rs @@ -26,7 +26,8 @@ impl<'a> ErrorComment<'a> { "Please file an issue on GitHub at [triagebot](https://github.com/rust-lang/triagebot) if there's \ a problem with this bot, or reach out on [#t-infra](https://rust-lang.zulipchat.com/#narrow/stream/242791-t-infra) on Zulip." )?; - self.issue.post_comment(client, &body).await + self.issue.post_comment(client, &body).await?; + Ok(()) } } @@ -45,7 +46,8 @@ impl<'a> PingComment<'a> { for user in self.users { write!(body, "@{} ", user)?; } - self.issue.post_comment(client, &body).await + self.issue.post_comment(client, &body).await?; + Ok(()) } }