@@ -3,18 +3,35 @@ use anyhow::bail;
33use super :: Context ;
44use crate :: {
55 config:: Config ,
6- github:: { Event , IssuesAction } ,
6+ db:: issue_data:: IssueData ,
7+ github:: { Event , IssuesAction , IssuesEvent , ReportedContentClassifiers } ,
78} ;
89
910mod modified_submodule;
1011mod 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+
1225pub ( 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