@@ -19,6 +19,7 @@ use crate::github::{CommitSha, GithubUser, LabelTrigger, MergeError, PullRequest
1919use crate :: permissions:: PermissionType ;
2020use crate :: utils:: text:: suppress_github_mentions;
2121use anyhow:: { Context , anyhow} ;
22+ use itertools:: Itertools ;
2223use octocrab:: params:: checks:: CheckRunConclusion ;
2324use octocrab:: params:: checks:: CheckRunOutput ;
2425use octocrab:: params:: checks:: CheckRunStatus ;
@@ -87,7 +88,11 @@ pub(super) async fn command_try_build(
8788 & repo. client ,
8889 & pr. github . head . sha ,
8990 & base_sha,
90- & auto_merge_commit_message ( pr, repo. client . repository ( ) , "<try>" , jobs) ,
91+ & create_merge_commit_message (
92+ pr,
93+ repo. client . repository ( ) ,
94+ MergeType :: Try { try_jobs : jobs } ,
95+ ) ,
9196 )
9297 . await ?
9398 {
@@ -339,28 +344,61 @@ fn get_pending_build(pr: &PullRequestModel) -> Option<&BuildModel> {
339344 . and_then ( |b| ( b. status == BuildStatus :: Pending ) . then_some ( b) )
340345}
341346
342- fn auto_merge_commit_message (
347+ /// Prefix used to specify custom try jobs in PR descriptions.
348+ const CUSTOM_TRY_JOB_PREFIX : & str = "try-job:" ;
349+
350+ enum MergeType {
351+ Try { try_jobs : Vec < String > } ,
352+ }
353+
354+ fn create_merge_commit_message (
343355 pr : & PullRequestData ,
344356 name : & GithubRepoName ,
345- reviewer : & str ,
346- jobs : Vec < String > ,
357+ merge_type : MergeType ,
347358) -> String {
348359 let pr_number = pr. number ( ) ;
360+
361+ let reviewer = match & merge_type {
362+ MergeType :: Try { .. } => "<try>" ,
363+ } ;
364+
365+ let mut pr_description = suppress_github_mentions ( & pr. github . message ) ;
366+ match & merge_type {
367+ // Strip all PR text for try builds, to avoid useless issue pings on the repository.
368+ // Only keep any lines starting with `CUSTOM_TRY_JOB_PREFIX`.
369+ MergeType :: Try { try_jobs } => {
370+ // If we do not have any custom try jobs, keep the ones that might be in the PR
371+ // description.
372+ pr_description = if try_jobs. is_empty ( ) {
373+ pr_description
374+ . lines ( )
375+ . map ( |l| l. trim ( ) )
376+ . filter ( |l| l. starts_with ( CUSTOM_TRY_JOB_PREFIX ) )
377+ . join ( "\n " )
378+ } else {
379+ // If we do have custom jobs, ignore the original description completely
380+ String :: new ( )
381+ } ;
382+ }
383+ } ;
384+
349385 let mut message = format ! (
350386 r#"Auto merge of {repo_owner}/{repo_name}#{pr_number} - {pr_label}, r={reviewer}
351387{pr_title}
352388
353- {pr_message }"# ,
389+ {pr_description }"# ,
354390 pr_label = pr. github. head_label,
355391 pr_title = pr. github. title,
356- pr_message = suppress_github_mentions( & pr. github. message) ,
357392 repo_owner = name. owner( ) ,
358393 repo_name = name. name( )
359394 ) ;
360395
361- // if jobs is empty, try-job won't be added to the message
362- for job in jobs {
363- message. push_str ( & format ! ( "\n try-job: {}" , job) ) ;
396+ match merge_type {
397+ MergeType :: Try { try_jobs } => {
398+ for job in try_jobs {
399+ message. push_str ( & format ! ( "\n {CUSTOM_TRY_JOB_PREFIX} {}" , job) ) ;
400+ }
401+ }
364402 }
365403 message
366404}
@@ -469,6 +507,92 @@ mod tests {
469507 . await ;
470508 }
471509
510+ #[ sqlx:: test]
511+ async fn try_commit_message_strip_description ( pool : sqlx:: PgPool ) {
512+ run_test ( pool, async |tester : & mut BorsTester | {
513+ tester
514+ . edit_pr ( default_repo_name ( ) , default_pr_number ( ) , |pr| {
515+ pr. description = r"This is a very good PR.
516+
517+ It fixes so many issues, sir."
518+ . to_string ( ) ;
519+ } )
520+ . await ?;
521+
522+ tester. post_comment ( "@bors try" ) . await ?;
523+ tester. expect_comments ( 1 ) . await ;
524+
525+ insta:: assert_snapshot!( tester. get_branch_commit_message( & tester. try_branch( ) ) , @r"
526+ Auto merge of rust-lang/borstest#1 - pr-1, r=<try>
527+ PR #1
528+ " ) ;
529+ Ok ( ( ) )
530+ } )
531+ . await ;
532+ }
533+
534+ #[ sqlx:: test]
535+ async fn try_commit_message_strip_description_keep_try_jobs ( pool : sqlx:: PgPool ) {
536+ run_test ( pool, async |tester : & mut BorsTester | {
537+ tester
538+ . edit_pr ( default_repo_name ( ) , default_pr_number ( ) , |pr| {
539+ pr. description = r"This is a very good PR.
540+
541+ try-job: Foo
542+
543+ It fixes so many issues, sir.
544+
545+ try-job: Bar
546+ "
547+ . to_string ( ) ;
548+ } )
549+ . await ?;
550+
551+ tester. post_comment ( "@bors try" ) . await ?;
552+ tester. expect_comments ( 1 ) . await ;
553+
554+ insta:: assert_snapshot!( tester. get_branch_commit_message( & tester. try_branch( ) ) , @r"
555+ Auto merge of rust-lang/borstest#1 - pr-1, r=<try>
556+ PR #1
557+
558+ try-job: Foo
559+ try-job: Bar
560+ " ) ;
561+ Ok ( ( ) )
562+ } )
563+ . await ;
564+ }
565+
566+ #[ sqlx:: test]
567+ async fn try_commit_message_overwrite_try_jobs ( pool : sqlx:: PgPool ) {
568+ run_test ( pool, async |tester : & mut BorsTester | {
569+ tester
570+ . edit_pr ( default_repo_name ( ) , default_pr_number ( ) , |pr| {
571+ pr. description = r"This is a very good PR.
572+
573+ try-job: Foo
574+ try-job: Bar
575+ "
576+ . to_string ( ) ;
577+ } )
578+ . await ?;
579+
580+ tester. post_comment ( "@bors try jobs=Baz,Baz2" ) . await ?;
581+ tester. expect_comments ( 1 ) . await ;
582+
583+ insta:: assert_snapshot!( tester. get_branch_commit_message( & tester. try_branch( ) ) , @r"
584+ Auto merge of rust-lang/borstest#1 - pr-1, r=<try>
585+ PR #1
586+
587+
588+ try-job: Baz
589+ try-job: Baz2
590+ " ) ;
591+ Ok ( ( ) )
592+ } )
593+ . await ;
594+ }
595+
472596 #[ sqlx:: test]
473597 async fn try_merge_branch_history ( pool : sqlx:: PgPool ) {
474598 let gh = run_test ( pool, async |tester| {
0 commit comments