Skip to content

Commit b66a8b6

Browse files
committed
Avoid posting unnecessary warnings comment
1 parent 93e7da7 commit b66a8b6

File tree

1 file changed

+62
-4
lines changed

1 file changed

+62
-4
lines changed

src/handlers/assign.rs

Lines changed: 62 additions & 4 deletions
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::{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>,
@@ -221,20 +234,65 @@ pub(super) async fn handle_input(
221234
}
222235
}
223236

237+
// Get the state of the warnings for this issue in the database
238+
let mut db = ctx.db.get().await;
239+
let mut state: IssueData<'_, PullRequestWarningsState> =
240+
IssueData::load(&mut db, &event.issue, PULL_REQUEST_WARNINGS_KEY).await?;
241+
224242
// Compute some warning messages to post to new (and old) PRs.
225243
let mut warnings = Vec::new();
226244
if let Some(exceptions) = config.warn_non_default_branch.enabled_and_exceptions() {
227245
warnings.extend(non_default_branch(exceptions, event));
228246
}
229247
warnings.extend(modifies_submodule(diff));
230-
if !warnings.is_empty() {
248+
249+
// Add, hide or hide&add a comment with the warnings.
250+
//
251+
// We only post a new comment when we haven't posted one with the same warnings before.
252+
if !warnings.is_empty() && state.data.last_warnings != warnings {
253+
// New set of warnings, let's post them.
254+
255+
// Hide a previous warnings comment if there was one.
256+
if let Some(last_warned_comment_id) = state.data.last_warned_comment {
257+
event
258+
.issue
259+
.hide_comment(
260+
&ctx.github,
261+
&last_warned_comment_id,
262+
ReportedContentClassifiers::Resolved,
263+
)
264+
.await?;
265+
}
266+
267+
// Format the warnings for user consumption on Github
231268
let warnings: Vec<_> = warnings
232269
.iter()
233270
.map(|warning| format!("* {warning}"))
234271
.collect();
235272
let warning = format!(":warning: **Warning** :warning:\n\n{}", warnings.join("\n"));
236-
event.issue.post_comment(&ctx.github, &warning).await?;
237-
};
273+
let comment = event.issue.post_comment(&ctx.github, &warning).await?;
274+
275+
// Save new state in the database
276+
state.data.last_warnings = warnings;
277+
state.data.last_warned_comment = Some(comment.node_id);
278+
state.save().await?;
279+
} else if warnings.is_empty() {
280+
// No warnings to be shown, let's hide a previous comment, if there was one.
281+
if let Some(last_warned_comment_id) = state.data.last_warned_comment {
282+
event
283+
.issue
284+
.hide_comment(
285+
&ctx.github,
286+
&last_warned_comment_id,
287+
ReportedContentClassifiers::Resolved,
288+
)
289+
.await?;
290+
291+
state.data.last_warnings = Vec::new();
292+
state.data.last_warned_comment = None;
293+
state.save().await?;
294+
}
295+
}
238296

239297
Ok(())
240298
}

0 commit comments

Comments
 (0)