|
22 | 22 |
|
23 | 23 | use crate::{
|
24 | 24 | 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}, |
26 | 27 | handlers::{Context, GithubClient, IssuesEvent},
|
27 | 28 | interactions::EditIssueBody,
|
28 | 29 | };
|
@@ -116,6 +117,18 @@ const REVIEWER_ALREADY_ASSIGNED: &str =
|
116 | 117 |
|
117 | 118 | Please choose another assignee.";
|
118 | 119 |
|
| 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 | + |
119 | 132 | #[derive(Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
120 | 133 | struct AssignData {
|
121 | 134 | user: Option<String>,
|
@@ -221,20 +234,65 @@ pub(super) async fn handle_input(
|
221 | 234 | }
|
222 | 235 | }
|
223 | 236 |
|
| 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 | + |
224 | 242 | // Compute some warning messages to post to new (and old) PRs.
|
225 | 243 | let mut warnings = Vec::new();
|
226 | 244 | if let Some(exceptions) = config.warn_non_default_branch.enabled_and_exceptions() {
|
227 | 245 | warnings.extend(non_default_branch(exceptions, event));
|
228 | 246 | }
|
229 | 247 | 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 |
231 | 268 | let warnings: Vec<_> = warnings
|
232 | 269 | .iter()
|
233 | 270 | .map(|warning| format!("* {warning}"))
|
234 | 271 | .collect();
|
235 | 272 | 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 | + } |
238 | 296 |
|
239 | 297 | Ok(())
|
240 | 298 | }
|
|
0 commit comments