Skip to content

Commit cc054e0

Browse files
authored
Merge pull request #1901 from Urgau/warnings-on-synchronize
Also show warnings when PRs are updated
2 parents ec68766 + 507cc27 commit cc054e0

File tree

1 file changed

+74
-5
lines changed

1 file changed

+74
-5
lines changed

Diff for: src/handlers/check_commits.rs

+74-5
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,35 @@ use anyhow::bail;
33
use super::Context;
44
use crate::{
55
config::Config,
6-
github::{Event, IssuesAction},
6+
db::issue_data::IssueData,
7+
github::{Event, IssuesAction, IssuesEvent, ReportedContentClassifiers},
78
};
89

910
mod modified_submodule;
1011
mod non_default_branch;
1112

13+
/// Key for the state in the database
14+
const CHECK_COMMITS_WARNINGS_KEY: &str = "check-commits-warnings";
15+
16+
/// State stored in the database
17+
#[derive(Debug, Default, serde::Deserialize, serde::Serialize)]
18+
struct CheckCommitsWarningsState {
19+
/// List of the last warnings in the most recent comment.
20+
last_warnings: Vec<String>,
21+
/// ID of the most recent warning comment.
22+
last_warned_comment: Option<String>,
23+
}
24+
1225
pub(super) async fn handle(ctx: &Context, event: &Event, config: &Config) -> anyhow::Result<()> {
1326
let Event::Issue(event) = event else {
1427
return Ok(());
1528
};
1629

17-
if !matches!(event.action, IssuesAction::Opened) || !event.issue.is_pr() {
30+
if !matches!(
31+
event.action,
32+
IssuesAction::Opened | IssuesAction::Synchronize
33+
) || !event.issue.is_pr()
34+
{
1835
return Ok(());
1936
}
2037

@@ -27,6 +44,7 @@ pub(super) async fn handle(ctx: &Context, event: &Event, config: &Config) -> any
2744

2845
let mut warnings = Vec::new();
2946

47+
// Compute the warnings
3048
if let Some(assign_config) = &config.assign {
3149
// For legacy reasons the non-default-branch and modifies-submodule warnings
3250
// are behind the `[assign]` config.
@@ -40,14 +58,65 @@ pub(super) async fn handle(ctx: &Context, event: &Event, config: &Config) -> any
4058
warnings.extend(modified_submodule::modifies_submodule(diff));
4159
}
4260

43-
if !warnings.is_empty() {
61+
handle_warnings(ctx, event, warnings).await
62+
}
63+
64+
// Add, hide or hide&add a comment with the warnings.
65+
async fn handle_warnings(
66+
ctx: &Context,
67+
event: &IssuesEvent,
68+
warnings: Vec<String>,
69+
) -> anyhow::Result<()> {
70+
// Get the state of the warnings for this PR in the database.
71+
let mut db = ctx.db.get().await;
72+
let mut state: IssueData<'_, CheckCommitsWarningsState> =
73+
IssueData::load(&mut db, &event.issue, CHECK_COMMITS_WARNINGS_KEY).await?;
74+
75+
// We only post a new comment when we haven't posted one with the same warnings before.
76+
if !warnings.is_empty() && state.data.last_warnings != warnings {
77+
// New set of warnings, let's post them.
78+
79+
// Hide a previous warnings comment if there was one before printing the new ones.
80+
if let Some(last_warned_comment_id) = state.data.last_warned_comment {
81+
event
82+
.issue
83+
.hide_comment(
84+
&ctx.github,
85+
&last_warned_comment_id,
86+
ReportedContentClassifiers::Resolved,
87+
)
88+
.await?;
89+
}
90+
91+
// Format the warnings for user consumption on Github
4492
let warnings: Vec<_> = warnings
4593
.iter()
4694
.map(|warning| format!("* {warning}"))
4795
.collect();
4896
let warning = format!(":warning: **Warning** :warning:\n\n{}", warnings.join("\n"));
49-
event.issue.post_comment(&ctx.github, &warning).await?;
50-
};
97+
let comment = event.issue.post_comment(&ctx.github, &warning).await?;
98+
99+
// Save new state in the database
100+
state.data.last_warnings = warnings;
101+
state.data.last_warned_comment = Some(comment.node_id);
102+
state.save().await?;
103+
} else if warnings.is_empty() {
104+
// No warnings to be shown, let's resolve a previous warnings comment, if there was one.
105+
if let Some(last_warned_comment_id) = state.data.last_warned_comment {
106+
event
107+
.issue
108+
.hide_comment(
109+
&ctx.github,
110+
&last_warned_comment_id,
111+
ReportedContentClassifiers::Resolved,
112+
)
113+
.await?;
114+
115+
state.data.last_warnings = Vec::new();
116+
state.data.last_warned_comment = None;
117+
state.save().await?;
118+
}
119+
}
51120

52121
Ok(())
53122
}

0 commit comments

Comments
 (0)