@@ -5,14 +5,14 @@ use crate::bors::event::{
55 PullRequestReadyForReview , PullRequestReopened , PullRequestUnassigned , PushToBranch ,
66} ;
77
8- use crate :: bors:: BorsContext ;
98use crate :: bors:: handlers:: handle_comment;
109use crate :: bors:: handlers:: unapprove_pr;
1110use crate :: bors:: handlers:: workflow:: { AutoBuildCancelReason , maybe_cancel_auto_build} ;
1211use crate :: bors:: merge_queue:: MergeQueueSender ;
1312use crate :: bors:: mergeability_queue:: MergeabilityQueueSender ;
13+ use crate :: bors:: { AUTO_BRANCH_NAME , BorsContext } ;
1414use crate :: bors:: { Comment , PullRequestStatus , RepositoryState } ;
15- use crate :: database:: { MergeableState , UpsertPullRequestParams } ;
15+ use crate :: database:: { MergeableState , PullRequestModel , UpsertPullRequestParams } ;
1616use crate :: github:: { CommitSha , PullRequestNumber } ;
1717use crate :: utils:: text:: pluralize;
1818use std:: sync:: Arc ;
@@ -34,7 +34,7 @@ pub(super) async fn handle_pull_request_edited(
3434 return Ok ( ( ) ) ;
3535 } ;
3636
37- mergeability_queue. enqueue_pr ( & pr_model) ;
37+ mergeability_queue. enqueue_pr ( & pr_model, None ) ;
3838
3939 if !pr_model. is_approved ( ) {
4040 return Ok ( ( ) ) ;
@@ -56,7 +56,7 @@ pub(super) async fn handle_push_to_pull_request(
5656 . upsert_pull_request ( repo_state. repository ( ) , pr. clone ( ) . into ( ) )
5757 . await ?;
5858
59- mergeability_queue. enqueue_pr ( & pr_model) ;
59+ mergeability_queue. enqueue_pr ( & pr_model, None ) ;
6060
6161 let auto_build_cancel_message = maybe_cancel_auto_build (
6262 & repo_state. client ,
@@ -119,15 +119,15 @@ pub(super) async fn handle_pull_request_opened(
119119 author : payload. pull_request . author . username . clone ( ) ,
120120 assignees,
121121 base_branch : payload. pull_request . base . name . clone ( ) ,
122- mergeable_state : MergeableState :: Unknown ,
122+ mergeable_state : payload . pull_request . mergeable_state . clone ( ) . into ( ) ,
123123 pr_status,
124124 } ,
125125 )
126126 . await ?;
127127
128128 process_pr_description_commands ( & payload, repo_state. clone ( ) , db, ctx, merge_queue_tx) . await ?;
129129
130- mergeability_queue. enqueue_pr ( & pr) ;
130+ mergeability_queue. enqueue_pr ( & pr, None ) ;
131131
132132 Ok ( ( ) )
133133}
@@ -169,7 +169,7 @@ pub(super) async fn handle_pull_request_reopened(
169169 . upsert_pull_request ( repo_state. repository ( ) , pr. clone ( ) . into ( ) )
170170 . await ?;
171171
172- mergeability_queue. enqueue_pr ( & pr) ;
172+ mergeability_queue. enqueue_pr ( & pr, None ) ;
173173
174174 Ok ( ( ) )
175175}
@@ -260,14 +260,44 @@ pub(super) async fn handle_push_to_branch(
260260 payload. branch
261261 ) ;
262262
263+ // Try to find an auto build that matches this SHA
264+ let merged_pr = find_pr_by_merged_commit ( & repo_state, & db, CommitSha ( payload. sha ) )
265+ . await
266+ . ok ( )
267+ . flatten ( )
268+ . map ( |pr| pr. number ) ;
269+
263270 for pr in affected_prs {
264- mergeability_queue. enqueue_pr ( & pr) ;
271+ mergeability_queue. enqueue_pr ( & pr, merged_pr ) ;
265272 }
266273 }
267274
268275 Ok ( ( ) )
269276}
270277
278+ /// Try to find a merged PR that might have produced a build with the given commit SHA.
279+ async fn find_pr_by_merged_commit (
280+ repo_state : & RepositoryState ,
281+ db : & PgDbClient ,
282+ sha : CommitSha ,
283+ ) -> anyhow:: Result < Option < PullRequestModel > > {
284+ let Some ( build) = db
285+ . find_build ( repo_state. repository ( ) , AUTO_BRANCH_NAME , sha)
286+ . await ?
287+ else {
288+ return Ok ( None ) ;
289+ } ;
290+
291+ let Some ( pr) = db. find_pr_by_build ( & build) . await ? else {
292+ return Ok ( None ) ;
293+ } ;
294+ if pr. auto_build . as_ref ( ) . map ( |b| b. id ) == Some ( build. id ) {
295+ Ok ( Some ( pr) )
296+ } else {
297+ Ok ( None )
298+ }
299+ }
300+
271301async fn process_pr_description_commands (
272302 payload : & PullRequestOpened ,
273303 repo : Arc < RepositoryState > ,
@@ -331,11 +361,12 @@ async fn notify_of_pushed_pr(
331361
332362#[ cfg( test) ]
333363mod tests {
364+ use insta:: assert_snapshot;
334365 use octocrab:: params:: checks:: { CheckRunConclusion , CheckRunStatus } ;
335366
336367 use crate :: bors:: PullRequestStatus ;
337368 use crate :: bors:: merge_queue:: AUTO_BUILD_CHECK_RUN_NAME ;
338- use crate :: tests:: { BorsTester , WorkflowRunData } ;
369+ use crate :: tests:: { BorsBuilder , BorsTester , GitHubState , WorkflowRunData } ;
339370 use crate :: {
340371 database:: { MergeableState , OctocrabMergeableState } ,
341372 tests:: { User , default_branch_name, default_repo_name, run_test} ,
@@ -409,7 +440,7 @@ mod tests {
409440 tester. get_pr_copy ( ( ) ) . await . expect_unapproved ( ) ;
410441 Ok ( ( ) )
411442 } )
412- . await ;
443+ . await ;
413444 }
414445
415446 #[ sqlx:: test]
@@ -623,13 +654,13 @@ mod tests {
623654 run_test ( pool, async |tester : & mut BorsTester | {
624655 let pr = tester
625656 . open_pr ( default_repo_name ( ) , |pr| {
626- pr. mergeable_state = OctocrabMergeableState :: Unknown
657+ pr. mergeable_state = OctocrabMergeableState :: Unknown ;
627658 } )
628659 . await ?;
629- tester. push_to_branch ( default_branch_name ( ) ) . await ?;
660+ tester. push_to_branch ( default_branch_name ( ) , "sha" ) . await ?;
630661 tester
631662 . modify_pr_state ( pr. id ( ) , |pr| {
632- pr. mergeable_state = OctocrabMergeableState :: Dirty
663+ pr. mergeable_state = OctocrabMergeableState :: Dirty ;
633664 } )
634665 . await ;
635666 tester
@@ -642,6 +673,124 @@ mod tests {
642673 . await ;
643674 }
644675
676+ #[ sqlx:: test]
677+ async fn conflict_message_disabled_in_config ( pool : sqlx:: PgPool ) {
678+ run_test ( pool, async |tester : & mut BorsTester | {
679+ let pr = tester
680+ . open_pr ( default_repo_name ( ) , |pr| {
681+ pr. mergeable_state = OctocrabMergeableState :: Clean ;
682+ } )
683+ . await ?;
684+ tester
685+ . modify_pr_state ( pr. id ( ) , |pr| {
686+ pr. mergeable_state = OctocrabMergeableState :: Dirty ;
687+ } )
688+ . await ;
689+ tester. push_to_branch ( default_branch_name ( ) , "sha" ) . await ?;
690+
691+ Ok ( ( ) )
692+ } )
693+ . await ;
694+ }
695+
696+ #[ sqlx:: test]
697+ async fn conflict_message_unknown_sha ( pool : sqlx:: PgPool ) {
698+ BorsBuilder :: new ( pool)
699+ . github ( GitHubState :: default ( ) . with_default_config (
700+ r#"
701+ merge_queue_enabled = true
702+ report_merge_conflicts = true
703+ "# ,
704+ ) ) . run_test ( async |tester : & mut BorsTester | {
705+ let pr = tester
706+ . open_pr ( default_repo_name ( ) , |pr| {
707+ pr. mergeable_state = OctocrabMergeableState :: Clean ;
708+ } )
709+ . await ?;
710+ tester
711+ . modify_pr_state ( pr. id ( ) , |pr| {
712+ pr. mergeable_state = OctocrabMergeableState :: Dirty ;
713+ } )
714+ . await ;
715+ tester. push_to_branch ( default_branch_name ( ) , "sha" ) . await ?;
716+ assert_snapshot ! ( tester. get_next_comment_text( pr) . await ?, @":umbrella: The latest upstream changes made this pull request unmergeable. Please [resolve the merge conflicts](https://rustc-dev-guide.rust-lang.org/git.html#rebasing-and-conflicts)." ) ;
717+
718+ Ok ( ( ) )
719+ } )
720+ . await ;
721+ }
722+
723+ #[ sqlx:: test]
724+ async fn conflict_message_unknown_sha_approved ( pool : sqlx:: PgPool ) {
725+ BorsBuilder :: new ( pool)
726+ . github ( GitHubState :: default ( ) . with_default_config (
727+ r#"
728+ merge_queue_enabled = true
729+ report_merge_conflicts = true
730+ "# ,
731+ ) ) . run_test ( async |tester : & mut BorsTester | {
732+ let pr = tester
733+ . open_pr ( default_repo_name ( ) , |pr| {
734+ pr. mergeable_state = OctocrabMergeableState :: Clean ;
735+ } )
736+ . await ?;
737+ tester. approve ( pr. id ( ) ) . await ?;
738+ tester
739+ . modify_pr_state ( pr. id ( ) , |pr| {
740+ pr. mergeable_state = OctocrabMergeableState :: Dirty ;
741+ } )
742+ . await ;
743+ tester. push_to_branch ( default_branch_name ( ) , "sha" ) . await ?;
744+ assert_snapshot ! ( tester. get_next_comment_text( pr. id( ) ) . await ?, @r"
745+ :umbrella: The latest upstream changes made this pull request unmergeable. Please [resolve the merge conflicts](https://rustc-dev-guide.rust-lang.org/git.html#rebasing-and-conflicts).
746+
747+ This pull request was unapproved.
748+ " ) ;
749+ tester. get_pr_copy ( pr. id ( ) ) . await . expect_unapproved ( ) ;
750+
751+ Ok ( ( ) )
752+ } )
753+ . await ;
754+ }
755+
756+ #[ sqlx:: test]
757+ async fn conflict_message_known_sha ( pool : sqlx:: PgPool ) {
758+ BorsBuilder :: new ( pool)
759+ . github ( GitHubState :: default ( ) . with_default_config (
760+ r#"
761+ merge_queue_enabled = true
762+ report_merge_conflicts = true
763+ "# ,
764+ ) ) . run_test ( async |tester : & mut BorsTester | {
765+ let pr2 = tester
766+ . open_pr ( default_repo_name ( ) , |pr| {
767+ pr. mergeable_state = OctocrabMergeableState :: Clean ;
768+ } )
769+ . await ?;
770+
771+ let pr1 = tester
772+ . open_pr ( default_repo_name ( ) , |_| { } )
773+ . await ?;
774+ tester. approve ( pr1. id ( ) ) . await ?;
775+ tester. start_auto_build ( pr1. id ( ) ) . await ?;
776+ tester. workflow_full_success ( tester. auto_branch ( ) . await ) . await ?;
777+ tester. process_merge_queue ( ) . await ;
778+ tester. expect_comments ( pr1. id ( ) , 1 ) . await ;
779+ let sha = tester. auto_branch ( ) . await . get_sha ( ) . to_string ( ) ;
780+
781+ tester
782+ . modify_pr_state ( pr2. id ( ) , |pr| {
783+ pr. mergeable_state = OctocrabMergeableState :: Dirty ;
784+ } )
785+ . await ;
786+ tester. push_to_branch ( default_branch_name ( ) , & sha) . await ?;
787+ assert_snapshot ! ( tester. get_next_comment_text( pr2. id( ) ) . await ?, @":umbrella: The latest upstream changes (presumably #3) made this pull request unmergeable. Please [resolve the merge conflicts](https://rustc-dev-guide.rust-lang.org/git.html#rebasing-and-conflicts)." ) ;
788+
789+ Ok ( ( ) )
790+ } )
791+ . await ;
792+ }
793+
645794 #[ sqlx:: test]
646795 async fn enqueue_prs_on_pr_opened ( pool : sqlx:: PgPool ) {
647796 run_test ( pool, async |tester : & mut BorsTester | {
@@ -722,7 +871,7 @@ mod tests {
722871 " ) ;
723872 Ok ( ( ) )
724873 } )
725- . await ;
874+ . await ;
726875 gh. check_cancelled_workflows ( default_repo_name ( ) , & [ 123 ] ) ;
727876 }
728877
@@ -747,7 +896,7 @@ mod tests {
747896 " ) ;
748897 Ok ( ( ) )
749898 } )
750- . await ;
899+ . await ;
751900 }
752901
753902 #[ sqlx:: test]
0 commit comments