3939 Task ,
4040)
4141from common .utils import redis_client , fix_await
42+ from common .models import ReproducerInfo
4243from constants import I_AM_JOTNAR , CAREFULLY_REVIEW_CHANGES
4344from observability import setup_observability
4445from tools .commands import RunShellCommandTool
@@ -288,6 +289,16 @@ def get_prompt() -> str:
288289 Everything from the previous attempt has been reset. Start over, follow the instructions from the start
289290 and don't forget to fix the issue.
290291 {{/build_error}}
292+ {{^reproducer_success}}
293+ The reproducer test case failed with the following error:
294+
295+ {{reproducer_result}}
296+
297+ Keep in mind the error and try to fix the patches in a way that makes the reproducer test case pass.
298+
299+ You can inspect the reproducer test case at {{reproducer_info.git_url}}/blob/{{reproducer_info.git_ref}}/{{reproducer_info.test}}.
300+ The test is located in the {{tmt_reproducer.git_ref}} branch of the {{tmt_reproducer.git_url}} repository.
301+ {{/reproducer_success}}
291302 """
292303
293304
@@ -535,9 +546,13 @@ class State(PackageUpdateState):
535546 attempts_remaining : int = Field (default = max_build_attempts )
536547 used_cherry_pick_workflow : bool = Field (default = False ) # Track if cherry-pick was used
537548 incremental_fix_attempts : int = Field (default = 0 ) # Track how many times we tried incremental fix
549+ build_url : str | None = Field (default = None )
550+ reproducer_success : bool = Field (default = False )
551+ reproducer_result : str | None = Field (default = None )
552+ reproducer_info : ReproducerInfo | None = Field (default = None )
538553
539554 async def run_workflow (
540- package , dist_git_branch , upstream_patches , jira_issue , cve_id , redis_conn = None
555+ package , dist_git_branch , upstream_patches , jira_issue , cve_id , redis_conn = None , reproducer_info = None
541556 ):
542557 local_tool_options ["working_directory" ] = None
543558
@@ -603,6 +618,9 @@ async def run_backport_agent(state):
603618 cve_id = state .cve_id ,
604619 upstream_patches = state .upstream_patches ,
605620 build_error = state .build_error ,
621+ reproducer_success = state .reproducer_success ,
622+ reproducer_result = state .reproducer_result ,
623+ reproducer_info = state .reproducer_info ,
606624 ),
607625 ),
608626 expected_output = BackportOutputSchema ,
@@ -663,6 +681,9 @@ async def fix_build_error(state):
663681 cve_id = state .cve_id ,
664682 upstream_patches = state .upstream_patches ,
665683 build_error = state .build_error ,
684+ reproducer_success = state .reproducer_success ,
685+ reproducer_result = state .reproducer_result ,
686+ reproducer_info = state .reproducer_info ,
666687 ),
667688 ),
668689 expected_output = BackportOutputSchema ,
@@ -736,10 +757,14 @@ async def run_build_agent(state):
736757 if build_result .success :
737758 # Build succeeded - reset incremental fix counter for potential future failures
738759 state .incremental_fix_attempts = 0
739- return "update_release"
760+ state .build_url = build_result .url
761+ if state .reproducer_info :
762+ return "run_reproducer_test_case"
763+ else :
764+ return "update_release"
740765 if build_result .is_timeout :
741766 logger .info (f"Build timed out for { state .jira_issue } , proceeding" )
742- return "update_release "
767+ return "run_testing_farm_test "
743768 state .attempts_remaining -= 1
744769 if state .attempts_remaining <= 0 :
745770 state .backport_result .success = False
@@ -878,6 +903,23 @@ async def create_merge_request_checklist(state):
878903 async def add_fusa_label (state ):
879904 return await PackageUpdateStep .add_fusa_label (state , "comment_in_jira" , dry_run = dry_run , gateway_tools = gateway_tools )
880905
906+ async def run_reproducer_test_case (state ):
907+ state .reproducer_success , state .reproducer_result = await tasks .run_tool (
908+ "run_testing_farm_test" ,
909+ git_url = state .reproducer_info .git_url ,
910+ git_ref = state .reproducer_info .git_ref ,
911+ path_to_test = state .reproducer_info .test ,
912+ package = state .build_url ,
913+ compose = state .dist_git_branch .upper () + "-Nightly" ,
914+ available_tools = gateway_tools ,
915+ )
916+ if state .reproducer_success :
917+ logger .info (f"Reproducer result: { state .reproducer_result } " )
918+ return "update_release"
919+ else :
920+ logger .error (f"Reproducer failed: { state .reproducer_result } " )
921+ return "run_backport_agent"
922+
881923 async def comment_in_jira (state ):
882924 if dry_run :
883925 return Workflow .END
@@ -903,6 +945,7 @@ async def comment_in_jira(state):
903945 workflow .add_step ("run_backport_agent" , run_backport_agent )
904946 workflow .add_step ("fix_build_error" , fix_build_error )
905947 workflow .add_step ("run_build_agent" , run_build_agent )
948+ workflow .add_step ("run_reproducer_test_case" , run_reproducer_test_case )
906949 workflow .add_step ("update_release" , update_release )
907950 workflow .add_step ("stage_changes" , stage_changes )
908951 workflow .add_step ("run_log_agent" , run_log_agent )
@@ -919,6 +962,9 @@ async def comment_in_jira(state):
919962 upstream_patches = upstream_patches ,
920963 jira_issue = jira_issue ,
921964 cve_id = cve_id ,
965+ reproducer_info = reproducer_info ,
966+ reproducer_success = False ,
967+ reproducer_result = None ,
922968 ),
923969 )
924970 return response .state
@@ -931,13 +977,24 @@ async def comment_in_jira(state):
931977 ):
932978 upstream_patches = upstream_patches_raw .split ("," )
933979 logger .info ("Running in direct mode with environment variables" )
980+ reproducer_info_repo_url = os .getenv ("REPRODUCER_INFO_REPO_URL" , None )
981+ reproducer_info_repo_ref = os .getenv ("REPRODUCER_INFO_REPO_REF" , None )
982+ reproducer_info_test = os .getenv ("REPRODUCER_INFO_TEST" , None )
983+ reproducer_info = None
984+ if reproducer_info_repo_url and reproducer_info_repo_ref and reproducer_info_test :
985+ reproducer_info = ReproducerInfo (
986+ git_url = reproducer_info_repo_url ,
987+ git_ref = reproducer_info_repo_ref ,
988+ test = reproducer_info_test ,
989+ )
934990 state = await run_workflow (
935991 package = package ,
936992 dist_git_branch = branch ,
937993 upstream_patches = upstream_patches ,
938994 jira_issue = jira_issue ,
939995 cve_id = os .getenv ("CVE_ID" , None ),
940996 redis_conn = None ,
997+ reproducer_info = reproducer_info ,
941998 )
942999 logger .info (f"Direct run completed: { state .backport_result .model_dump_json (indent = 4 )} " )
9431000 return
@@ -967,7 +1024,7 @@ async def comment_in_jira(state):
9671024 logger .info (
9681025 f"Processing backport for package: { backport_data .package } , "
9691026 f"JIRA: { backport_data .jira_issue } , branch: { dist_git_branch } , "
970- f"attempt: { task .attempts + 1 } "
1027+ f"attempt: { task .attempts + 1 } , reproducer info: { backport_data . reproducer_info } "
9711028 )
9721029
9731030 async def retry (task , error ):
@@ -1000,6 +1057,7 @@ async def retry(task, error):
10001057 jira_issue = backport_data .jira_issue ,
10011058 cve_id = backport_data .cve_id ,
10021059 redis_conn = redis ,
1060+ reproducer_info = backport_data .reproducer_info ,
10031061 )
10041062 logger .info (
10051063 f"Backport processing completed for { backport_data .jira_issue } , " f"success: { state .backport_result .success } "
0 commit comments