1515import json
1616import logging
1717import re
18+ import stat
1819import uuid
1920from datetime import datetime
2021from token import OP
2829from redis_release .bht .state import reset_model_to_defaults
2930
3031from ..github_client_async import GitHubClientAsync
31- from ..models import WorkflowConclusion , WorkflowRun , WorkflowStatus
32+ from ..models import (
33+ PackageType ,
34+ RedisVersion ,
35+ ReleaseType ,
36+ WorkflowConclusion ,
37+ WorkflowRun ,
38+ WorkflowStatus ,
39+ )
3240from .decorators import FlagGuard
3341from .logging_wrapper import PyTreesLoggerWrapper
3442from .state import Package , PackageMeta , ReleaseMeta , Workflow
@@ -55,6 +63,12 @@ def log_exception_and_return_failure(self, e: Exception) -> Status:
5563 self .logger ._logger .error (f"[red]Full traceback:[/red]" , exc_info = True )
5664 return Status .FAILURE
5765
66+ def log_once (self , key : str , container : Dict [str , bool ]) -> bool :
67+ if key not in container :
68+ container [key ] = True
69+ return True
70+ return False
71+
5872
5973class ReleaseAction (LoggingAction ):
6074 task : Optional [asyncio .Task [Any ]] = None
@@ -100,7 +114,6 @@ def initialise(self) -> None:
100114 return
101115
102116 try :
103- from ..models import RedisVersion
104117
105118 self .release_version = RedisVersion .parse (self .release_meta .tag )
106119 self .logger .debug (
@@ -141,9 +154,12 @@ def update(self) -> Status:
141154
142155 if detected_branch :
143156 self .package_meta .ref = detected_branch
144- self .logger .info (
145- f"[green]Target ref identified:[/green] { self .package_meta .ref } "
146- )
157+ if self .log_once (
158+ "target_ref_identified" , self .package_meta .ephemeral .log_once_flags
159+ ):
160+ self .logger .info (
161+ f"[green]Target ref identified:[/green] { self .package_meta .ref } "
162+ )
147163 self .feedback_message = f"Target ref set to { self .package_meta .ref } "
148164 return Status .SUCCESS
149165 else :
@@ -255,6 +271,12 @@ def initialise(self) -> None:
255271 self .workflow .inputs ["release_tag" ] = self .release_meta .tag
256272 ref = self .package_meta .ref if self .package_meta .ref is not None else "main"
257273 self .workflow .ephemeral .trigger_attempted = True
274+ if self .log_once (
275+ "workflow_trigger_start" , self .workflow .ephemeral .log_once_flags
276+ ):
277+ self .logger .info (
278+ f"Triggering workflow { self .workflow .workflow_file } , ref: { ref } , uuid: { self .workflow .uuid } "
279+ )
258280 self .task = asyncio .create_task (
259281 self .github_client .trigger_workflow (
260282 self .package_meta .repo ,
@@ -273,9 +295,12 @@ def update(self) -> Status:
273295
274296 self .task .result ()
275297 self .workflow .triggered_at = datetime .now ()
276- logger .info (
277- f"[green]Workflow triggered successfully:[/green] { self .workflow .uuid } "
278- )
298+ if self .log_once (
299+ "workflow_triggered" , self .workflow .ephemeral .log_once_flags
300+ ):
301+ logger .info (
302+ f"[green]Workflow triggered successfully:[/green] { self .workflow .uuid } "
303+ )
279304 self .feedback_message = "workflow triggered"
280305 return Status .SUCCESS
281306 except Exception as e :
@@ -308,7 +333,12 @@ def initialise(self) -> None:
308333 "[red]Workflow UUID is None - cannot identify workflow[/red]"
309334 )
310335 return
311-
336+ if self .log_once (
337+ "workflow_identify_start" , self .workflow .ephemeral .log_once_flags
338+ ):
339+ self .logger .info (
340+ f"Start identifying workflow { self .workflow .workflow_file } , uuid: { self .workflow .uuid } "
341+ )
312342 self .task = asyncio .create_task (
313343 self .github_client .identify_workflow (
314344 self .package_meta .repo , self .workflow .workflow_file , self .workflow .uuid
@@ -328,9 +358,12 @@ def update(self) -> Status:
328358 return Status .FAILURE
329359
330360 self .workflow .run_id = result .run_id
331- self .logger .info (
332- f"[green]Workflow found successfully:[/green] uuid: { self .workflow .uuid } , run_id: { self .workflow .run_id } "
333- )
361+ if self .log_once (
362+ "workflow_identified" , self .workflow .ephemeral .log_once_flags
363+ ):
364+ self .logger .info (
365+ f"[green]Workflow found successfully:[/green] uuid: { self .workflow .uuid } , run_id: { self .workflow .run_id } "
366+ )
334367 self .feedback_message = (
335368 f"Workflow identified, run_id: { self .workflow .run_id } "
336369 )
@@ -360,6 +393,12 @@ def initialise(self) -> None:
360393 )
361394 return
362395
396+ if self .log_once (
397+ "workflow_status_update" , self .workflow .ephemeral .log_once_flags
398+ ):
399+ self .logger .info (
400+ f"Start checking workflow { self .workflow .workflow_file } , run_id: { self .workflow .run_id } status"
401+ )
363402 self .task = asyncio .create_task (
364403 self .github_client .get_workflow_run (
365404 self .package_meta .repo , self .workflow .run_id
@@ -374,6 +413,12 @@ def update(self) -> Status:
374413 return Status .RUNNING
375414
376415 result = self .task .result ()
416+ if self .log_once (
417+ "workflow_status_current" , self .workflow .ephemeral .log_once_flags
418+ ):
419+ self .logger .info (
420+ f"Workflow { self .workflow .workflow_file } , run_id: { self .workflow .run_id } current status: { result .status } , { result .conclusion } "
421+ )
377422 if self .workflow .status != result .status :
378423 self .logger .info (
379424 f"Workflow { self .workflow .workflow_file } ({ self .workflow .run_id } ) status changed: { self .workflow .status } -> { result .status } "
@@ -583,6 +628,94 @@ def update(self) -> Status: # type: ignore
583628 return Status .SUCCESS
584629
585630
631+ class GenericWorkflowInputs (ReleaseAction ):
632+ def __init__ (
633+ self ,
634+ name : str ,
635+ workflow : Workflow ,
636+ package_meta : PackageMeta ,
637+ release_meta : ReleaseMeta ,
638+ log_prefix : str = "" ,
639+ ) -> None :
640+ self .workflow = workflow
641+ self .package_meta = package_meta
642+ self .release_meta = release_meta
643+ super ().__init__ (name = name , log_prefix = log_prefix )
644+
645+ def update (self ) -> Status :
646+ return Status .SUCCESS
647+
648+
649+ def create_prepare_build_workflow_inputs (
650+ name : str ,
651+ workflow : Workflow ,
652+ package_meta : PackageMeta ,
653+ release_meta : ReleaseMeta ,
654+ log_prefix : str ,
655+ ) -> Behaviour :
656+ cls_map = {
657+ PackageType .DEBIAN : DebianWorkflowInputs ,
658+ }
659+
660+ selected_class = (
661+ cls_map .get (package_meta .package_type , GenericWorkflowInputs )
662+ if package_meta .package_type
663+ else GenericWorkflowInputs
664+ )
665+ return selected_class (
666+ name ,
667+ workflow ,
668+ package_meta ,
669+ release_meta ,
670+ log_prefix = log_prefix ,
671+ )
672+
673+
674+ def create_prepare_publish_workflow_inputs (
675+ name : str ,
676+ workflow : Workflow ,
677+ package_meta : PackageMeta ,
678+ release_meta : ReleaseMeta ,
679+ log_prefix : str ,
680+ ) -> Behaviour :
681+ cls_map = {
682+ PackageType .DEBIAN : DebianWorkflowInputs ,
683+ }
684+
685+ selected_class = (
686+ cls_map .get (package_meta .package_type , GenericWorkflowInputs )
687+ if package_meta .package_type
688+ else GenericWorkflowInputs
689+ )
690+ return selected_class (
691+ name ,
692+ workflow ,
693+ package_meta ,
694+ release_meta ,
695+ log_prefix = log_prefix ,
696+ )
697+
698+
699+ class DebianWorkflowInputs (ReleaseAction ):
700+ def __init__ (
701+ self ,
702+ name : str ,
703+ workflow : Workflow ,
704+ package_meta : PackageMeta ,
705+ release_meta : ReleaseMeta ,
706+ log_prefix : str = "" ,
707+ ) -> None :
708+ self .workflow = workflow
709+ self .package_meta = package_meta
710+ self .release_meta = release_meta
711+ super ().__init__ (name = f"{ name } - debian" , log_prefix = log_prefix )
712+
713+ def update (self ) -> Status :
714+ if self .release_meta .release_type is not None :
715+ self .workflow .inputs ["release_type" ] = self .release_meta .release_type .value
716+ return Status .SUCCESS
717+
718+
586719### Conditions ###
587720
588721
@@ -595,6 +728,10 @@ def __init__(
595728
596729 def update (self ) -> Status :
597730 if self .package_meta .ref is not None :
731+ if self .log_once (
732+ "target_ref_identified" , self .package_meta .ephemeral .log_once_flags
733+ ):
734+ self .logger .info (f"Target ref identified: { self .package_meta .ref } " )
598735 return Status .SUCCESS
599736 return Status .FAILURE
600737
@@ -607,6 +744,12 @@ def __init__(self, name: str, workflow: Workflow, log_prefix: str = "") -> None:
607744 def update (self ) -> Status :
608745 self .logger .debug (f"IsWorkflowTriggered: { self .workflow } " )
609746 if self .workflow .triggered_at is not None :
747+ if self .log_once (
748+ "workflow_triggered" , self .workflow .ephemeral .log_once_flags
749+ ):
750+ self .logger .info (
751+ f"Workflow is triggered at: { self .workflow .triggered_at } "
752+ )
610753 return Status .SUCCESS
611754 return Status .FAILURE
612755
@@ -619,6 +762,12 @@ def __init__(self, name: str, workflow: Workflow, log_prefix: str = "") -> None:
619762 def update (self ) -> Status :
620763 self .logger .debug (f"{ self .workflow } " )
621764 if self .workflow .run_id is not None :
765+ if self .log_once (
766+ "workflow_identified" , self .workflow .ephemeral .log_once_flags
767+ ):
768+ self .logger .info (
769+ f"Workflow is identified, run_id: { self .workflow .run_id } "
770+ )
622771 return Status .SUCCESS
623772 return Status .FAILURE
624773
@@ -630,6 +779,10 @@ def __init__(self, name: str, workflow: Workflow, log_prefix: str = "") -> None:
630779
631780 def update (self ) -> Status :
632781 if self .workflow .status == WorkflowStatus .COMPLETED :
782+ if self .log_once (
783+ "workflow_completed" , self .workflow .ephemeral .log_once_flags
784+ ):
785+ self .logger .info (f"Workflow is completed" )
633786 return Status .SUCCESS
634787 return Status .FAILURE
635788
@@ -641,6 +794,10 @@ def __init__(self, name: str, workflow: Workflow, log_prefix: str = "") -> None:
641794
642795 def update (self ) -> Status :
643796 if self .workflow .conclusion == WorkflowConclusion .SUCCESS :
797+ if self .log_once (
798+ "workflow_successful" , self .workflow .ephemeral .log_once_flags
799+ ):
800+ self .logger .info (f"Workflow completed with success status" )
644801 return Status .SUCCESS
645802 return Status .FAILURE
646803
@@ -652,6 +809,10 @@ def __init__(self, name: str, workflow: Workflow, log_prefix: str = "") -> None:
652809
653810 def update (self ) -> Status :
654811 if self .workflow .artifacts is not None :
812+ if self .log_once (
813+ "workflow_artifacts" , self .workflow .ephemeral .log_once_flags
814+ ):
815+ self .logger .info (f"Workflow has artifacts" )
655816 return Status .SUCCESS
656817 return Status .FAILURE
657818
@@ -663,11 +824,13 @@ def __init__(self, name: str, workflow: Workflow, log_prefix: str = "") -> None:
663824
664825 def update (self ) -> Status :
665826 if self .workflow .result is not None :
827+ if self .log_once ("workflow_result" , self .workflow .ephemeral .log_once_flags ):
828+ self .logger .info (f"Workflow is successful and has result" )
666829 return Status .SUCCESS
667830 return Status .FAILURE
668831
669832
670- class NeedToPublish (LoggingAction ):
833+ class NeedToPublishRelease (LoggingAction ):
671834 """Check the release type and package configuration to determine if we need to run publish workflow."""
672835
673836 def __init__ (
@@ -682,20 +845,44 @@ def __init__(
682845 super ().__init__ (name = name , log_prefix = log_prefix )
683846
684847 def update (self ) -> Status :
685- # Check if this is an internal release by matching the pattern -int\d*$ in the tag
686- if self .release_meta .tag and re .search (r"-int\d*$" , self .release_meta .tag ):
687- self .logger .debug (f"Asssuming internal release: { self .release_meta .tag } " )
848+ if self .release_meta .release_type == ReleaseType .INTERNAL :
688849 if self .package_meta .publish_internal_release :
689850 self .logger .debug (
690- f"Publishing internal release: { self .release_meta .tag } "
851+ f"Internal release requires publishing : { self .release_meta .tag } "
691852 )
692853 return Status .SUCCESS
693- self .logger .debug (
694- f"Skip publishing internal release: { self .release_meta .tag } "
695- )
854+ else :
855+ self .logger .debug (
856+ f"Skip publishing internal release: { self .release_meta .tag } "
857+ )
696858 return Status .FAILURE
859+ return Status .FAILURE
860+
861+
862+ class DetectReleaseType (LoggingAction ):
863+ def __init__ (
864+ self , name : str , release_meta : ReleaseMeta , log_prefix : str = ""
865+ ) -> None :
866+ self .release_meta = release_meta
867+ super ().__init__ (name = name , log_prefix = log_prefix )
697868
698- self .logger .debug (f"Public release: { self .release_meta .tag } " )
869+ def update (self ) -> Status :
870+ if self .release_meta .release_type is not None :
871+ if self .log_once (
872+ "release_type_detected" , self .release_meta .ephemeral .log_once_flags
873+ ):
874+ self .logger .info (
875+ f"Detected release type: { self .release_meta .release_type } "
876+ )
877+ return Status .SUCCESS
878+ if self .release_meta .tag and re .search (r"-int\d*$" , self .release_meta .tag ):
879+ self .release_meta .release_type = ReleaseType .INTERNAL
880+ else :
881+ self .release_meta .release_type = ReleaseType .PUBLIC
882+ self .log_once (
883+ "release_type_detected" , self .release_meta .ephemeral .log_once_flags
884+ )
885+ self .logger .info (f"Detected release type: { self .release_meta .release_type } " )
699886 return Status .SUCCESS
700887
701888
0 commit comments