Skip to content

Commit cfc490a

Browse files
committed
Separate trigger inputs, logging improvements
1 parent a7cf701 commit cfc490a

File tree

8 files changed

+368
-54
lines changed

8 files changed

+368
-54
lines changed

src/redis_release/bht/behaviours.py

Lines changed: 208 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import json
1616
import logging
1717
import re
18+
import stat
1819
import uuid
1920
from datetime import datetime
2021
from token import OP
@@ -28,7 +29,14 @@
2829
from redis_release.bht.state import reset_model_to_defaults
2930

3031
from ..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+
)
3240
from .decorators import FlagGuard
3341
from .logging_wrapper import PyTreesLoggerWrapper
3442
from .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

5973
class 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

Comments
 (0)