Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 10 additions & 12 deletions src/sentry/integrations/discord/message_builder/issues.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import annotations

from sentry import features, tagstore
from sentry import tagstore
from sentry.integrations.discord.message_builder import LEVEL_TO_COLOR
from sentry.integrations.discord.message_builder.base.base import (
DiscordMessage,
Expand All @@ -24,9 +24,8 @@
from sentry.models.group import Group, GroupStatus
from sentry.models.project import Project
from sentry.models.rule import Rule
from sentry.notifications.notification_action.utils import should_fire_workflow_actions
from sentry.notifications.notifications.base import ProjectNotification
from sentry.notifications.utils.rules import get_key_from_rule_data
from sentry.notifications.utils.rules import get_rule_or_workflow_id
from sentry.services.eventstore.models import GroupEvent

from ..message_builder.base.component import DiscordComponentCustomIds as CustomIds
Expand Down Expand Up @@ -60,26 +59,25 @@ def build(self, notification_uuid: str | None = None) -> DiscordMessage:
obj: Group | GroupEvent = self.event if self.event is not None else self.group
rule_id = None
rule_environment_id = None
key = "legacy_rule_id"
if self.rules:
rule_environment_id = self.rules[0].environment_id
if features.has("organizations:workflow-engine-ui-links", self.group.organization):
rule_id = int(get_key_from_rule_data(self.rules[0], "workflow_id"))
elif should_fire_workflow_actions(self.group.organization, self.group.type):
rule_id = int(get_key_from_rule_data(self.rules[0], "legacy_rule_id"))
else:
rule_id = self.rules[0].id
try:
key, rule_id = get_rule_or_workflow_id(self.rules[0])
except AssertionError:
rule_id = str(self.rules[0].id)

url = None

if features.has("organizations:workflow-engine-ui-links", self.group.organization):
if key == "workflow_id":
url = get_title_link_workflow_engine_ui(
self.group,
self.event,
self.link_to_event,
self.issue_details,
self.notification,
ExternalProviders.DISCORD,
rule_id,
int(rule_id) if rule_id else None,
rule_environment_id,
notification_uuid=notification_uuid,
)
Expand All @@ -91,7 +89,7 @@ def build(self, notification_uuid: str | None = None) -> DiscordMessage:
self.issue_details,
self.notification,
ExternalProviders.DISCORD,
rule_id,
int(rule_id) if rule_id else None,
rule_environment_id,
notification_uuid=notification_uuid,
)
Expand Down
11 changes: 4 additions & 7 deletions src/sentry/integrations/messaging/message_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from sentry.notifications.notifications.base import BaseNotification
from sentry.notifications.notifications.rules import AlertRuleNotification
from sentry.notifications.utils.links import create_link_to_workflow
from sentry.notifications.utils.rules import get_key_from_rule_data
from sentry.notifications.utils.rules import get_key_from_rule_data, get_rule_or_workflow_id
from sentry.services.eventstore.models import Event, GroupEvent
from sentry.users.services.user import RpcUser
from sentry.utils.http import absolute_uri
Expand Down Expand Up @@ -291,12 +291,9 @@ def build_footer(
) -> str:
footer = f"{group.qualified_short_id}"
if rules:
if features.has("organizations:workflow-engine-ui-links", group.organization):
rule_url = absolute_uri(
create_link_to_workflow(
group.organization.id, get_key_from_rule_data(rules[0], "workflow_id")
)
)
key, value = get_rule_or_workflow_id(rules[0])
if key == "workflow_id":
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is where variant types would be nice..

it could be like

match get_rule_or_workflow_id(rules[0]):
     case WorkflowId(value):
           rule_url = ..
     case LegacyRuleId(_):
           rule_url = build_rule_url(...)

rule_url = absolute_uri(create_link_to_workflow(group.organization.id, value))
else:
rule_url = build_rule_url(rules[0], group, project)

Expand Down
38 changes: 24 additions & 14 deletions src/sentry/integrations/opsgenie/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

from typing import Literal

from sentry import features
from sentry.integrations.client import ApiClient
from sentry.integrations.models.integration import Integration
from sentry.integrations.on_call.metrics import OnCallInteractionType
Expand All @@ -12,7 +11,7 @@
from sentry.models.group import Group
from sentry.notifications.notification_action.utils import should_fire_workflow_actions
from sentry.notifications.utils.links import create_link_to_workflow
from sentry.notifications.utils.rules import get_key_from_rule_data
from sentry.notifications.utils.rules import get_key_from_rule_data, split_rules_by_rule_workflow_id
from sentry.services.eventstore.models import Event, GroupEvent
from sentry.shared_integrations.exceptions import ApiError

