@@ -72,6 +72,15 @@ pub enum PrReviewSetEntryStatus {
7272 Skipped ,
7373}
7474
75+ impl PrReviewSetEntryStatus {
76+ pub fn as_str ( self ) -> & ' static str {
77+ match self {
78+ Self :: Failed => "failed" ,
79+ Self :: Skipped => "skipped" ,
80+ }
81+ }
82+ }
83+
7584#[ derive( Debug , Clone , Default , Serialize , Deserialize ) ]
7685pub struct CrossPrFindings {
7786 pub contract_drifts : Vec < CrossPrContractDrift > ,
@@ -242,8 +251,13 @@ impl MultiPrDeltaReport {
242251 . map_or_else ( || error. id . clone ( ) , |pr| format ! ( "#{pr}" ) ) ;
243252 let _ = writeln ! (
244253 buf,
245- "| {:?} | {} | `{}` | `{}`..`{}` | {} |" ,
246- error. status, pr, error. repo, error. base, error. head, error. message
254+ "| {} | {} | `{}` | `{}`..`{}` | {} |" ,
255+ error. status. as_str( ) ,
256+ pr,
257+ error. repo,
258+ error. base,
259+ error. head,
260+ error. message
247261 ) ;
248262 }
249263 }
@@ -506,7 +520,13 @@ fn set_fingerprint_for_report(manifest: &PrSetManifest, prs: &[PerPrDeltaReport]
506520 . and_then ( Value :: as_str)
507521 . unwrap_or ( pr. head . as_str ( ) )
508522 . to_owned ( ) ,
509- config_hash : String :: new ( ) ,
523+ config_hash : pr
524+ . delta_report
525+ . get ( "safety" )
526+ . and_then ( |safety| safety. get ( "config_hash" ) )
527+ . and_then ( Value :: as_str)
528+ . unwrap_or_default ( )
529+ . to_owned ( ) ,
510530 gather_step_version : env ! ( "CARGO_PKG_VERSION" ) . to_owned ( ) ,
511531 } )
512532 . collect ( ) ;
@@ -546,6 +566,10 @@ mod tests {
546566 use crate :: pr_review:: multi_pr:: manifest:: { PrEntry , PrSetManifest } ;
547567
548568 fn pr ( id : & str , side : & str ) -> PerPrDeltaReport {
569+ pr_with_config_hash ( id, side, "cfg" )
570+ }
571+
572+ fn pr_with_config_hash ( id : & str , side : & str , config_hash : & str ) -> PerPrDeltaReport {
549573 PerPrDeltaReport {
550574 id : id. to_owned ( ) ,
551575 repo : id. to_owned ( ) ,
@@ -559,7 +583,8 @@ mod tests {
559583 "head_sha" : "2222222222222222222222222222222222222222"
560584 } ,
561585 "safety" : {
562- "cache_key" : "workspace:base:head"
586+ "cache_key" : "workspace:base:head" ,
587+ "config_hash" : config_hash
563588 } ,
564589 "changed_files" : [ "src/app.ts" ] ,
565590 "routes" : { "added" : [ ] , "removed" : [ ] , "changed" : [ ] } ,
@@ -644,6 +669,42 @@ mod tests {
644669 assert_eq ! ( report. metadata. completed_prs, 1 ) ;
645670 assert_eq ! ( report. metadata. failed_prs, 0 ) ;
646671 assert_eq ! ( report. metadata. skipped_prs, 1 ) ;
647- assert ! ( report. render_markdown( ) . contains( "Cross-PR findings" ) ) ;
672+ let markdown = report. render_markdown ( ) ;
673+ assert ! ( markdown. contains( "Cross-PR findings" ) ) ;
674+ assert ! (
675+ markdown. contains( "| skipped | #2 |" ) ,
676+ "markdown should use the stable serialized status label: {markdown}"
677+ ) ;
678+ }
679+
680+ #[ test]
681+ fn set_fingerprint_includes_child_config_hash ( ) {
682+ let manifest = PrSetManifest {
683+ version : 0 ,
684+ id : "checkout-refresh" . to_owned ( ) ,
685+ title : None ,
686+ prs : vec ! [ PrEntry {
687+ id: "api" . to_owned( ) ,
688+ repo: "api" . to_owned( ) ,
689+ base: "main" . to_owned( ) ,
690+ head: "feature/api" . to_owned( ) ,
691+ pr: Some ( 1 ) ,
692+ depends_on: vec![ ] ,
693+ } ] ,
694+ } ;
695+
696+ let first = super :: set_fingerprint_for_report (
697+ & manifest,
698+ & [ pr_with_config_hash ( "api" , "producer" , "cfg-a" ) ] ,
699+ ) ;
700+ let second = super :: set_fingerprint_for_report (
701+ & manifest,
702+ & [ pr_with_config_hash ( "api" , "producer" , "cfg-b" ) ] ,
703+ ) ;
704+
705+ assert_ne ! (
706+ first, second,
707+ "set fingerprint must change when a child review config hash changes"
708+ ) ;
648709 }
649710}
0 commit comments