|
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::{pr_tracking::has_user_capacity, 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>,
|
@@ -217,20 +230,65 @@ pub(super) async fn handle_input(
|
217 | 230 | }
|
218 | 231 | }
|
219 | 232 |
|
| 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 | + |
220 | 238 | // Compute some warning messages to post to new (and old) PRs.
|
221 | 239 | let mut warnings = Vec::new();
|
222 | 240 | if let Some(exceptions) = config.warn_non_default_branch.enabled_and_exceptions() {
|
223 | 241 | warnings.extend(non_default_branch(exceptions, event));
|
224 | 242 | }
|
225 | 243 | 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 |
227 | 264 | let warnings: Vec<_> = warnings
|
228 | 265 | .iter()
|
229 | 266 | .map(|warning| format!("* {warning}"))
|
230 | 267 | .collect();
|
231 | 268 | 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 | + } |
234 | 292 |
|
235 | 293 | Ok(())
|
236 | 294 | }
|
|
0 commit comments