Expand Down Expand Up @@ -91,19 +90,30 @@ def build_issue_alert_payload(
group_params = {"referrer": IntegrationProviderSlug.OPSGENIE.value}
if notification_uuid:
group_params["notification_uuid"] = notification_uuid

rules_and_workflows = split_rules_by_rule_workflow_id(rules)
workflow_urls = self._get_workflow_urls(group, rules_and_workflows.workflow_rules)
rule_urls = self._get_rule_urls(group, rules_and_workflows.rules)
rule_workflow_context = {}
if features.has("organizations:workflow-engine-ui-links", group.project.organization):
workflow_urls = self._get_workflow_urls(group, rules)
rule_workflow_context = {
"Triggering Workflows": ", ".join([rule.label for rule in rules]),
"Triggering Workflow URLs": "\n".join(workflow_urls),
}
else:
rule_urls = self._get_rule_urls(group, rules)
rule_workflow_context = {
"Triggering Rules": ", ".join([rule.label for rule in rules]),
"Triggering Rule URLs": "\n".join(rule_urls),
}
if rule_urls:
rule_workflow_context.update(
{
"Triggering Rules": ", ".join(
[rule.label for rule in rules_and_workflows.rules]
),
"Triggering Rule URLs": "\n".join(rule_urls),
}
)
if workflow_urls:
rule_workflow_context.update(
{
"Triggering Workflows": ", ".join(
[workflow.label for workflow in rules_and_workflows.workflow_rules]
),
"Triggering Workflow URLs": "\n".join(workflow_urls),
}
)

payload["details"] = {
"Sentry ID": str(group.id),
"Sentry Group": getattr(group, "title", group.message).encode("utf-8"),
Expand Down
27 changes: 15 additions & 12 deletions src/sentry/integrations/slack/message_builder/issues.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@
from sentry.models.repository import Repository
from sentry.models.rule import Rule
from sentry.models.team import Team
from sentry.notifications.notification_action.utils import should_fire_workflow_actions
from sentry.notifications.notifications.base import ProjectNotification
from sentry.notifications.platform.slack.renderers.seer import SeerSlackRenderer
from sentry.notifications.platform.templates.seer import SeerAutofixTrigger
Expand All @@ -64,7 +63,7 @@
dedupe_suggested_assignees,
get_suspect_commit_users,
)
from sentry.notifications.utils.rules import get_key_from_rule_data
from sentry.notifications.utils.rules import get_rule_or_workflow_id
from sentry.services.eventstore.models import Event, GroupEvent
from sentry.snuba.referrer import Referrer
from sentry.types.actor import Actor
Expand Down Expand Up @@ -669,18 +668,22 @@ def build(self, notification_uuid: str | None = None) -> SlackBlock:

rule_id = None
rule_environment_id = None
key = "legacy_rule_id"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe 'rule_id_type'? "key" is pretty vague.

if self.rules:
if features.has("organizations:workflow-engine-ui-links", self.group.organization):
rule_id = int(get_key_from_rule_data(self.rules[0], "workflow_id"))
workflow = Workflow.objects.filter(id=rule_id).first()
rule_environment_id = workflow.environment_id if workflow else None
elif should_fire_workflow_actions(self.group.organization, self.group.type):
rule_id = int(get_key_from_rule_data(self.rules[0], "legacy_rule_id"))
rule = Rule.objects.filter(id=rule_id).first()
rule_environment_id = rule.environment_id if rule else None
else:
try:
key, value = get_rule_or_workflow_id(self.rules[0])
except AssertionError:
rule_id = self.rules[0].id
rule_environment_id = self.rules[0].environment_id
else:
if key == "workflow_id":
rule_id = int(value)
workflow = Workflow.objects.filter(id=rule_id).first()
rule_environment_id = workflow.environment_id if workflow else None
else:
rule_id = int(value)
rule = Rule.objects.filter(id=rule_id).first()
rule_environment_id = rule.environment_id if rule else None

# build up actions text
if self.actions and self.identity and not action_text:
Expand All @@ -689,7 +692,7 @@ def build(self, notification_uuid: str | None = None) -> SlackBlock:
has_action = True

title_link = None
if features.has("organizations:workflow-engine-ui-links", self.group.organization):
if key == "workflow_id":
title_link = get_title_link_workflow_engine_ui(
self.group,
self.event,
Expand Down
14 changes: 5 additions & 9 deletions src/sentry/integrations/slack/message_builder/util.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
from collections.abc import Sequence

from sentry import features
from sentry.integrations.messaging.message_builder import build_rule_url
from sentry.integrations.slack.message_builder.types import SLACK_URL_FORMAT
from sentry.models.group import Group
from sentry.models.project import Project
from sentry.models.rule import Rule
from sentry.notifications.utils.links import create_link_to_workflow
from sentry.notifications.utils.rules import get_key_from_rule_data
from sentry.notifications.utils.rules import get_rule_or_workflow_id
from sentry.utils.http import absolute_uri


Expand All @@ -19,14 +18,11 @@ def build_slack_footer(
footer = f"{group.qualified_short_id}"

if rules:
if features.has("organizations:workflow-engine-ui-links", group.organization):
rule_url = absolute_uri(
create_link_to_workflow(
group.organization.id, get_key_from_rule_data(rules[0], "workflow_id")
)
)
else:
key, value = get_rule_or_workflow_id(rules[0])
if key == "legacy_rule_id":
rule_url = build_rule_url(rules[0], group, project)
else:
rule_url = absolute_uri(create_link_to_workflow(group.organization.id, value))
# If this notification is triggered via the "Send Test Notification"
# button then the label is not defined, but the url works.
text = rules[0].label if rules[0].label else "Test Alert"
Expand Down
5 changes: 5 additions & 0 deletions src/sentry/notifications/utils/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,9 @@ def get_rule_or_workflow_id(rule: Rule) -> tuple[str, str]:
try:
return ("legacy_rule_id", get_key_from_rule_data(rule, "legacy_rule_id"))
except AssertionError:
pass

try:
return ("workflow_id", get_key_from_rule_data(rule, "workflow_id"))
except AssertionError:
return ("legacy_rule_id", str(rule.id))
7 changes: 3 additions & 4 deletions src/sentry/rules/actions/integrations/create_ticket/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

from rest_framework.response import Response

from sentry import features
from sentry.constants import ObjectStatus
from sentry.exceptions import InvalidIdentity
from sentry.integrations.base import IntegrationInstallation
Expand Down Expand Up @@ -143,9 +142,9 @@ def create_issue(event: GroupEvent, futures: Sequence[RuleFuture]) -> None:
installation, IssueBasicIntegration
), "Installation must be an IssueBasicIntegration to create a ticket"
data["title"] = installation.get_group_title(event.group, event)
if features.has("organizations:workflow-engine-ui-links", organization):
workflow_id = data.get("workflow_id")
assert workflow_id is not None

workflow_id = data.get("workflow_id")
if workflow_id is not None:
data["description"] = build_description_workflow_engine_ui(
event, workflow_id, installation, generate_footer
)
Expand Down
16 changes: 7 additions & 9 deletions src/sentry/sentry_apps/tasks/sentry_apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from requests import HTTPError, Timeout
from requests.exceptions import ChunkedEncodingError, ConnectionError, RequestException

from sentry import analytics, features, nodestore
from sentry import analytics, nodestore
from sentry.analytics.events.alert_rule_ui_component_webhook_sent import (
AlertRuleUiComponentWebhookSentEvent,
)
Expand Down Expand Up @@ -40,7 +40,7 @@
from sentry.models.organization import Organization
from sentry.models.organizationmapping import OrganizationMapping
from sentry.models.project import Project
from sentry.notifications.utils.rules import get_key_from_rule_data
from sentry.notifications.utils.rules import get_rule_or_workflow_id
from sentry.sentry_apps.api.serializers.app_platform_event import AppPlatformEvent
from sentry.sentry_apps.metrics import (
SentryAppEventType,
Expand Down Expand Up @@ -720,8 +720,6 @@ def send_resource_change_webhook(


def notify_sentry_app(event: GroupEvent, futures: Sequence[RuleFuture]):
from sentry.notifications.notification_action.utils import should_fire_workflow_actions

for f in futures:
if not f.kwargs.get("sentry_app"):
logger.info(
Expand All @@ -742,16 +740,16 @@ def notify_sentry_app(event: GroupEvent, futures: Sequence[RuleFuture]):
# if we are using the new workflow engine, we need to use the legacy rule id
# Ignore test notifications
if int(id) != -1:
if features.has("organizations:workflow-engine-ui-links", event.group.organization):
id = get_key_from_rule_data(f.rule, "workflow_id")
elif should_fire_workflow_actions(event.group.organization, event.group.type):
id = get_key_from_rule_data(f.rule, "legacy_rule_id")
try:
_, id = get_rule_or_workflow_id(f.rule)
except AssertionError:
pass

settings = f.kwargs.get("schema_defined_settings")
if settings:
extra_kwargs["additional_payload_key"] = "issue_alert"
extra_kwargs["additional_payload"] = {
"id": id,
"id": int(id),
"title": f.rule.label,
"sentry_app_id": f.kwargs["sentry_app"].id,
"settings": settings,
Expand Down
2 changes: 1 addition & 1 deletion tests/sentry/sentry_apps/tasks/test_sentry_apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ def test_send_alert_event_with_additional_payload_legacy_rule_id(
assert payload["data"]["triggered_rule"] == rule.label
assert payload["data"]["issue_alert"] == {
# Use the legacy rule id
"id": "123",
"id": 123,
"title": rule.label,
"sentry_app_id": self.sentry_app.id,
"settings": settings,
Expand Down
Loading