1+
2+ #%%
13import os
24import re
35import requests
46import json
57from datetime import datetime
68from pathlib import Path
79import logging
10+ from apex_algorithm_qa_tools .scenarios import get_benchmark_scenarios , get_project_root
811
912# Configure logging
1013logging .basicConfig (level = logging .INFO )
1316# Configuration
1417GITHUB_REPO = "ESA-APEx/apex_algorithms"
1518GITHUB_TOKEN = os .getenv ("APEX_ISSUE_TOKEN" )
16- ISSUE_LABEL = "test -failure"
19+ ISSUE_LABEL = "benchmark -failure"
1720SCENARIO_BASE_PATH = "qa/benchmarks/scenarios/"
1821WORKFLOW_BASE_URL = f"https://github.com/{ os .getenv ('GITHUB_REPOSITORY' )} /actions/runs/{ os .getenv ('GITHUB_RUN_ID' )} "
1922
@@ -34,7 +37,6 @@ def get_existing_issues():
3437def get_scenario_details (scenario_id ):
3538 """Retrieve details for a given scenario ID"""
3639 try :
37- from apex_algorithm_qa_tools .scenarios import get_benchmark_scenarios
3840 for scenario in get_benchmark_scenarios ():
3941 if scenario .id == scenario_id :
4042 return {
@@ -51,7 +53,36 @@ def get_scenario_details(scenario_id):
5153 except Exception as e :
5254 logger .error (f"Error loading scenarios: { str (e )} " )
5355 return None
56+
57+ def get_scenario_contacts (scenario_id : str ) -> list :
58+ """Find contact info by searching through algorithm catalog structure"""
59+ algorithm_catalog = get_project_root () / "algorithm_catalog"
60+
61+ # Search through all provider directories
62+ for provider_dir in algorithm_catalog .iterdir ():
63+ if not provider_dir .is_dir ():
64+ continue
65+
66+ # Check for matching algorithm directory
67+ algorithm_dir = provider_dir / scenario_id
68+ if not algorithm_dir .exists ():
69+ continue
70+
71+ # Look for records file
72+ records_path = algorithm_dir / "records" / f"{ scenario_id } .json"
73+ if records_path .exists ():
74+ try :
75+ with open (records_path ) as f :
76+ record = json .load (f )
77+ return record .get ("properties" , {}).get ("contacts" , [])
78+ except Exception as e :
79+ logger .error (f"Error loading contacts from { records_path } : { str (e )} " )
80+ return []
81+
82+ logger .warning (f"No contacts found for scenario { scenario_id } " )
83+ return []
5484
85+
5586def parse_failed_tests ():
5687 """Parse pytest output to find failed scenarios and their logs"""
5788 log_file = Path ("qa/benchmarks/pytest_output.txt" )
@@ -90,6 +121,29 @@ def parse_failed_tests():
90121def build_issue_body (scenario , logs , failure_count ):
91122 """Construct the issue body with technical details"""
92123 timestamp = datetime .now ().strftime ("%Y-%m-%d %H:%M:%S" )
124+ contacts = get_scenario_contacts (scenario ['id' ])
125+
126+ contact_table = ""
127+ if contacts :
128+ try :
129+ contact_table = "\n \n **Responsible Contacts**:\n \n "
130+ contact_table += "| Name | Organization | Contact |\n "
131+ contact_table += "|------|--------------|---------|\n "
132+ for contact in contacts :
133+ # Extract links from contact instructions
134+ contact_info = contact .get ('contactInstructions' , '' )
135+ if contact .get ('links' ):
136+ links = [f"[{ link ['title' ]} ]({ link ['href' ]} )" for link in contact ['links' ]]
137+ contact_info += " (" + ", " .join (links ) + ")"
138+
139+ contact_table += (
140+ f"| { contact .get ('name' , '' )} "
141+ f"| { contact .get ('organization' , '' )} "
142+ f"| { contact_info } |\n "
143+ )
144+ except Exception as e :
145+ pass
146+
93147
94148 return f"""
95149## Benchmark Failure: { scenario ['id' ]}
@@ -98,12 +152,17 @@ def build_issue_body(scenario, logs, failure_count):
98152**Backend System**: { scenario ['backend' ]}
99153**Failure Count**: { failure_count }
100154**Timestamp**: { timestamp }
155+
101156**LINKS**:
102157- Workflow Run: { WORKFLOW_BASE_URL }
103158- Scenario Definition: { get_scenario_link (scenario ['id' ])}
104159- Artifacts: { WORKFLOW_BASE_URL } #artifacts
105160
106161---
162+ ### Contact information
163+ { contact_table }
164+ ---
165+
107166
108167### Technical Details
109168
@@ -116,9 +175,6 @@ def build_issue_body(scenario, logs, failure_count):
116175```plaintext
117176{ logs }
118177```
119-
120-
121-
122178"""
123179
124180def get_scenario_link (scenario_id ):
@@ -168,8 +224,9 @@ def update_existing_issue(issue, scenario, new_logs):
168224**Workflow Run**: { WORKFLOW_BASE_URL }
169225
170226**Error Logs**:
227+ ```plaintext
171228{ new_logs }
172- """
229+ ``` """
173230
174231 updated_body = f"{ current_body } \n \n { update_section } "
175232 updated_body = re .sub (r"Failure Count: \d+" , f"Failure Count: { failure_count } " , updated_body )
@@ -204,4 +261,7 @@ def main():
204261 create_new_issue (scenario , logs )
205262
206263if __name__ == "__main__" :
207- main ()
264+ main ()
265+
266+
267+ #%%
0 commit comments