Skip to content

Commit 8054910

Browse files
committed
Avoid posting unnecessary warnings comment
1 parent 0e2641e commit 8054910

File tree

1 file changed

+62
-4
lines changed

1 file changed

+62
-4
lines changed

src/handlers/assign.rs

+62-4
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
2323
use crate::{
2424
config::{AssignConfig, WarnNonDefaultBranchException},
25-
github::{self, Event, FileDiff, Issue, IssuesAction, Selection},
25+
db::issue_data::IssueData,
26+
github::{self, Event, FileDiff, Issue, IssuesAction, ReportedContentClassifiers, Selection},
2627
handlers::{pr_tracking::has_user_capacity, Context, GithubClient, IssuesEvent},
2728
interactions::EditIssueBody,
2829
};
@@ -116,6 +117,18 @@ const REVIEWER_ALREADY_ASSIGNED: &str =
116117
117118
Please choose another assignee.";
118119

120+
/// Key for teh state in the database
121+
const PULL_REQUEST_WARNINGS_KEY: &str = "pr-warnings";
122+
123+
/// State stored in the database for a PR.
124+
#[derive(Debug, Default, serde::Deserialize, serde::Serialize)]
125+
struct PullRequestWarningsState {
126+
/// List of the last warnings in the most recent comment.
127+
last_warnings: Vec<String>,
128+
/// ID of the most recent warning comment.
129+
last_warned_comment: Option<String>,
130+
}
131+
119132
#[derive(Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
120133
struct AssignData {
121134
user: Option<String>,
@@ -217,20 +230,65 @@ pub(super) async fn handle_input(
217230
}
218231
}
219232

233+
// Get the state of the warnings for this issue in the database
234+
let mut db = ctx.db.get().await;
235+
let mut state: IssueData<'_, PullRequestWarningsState> =
236+
IssueData::load(&mut db, &event.issue, PULL_REQUEST_WARNINGS_KEY).await?;
237+
220238
// Compute some warning messages to post to new (and old) PRs.
221239
let mut warnings = Vec::new();
222240
if let Some(exceptions) = config.warn_non_default_branch.enabled_and_exceptions() {
223241
warnings.extend(non_default_branch(exceptions, event));
224242
}
225243
warnings.extend(modifies_submodule(diff));
226-
if !warnings.is_empty() {
244+
245+
// Add, hide or hide&add a comment with the warnings.
246+
//
247+
// We only post a new comment when we haven't posted one with the same warnings before.
248+
if !warnings.is_empty() && state.data.last_warnings != warnings {
249+
// New set of warnings, let's post them.
250+
251+
// Hide a previous warnings comment if there was one.
252+
if let Some(last_warned_comment_id) = state.data.last_warned_comment {
253+
event
254+
.issue
255+
.hide_comment(
256+
&ctx.github,
257+
&last_warned_comment_id,
258+
ReportedContentClassifiers::Resolved,
259+
)
260+
.await?;
261+
}
262+
263+
// Format the warnings for user consumption on Github
227264
let warnings: Vec<_> = warnings
228265
.iter()
229266
.map(|warning| format!("* {warning}"))
230267
.collect();
231268
let warning = format!(":warning: **Warning** :warning:\n\n{}", warnings.join("\n"));
232-
event.issue.post_comment(&ctx.github, &warning).await?;
233-
};
269+
let comment = event.issue.post_comment(&ctx.github, &warning).await?;
270+
271+
// Save new state in the database
272+
state.data.last_warnings = warnings;
273+
state.data.last_warned_comment = Some(comment.node_id);
274+
state.save().await?;
275+
} else if warnings.is_empty() {
276+
// No warnings to be shown, let's hide a previous comment, if there was one.
277+
if let Some(last_warned_comment_id) = state.data.last_warned_comment {
278+
event
279+
.issue
280+
.hide_comment(
281+
&ctx.github,
282+
&last_warned_comment_id,
283+
ReportedContentClassifiers::Resolved,
284+
)
285+
.await?;
286+
287+
state.data.last_warnings = Vec::new();
288+
state.data.last_warned_comment = None;
289+
state.save().await?;
290+
}
291+
}
234292

235293
Ok(())
236294
}

0 commit comments

Comments
 (0)