diff --git a/docs/v3/concepts/automations.mdx b/docs/v3/concepts/automations.mdx index 95e6b702aca7..bac942aa92c2 100644 --- a/docs/v3/concepts/automations.mdx +++ b/docs/v3/concepts/automations.mdx @@ -85,6 +85,23 @@ Prefect infers the relevant event whenever possible, but sometimes one does not Specify a name and, optionally, a description for the automation. +### Tracing automation actions + +When an automation fires, it emits events that you can use to trace what happened: + +- `prefect.automation.triggered` or `prefect.automation.resolved` - emitted when the trigger condition is met +- `prefect.automation.action.triggered` - emitted when an action starts +- `prefect.automation.action.executed` or `prefect.automation.action.failed` - emitted when an action completes + +The action events include related resources that link back to their source events: + +| Related resource role | Description | +| --------------------- | ----------- | +| `triggering-event` | The original event that caused the automation to fire | +| `automation-triggered-event` | The `automation.triggered` or `automation.resolved` event that prompted the action | + +These links help you trace from an action failure back to the specific trigger and original event that caused it. + ## Sending notifications with automations diff --git a/src/prefect/server/events/actions.py b/src/prefect/server/events/actions.py index b51b4296a6c9..7ed0abb2bf24 100644 --- a/src/prefect/server/events/actions.py +++ b/src/prefect/server/events/actions.py @@ -174,8 +174,17 @@ async def fail(self, triggered_action: "TriggeredAction", reason: str) -> None: if abs(time_since_trigger) < TIGHT_TIMING: follows_id = triggered_action.triggering_event.id - # Build related resources including triggering event reference + # Build related resources including automation.triggered and triggering event related_resources = list(self._resulting_related_resources) + if triggered_action.automation_triggered_event_id: + related_resources.append( + RelatedResource( + { + "prefect.resource.id": f"prefect.event.{triggered_action.automation_triggered_event_id}", + "prefect.resource.role": "automation-triggered-event", + } + ) + ) if triggered_action.triggering_event: related_resources.append( RelatedResource( @@ -190,7 +199,7 @@ async def fail(self, triggered_action: "TriggeredAction", reason: str) -> None: occurred=triggered_action.triggered, event="prefect.automation.action.triggered", resource=resource, - related=related_resources, + related=self._resulting_related_resources, payload=action_details, id=triggered_event_id, follows=follows_id, @@ -201,7 +210,7 @@ async def fail(self, triggered_action: "TriggeredAction", reason: str) -> None: occurred=now("UTC"), event="prefect.automation.action.failed", resource=resource, - related=self._resulting_related_resources, + related=related_resources, payload={ **action_details, "reason": reason, @@ -254,8 +263,17 @@ async def succeed(self, triggered_action: "TriggeredAction") -> None: if abs(time_since_trigger) < TIGHT_TIMING: follows_id = triggered_action.triggering_event.id - # Build related resources including triggering event reference + # Build related resources including automation.triggered and triggering event related_resources = list(self._resulting_related_resources) + if triggered_action.automation_triggered_event_id: + related_resources.append( + RelatedResource( + { + "prefect.resource.id": f"prefect.event.{triggered_action.automation_triggered_event_id}", + "prefect.resource.role": "automation-triggered-event", + } + ) + ) if triggered_action.triggering_event: related_resources.append( RelatedResource( @@ -269,13 +287,7 @@ async def succeed(self, triggered_action: "TriggeredAction") -> None: Event( occurred=triggered_action.triggered, event="prefect.automation.action.triggered", - resource=Resource( - { - "prefect.resource.id": automation_resource_id, - "prefect.resource.name": automation.name, - "prefect.trigger-type": automation.trigger.type, - } - ), + resource=resource, related=related_resources, payload=action_details, id=triggered_event_id, @@ -286,14 +298,8 @@ async def succeed(self, triggered_action: "TriggeredAction") -> None: Event( occurred=now("UTC"), event="prefect.automation.action.executed", - resource=Resource( - { - "prefect.resource.id": automation_resource_id, - "prefect.resource.name": automation.name, - "prefect.trigger-type": automation.trigger.type, - } - ), - related=self._resulting_related_resources, + resource=resource, + related=related_resources, payload={ **action_details, **self._result_details, diff --git a/src/prefect/server/events/schemas/automations.py b/src/prefect/server/events/schemas/automations.py index 8b0a12c23aed..c08ec6392f78 100644 --- a/src/prefect/server/events/schemas/automations.py +++ b/src/prefect/server/events/schemas/automations.py @@ -760,6 +760,24 @@ class TriggeredAction(PrefectBaseModel): default=0, description="The index of the action within the automation", ) + automation_triggered_event_id: UUID | None = Field( + default=None, + description=( + "The ID of the automation.triggered or automation.resolved event that " + "prompted this action, used to link automation.action.* events back to " + "the state change event" + ), + ) + + @field_validator("automation_triggered_event_id") + @classmethod + def validate_automation_triggered_event_id(cls, v, info): + """Ensure automation_triggered_event_id is only set when triggering_event exists.""" + if v is not None and info.data.get("triggering_event") is None: + raise ValueError( + "automation_triggered_event_id can only be set when triggering_event is provided" + ) + return v def idempotency_key(self) -> str: """Produce a human-friendly idempotency key for this action""" diff --git a/src/prefect/server/events/triggers.py b/src/prefect/server/events/triggers.py index 7ded68a1f7f4..f36e55bdb203 100644 --- a/src/prefect/server/events/triggers.py +++ b/src/prefect/server/events/triggers.py @@ -436,21 +436,37 @@ async def act(firing: Firing) -> None: } await messaging.publish(state_change_events.values()) - # By default, all `automation.actions` are fired - source_actions: List[Tuple[Optional[ReceivedEvent], ServerActionTypes]] = [ - (firing.triggering_event, action) for action in automation.actions + # Determine the primary state change event ID for linking action events back to + # the automation.triggered or automation.resolved event. Prefer Triggered over + # Resolved when both are present. + primary_state_change_event = state_change_events.get( + TriggerState.Triggered + ) or state_change_events.get(TriggerState.Resolved) + primary_state_change_event_id = ( + primary_state_change_event.id if primary_state_change_event else None + ) + + # By default, all `automation.actions` are fired. Each tuple contains: + # (triggering_event, action, automation_triggered_event_id) + source_actions: List[ + Tuple[Optional[ReceivedEvent], ServerActionTypes, UUID | None] + ] = [ + (firing.triggering_event, action, primary_state_change_event_id) + for action in automation.actions ] # Conditionally add in actions that fire on specific trigger states if TriggerState.Triggered in firing.trigger_states: + triggered_event = state_change_events[TriggerState.Triggered] source_actions += [ - (state_change_events[TriggerState.Triggered], action) + (triggered_event, action, primary_state_change_event_id) for action in automation.actions_on_trigger ] if TriggerState.Resolved in firing.trigger_states: + resolved_event = state_change_events[TriggerState.Resolved] source_actions += [ - (state_change_events[TriggerState.Resolved], action) + (resolved_event, action, primary_state_change_event_id) for action in automation.actions_on_resolve ] @@ -463,8 +479,13 @@ async def act(firing: Firing) -> None: triggering_event=action_triggering_event, action=action, action_index=index, + automation_triggered_event_id=automation_triggered_event_id, ) - for index, (action_triggering_event, action) in enumerate(source_actions) + for index, ( + action_triggering_event, + action, + automation_triggered_event_id, + ) in enumerate(source_actions) ] async with messaging.create_actions_publisher() as publisher: diff --git a/tests/events/server/actions/test_actions_service.py b/tests/events/server/actions/test_actions_service.py index 94dd0b7f115f..c26dd941f094 100644 --- a/tests/events/server/actions/test_actions_service.py +++ b/tests/events/server/actions/test_actions_service.py @@ -3,9 +3,16 @@ import pytest +from prefect._internal.uuid7 import uuid7 from prefect.server.events import actions from prefect.server.events.clients import AssertingEventsClient -from prefect.server.events.schemas.automations import TriggeredAction +from prefect.server.events.schemas.automations import ( + Automation, + Firing, + TriggeredAction, + TriggerState, +) +from prefect.server.events.schemas.events import ReceivedEvent from prefect.server.utilities.messaging import MessageHandler from prefect.server.utilities.messaging.memory import MemoryMessage from prefect.types import DateTime @@ -129,7 +136,13 @@ async def test_successes_emit_events( executed_event.resource["prefect.resource.name"] == "React immediately to spiders" ) - assert not executed_event.related + # Verify triggering-event related resource on executed event + assert len(executed_event.related) == 1 + assert ( + executed_event.related[0]["prefect.resource.id"] + == f"prefect.event.{email_me_when_that_dang_spider_comes.triggering_event.id}" + ) + assert executed_event.related[0]["prefect.resource.role"] == "triggering-event" assert executed_event.payload == { "action_index": 0, "action_type": "do-nothing", @@ -189,7 +202,13 @@ async def test_failures_emit_events( executed_event.resource["prefect.resource.name"] == "React immediately to spiders" ) - assert not executed_event.related + # Verify triggering-event related resource on failed event + assert len(executed_event.related) == 1 + assert ( + executed_event.related[0]["prefect.resource.id"] + == f"prefect.event.{email_me_when_that_dang_spider_comes.triggering_event.id}" + ) + assert executed_event.related[0]["prefect.resource.role"] == "triggering-event" assert executed_event.payload == { "action_index": 0, "action_type": "do-nothing", @@ -287,3 +306,248 @@ async def test_action_triggered_event_follows_triggering_event( # The action.executed event should still link to action.triggered assert executed_event.follows == triggered_event.id + + +async def test_success_events_include_automation_triggered_event_link( + message_handler: MessageHandler, + arachnophobia: Automation, + daddy_long_legs_walked: ReceivedEvent, +): + """ + When automation_triggered_event_id is set on a TriggeredAction, action events + should include a related resource linking to the automation.triggered event. + + This enables users to trace from automation.action.failed back to the + corresponding automation.triggered event. + """ + automation_triggered_id = uuid7() + + firing = Firing( + trigger=arachnophobia.trigger, + trigger_states={TriggerState.Triggered}, + triggered=now("UTC"), + triggering_labels={"hello": "world"}, + triggering_event=daddy_long_legs_walked, + ) + triggered_action = TriggeredAction( + automation=arachnophobia, + firing=firing, + triggered=firing.triggered, + triggering_labels=firing.triggering_labels, + triggering_event=firing.triggering_event, + action=arachnophobia.actions[0], + automation_triggered_event_id=automation_triggered_id, + ) + + await message_handler( + MemoryMessage( + data=triggered_action.model_dump_json().encode(), + attributes=None, + ) + ) + + assert AssertingEventsClient.last + (triggered_event, executed_event) = AssertingEventsClient.last.events + + # Verify automation-triggered-event related resource on action.triggered event + automation_triggered_related = next( + ( + r + for r in triggered_event.related + if r["prefect.resource.role"] == "automation-triggered-event" + ), + None, + ) + assert automation_triggered_related is not None + assert ( + automation_triggered_related["prefect.resource.id"] + == f"prefect.event.{automation_triggered_id}" + ) + + # The triggering-event related resource should still be present + triggering_event_related = next( + ( + r + for r in triggered_event.related + if r["prefect.resource.role"] == "triggering-event" + ), + None, + ) + assert triggering_event_related is not None + assert ( + triggering_event_related["prefect.resource.id"] + == f"prefect.event.{daddy_long_legs_walked.id}" + ) + + # Verify automation-triggered-event related resource on action.executed event + executed_automation_triggered_related = next( + ( + r + for r in executed_event.related + if r["prefect.resource.role"] == "automation-triggered-event" + ), + None, + ) + assert executed_automation_triggered_related is not None + assert ( + executed_automation_triggered_related["prefect.resource.id"] + == f"prefect.event.{automation_triggered_id}" + ) + + # Verify triggering-event related resource on action.executed event + executed_triggering_event_related = next( + ( + r + for r in executed_event.related + if r["prefect.resource.role"] == "triggering-event" + ), + None, + ) + assert executed_triggering_event_related is not None + assert ( + executed_triggering_event_related["prefect.resource.id"] + == f"prefect.event.{daddy_long_legs_walked.id}" + ) + + +async def test_failure_events_include_automation_triggered_event_link( + message_handler: MessageHandler, + act: mock.AsyncMock, + arachnophobia: Automation, + daddy_long_legs_walked: ReceivedEvent, +): + """ + When automation_triggered_event_id is set on a TriggeredAction and the action + fails, the action.triggered event should include a related resource linking to + the automation.triggered event. + """ + act.side_effect = actions.ActionFailed("something went wrong") + + automation_triggered_id = uuid7() + + firing = Firing( + trigger=arachnophobia.trigger, + trigger_states={TriggerState.Triggered}, + triggered=now("UTC"), + triggering_labels={"hello": "world"}, + triggering_event=daddy_long_legs_walked, + ) + triggered_action = TriggeredAction( + automation=arachnophobia, + firing=firing, + triggered=firing.triggered, + triggering_labels=firing.triggering_labels, + triggering_event=firing.triggering_event, + action=arachnophobia.actions[0], + automation_triggered_event_id=automation_triggered_id, + ) + + await message_handler( + MemoryMessage( + data=triggered_action.model_dump_json().encode(), + attributes=None, + ) + ) + + assert AssertingEventsClient.last + (triggered_event, failed_event) = AssertingEventsClient.last.events + + # Verify automation-triggered-event related resource on action.triggered event + automation_triggered_related = next( + ( + r + for r in triggered_event.related + if r["prefect.resource.role"] == "automation-triggered-event" + ), + None, + ) + assert automation_triggered_related is not None + assert ( + automation_triggered_related["prefect.resource.id"] + == f"prefect.event.{automation_triggered_id}" + ) + + # Verify the failed event is properly formed + assert failed_event.event == "prefect.automation.action.failed" + assert failed_event.payload["reason"] == "something went wrong" + + # Verify automation-triggered-event related resource on action.failed event + failed_automation_triggered_related = next( + ( + r + for r in failed_event.related + if r["prefect.resource.role"] == "automation-triggered-event" + ), + None, + ) + assert failed_automation_triggered_related is not None + assert ( + failed_automation_triggered_related["prefect.resource.id"] + == f"prefect.event.{automation_triggered_id}" + ) + + # Verify triggering-event related resource on action.failed event + failed_triggering_event_related = next( + ( + r + for r in failed_event.related + if r["prefect.resource.role"] == "triggering-event" + ), + None, + ) + assert failed_triggering_event_related is not None + assert ( + failed_triggering_event_related["prefect.resource.id"] + == f"prefect.event.{daddy_long_legs_walked.id}" + ) + + +async def test_action_events_without_automation_triggered_event_id( + message_handler: MessageHandler, + email_me_when_that_dang_spider_comes: TriggeredAction, +): + """ + When automation_triggered_event_id is None (the default), events should still + include the triggering-event related resource but no automation-triggered-event. + """ + # The default fixture doesn't set automation_triggered_event_id + assert email_me_when_that_dang_spider_comes.automation_triggered_event_id is None + + await message_handler( + MemoryMessage( + data=email_me_when_that_dang_spider_comes.model_dump_json().encode(), + attributes=None, + ) + ) + + assert AssertingEventsClient.last + (triggered_event, executed_event) = AssertingEventsClient.last.events + + # action.triggered should only have the triggering-event related resource + assert len(triggered_event.related) == 1 + assert triggered_event.related[0]["prefect.resource.role"] == "triggering-event" + + # No automation-triggered-event related resource on action.triggered + triggered_automation_related = next( + ( + r + for r in triggered_event.related + if r["prefect.resource.role"] == "automation-triggered-event" + ), + None, + ) + assert triggered_automation_related is None + + # action.executed should have triggering-event but no automation-triggered-event + assert len(executed_event.related) == 1 + assert executed_event.related[0]["prefect.resource.role"] == "triggering-event" + + executed_automation_related = next( + ( + r + for r in executed_event.related + if r["prefect.resource.role"] == "automation-triggered-event" + ), + None, + ) + assert executed_automation_related is None diff --git a/tests/events/server/actions/test_calling_webhook.py b/tests/events/server/actions/test_calling_webhook.py index 1b2d092968fb..408444463f0e 100644 --- a/tests/events/server/actions/test_calling_webhook.py +++ b/tests/events/server/actions/test_calling_webhook.py @@ -427,6 +427,12 @@ async def test_success_event( "prefect.resource.role": "block-type", } ), + RelatedResource.model_validate( + { + "prefect.resource.id": f"prefect.event.{call_webhook.triggering_event.id}", + "prefect.resource.role": "triggering-event", + } + ), ] assert executed_event.payload == { "action_index": 0, diff --git a/tests/events/server/actions/test_cancelling_flow_run.py b/tests/events/server/actions/test_cancelling_flow_run.py index 4121d43aef52..24e6bedc1df9 100644 --- a/tests/events/server/actions/test_cancelling_flow_run.py +++ b/tests/events/server/actions/test_cancelling_flow_run.py @@ -247,7 +247,13 @@ async def test_success_event( "prefect.resource.id": f"prefect.flow-run.{super_long_exposure.id}", "prefect.resource.role": "target", } - ) + ), + RelatedResource.model_validate( + { + "prefect.resource.id": f"prefect.event.{cancel_that_weird_exposure.triggering_event.id}", + "prefect.resource.role": "triggering-event", + } + ), ] assert executed_event.payload == { "action_index": 0, diff --git a/tests/events/server/actions/test_changing_flow_run_state.py b/tests/events/server/actions/test_changing_flow_run_state.py index bf3af3a225af..9c883ffe0c2b 100644 --- a/tests/events/server/actions/test_changing_flow_run_state.py +++ b/tests/events/server/actions/test_changing_flow_run_state.py @@ -319,7 +319,13 @@ async def test_success_event( "prefect.resource.id": f"prefect.flow-run.{super_long_exposure.id}", "prefect.resource.role": "target", } - ) + ), + RelatedResource.model_validate( + { + "prefect.resource.id": f"prefect.event.{crash_that_weird_exposure.triggering_event.id}", + "prefect.resource.role": "triggering-event", + } + ), ] assert executed_event.payload == { "action_index": 0, diff --git a/tests/events/server/actions/test_pausing_resuming_deployment.py b/tests/events/server/actions/test_pausing_resuming_deployment.py index 3629df9ac2bc..fffd2f99a8b1 100644 --- a/tests/events/server/actions/test_pausing_resuming_deployment.py +++ b/tests/events/server/actions/test_pausing_resuming_deployment.py @@ -489,7 +489,13 @@ async def test_pausing_success_event( "prefect.resource.id": f"prefect.deployment.{hourly_garden_patrol.id}", "prefect.resource.role": "target", } - ) + ), + RelatedResource.model_validate( + { + "prefect.resource.id": f"prefect.event.{pause_their_deployment.triggering_event.id}", + "prefect.resource.role": "triggering-event", + } + ), ] assert executed_event.payload == { "action_index": 0, @@ -540,7 +546,13 @@ async def test_resuming_success_event( "prefect.resource.id": f"prefect.deployment.{hourly_garden_patrol.id}", "prefect.resource.role": "target", } - ) + ), + RelatedResource.model_validate( + { + "prefect.resource.id": f"prefect.event.{resume_their_deployment.triggering_event.id}", + "prefect.resource.role": "triggering-event", + } + ), ] assert executed_event.payload == { "action_index": 0, diff --git a/tests/events/server/actions/test_pausing_resuming_work_pool.py b/tests/events/server/actions/test_pausing_resuming_work_pool.py index bbf56aa8030a..003d3fc51437 100644 --- a/tests/events/server/actions/test_pausing_resuming_work_pool.py +++ b/tests/events/server/actions/test_pausing_resuming_work_pool.py @@ -303,7 +303,13 @@ async def test_pausing_publishes_success_event( "prefect.resource.name": work_pool.name, "prefect.resource.role": "target", } - ) + ), + RelatedResource.model_validate( + { + "prefect.resource.id": f"prefect.event.{triggered_pause_action.triggering_event.id}", + "prefect.resource.role": "triggering-event", + } + ), ] assert executed_event.payload == { "action_index": 0, @@ -544,7 +550,13 @@ async def test_resuming_publishes_success_event( "prefect.resource.name": paused_work_pool.name, "prefect.resource.role": "target", } - ) + ), + RelatedResource.model_validate( + { + "prefect.resource.id": f"prefect.event.{triggered_resume_action.triggering_event.id}", + "prefect.resource.role": "triggering-event", + } + ), ] assert executed_event.payload == { "action_index": 0, diff --git a/tests/events/server/actions/test_pausing_resuming_work_queue.py b/tests/events/server/actions/test_pausing_resuming_work_queue.py index 1675ae8fb26d..0b6643db0538 100644 --- a/tests/events/server/actions/test_pausing_resuming_work_queue.py +++ b/tests/events/server/actions/test_pausing_resuming_work_queue.py @@ -465,7 +465,13 @@ async def test_pausing_success_event( "prefect.resource.id": f"prefect.work-queue.{patrols_queue.id}", "prefect.resource.role": "target", } - ) + ), + RelatedResource.model_validate( + { + "prefect.resource.id": f"prefect.event.{pause_related_patrols.triggering_event.id}", + "prefect.resource.role": "triggering-event", + } + ), ] assert executed_event.payload == { "action_index": 0, @@ -516,7 +522,13 @@ async def test_resuming_success_event( "prefect.resource.id": f"prefect.work-queue.{patrols_queue.id}", "prefect.resource.role": "target", } - ) + ), + RelatedResource.model_validate( + { + "prefect.resource.id": f"prefect.event.{resume_the_associated_queue.triggering_event.id}", + "prefect.resource.role": "triggering-event", + } + ), ] assert executed_event.payload == { "action_index": 0, diff --git a/tests/events/server/actions/test_resuming_flow_run.py b/tests/events/server/actions/test_resuming_flow_run.py index 9d2dd7702cd8..7e6d025009ae 100644 --- a/tests/events/server/actions/test_resuming_flow_run.py +++ b/tests/events/server/actions/test_resuming_flow_run.py @@ -161,7 +161,13 @@ async def test_resume_flow_run_success_event( "prefect.resource.id": f"prefect.flow-run.{paused_flow_run.id}", "prefect.resource.role": "target", } - ) + ), + RelatedResource.model_validate( + { + "prefect.resource.id": f"prefect.event.{resume_that_paused_flow_run.triggering_event.id}", + "prefect.resource.role": "triggering-event", + } + ), ] assert executed_event.payload == { "action_index": 0, diff --git a/tests/events/server/actions/test_running_deployment.py b/tests/events/server/actions/test_running_deployment.py index 66173f57e9d7..cd3910e27af5 100644 --- a/tests/events/server/actions/test_running_deployment.py +++ b/tests/events/server/actions/test_running_deployment.py @@ -519,6 +519,12 @@ async def test_success_event( "prefect.resource.role": "flow-run", } ), + RelatedResource.model_validate( + { + "prefect.resource.id": f"prefect.event.{snap_that_naughty_woodchuck.triggering_event.id}", + "prefect.resource.role": "triggering-event", + } + ), ] assert executed_event.payload == { "action_index": 0, diff --git a/tests/events/server/actions/test_sending_notification.py b/tests/events/server/actions/test_sending_notification.py index 6637075b7b50..425be19b7675 100644 --- a/tests/events/server/actions/test_sending_notification.py +++ b/tests/events/server/actions/test_sending_notification.py @@ -276,6 +276,12 @@ async def test_success_event( "prefect.resource.role": "block-type", } ), + RelatedResource.model_validate( + { + "prefect.resource.id": f"prefect.event.{notify_me.triggering_event.id}", + "prefect.resource.role": "triggering-event", + } + ), ] assert executed_event.payload == { "action_index": 0, @@ -348,6 +354,12 @@ async def test_captures_notification_failures( "prefect.resource.role": "block-type", } ), + RelatedResource.model_validate( + { + "prefect.resource.id": f"prefect.event.{notify_me.triggering_event.id}", + "prefect.resource.role": "triggering-event", + } + ), ] assert failed_event.payload == { "action_index": 0, diff --git a/tests/events/server/actions/test_suspending_flow_run.py b/tests/events/server/actions/test_suspending_flow_run.py index 61ef3892daa8..06c150c59a76 100644 --- a/tests/events/server/actions/test_suspending_flow_run.py +++ b/tests/events/server/actions/test_suspending_flow_run.py @@ -243,7 +243,13 @@ async def test_success_event( "prefect.resource.id": f"prefect.flow-run.{super_long_exposure.id}", "prefect.resource.role": "target", } - ) + ), + RelatedResource.model_validate( + { + "prefect.resource.id": f"prefect.event.{suspend_that_weird_exposure.triggering_event.id}", + "prefect.resource.role": "triggering-event", + } + ), ] assert executed_event.payload == { "action_index": 0, diff --git a/tests/events/server/triggers/test_service.py b/tests/events/server/triggers/test_service.py index 46b5c58f7abe..0a7f23915173 100644 --- a/tests/events/server/triggers/test_service.py +++ b/tests/events/server/triggers/test_service.py @@ -57,6 +57,7 @@ async def test_acting_publishes_an_action_message_from_a_reactive_event( triggering_event=daddy_long_legs_walked, action=actions.DoNothing(), id=parsed.id, + automation_triggered_event_id=parsed.automation_triggered_event_id, ) @@ -90,6 +91,7 @@ async def test_acting_publishes_an_action_message_from_a_proactive_trigger( triggering_event=None, action=actions.DoNothing(), id=parsed.id, + automation_triggered_event_id=parsed.automation_triggered_event_id, )