1+ use crate :: db:: issue_data:: IssueData ;
12use crate :: {
23 config:: AutolabelConfig ,
34 github:: { IssuesAction , IssuesEvent , Label } ,
@@ -6,6 +7,15 @@ use crate::{
67use anyhow:: Context as _;
78use tracing as log;
89
10+ /// Key for the state in the database
11+ const AUTOLABEL_KEY : & str = "autolabel" ;
12+
13+ /// State stored in the database
14+ #[ derive( Debug , Default , serde:: Deserialize , serde:: Serialize ) ]
15+ struct AutolabelState {
16+ new_pr_labels_applied : bool ,
17+ }
18+
919pub ( super ) struct AutolabelInput {
1020 add : Vec < Label > ,
1121 remove : Vec < Label > ,
@@ -27,6 +37,12 @@ pub(super) async fn parse_input(
2737 // remove. Not much can be done about that currently; the before/after on
2838 // synchronize may be straddling a rebase, which will break diff generation.
2939 if event. action == IssuesAction :: Opened || event. action == IssuesAction :: Synchronize {
40+ let mut db = ctx. db . get ( ) . await ;
41+ let mut state: IssueData < ' _ , AutolabelState > =
42+ IssueData :: load ( & mut db, & event. issue , AUTOLABEL_KEY )
43+ . await
44+ . map_err ( |e| e. to_string ( ) ) ?;
45+
3046 let files = event
3147 . issue
3248 . diff ( & ctx. github )
@@ -69,11 +85,18 @@ pub(super) async fn parse_input(
6985 name : label. to_owned ( ) ,
7086 } ) ;
7187 }
72- if cfg. new_pr && event. action == IssuesAction :: Opened {
73- autolabels. push ( Label {
74- name : label. to_owned ( ) ,
75- } ) ;
76- }
88+ }
89+
90+ // Newly opened non-draft PRs or PRs that were opened as draft and that were marked as
91+ // "ready for review" for the first time are treated as "new PRs".
92+ let treat_as_new_pr = ( event. action == IssuesAction :: Opened && !event. issue . draft )
93+ || ( event. action == IssuesAction :: ReadyForReview
94+ && !state. data . new_pr_labels_applied ) ;
95+ if cfg. new_pr && treat_as_new_pr {
96+ autolabels. push ( Label {
97+ name : label. to_owned ( ) ,
98+ } ) ;
99+ state. data . new_pr_labels_applied = true ;
77100 }
78101
79102 if event. issue . pull_request . is_none ( )
@@ -86,6 +109,8 @@ pub(super) async fn parse_input(
86109 }
87110 }
88111
112+ state. save ( ) . await . map_err ( |e| e. to_string ( ) ) ?;
113+
89114 if !autolabels. is_empty ( ) {
90115 return Ok ( Some ( AutolabelInput {
91116 add : autolabels,
0 commit comments