@@ -691,6 +691,10 @@ def get_new_fails_this_pr(
691691
692692 # Combine both types of fails and select only desired columns
693693 desired_columns = ["job_name" , "test_name" , "test_status" , "results_link" ]
694+ if len (checks_fails ) > 0 and "labels" in checks_fails .columns :
695+ desired_columns .insert (desired_columns .index ("results_link" ), "labels" )
696+ if len (regression_fails ) > 0 :
697+ regression_fails ["labels" ] = ""
694698 all_pr_fails = pd .concat ([checks_fails , regression_fails ], ignore_index = True )[
695699 desired_columns
696700 ]
@@ -976,6 +980,82 @@ def format_test_status(text: str) -> str:
976980 return f'<span style="font-weight: bold; color: { color } ">{ text } </span>'
977981
978982
983+ def _label_names_from_ext (ext : dict ) -> list [str ]:
984+ names = []
985+ for item in ext .get ("labels" ) or []:
986+ if isinstance (item , str ):
987+ name = item
988+ elif isinstance (item , dict ) and item .get ("name" ):
989+ name = item ["name" ]
990+ else :
991+ continue
992+ if name != "cidb" :
993+ names .append (name )
994+ return names
995+
996+
997+ def fetch_workflow_result_json (
998+ pr_number : int , branch : str , commit_sha : str
999+ ) -> dict | None :
1000+ if pr_number == 0 :
1001+ ref_param = f"REF={ branch } "
1002+ workflow_name = "MasterCI"
1003+ else :
1004+ ref_param = f"PR={ pr_number } "
1005+ workflow_name = "PR"
1006+
1007+ status_file = f"result_{ workflow_name .lower ()} .json"
1008+ s3_path = (
1009+ f"https://{ S3_BUCKET } .s3.amazonaws.com/"
1010+ f"{ ref_param .replace ('=' , 's/' )} /{ commit_sha } /{ status_file } "
1011+ )
1012+ try :
1013+ response = requests .get (s3_path , timeout = 30 )
1014+ if response .status_code != 200 :
1015+ return None
1016+ return response .json ()
1017+ except Exception as e :
1018+ print (f"WARNING:Failed to fetch workflow result from { s3_path } : { e } " )
1019+ return None
1020+
1021+
1022+ def get_failure_labels_from_workflow (workflow_data : dict | None ) -> dict :
1023+ if not workflow_data :
1024+ return {}
1025+ labels_map = {}
1026+ for job in workflow_data .get ("results" ) or []:
1027+ job_name = job .get ("name" )
1028+ if not job_name :
1029+ continue
1030+ for leaf in job .get ("results" ) or []:
1031+ test_name = leaf .get ("name" )
1032+ if not test_name :
1033+ continue
1034+ names = _label_names_from_ext (leaf .get ("ext" ) or {})
1035+ if names :
1036+ labels_map [(job_name , test_name )] = ", " .join (names )
1037+ return labels_map
1038+
1039+
1040+ def add_labels_to_checks_fails (
1041+ checks_fails : pd .DataFrame , workflow_data : dict | None
1042+ ) -> pd .DataFrame :
1043+ if checks_fails is None or len (checks_fails ) == 0 :
1044+ return checks_fails
1045+ labels_map = get_failure_labels_from_workflow (workflow_data )
1046+ df = checks_fails .copy ()
1047+ df ["labels" ] = df .apply (
1048+ lambda row : labels_map .get ((row ["job_name" ], row ["test_name" ]), "" ),
1049+ axis = 1 ,
1050+ )
1051+ cols = [c for c in df .columns if c != "labels" ]
1052+ if "results_link" in cols :
1053+ cols .insert (cols .index ("results_link" ), "labels" )
1054+ else :
1055+ cols .append ("labels" )
1056+ return df [cols ]
1057+
1058+
9791059def format_results_as_html_table (results , * , branch_name : str = "" ) -> str :
9801060 if not isinstance (results , pd .DataFrame ):
9811061 return results
@@ -1012,42 +1092,30 @@ def format_col_name(col_name: str) -> str:
10121092 "PR Labels" : lambda labels : format_pr_labels_with_verification (
10131093 labels , branch_name = branch_name
10141094 ),
1095+ "Labels" : lambda labels : html .escape (str (labels ), quote = True ) if labels else "" ,
10151096 }
10161097
1017- html = results .to_html (
1098+ return results .to_html (
10181099 index = False ,
10191100 formatters = formatters ,
10201101 escape = False ,
10211102 border = 0 ,
10221103 classes = ["test-results-table" ],
10231104 )
1024- return html
10251105
10261106
10271107def backfill_skipped_statuses (
1028- job_statuses : pd .DataFrame , pr_number : int , branch : str , commit_sha : str
1108+ job_statuses : pd .DataFrame ,
1109+ workflow_result : dict | None ,
10291110):
10301111 """
10311112 Fill in the job statuses for skipped jobs.
10321113 """
1033-
1034- if pr_number == 0 :
1035- ref_param = f"REF={ branch } "
1036- workflow_name = "MasterCI"
1037- else :
1038- ref_param = f"PR={ pr_number } "
1039- workflow_name = "PR"
1040-
1041- status_file = f"result_{ workflow_name .lower ()} .json"
1042- s3_path = f"https://{ S3_BUCKET } .s3.amazonaws.com/{ ref_param .replace ('=' , 's/' )} /{ commit_sha } /{ status_file } "
1043- response = requests .get (s3_path )
1044-
1045- if response .status_code != 200 :
1114+ if workflow_result is None :
10461115 return job_statuses
10471116
1048- status_data = response .json ()
10491117 skipped_jobs = []
1050- for job in status_data ["results" ]:
1118+ for job in workflow_result ["results" ]:
10511119 if job ["status" ] == "skipped" and len (job ["links" ]) > 0 :
10521120 skipped_jobs .append (
10531121 {
@@ -1192,10 +1260,15 @@ def create_workflow_report(
11921260 settings = {"use_numpy" : True },
11931261 )
11941262
1263+ workflow_result = fetch_workflow_result_json (pr_number , branch_name , commit_sha )
1264+
11951265 results_dfs = {
11961266 "prs_in_release" : [],
11971267 "job_statuses" : get_commit_statuses (commit_sha ),
1198- "checks_fails" : get_checks_fails (db_client , commit_sha , branch_name ),
1268+ "checks_fails" : add_labels_to_checks_fails (
1269+ get_checks_fails (db_client , commit_sha , branch_name ),
1270+ workflow_result ,
1271+ ),
11991272 "checks_known_fails" : [],
12001273 "pr_new_fails" : [],
12011274 "checks_errors" : get_checks_errors (db_client , commit_sha , branch_name ),
@@ -1257,7 +1330,8 @@ def create_workflow_report(
12571330 pr_info = {}
12581331
12591332 results_dfs ["job_statuses" ] = backfill_skipped_statuses (
1260- results_dfs ["job_statuses" ], pr_number , branch_name , commit_sha
1333+ results_dfs ["job_statuses" ],
1334+ workflow_result ,
12611335 )
12621336
12631337 high_cve_count = 0
0 commit comments